21 commits - c++/autogen.sh c++/CMakeLists.txt c++/compiled c++/.gitignore c++/lib c++/Makefile.am cmake/modules c++/README c++/tests .gitignore libkolab/akonadi-version.h.cmake libkolab/calendaring libkolab/CMakeLists.txt libkolab/conversion libkolab/kolab_export.h libkolab/kolabformat libkolab/kolabformatV2 libkolab/mime libkolab/tests libkolabxml/autogen.sh libkolabxml/CMakeLists.txt libkolabxml/compiled libkolabxml/.gitignore libkolabxml/lib libkolabxml/Makefile.am libkolabxml/README libkolabxml/tests upgradetool/CMakeLists.txt upgradetool/upgradetool.cpp upgradetool/upgradetooltests.cpp upgradetool/upgradetooltests.h upgradetool/upgradeutilities.cpp upgradetool/upgradeutilities.h

Christian Mollekopf mollekopf at kolabsys.com
Fri Mar 23 16:16:17 CET 2012


 .gitignore                                       |    3 
 c++/.gitignore                                   |    1 
 c++/CMakeLists.txt                               |  136 -
 c++/Makefile.am                                  |   41 
 c++/README                                       |   22 
 c++/autogen.sh                                   |    9 
 c++/compiled/README                              |   20 
 c++/compiled/XMLParserWrapper.cpp                |  295 ---
 c++/compiled/XMLParserWrapper.h                  |   89 -
 c++/compiled/grammar-input-stream.cxx            |  115 -
 c++/compiled/grammar-input-stream.hxx            |   53 
 c++/compiled/xsdbin.cxx                          |  505 ------
 c++/lib/CMakeLists.txt                           |   72 
 c++/lib/DEVELOPMENT                              |  104 -
 c++/lib/base64.cpp                               |  123 -
 c++/lib/base64.h                                 |    5 
 c++/lib/calendaring.cpp                          |   54 
 c++/lib/calendaring.h                            |   35 
 c++/lib/global_definitions.h                     |   37 
 c++/lib/incidence_p.h                            |   65 
 c++/lib/kolabcontact.cpp                         |  495 ------
 c++/lib/kolabcontact.h                           |  380 -----
 c++/lib/kolabcontainers.cpp                      |  729 ---------
 c++/lib/kolabcontainers.h                        |  400 -----
 c++/lib/kolabconversions.h                       |  189 --
 c++/lib/kolabevent.cpp                           |  338 ----
 c++/lib/kolabevent.h                             |  124 -
 c++/lib/kolabformat.cpp                          |  163 --
 c++/lib/kolabformat.h                            |   84 -
 c++/lib/kolabformat.i                            |   42 
 c++/lib/kolabjournal.cpp                         |  191 --
 c++/lib/kolabjournal.h                           |   87 -
 c++/lib/kolabkcalconversion.cpp                  |  746 ----------
 c++/lib/kolabkcalconversion.h                    |   51 
 c++/lib/kolabnote.cpp                            |  185 --
 c++/lib/kolabnote.h                              |   75 -
 c++/lib/kolabtodo.cpp                            |  327 ----
 c++/lib/kolabtodo.h                              |  122 -
 c++/lib/php/CMakeLists.txt                       |   36 
 c++/lib/php/test.php                             |  162 --
 c++/lib/python/CMakeLists.txt                    |   34 
 c++/lib/python/test.py                           |   16 
 c++/lib/shared_conversions.h                     |  122 -
 c++/lib/uricode.h                                |  122 -
 c++/lib/utils.cpp                                |  232 ---
 c++/lib/utils.h                                  |  122 -
 c++/lib/xcalconversions.h                        | 1709 -----------------------
 c++/lib/xcardconversions.h                       | 1100 --------------
 c++/tests/CMakeLists.txt                         |   21 
 c++/tests/bindingstest.cpp                       |  568 -------
 c++/tests/bindingstest.h                         |   44 
 c++/tests/conversiontest.cpp                     |  268 ---
 c++/tests/conversiontest.h                       |   45 
 c++/tests/kcalconversiontest.cpp                 |  707 ---------
 c++/tests/kcalconversiontest.h                   |   38 
 c++/tests/serializers.h                          |  218 --
 c++/tests/testfiles/icalEvent.xml                |   92 -
 c++/tests/testfiles/testevent.xml                |   26 
 c++/tests/testfiles/testkolabevent.xml           |   29 
 cmake/modules/FindKDELibraries.cmake             |   30 
 cmake/modules/FindKolabInternal.cmake            |   51 
 libkolab/CMakeLists.txt                          |   47 
 libkolab/akonadi-version.h.cmake                 |   25 
 libkolab/calendaring/calendaring.cpp             |   54 
 libkolab/calendaring/calendaring.h               |   35 
 libkolab/calendaring/calendaring.i               |   24 
 libkolab/conversion/CMakeLists.txt               |   32 
 libkolab/conversion/kcalconversion.cpp           |  746 ++++++++++
 libkolab/conversion/kcalconversion.h             |   53 
 libkolab/conversion/tests/CMakeLists.txt         |   10 
 libkolab/conversion/tests/kcalconversiontest.cpp |  714 +++++++++
 libkolab/conversion/tests/kcalconversiontest.h   |   38 
 libkolab/kolab_export.h                          |   50 
 libkolab/kolabformat/CMakeLists.txt              |    1 
 libkolab/kolabformat/kolabobject.cpp             |  447 ++++++
 libkolab/kolabformat/kolabobject.h               |   95 +
 libkolab/kolabformatV2/CMakeLists.txt            |   37 
 libkolab/kolabformatV2/contact.cpp               |    6 
 libkolab/kolabformatV2/contact.h                 |    6 
 libkolab/kolabformatV2/distributionlist.cpp      |    4 
 libkolab/kolabformatV2/distributionlist.h        |    6 
 libkolab/kolabformatV2/event.cpp                 |    2 
 libkolab/kolabformatV2/event.h                   |    6 
 libkolab/kolabformatV2/incidence.cpp             |    2 
 libkolab/kolabformatV2/incidence.h               |    6 
 libkolab/kolabformatV2/journal.cpp               |    2 
 libkolab/kolabformatV2/journal.h                 |    8 
 libkolab/kolabformatV2/kolabbase.cpp             |    2 
 libkolab/kolabformatV2/kolabbase.h               |   10 
 libkolab/kolabformatV2/note.cpp                  |    2 
 libkolab/kolabformatV2/note.h                    |    8 
 libkolab/kolabformatV2/task.cpp                  |    2 
 libkolab/kolabformatV2/task.h                    |    8 
 libkolab/mime/mimeutils.cpp                      |  200 ++
 libkolab/mime/mimeutils.h                        |   64 
 libkolab/tests/CMakeLists.txt                    |    9 
 libkolab/tests/benchmark.cpp                     |   90 +
 libkolab/tests/benchmark.h                       |   35 
 libkolabxml/.gitignore                           |    1 
 libkolabxml/CMakeLists.txt                       |  129 +
 libkolabxml/Makefile.am                          |   41 
 libkolabxml/README                               |   22 
 libkolabxml/autogen.sh                           |    9 
 libkolabxml/compiled/README                      |   20 
 libkolabxml/compiled/XMLParserWrapper.cpp        |  295 +++
 libkolabxml/compiled/XMLParserWrapper.h          |   89 +
 libkolabxml/compiled/grammar-input-stream.cxx    |  115 +
 libkolabxml/compiled/grammar-input-stream.hxx    |   53 
 libkolabxml/compiled/xsdbin.cxx                  |  505 ++++++
 libkolabxml/lib/CMakeLists.txt                   |   52 
 libkolabxml/lib/DEVELOPMENT                      |  104 +
 libkolabxml/lib/base64.cpp                       |  123 +
 libkolabxml/lib/base64.h                         |    5 
 libkolabxml/lib/global_definitions.h             |   37 
 libkolabxml/lib/incidence_p.h                    |   65 
 libkolabxml/lib/kolabcontact.cpp                 |  495 ++++++
 libkolabxml/lib/kolabcontact.h                   |  380 +++++
 libkolabxml/lib/kolabcontainers.cpp              |  729 +++++++++
 libkolabxml/lib/kolabcontainers.h                |  400 +++++
 libkolabxml/lib/kolabconversions.h               |  181 ++
 libkolabxml/lib/kolabevent.cpp                   |  338 ++++
 libkolabxml/lib/kolabevent.h                     |  124 +
 libkolabxml/lib/kolabformat.cpp                  |  163 ++
 libkolabxml/lib/kolabformat.h                    |   84 +
 libkolabxml/lib/kolabformat.i                    |   42 
 libkolabxml/lib/kolabjournal.cpp                 |  191 ++
 libkolabxml/lib/kolabjournal.h                   |   87 +
 libkolabxml/lib/kolabnote.cpp                    |  185 ++
 libkolabxml/lib/kolabnote.h                      |   75 +
 libkolabxml/lib/kolabtodo.cpp                    |  327 ++++
 libkolabxml/lib/kolabtodo.h                      |  122 +
 libkolabxml/lib/php/CMakeLists.txt               |   36 
 libkolabxml/lib/php/test.php                     |  162 ++
 libkolabxml/lib/python/CMakeLists.txt            |   34 
 libkolabxml/lib/python/test.py                   |   16 
 libkolabxml/lib/shared_conversions.h             |  122 +
 libkolabxml/lib/uricode.h                        |  122 +
 libkolabxml/lib/utils.cpp                        |  248 +++
 libkolabxml/lib/utils.h                          |  122 +
 libkolabxml/lib/xcalconversions.h                | 1701 ++++++++++++++++++++++
 libkolabxml/lib/xcardconversions.h               | 1092 ++++++++++++++
 libkolabxml/tests/CMakeLists.txt                 |   17 
 libkolabxml/tests/bindingstest.cpp               |  560 +++++++
 libkolabxml/tests/bindingstest.h                 |   43 
 libkolabxml/tests/conversiontest.cpp             |  275 +++
 libkolabxml/tests/conversiontest.h               |   47 
 libkolabxml/tests/serializers.h                  |  218 ++
 libkolabxml/tests/testfiles/icalEvent.xml        |   92 +
 libkolabxml/tests/testfiles/testevent.xml        |   26 
 libkolabxml/tests/testfiles/testkolabevent.xml   |   29 
 upgradetool/CMakeLists.txt                       |   29 
 upgradetool/upgradetool.cpp                      |   74 
 upgradetool/upgradetooltests.cpp                 |   18 
 upgradetool/upgradetooltests.h                   |   18 
 upgradetool/upgradeutilities.cpp                 |   77 +
 upgradetool/upgradeutilities.h                   |   39 
 156 files changed, 13734 insertions(+), 12261 deletions(-)

New commits:
commit 26fa82fd370e0426f0ae83105954f0d1e64fc3e7
Merge: 6fec1ed 2eb51d1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 16:15:05 2012 +0100

    Merge branch 'dev/upgrade-migration'
    
    Conflicts:
    	libkolabxml/CMakeLists.txt
    	libkolabxml/lib/kolabconversions.h
    	libkolabxml/lib/xcalconversions.h
    	libkolabxml/lib/xcardconversions.h

diff --cc cmake/modules/FindKDELibraries.cmake
index 0000000,6d81cc6..6edf4dd
mode 000000,100644..100644
--- a/cmake/modules/FindKDELibraries.cmake
+++ b/cmake/modules/FindKDELibraries.cmake
@@@ -1,0 -1,30 +1,30 @@@
+ #Find some libraries
 -find_library(KCALCORE_LIBRARY NAMES kcalcore)
++find_library(KCALCORE_LIBRARY NAMES kcalcore PATH_SUFFIXES kde4/devel)
+ if(KCALCORE_LIBRARY)
+     set(KCALCORE_LIBRARY_FOUND ON)
+     message("KCalCore found: ${KCALCORE_LIBRARY}")
+ endif(KCALCORE_LIBRARY)
+ 
+ find_library(KMIME_LIBRARY NAMES kmime)
+ if(KMIME_LIBRARY)
+     set(KMIME_LIBRARY_FOUND ON)
+     message("KMime found: ${KMIME_LIBRARY}")
+ endif(KMIME_LIBRARY)
+ 
+ find_library(KABC_LIBRARY NAMES kabc)
+ if(KABC_LIBRARY)
+     set(KABC_LIBRARY_FOUND ON)
+     message("KABC found: ${KABC_LIBRARY}")
+ endif(KABC_LIBRARY)
+ 
+ find_library(AKONADI-KDE_LIBRARY NAMES akonadi-kde)
+ if(AKONADI-KDE_LIBRARY)
+     set(AKONADI-KDE_LIBRARY_FOUND ON)
+     message("AKONADI-KDE found: ${AKONADI-KDE_LIBRARY}")
+ endif(AKONADI-KDE_LIBRARY)
+ 
+ find_library(AKONADI-NOTES_LIBRARY NAMES akonadi-notes)
+ if(AKONADI-NOTES_LIBRARY)
+     set(AKONADI-NOTES_LIBRARY_FOUND ON)
+     message("AKONADI-NOTES found: ${AKONADI-NOTES_LIBRARY}")
+ endif(AKONADI-NOTES_LIBRARY)
diff --cc libkolabxml/CMakeLists.txt
index 0000000,c76f992..ae8b503
mode 000000,100644..100644
--- a/libkolabxml/CMakeLists.txt
+++ b/libkolabxml/CMakeLists.txt
@@@ -1,0 -1,127 +1,129 @@@
+ project(kolabxmlbindings)
+ 
+ cmake_minimum_required(VERSION 2.6)
+ 
+ # only available from cmake-2.8.0
+ if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7)
+     cmake_policy(SET CMP0012 NEW)
+ endif()
+ 
+ # only available from cmake-2.8.4
+ if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND
+     ${CMAKE_PATCH_VERSION} GREATER 3)
+     cmake_policy(SET CMP0017 NEW)
+ endif()
+ 
++# Do not use RPATH
++set(CMAKE_SKIP_RPATH ON)
+ include( ../cmake/modules/FindKolabInternal.cmake )
+ 
+ find_package(Boost COMPONENTS thread REQUIRED)
+ 
+ if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
+     find_library(UUID NAMES uuid)
+     if(UUID)
+         message("uuid found")
+     else (UUID)
+         message(FATAL_ERROR "uuid NOT found!")
+     endif(UUID)
+ endif()
+ 
+ find_package(Qt4)
+ find_program( XSDCXX xsdcxx /usr/bin/)
+ if(XSDCXX)
+     message("xsd code generator found")
+ else (XSDCXX)
+     message(FATAL_ERROR
+     "xsd code generator NOT found!")
+ endif(XSDCXX)
+ 
+ find_library(XERCES_C NAMES xerces-c xerces-c_2)
+ if(XERCES_C)
+     message("xerces found")
+ else (XERCES_C)
+     message(FATAL_ERROR
+     "xerces NOT found!")
+ endif(XERCES_C)
+ 
+ find_program(SWIG swig /usr/bin/)
+ if(SWIG)
+     set(SWIG_FOUND ON)
+     message("SWIG found")
+ endif(SWIG)
+ 
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
+ 
+ # set( CMAKE_VERBOSE_MAKEFILE on )
+ 
+ set(CMAKE_BUILD_TYPE Debug)
+ 
+ set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
+ file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
+ 
+ set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
+ 
+ # Generate bindings
+ 
+ set( SCHEMAS
+     ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd
+     ${SCHEMA_DIR}/ical/iCalendar-params.xsd
+     ${SCHEMA_DIR}/ical/iCalendar-props.xsd
+     ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+     ${SCHEMA_DIR}/xCard.xsd
+     ${SCHEMA_DIR}/kolabformat-xcard.xsd
+     ${SCHEMA_DIR}/kolabformat.xsd
+ )
+ 
+ set( SCHEMA_SOURCEFILES  
+     ${CMAKE_BUILD_DIR}/bindings/kolabformat.cxx
+     ${CMAKE_BUILD_DIR}/bindings/xCard.cxx
+     ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcal.cxx
+     ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcard.cxx
+     ${CMAKE_BUILD_DIR}/bindings/iCalendar-params.cxx
+     ${CMAKE_BUILD_DIR}/bindings/iCalendar-props.cxx
+     ${CMAKE_BUILD_DIR}/bindings/iCalendar-valtypes.cxx
+ #     bindings/iCalendar-link-extension.cxx
+ #     bindings/iCalendar-bw-extensions.cxx
+ #     bindings/iCalendar-ms-extensions.cxx
+ )
+ 
+ #xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd
+ # --generate-inline --extern-xml-schema xml-schema.xsd
+ # --cxx-suffix .cpp --hxx-suffix .h   
+ add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
+     COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization  --namespace-map http://kolab.org=KolabXSD --root-element icalendar --root-element vcards --root-element note --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
+     COMMENT "Generating XSD bindings"
+     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+     DEPENDS ${SCHEMAS}
+     VERBATIM
+     )
+ 
+ # Compile Schemas
+ add_executable(xsdbin compiled/xsdbin.cxx)
+ target_link_libraries(xsdbin ${XERCES_C})
+ 
+ 
+ 
+ add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
+     COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR} ${SCHEMAS}
+     COMMENT "Compiling Kolab XSD schema"
+     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+     DEPENDS ${SCHEMAS} xsdbin
+     VERBATIM
+     )
+ set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BUILD_DIR}/kolabformat-xcal-schema.cxx)
+ 
+ # ---------
+ 
+ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
+ ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
+ 
+ include_directories( ./ )
+ include_directories( compiled )
+ include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+ 
+ add_subdirectory(lib)
+ if (${QT_FOUND})
+     add_subdirectory(tests)
+ endif()
+ 
diff --cc libkolabxml/Makefile.am
index 0000000,be0206b..13d0dae
mode 000000,100644..100644
--- a/libkolabxml/Makefile.am
+++ b/libkolabxml/Makefile.am
@@@ -1,0 -1,36 +1,41 @@@
+ EXTRA_DIST = \
+ 	autogen.sh \
+ 	CMakeLists.txt \
+ 	Makefile.am \
+ 	README \
+ 	compiled/ \
+ 	compiled/grammar-input-stream.cxx \
+ 	compiled/grammar-input-stream.hxx \
+ 	compiled/README \
+ 	compiled/XMLParserWrapper.cpp \
+ 	compiled/XMLParserWrapper.h \
+ 	compiled/xsdbin.cxx \
+ 	lib/ \
+ 	$(wildcard lib/*.cpp) \
+ 	$(wildcard lib/*.h) \
++	$(wildcard lib/*.i) \
+ 	lib/CMakeLists.txt \
+ 	lib/DEVELOPMENT \
 -	lib/kolabcontainers.i \
 -	lib/kolabformat.i \
+ 	lib/php/ \
+ 	lib/php/CMakeLists.txt \
+ 	lib/php/test.php \
+ 	lib/python/ \
+ 	lib/python/CMakeLists.txt \
+ 	lib/python/test.py \
+ 	tests/ \
+ 	$(wildcard tests/*.cpp) \
+ 	$(wildcard tests/*.h) \
+ 	tests/CMakeLists.txt \
+ 	tests/testfiles/ \
+ 	$(wildcard tests/testfiles/*.xml)
+ 
+ all:
+ 	@rm -rf build/
+ 	@mkdir -p build/
 -	@cd build/; cmake ..; make
++	@cd build/; cmake \
++		-DCMAKE_INSTALL_PREFIX=$(prefix) \
++		..; make
++
++install:
++	make -C build/ install
++
diff --cc libkolabxml/lib/xcardconversions.h
index 0000000,0be6f0a..b3c1577
mode 000000,100644..100644
--- a/libkolabxml/lib/xcardconversions.h
+++ b/libkolabxml/lib/xcardconversions.h
@@@ -1,0 -1,1092 +1,1092 @@@
+ /*
+  * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+  *
+  * This program is free software: you can redistribute it and/or modify
+  * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public License
+  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+ 
+ #ifndef KOLABXCARDCONVERSION_H
+ #define KOLABXCARDCONVERSION_H
+ 
+ #include <bindings/kolabformat-xcard.hxx>
+ #include "kolabcontainers.h"
+ #include <XMLParserWrapper.h>
+ #include <boost/shared_ptr.hpp>
+ #include <boost/foreach.hpp>
+ #include <boost/lexical_cast.hpp>
+ #include <iomanip>
+ #include "global_definitions.h"
+ #include "utils.h"
+ #include "kolabcontact.h"
+ #include "shared_conversions.h"
+ 
+ namespace Kolab {
+     namespace XCARD {
+         
+     const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+     const char* const INDIVIDUAL = "individual";
+     const char* const GROUP = "group";
+     const char* const MIME_PGP_KEYS = "application/pgp-keys";
+     const char* const MIME_PKCS7_MIME = "application/pkcs7-mime";
+ 
+ using namespace Kolab::Utils;
+     
+ template <typename T> 
+ std::string getType();
+ 
+ template <> 
+ std::string getType<Kolab::Contact>()
+ {
+     return INDIVIDUAL;
+ }
+ 
+ template <> 
+ std::string getType<Kolab::DistList>()
+ {
+     return GROUP;
+ }
+ 
+ template <typename T>
+ xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input)
+ {
+     xsd::cxx::tree::sequence<T> list;
+     BOOST_FOREACH(const std::string &s, input) {
+         list.push_back(T(s));
+     }
+     return list;
+ }
+ 
+ template <typename T>
+ xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input, int preferredIndex)
+ {
+     xsd::cxx::tree::sequence<T> list;
+     int index = 0;
+     BOOST_FOREACH(const std::string &s, input) {
+         T im(s);
+         if(preferredIndex == index) {
+             typename T::parameters_type parameters;
+             parameters.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+             im.parameters(parameters);
+         }
+         index++;
+         list.push_back(im);
+     }
+     return list;
+ }
+ 
+ template <typename T>
+ std::vector<std::string> toUriList(const xsd::cxx::tree::sequence<T> &input)
+ {
+     std::vector<std::string> list;
+     BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, input) {
+         list.push_back(s.uri());
+     }
+     return list;
+ }
+ 
+ template <typename T>
+ std::vector<std::string> toTextList(const xsd::cxx::tree::sequence<T> &input)
+ {
+     std::vector<std::string> list;
+     BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, input) {
+         list.push_back(s.text());
+     }
+     return list;
+ }
+ 
+ std::vector<std::string> toStringList(const ::xsd::cxx::tree::sequence< ::xml_schema::string > &s)
+ {
+     std::vector<std::string> d;
+     std::copy(s.begin(), s.end(), std::back_inserter(d));
+     return d;
+ }
+ 
+ ::xsd::cxx::tree::sequence< ::xml_schema::string > fromStringList(const std::vector<std::string> &s)
+ {
+     ::xsd::cxx::tree::sequence< ::xml_schema::string > d;
+     std::copy(s.begin(), s.end(), std::back_inserter(d));
+     return d;
+ }
+ 
+ std::string fromDate(const cDateTime &dt)
+ {
+     if (!dt.isDateOnly()) {
+         WARNING("fromDate called on date time value");
+     }
+     std::stringstream s;
+     s.fill('0');
+     s.width(4);
+     s << dt.year();
+     s.width(2);
+     s << dt.month();
+     s.width(2);
+     s << dt.day();
+     return s.str();
+ }
+ 
+ std::string fromDateTime(const cDateTime &dt)
+ {
+     std::stringstream s;
+     s.fill('0');
+     s << std::right; 
+     s.width(4);
+     s << dt.year();
+     s.width(2);
+     s << dt.month();
+     s.width(2);
+     s << dt.day();
+     s.width(1);
+     if (dt.isDateOnly()) {
+         return s.str();
+     }
+     s << "T";
+     s.width(2);
+     s << dt.hour();
+     s.width(2);
+     s << dt.minute();
+     s.width(2);
+     s << dt.second();
+     if (dt.isUTC()) {
+         s << "Z";
+     }
+     return s.str();
+ }
+ 
+ cDateTime toDateTime(const std::string &input)
+ {
+     int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
+     bool isUtc = false;
+     try {
+         year = boost::lexical_cast<int>(input.substr(0, 4));
+         month = boost::lexical_cast<int>(input.substr(4, 2));
+         day = boost::lexical_cast<int>(input.substr(6, 2));
+         if (input.size() >= 15) { //Minimum for time
+             if (input.at(8) != 'T') {
+                 ERROR("Wrong demiliter");
+                 return cDateTime();
+             }
+             hour = boost::lexical_cast<int>(input.substr(9, 2));
+             minute = boost::lexical_cast<int>(input.substr(11, 2));
+             second = boost::lexical_cast<int>(input.substr(13, 2));
+         } else {
+             if (input.size() >= 9) {
+                 ERROR("Invalid dt " + input);
+                 return cDateTime();
+             }
+             return cDateTime(year, month, day);
+         }
+         if (input.size() >= 16) {
+             if (input.at(15) == 'Z') {
+                 isUtc = true;
+             } else {
+                 ERROR("wrong utc char? " + input.at(15));
+                 return cDateTime();
+             }
+         }
+     } catch (boost::bad_lexical_cast &c) {
+         ERROR("failed to convert: "+std::string(c.what()));
+         return cDateTime();
+     } catch (...) {
+         ERROR("failed to convert: unkown exception");
+         return cDateTime();
+     }
+     return cDateTime(year, month, day, hour, minute, second, isUtc);
+ }
+ 
+ cDateTime toDateTime(const vcard_4_0::DateDatetimePropertyType &prop)
+ {
+     if (prop.date_time()) {
+         return toDateTime(*prop.date_time());
+     } else if (prop.date()) {
+         return toDateTime(*prop.date());
+     }
+     ERROR("no date and no datetime");
+     return cDateTime();
+ }
+ 
+ template <typename T>
+ T fromDateTime(const Kolab::cDateTime &dt)
+ {
+     T prop;
+ 
+     if (dt.isDateOnly()) {
+         prop.date(fromDate(dt));
+     } else {
+         prop.date_time(fromDateTime(dt));
+     }
+     return prop;
+ }
+ 
+ vcard_4_0::PrefTypeValueType fromCryptoPref(Kolab::Crypto::CryptoPref pref)
+ {
+     switch (pref) {
+         case Kolab::Crypto::Always:
+             return vcard_4_0::CryptoType::encryptpref_type::text_type::Always;
+         case Kolab::Crypto::Ask:
+             return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
+         case Kolab::Crypto::IfPossible:
+             return vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible;
+         case Kolab::Crypto::Never:
+             return vcard_4_0::CryptoType::encryptpref_type::text_type::Never;
+         default:
+             WARNING("unknown encrypt pref");
+     }
+     return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
+ }
+ 
+ Kolab::Crypto::CryptoPref toCryptoPref(vcard_4_0::PrefTypeValueType pref)
+ {
+     switch (pref) {
+         case vcard_4_0::CryptoType::encryptpref_type::text_type::Always:
+             return Kolab::Crypto::Always;
+         case vcard_4_0::CryptoType::encryptpref_type::text_type::Ask:
+             return Kolab::Crypto::Ask;
+         case vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible:
+             return Kolab::Crypto::IfPossible;
+         case vcard_4_0::CryptoType::encryptpref_type::text_type::Never:
+             return Kolab::Crypto::Never;
+         default:
+             WARNING("unknown encrypt pref");
+     }
+     return Kolab::Crypto::Ask;
+ }
+ 
+ vcard_4_0::relatedPropType fromRelated(const Kolab::Related &r)
+ {
+     using namespace vcard_4_0;
+     vcard_4_0::relatedPropType related;
+     if (r.type() == Kolab::Related::Uid) {
+         related.uri(r.uri());
+     } else {
+         related.text(r.text());
+     }
+     if (r.relationTypes() != Kolab::Related::NoRelation) {
+         
+         vcard::adr_type::parameters_type::baseParameter_sequence base;
+         vcard::adr_type::parameters_type b;
+         
+         vcard_4_0::typeParamType::text_sequence seq;
+         if (r.relationTypes() & Kolab::Related::Child) {
+             seq.push_back(TypeValueType::child);
+         }
+         if (r.relationTypes() & Kolab::Related::Spouse) {
+             seq.push_back(TypeValueType::spouse);
+         }
+         if (r.relationTypes() & Kolab::Related::Assistant) {
+             seq.push_back(TypeValueType::x_assistant);
+         }
+         if (r.relationTypes() & Kolab::Related::Manager) {
+             seq.push_back(TypeValueType::x_manager);
+         }
+         if (!seq.empty()) {
+             vcard_4_0::typeParamType type;
+             type.text(seq);
+             b.baseParameter().push_back(type);
+         }
+         
+         related.parameters(b);
+     }
+     
+     return related;
+ }
+ 
+ Kolab::Related toRelated(const vcard_4_0::relatedPropType &r)
+ {
+     Kolab::Related::DescriptionType type = Kolab::Related::Invalid;
+     std::string textOrUri;
+     if (r.uri()) {
+         type = Kolab::Related::Uid;
+         textOrUri = *r.uri();
+     } else if (r.text()) {
+         type = Kolab::Related::Text;
+         textOrUri = *r.text();
+     } else {
+         ERROR("no text and no uri");
+         return Kolab::Related();
+     }
+     Kolab::Related related(type, textOrUri);
+     if (r.parameters()) {
+         BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*r.parameters()).baseParameter()) {
+             if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                 int types = 0;
+                 BOOST_FOREACH(const std::string &s, rel->text()) {
+                     if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::child)) {
+                         types |= Kolab::Related::Child;
+                     }
+                     if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::spouse)) {
+                         types |= Kolab::Related::Spouse;
+                     }
+                     if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_assistant)) {
+                         types |= Kolab::Related::Assistant;
+                     }
+                     if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_manager)) {
+                         types |= Kolab::Related::Manager;
+                     }
+                 }
+                 related.setRelationTypes(types);
+             } 
+         }
+     }
+     return related;
+ }
+ 
+ vcard_4_0::vcard::adr_type fromAddress(const Kolab::Address &address)
+ {
+     using namespace vcard_4_0;
+     vcard::adr_type a(vcard::adr_type::pobox_type(std::string()/*address.pobox()*/), 
+                       vcard::adr_type::ext_type(std::string()/*address.ext()*/),
+                                                 vcard::adr_type::street_type(address.street()),
+                                                 vcard::adr_type::locality_type(address.locality()),
+                                                 vcard::adr_type::region_type(address.region()),
+                                                 address.code(),
+                                                 vcard::adr_type::country_type(address.country())
+                       );
+     vcard::adr_type::parameters_type b;
+     if (address.types()) {
+         vcard_4_0::typeParamType::text_sequence seq;
+         if (address.types() & Kolab::Address::Home) {
+             seq.push_back(TypeValueType::home);
+         }
+         if (address.types() & Kolab::Address::Work) {
+             seq.push_back(TypeValueType::work);
+         }
+         if (!seq.empty()) {
+             vcard_4_0::typeParamType type;
+             type.text(seq);
+             b.baseParameter().push_back(type);
+         }
+     }
+     if (!address.label().empty()) {
+         b.baseParameter().push_back(vcard_4_0::labelParamType(address.label()));
+     }
+     a.parameters(b);
+     return a;
+ }
+ 
+ Kolab::Address toAddress(const vcard_4_0::vcard::adr_type &adr, bool *isPreferred = 0)
+ {
+     using namespace vcard_4_0;
+     Address address;
+     if (adr.parameters()) {
+         BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*adr.parameters()).baseParameter()) {
+             if (const vcard_4_0::labelParamType *rel = dynamic_cast<const vcard_4_0::labelParamType*> (&param)) {
+                 address.setLabel(rel->text());
+             } else if (isPreferred && dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                 *isPreferred = true;
+             } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                 int types = 0;
+                 BOOST_FOREACH(const std::string &s, rel->text()) {
+                     if (s == TypeValueType(TypeValueType::work)) {
+                         types |= Kolab::Telephone::Work;
+                     }
+                     if (s == TypeValueType(TypeValueType::home)) {
+                         types |= Kolab::Telephone::Home;
+                     }
+                 }
+                 address.setTypes(types);
+             } 
+         }
+     }
+     
+     address.setCode(adr.code());
+     address.setCountry(adr.country());
+     address.setLocality(adr.locality());
+     address.setRegion(adr.region());
+     address.setStreet(adr.street());
+     return address;
+ }
+ 
+ std::string toGeoUri(double lat, double lon)
+ {
+     //lexical_cast doesn't work, so we're using stringstream
+     std::stringstream s;
+     s << "geo:";
+     s.precision(15); //can't use std::numeric_limits<double>::max_digits10 because that's c++ 0x, it should be 17, but that seems to cause rounding problems... no idea why.
+     s << lat << ",";
+     s.precision(15); //Needed to get the right precision somehow...
+     s << lon;
+     return s.str();
+ }
+ 
+ bool fromGeoUri(const std::string &uri, double &lat, double &lon)
+ {
+     if (uri.substr(0,4) != std::string("geo:")) {
+         WARNING("not a geo uri");
+         return false;
+     }
+     std::size_t pos1 = uri.find(",");
+     if (pos1 == std::string::npos) {
+         WARNING("not a valid geo uri");
+         return false;
+     }
+     lat = boost::lexical_cast<double>(uri.substr(4, pos1-4));
+     lon = boost::lexical_cast<double>(uri.substr(pos1+1, uri.size()-pos1-1));
+     return true;
+ }
+ 
+ template <typename T> 
+ void writeCard(vcard_4_0::vcard &vcard, const T &);
+ 
+ template <> 
+ void writeCard<Kolab::Contact>(vcard_4_0::vcard &vcard, const Kolab::Contact &contact)
+ {
+     using namespace vcard_4_0;
+     
+     if (!contact.categories().empty()) {
+         vcard_4_0::vcard::categories_type cat;
+         vcard_4_0::vcard::categories_type::text_sequence seq;
+         BOOST_FOREACH(const std::string &s, contact.categories()) {
+             seq.push_back(s);
+         }
+         cat.text(seq);
+         vcard.categories(cat);
+     }
+     
+     if (contact.nameComponents().isValid()) {
+         const NameComponents &nc = contact.nameComponents();
+         vcard::n_type n;
+         n.surname(fromStringList(nc.surnames()));
+         n.given(fromStringList(nc.given()));
+         n.additional(fromStringList(nc.additional()));
+         n.prefix(fromStringList(nc.prefixes()));
+         n.suffix(fromStringList(nc.suffixes()));
+         vcard.n(n);
+     }
+     
+     if (!contact.note().empty()) {
+         vcard.note(vcard::note_type(contact.note()));
+     }
+     
+     if (!contact.freeBusyUrl().empty()) {
+         vcard.fburl(vcard::fburl_type(contact.freeBusyUrl()));
+     }
+     
+     if (!contact.titles().empty()) {
+         vcard.title(fromList<vcard::title_type>(contact.titles()));
+     }
+     
+     if (!contact.affiliations().empty()) {
+         vcard::group_sequence affiliations;
+         BOOST_FOREACH(const Affiliation &a, contact.affiliations()) {
+             affiliationPropType::org_type org;
+             org.text().push_back(a.organisation());
+             BOOST_FOREACH(const std::string &unit, a.organisationalUnits()) {
+                 org.text().push_back(unit);
+             }
+             vcard::group_type group(org);
+             if (!a.logo().empty()) {
+                 group.logo(affiliationPropType::logo_type(uriInlineEncoding(a.logo(), a.logoMimetype())));
+             }
+             group.role(fromList<affiliationPropType::role_type>(a.roles()));
+             BOOST_FOREACH(const Related &rel, a.relateds()) {
+                 group.related().push_back(fromRelated(rel));
+             }
+             BOOST_FOREACH(const Address &adr, a.addresses()) {
+                 group.adr().push_back(fromAddress(adr));
+             }
+ 
+             affiliations.push_back(group);
+         }
+         vcard.group(affiliations);
+     }
+     
+     if (!contact.urls().empty()) {
+         vcard.url(fromList<vcard::url_type>(contact.urls()));
+     }
+     
+     if (!contact.addresses().empty()) {
+         vcard::adr_sequence adrs;
+         int index = 0;
+         BOOST_FOREACH(const Kolab::Address &address, contact.addresses()) {
+             vcard::adr_type a = fromAddress(address);
+             if(contact.addressPreferredIndex() == index) {
+                 if (a.parameters()) {
+                     (*a.parameters()).baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+                 } else {
+                     vcard::adr_type::parameters_type b;
+                     b.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+                     a.parameters(b);
+                 }
+             }
+             index++;
+             adrs.push_back(a);
+         }
+         vcard.adr(adrs);
+     }
+     
+     if (!contact.nickNames().empty()) {
+         vcard::nickname_type::text_sequence textsequence;
+         BOOST_FOREACH(const std::string &s, contact.nickNames()) {
+             textsequence.push_back(s);
+         }
+         vcard::nickname_type nickName;
+         nickName.text(textsequence);
+         vcard.nickname(nickName);
+     }
+     
+     if (!contact.relateds().empty()) {
+         vcard::related_sequence seq;
+         BOOST_FOREACH(const Kolab::Related &r, contact.relateds()) {
+             seq.push_back(fromRelated(r));
+         }
+         vcard.related(seq);
+     }
+     
+     if (contact.bDay().isValid()) {
+         Kolab::cDateTime dt = contact.bDay();
+         if (dt.isUTC() || !dt.timezone().empty()) {
+             WARNING("Must be local time, local time assumed");
+             dt.setUTC(false);
+         }
+         vcard.bday(fromDateTime<vcard::bday_type>(dt));
+     }
+     
+     if (contact.anniversary().isValid()) {
+         Kolab::cDateTime dt = contact.anniversary();
+         if (dt.isUTC() || !dt.timezone().empty()) {
+             WARNING("Must be local time, local time assumed");
+             dt.setUTC(false);
+         }
+         vcard.anniversary(fromDateTime<vcard::anniversary_type>(dt));
+     }
+     
+     if (!contact.photo().empty()) {
+         vcard::photo_type photo(vcard_4_0::UriPropertyType::uri_type(uriInlineEncoding(contact.photo(), contact.photoMimetype())));
+         vcard.photo(photo);
+     }
+     
+     if (contact.gender() != Contact::NotSet) {
+         switch (contact.gender()) {
+             case Contact::NotSpecified:
+                 vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::empty));
+                 break;
+             case Contact::Male:
+                 vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::M));
+                 break;
+             case Contact::Female:
+                 vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::F));
+                 break;
+             default:
+                 ERROR("Unhandled gender");
+         }
+     }
+     
+     if (!contact.languages().empty()) {
+         vcard.lang(fromList<vcard::lang_type>(contact.languages()));
+     }
+     
+     if (!contact.telephones().empty()) {
+         vcard::tel_sequence seq;
+         int index = 0;
+         BOOST_FOREACH(const Kolab::Telephone &t, contact.telephones()) {
+             vcard::tel_type tel(t.number());
+             vcard_4_0::typeParamType telTypeParam;
+             if (t.types() & Kolab::Telephone::Car) {
+                 telTypeParam.text().push_back(TypeValueType::x_car);
+             } 
+             if (t.types() & Kolab::Telephone::Cell) {
+                 telTypeParam.text().push_back(TypeValueType::cell);
+             } 
+             if (t.types() & Kolab::Telephone::Fax) {
+                 telTypeParam.text().push_back(TypeValueType::fax);
+             } 
+             if (t.types() & Kolab::Telephone::Home) {
+                 telTypeParam.text().push_back(TypeValueType::home);
+             } 
+             if (t.types() & Kolab::Telephone::Work) {
+                 telTypeParam.text().push_back(TypeValueType::work);
+             } 
+             if (t.types() & Kolab::Telephone::Text) {
+                 telTypeParam.text().push_back(TypeValueType::text);
+             } 
+             if (t.types() & Kolab::Telephone::Voice) {
+                 telTypeParam.text().push_back(TypeValueType::voice);
+             } 
+             if (t.types() & Kolab::Telephone::Video) {
+                 telTypeParam.text().push_back(TypeValueType::video);
+             } 
+             if (t.types() & Kolab::Telephone::Textphone) {
+                 telTypeParam.text().push_back(TypeValueType::textphone);
+             } 
+             if (t.types() & Kolab::Telephone::Pager) {
+                 telTypeParam.text().push_back(TypeValueType::pager);
+             }
+             vcard::tel_type::parameters_type params;
+             if(contact.telephonesPreferredIndex() == index) {
+                 params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+             }
+             index++;
+ 
+             if (!telTypeParam.text().empty()) {
+                 params.baseParameter().push_back(telTypeParam);
+                 tel.parameters(params);
+             }
+             seq.push_back(tel);
+         }
+         vcard.tel(seq);
+     }
+     
+     if (!contact.imAddresses().empty()) {
+         vcard.impp(fromList<vcard::impp_type>(contact.imAddresses(), contact.imAddressPreferredIndex()));
+     }
+     
+     if (!contact.emailAddresses().empty()) {
+         vcard.email(fromList<vcard::email_type>(contact.emailAddresses(), contact.emailAddressPreferredIndex()));
+     }
+     
+     if (!contact.gpsPos().empty()) {
+         vcard_4_0::vcard::geo_sequence list;
+         BOOST_FOREACH(const Kolab::Geo &g ,contact.gpsPos()) {
+             list.push_back(vcard_4_0::vcard::geo_type(toGeoUri(g.latitude, g.longitude)));
+         }
+         vcard.geo(list);
+     }
+     
+     if (contact.crypto().isValid()) {
+         vcard::x_crypto_type crypto;
+         const Kolab::Crypto &c = contact.crypto();
+         if (c.allowed()) {
+             vcard::x_crypto_type::allowed_type::text_sequence seq;
+             if (c.allowed() & Kolab::Crypto::PGPinline) {
+                 seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE);
+             }
+             if (c.allowed() & Kolab::Crypto::PGPmime) {
+                 seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_MIME);
+             }
+             if (c.allowed() & Kolab::Crypto::SMIME) {
+                 seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIME);
+             }
+             if (c.allowed() & Kolab::Crypto::SMIMEopaque) {
+                 seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque);
+             }
+             vcard::x_crypto_type::allowed_type allowed;
+             allowed.text(seq);
+             crypto.allowed(allowed);
+         }
+         vcard_4_0::vcard::key_sequence keys;
+         if (!c.pgpKey().empty()) {
+             keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.pgpKey(), MIME_PGP_KEYS)));
+         }
+         if (!c.smimeKey().empty()) {
+             keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.smimeKey(), MIME_PKCS7_MIME)));
+         }
+         if (!keys.empty()) {
+             vcard.key(keys);
+         }
+         crypto.encryptpref(fromCryptoPref(c.encryptPref()));
+         crypto.signpref(fromCryptoPref(c.signPref()));
+ 
+         vcard.x_crypto(crypto);
+     }
+ 
+ 
+ }
+ 
+ template <> 
+ void writeCard<Kolab::DistList>(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist)
+ {
+     if (!distlist.members().empty()) {
+         vcard_4_0::vcard::member_sequence members;
+         BOOST_FOREACH (const Kolab::ContactReference &m, distlist.members()) {
+             members.push_back(vcard_4_0::vcard::member_type(Shared::fromContactReference(m)));
+         }
+         vcard.member(members);
+     } else {
+         WARNING("empty distlist");
+     }
+ }
+ 
+ 
+ 
+ template <typename T>
+ std::string serializeCard(const T &card, const std::string prod = std::string()) {
+ 
+     using namespace vcard_4_0;
+     
+     clearErrors();
+ 
+     try {
+         vcard_4_0::vcard::uid_type uid(Shared::toURN(getUID(card.uid())));
+         setCreatedUid(Shared::fromURN(uid.uri()));
+         vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
+         vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
+         vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
+         vcard_4_0::vcard::kind_type kind(getType<T>());
+         vcard_4_0::vcard::fn_type fn(card.name());
+ 
+         vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+         
+         writeCard<T>(vcard, card);
+         
+         if (!card.customProperties().empty()) {
+             BOOST_FOREACH(const Kolab::CustomProperty &a, card.customProperties()) {
+                 vcard.x_custom().push_back(vcard_4_0::CustomType(a.identifier, a.value));
+             }
+         }
+         
+         VcardsType vcards(vcard);
+ 
+         xml_schema::namespace_infomap map;
+         map[""].name = XCARD_NAMESPACE;
+         
+         std::ostringstream ostringstream;
+         vcard_4_0::vcards(ostringstream, vcards, map);
+         return ostringstream.str();
+     } catch  (const xml_schema::exception& e) {
+         CRITICAL("Unknown Exception: failed to write Contact");
+     }
+     return std::string();
+ }
+ 
+ template <typename T>
+ boost::shared_ptr<T> readCard(const vcard_4_0::VcardsType::vcard_type &vcard);
+ 
+ template <>
+ boost::shared_ptr<Kolab::Contact> readCard <Kolab::Contact> (const vcard_4_0::VcardsType::vcard_type &vcard)
+ {
+     using namespace vcard_4_0;
+     boost::shared_ptr<Kolab::Contact> contact(new Kolab::Contact);
+     
+     if (vcard.categories()) {
+         contact->setCategories(toStringList((*vcard.categories()).text()));
+     }
+     
+     if (vcard.n()) {
+         NameComponents nc;
+         nc.setSurnames(toStringList((*vcard.n()).surname()));
+         nc.setGiven(toStringList((*vcard.n()).given()));
+         nc.setPrefixes(toStringList((*vcard.n()).prefix()));
+         nc.setSuffixes(toStringList((*vcard.n()).suffix()));
+         nc.setAdditional(toStringList((*vcard.n()).additional()));
+         contact->setNameComponents(nc);
+     }
+     if (vcard.note()) {
+         contact->setNote((*vcard.note()).text());
+     }
+     if (vcard.fburl()) {
+         contact->setFreeBusyUrl((*vcard.fburl()).uri());
+     }
+     if (!vcard.title().empty()) {
+         contact->setTitles(toTextList<vcard::title_type >(vcard.title()));
+     }
+     if (!vcard.group().empty()) {
+         std::vector<Kolab::Affiliation> list;
+         BOOST_FOREACH (const vcard::group_type &group, vcard.group()) {
+             Kolab::Affiliation aff;
+             if (!group.org().text().empty()) {
+                 aff.setOrganisation(*group.org().text().begin());
+                 std::vector<std::string> units;
+                 for ( vcard_4_0::NonEmptyTextListPropertyType::text_const_iterator it = ++group.org().text().begin(); it != group.org().text().end(); it++) {
+                     units.push_back(*it);
+                 }
+                 aff.setOrganisationalUnits(units);
+             } else {
+                 WARNING("No org present");
+             }
+             std::string mimetype;
+             if (group.logo()) {
+                 const std::string &logo = uriInlineDecoding((*group.logo()).uri(), mimetype);
+                 aff.setLogo(logo, mimetype);
+             }
+             aff.setRoles(toTextList<vcard::group_type::role_type>(group.role()));
+             std::vector<Related> relateds;
+             BOOST_FOREACH(const vcard::group_type::related_type &rel, group.related()) {
+                 relateds.push_back(toRelated(rel));
+             }
+             aff.setRelateds(relateds);
+             std::vector<Address> addresses;
+             BOOST_FOREACH(const vcard::group_type::adr_type &adr, group.adr()) {
+                 addresses.push_back(toAddress(adr));
+             }
+             aff.setAddresses(addresses);
+             list.push_back(aff);
+         }
+         contact->setAffiliations(list);
+     }
+     if (!vcard.url().empty()) {
+         contact->setUrls(toUriList<vcard::url_type >(vcard.url()));
+     }
+     if (!vcard.adr().empty()) {
+         std::vector<Kolab::Address> list;
+         int preferredIndex = -1;
+         int index = 0;
+         BOOST_FOREACH(const vcard::adr_type &adr, vcard.adr()) {
+             bool isPreferred = false;
+             const Kolab::Address &address = toAddress(adr, &isPreferred);
+             if (isPreferred) {
+                 preferredIndex = index;
+             }
+             index++;
+             list.push_back(address);
+         }
+         contact->setAddresses(list, preferredIndex);
+     }
+     if (vcard.nickname()) {
+         contact->setNickNames(toTextList<TextListPropertyType::text_type>((*vcard.nickname()).text()));
+     }
+     if (!vcard.related().empty()) {
+         std::vector<Related> list;
+         BOOST_FOREACH(const vcard_4_0::vcard::related_type &r, vcard.related()) {
+             list.push_back(toRelated(r));
+         }
+         contact->setRelateds(list);
+     }
+     if (vcard.bday()) {
+         contact->setBDay(toDateTime(*vcard.bday()));
+     }
+     if (vcard.anniversary()) {
+         contact->setAnniversary(toDateTime(*vcard.anniversary()));
+     }
+     if (vcard.photo()) {
+         std::string mimetype;
+         const std::string decodedPhoto =  uriInlineDecoding((*vcard.photo()).uri(), mimetype);
+         contact->setPhoto(decodedPhoto, mimetype);
+     }
+     if (vcard.gender()) {
+         if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::empty) {
+             contact->setGender(Kolab::Contact::NotSpecified);
+         } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::M) {
+             contact->setGender(Kolab::Contact::Male);
+         } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::F) {
+             contact->setGender(Kolab::Contact::Female);
+         }
+     }
+     if (!vcard.lang().empty()) {
+         std::vector<std::string> list;
+         BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) {
+             list.push_back(l.language_tag());
+         }
+         contact->setLanguages(list);
+     }
+     if (!vcard.tel().empty()) {
+         std::vector<Kolab::Telephone> list;
+         int preferredIndex = -1;
+         int index = 0;
+         BOOST_FOREACH(const vcard::tel_type &tel, vcard.tel()) {
+             Kolab::Telephone telephone;
+             if (tel.parameters()) {
+                 BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*tel.parameters()).baseParameter()) {
+                     if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                         preferredIndex = index;
+                     } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                         int types = 0;
+                         BOOST_FOREACH(const std::string &s, rel->text()) {
+                             if (s == TypeValueType(TypeValueType::work)) {
+                                 types |= Kolab::Telephone::Work;
+                             }
+                             if (s == TypeValueType(TypeValueType::home)) {
+                                 types |= Kolab::Telephone::Home;
+                             }
+                             if (s == TypeValueType(TypeValueType::text)) {
+                                 types |= Kolab::Telephone::Text;
+                             }
+                             if (s == TypeValueType(TypeValueType::voice)) {
+                                 types |= Kolab::Telephone::Voice;
+                             }
+                             if (s == TypeValueType(TypeValueType::fax)) {
+                                 types |= Kolab::Telephone::Fax;
+                             }
+                             if (s == TypeValueType(TypeValueType::cell)) {
+                                 types |= Kolab::Telephone::Cell;
+                             }
+                             if (s == TypeValueType(TypeValueType::video)) {
+                                 types |= Kolab::Telephone::Video;
+                             }
+                             if (s == TypeValueType(TypeValueType::pager)) {
+                                 types |= Kolab::Telephone::Pager;
+                             }
+                             if (s == TypeValueType(TypeValueType::textphone)) {
+                                 types |= Kolab::Telephone::Textphone;
+                             }
+                             if (s == TypeValueType(TypeValueType::x_car)) {
+                                 types |= Kolab::Telephone::Car;
+                             }
+                         }
+                         telephone.setTypes(types);
+                     } 
+                 }
+             }
+             index++;
+ 
+             telephone.setNumber(tel.text());
+             list.push_back(telephone);
+         }
+         contact->setTelephones(list, preferredIndex);
+     }
+     
+     if (!vcard.impp().empty()) {
+         int preferredIndex = -1;
+         
+         std::vector<std::string> list;
+         int i = 0;
+         BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, vcard.impp()) {
+             if (s.parameters()) {
+                 BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                     if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                         preferredIndex = i;
+                     } 
+                 }
+             }
+             i++;
+             list.push_back(s.uri());
+         }
+         
+         contact->setIMaddresses(list, preferredIndex);
+     }
+     if (!vcard.email().empty()) {
+         int preferredIndex = -1;
+         
+         std::vector<std::string> list;
+         int i = 0;
+         BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, vcard.email()) {
+             if (s.parameters()) {
+                 BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                     if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                         preferredIndex = i;
+                     } 
+                 }
+             }
+             i++;
+             list.push_back(s.text());
+         }
+         
+         contact->setEmailAddresses(list, preferredIndex);
+     }
+     if (!vcard.geo().empty()) {
+         std::vector<Geo> list;
+         BOOST_FOREACH(const vcard_4_0::geoPropType &s, vcard.geo()) {
+             double lon = 0.0;
+             double lat = 0.0;
+             if (fromGeoUri(s.uri(), lat, lon)) {
+                 list.push_back(Kolab::Geo(lat, lon));
+             }
+         }
+         contact->setGPSpos(list);
+     }
+     if (vcard.x_crypto()) {
+         const vcard_4_0::vcard::x_crypto_type &crypto = *vcard.x_crypto();
+         Kolab::Crypto c;
+         if (crypto.allowed()) {
+             int allowed = 0;
+             BOOST_FOREACH(const vcard_4_0::vcard::x_crypto_type::allowed_type::text_type &m, crypto.allowed()->text()) {
+                 if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE) {
+                     allowed |= Kolab::Crypto::PGPinline;
+                 } else if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_MIME) {
+                     allowed |= Kolab::Crypto::PGPmime;
+                 } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIME) {
+                     allowed |= Kolab::Crypto::SMIME;
+                 } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque) {
+                     allowed |= Kolab::Crypto::SMIMEopaque;
+                 } else {
+                     WARNING("unknown allowed property");
+                 }
+             }
+             c.setAllowed(allowed);
+         }
+         if (!vcard.key().empty()) {
+             BOOST_FOREACH(const vcard_4_0::keyPropType &k, vcard.key()) {
+                 std::string mimetype;
+                 const std::string &key = uriInlineDecoding(k.uri(), mimetype);
+                 if (mimetype == MIME_PGP_KEYS) {
+                     c.setPGPKey(key);
+                 } else if (mimetype == MIME_PKCS7_MIME) {
+                     c.setSMIMEKey(key);
+                 } else {
+                     WARNING("wrong mimetype on key");
+                 }
+             }
+         }
+         if (crypto.encryptpref()) {
+             c.setEncryptPref(toCryptoPref(crypto.encryptpref()->text()));
+         }
+         if (crypto.signpref()) {
+             c.setSignPref(toCryptoPref(crypto.signpref()->text()));
+         }
+         contact->setCrypto(c);
+     }
+     return contact;
+ }
+ 
+ template <>
+ boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
+ {
+     using namespace vcard_4_0;
+     boost::shared_ptr<Kolab::DistList> distlist(new Kolab::DistList);
+ 
+     if (!vcard.member().empty()) {
+         std::vector<Kolab::ContactReference> members;
+ 
+         BOOST_FOREACH(const vcard_4_0::vcard::member_type & m, vcard.member()) {
+             members.push_back(Shared::toContactReference(m.uri()));
+         }
+         distlist->setMembers(members);
+     } else {
+         WARNING("empty distlist");
+     }
+     return distlist;
+ }
+ 
+ template <typename T>
+ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
+ {
+     clearErrors();
+     try {
+         std::auto_ptr<vcard_4_0::VcardsType> vcards;
+         if (isUrl) {
+             xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+             if (doc.get()) {
+                 vcards = vcard_4_0::vcards(doc);
+             }
+         } else {
+             xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+             if (doc.get()) {
+                 vcards = vcard_4_0::vcards(doc);
+             }
+         }
+ 
+         if (!vcards.get()) {
+             CRITICAL("failed to parse card!");
+             return boost::shared_ptr<T>();
+         }
+         
+         boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
+         card->setUid(Shared::fromURN(vcards->vcard().uid().uri()));
+         card->setName(vcards->vcard().fn().text());
+         
+         setProductId( vcards->vcard().prodid().text() );
+ //         setFormatVersion( vcards->vcard().version().text() );
+ //         global_xCardVersion = vcalendar.properties().version().text();
+         setKolabVersion( vcards->vcard().x_kolab_version().text() );
+         
+         if (!vcards->vcard().x_custom().empty()) {
+             std::vector<Kolab::CustomProperty> customProperties;
+             BOOST_FOREACH(const vcard_4_0::CustomType &p, vcards->vcard().x_custom()) {
+                 customProperties.push_back(CustomProperty(p.identifier(), p.value()));
+             }
+             card->setCustomProperties(customProperties);
+         }
+         
+         return card;
+     } catch  (const xml_schema::exception& e) {
+         std::cerr <<  e << std::endl;
+         CRITICAL("Failed to read card!");
+     }
+ 
+     return boost::shared_ptr<T>();
+ }
+ 
+     }
+     
+ } //Namespace
+ 
 -#endif
++#endif


commit 2eb51d1847a4007e42d147847443aa60ad703990
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 15:58:00 2012 +0100

    renamed the c++ directory to libkolabxml

diff --git a/c++/.gitignore b/c++/.gitignore
deleted file mode 100644
index a007fea..0000000
--- a/c++/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/*
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
deleted file mode 100644
index c76f992..0000000
--- a/c++/CMakeLists.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-project(kolabxmlbindings)
-
-cmake_minimum_required(VERSION 2.6)
-
-# only available from cmake-2.8.0
-if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7)
-    cmake_policy(SET CMP0012 NEW)
-endif()
-
-# only available from cmake-2.8.4
-if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND
-    ${CMAKE_PATCH_VERSION} GREATER 3)
-    cmake_policy(SET CMP0017 NEW)
-endif()
-
-include( ../cmake/modules/FindKolabInternal.cmake )
-
-find_package(Boost COMPONENTS thread REQUIRED)
-
-if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
-    find_library(UUID NAMES uuid)
-    if(UUID)
-        message("uuid found")
-    else (UUID)
-        message(FATAL_ERROR "uuid NOT found!")
-    endif(UUID)
-endif()
-
-find_package(Qt4)
-find_program( XSDCXX xsdcxx /usr/bin/)
-if(XSDCXX)
-    message("xsd code generator found")
-else (XSDCXX)
-    message(FATAL_ERROR
-    "xsd code generator NOT found!")
-endif(XSDCXX)
-
-find_library(XERCES_C NAMES xerces-c xerces-c_2)
-if(XERCES_C)
-    message("xerces found")
-else (XERCES_C)
-    message(FATAL_ERROR
-    "xerces NOT found!")
-endif(XERCES_C)
-
-find_program(SWIG swig /usr/bin/)
-if(SWIG)
-    set(SWIG_FOUND ON)
-    message("SWIG found")
-endif(SWIG)
-
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
-
-# set( CMAKE_VERBOSE_MAKEFILE on )
-
-set(CMAKE_BUILD_TYPE Debug)
-
-set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
-file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
-
-set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
-
-# Generate bindings
-
-set( SCHEMAS
-    ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd
-    ${SCHEMA_DIR}/ical/iCalendar-params.xsd
-    ${SCHEMA_DIR}/ical/iCalendar-props.xsd
-    ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
-    ${SCHEMA_DIR}/xCard.xsd
-    ${SCHEMA_DIR}/kolabformat-xcard.xsd
-    ${SCHEMA_DIR}/kolabformat.xsd
-)
-
-set( SCHEMA_SOURCEFILES  
-    ${CMAKE_BUILD_DIR}/bindings/kolabformat.cxx
-    ${CMAKE_BUILD_DIR}/bindings/xCard.cxx
-    ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcal.cxx
-    ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcard.cxx
-    ${CMAKE_BUILD_DIR}/bindings/iCalendar-params.cxx
-    ${CMAKE_BUILD_DIR}/bindings/iCalendar-props.cxx
-    ${CMAKE_BUILD_DIR}/bindings/iCalendar-valtypes.cxx
-#     bindings/iCalendar-link-extension.cxx
-#     bindings/iCalendar-bw-extensions.cxx
-#     bindings/iCalendar-ms-extensions.cxx
-)
-
-#xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd
-# --generate-inline --extern-xml-schema xml-schema.xsd
-# --cxx-suffix .cpp --hxx-suffix .h   
-add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization  --namespace-map http://kolab.org=KolabXSD --root-element icalendar --root-element vcards --root-element note --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
-    COMMENT "Generating XSD bindings"
-    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-    DEPENDS ${SCHEMAS}
-    VERBATIM
-    )
-
-# Compile Schemas
-add_executable(xsdbin compiled/xsdbin.cxx)
-target_link_libraries(xsdbin ${XERCES_C})
-
-
-
-add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
-    COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR} ${SCHEMAS}
-    COMMENT "Compiling Kolab XSD schema"
-    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-    DEPENDS ${SCHEMAS} xsdbin
-    VERBATIM
-    )
-set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BUILD_DIR}/kolabformat-xcal-schema.cxx)
-
-# ---------
-
-SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
-ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
-
-include_directories( ./ )
-include_directories( compiled )
-include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
-
-add_subdirectory(lib)
-if (${QT_FOUND})
-    add_subdirectory(tests)
-endif()
-
diff --git a/c++/Makefile.am b/c++/Makefile.am
deleted file mode 100644
index be0206b..0000000
--- a/c++/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-EXTRA_DIST = \
-	autogen.sh \
-	CMakeLists.txt \
-	Makefile.am \
-	README \
-	compiled/ \
-	compiled/grammar-input-stream.cxx \
-	compiled/grammar-input-stream.hxx \
-	compiled/README \
-	compiled/XMLParserWrapper.cpp \
-	compiled/XMLParserWrapper.h \
-	compiled/xsdbin.cxx \
-	lib/ \
-	$(wildcard lib/*.cpp) \
-	$(wildcard lib/*.h) \
-	lib/CMakeLists.txt \
-	lib/DEVELOPMENT \
-	lib/kolabcontainers.i \
-	lib/kolabformat.i \
-	lib/php/ \
-	lib/php/CMakeLists.txt \
-	lib/php/test.php \
-	lib/python/ \
-	lib/python/CMakeLists.txt \
-	lib/python/test.py \
-	tests/ \
-	$(wildcard tests/*.cpp) \
-	$(wildcard tests/*.h) \
-	tests/CMakeLists.txt \
-	tests/testfiles/ \
-	$(wildcard tests/testfiles/*.xml)
-
-all:
-	@rm -rf build/
-	@mkdir -p build/
-	@cd build/; cmake ..; make
diff --git a/c++/README b/c++/README
deleted file mode 100644
index 88b9c36..0000000
--- a/c++/README
+++ /dev/null
@@ -1,22 +0,0 @@
-Build with:
-
-$mkdir build
-$cd build
-$cmake ..
-$make
-
-
-Minimum requirements are:
--cmake 2.6
--boost >= 1.47
--xerces-c >= 3.0
--cxx >= 3.0 (http://www.codesynthesis.com/products/xsd/)
-
-For further features:
--SWIG >= 2.0
--QT >= 4.7
--KCalCore/KDECore >= 4.7
-
-
-For further information see lib/DEVELOPMENT.
-
diff --git a/c++/autogen.sh b/c++/autogen.sh
deleted file mode 100755
index 8ed1fd5..0000000
--- a/c++/autogen.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-# Rebuilds the entire foo in one go. One shot, one kill.
-
-rm -rf build/
-mkdir -p build
-cd build
-cmake ..
-make
diff --git a/c++/compiled/README b/c++/compiled/README
deleted file mode 100644
index c2ff791..0000000
--- a/c++/compiled/README
+++ /dev/null
@@ -1,20 +0,0 @@
-Code needed to compile schemas so they can be embeeded into the binary.
-
-According to the xsd example in xsd/examples/cxx/tree/embedded/
-
-xsdbin.cxx
-  Tool for converting one or more XML Schema files to the compressed binary
-  representation. The output is written as a pair of C++ source files 
-  containing the array with the binary data. Use the --help option to see
-  the tool's usage information.
-
-library-schema.hxx
-library-schema.cxx
-  Binary representation of the library.xsd schema. These files are generated
-  by the xsdbin tool.
-
-grammar-input-stream.hxx
-grammar-input-stream.cxx
-  Input stream implementation with the special-purpose schema grammar 
-  decompression algorithm. It is used to load the binary schema representation
-  produced by the xsdbin tool.
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
deleted file mode 100644
index dffff8d..0000000
--- a/c++/compiled/XMLParserWrapper.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "XMLParserWrapper.h"
-
-#include <memory>   // std::auto_ptr
-#include <fstream>
-#include <iostream>
-
-#include <xercesc/dom/DOM.hpp>
-#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
-#include <xercesc/util/PlatformUtils.hpp>
-#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
-#include <xercesc/framework/Wrapper4InputSource.hpp>
-
-#if _XERCES_VERSION >= 30000
-#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
-#else
-#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
-#endif
-
-#include <xsd/cxx/xml/string.hxx>
-#include <xsd/cxx/xml/dom/auto-ptr.hxx>
-#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
-#include <xsd/cxx/xml/sax/std-input-source.hxx>
-
-#include <xsd/cxx/tree/error-handler.hxx>
-
-#include <boost/thread.hpp>
-
-#include "kolabformat-xcal-schema.hxx"
-#include "grammar-input-stream.hxx"
-
-XMLParserWrapper::XMLParserWrapper()
-:   ehp(eh),
-    parser(0),
-    gp(0)
-{
-    // We need to initialize the Xerces-C++ runtime because we
-    // are doing the XML-to-DOM parsing ourselves.
-    //
-    xercesc::XMLPlatformUtils::Initialize ();
-    init();
-}
-
-
-XMLParserWrapper::~XMLParserWrapper()
-{
-    delete parser;
-    delete gp;
-    xercesc::XMLPlatformUtils::Terminate ();
-
-}
-
-boost::thread_specific_ptr<XMLParserWrapper> ptr;
-
-XMLParserWrapper& XMLParserWrapper::inst()
-{
-    XMLParserWrapper *t = ptr.get();
-    if (!t) {
-        t = new XMLParserWrapper();
-        ptr.reset(t);
-    }
-    return *t;
-}
-
-
-void XMLParserWrapper::init()
-{
-    using namespace std;
-    
-    if (parser) {
-        return;
-    }
-    try
-    {
-        using namespace xercesc;
-        namespace xml = xsd::cxx::xml;
-        namespace tree = xsd::cxx::tree;
-        // Create and load the grammar pool.
-        //
-        MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
-
-        gp = new XMLGrammarPoolImpl (mm);
-
-        try
-        {
-            grammar_input_stream is (iCalendar_schema, sizeof (iCalendar_schema));
-            gp->deserializeGrammars(&is);
-        }
-        catch(const XSerializationException& e)
-        {
-            cerr << "unable to load schema: " << xml::transcode<char> (e.getMessage ()) << endl;
-            return;
-        }
-
-        // Lock the grammar pool. This is necessary if we plan to use the
-        // same grammar pool in multiple threads (this way we can reuse the
-        // same grammar in multiple parsers). Locking the pool disallows any
-        // modifications to the pool, such as an attempt by one of the threads
-        // to cache additional schemas.
-        //
-        gp->lockPool ();
-
-        // Get an implementation of the Load-Store (LS) interface.
-        //
-        const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
-
-        DOMImplementation* impl (
-        DOMImplementationRegistry::getDOMImplementation (ls_id));
-
-    #if _XERCES_VERSION >= 30000
-
-        // Xerces-C++ 3.0.0 and later.
-        //
-        parser = impl->createLSParser (
-            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
-
-        DOMConfiguration* conf (parser->getDomConfig ());
-
-        // Discard comment nodes in the document.
-        //
-        conf->setParameter (XMLUni::fgDOMComments, false);
-
-        // Enable datatype normalization.
-        //
-        conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
-
-        // Do not create EntityReference nodes in the DOM tree. No
-        // EntityReference nodes will be created, only the nodes
-        // corresponding to their fully expanded substitution text
-        // will be created.
-        //
-        conf->setParameter (XMLUni::fgDOMEntities, false);
-
-        // Perform namespace processing.
-        //
-        conf->setParameter (XMLUni::fgDOMNamespaces, true);
-
-        // Do not include ignorable whitespace in the DOM tree.
-        //
-        conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
-
-        // Enable validation.
-        //
-        conf->setParameter (XMLUni::fgDOMValidate, true);
-        conf->setParameter (XMLUni::fgXercesSchema, true);
-        conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
-
-        // Xerces-C++ 3.1.0 is the first version with working multi import
-        // support.
-        //
-    #if _XERCES_VERSION >= 30100
-        conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
-    #endif
-
-        // Use the loaded grammar during parsing.
-        //
-        conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
-
-        // Disable loading schemas via other means (e.g., schemaLocation).
-        //
-        conf->setParameter (XMLUni::fgXercesLoadSchema, false);
-
-        // We will release the DOM document ourselves.
-        //
-        conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
-        
-        
-
-        // Set error handler.
-        //
-//         tree::error_handler<char> eh;
-//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
-        conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
-
-    #else // _XERCES_VERSION >= 30000
-
-        // Same as above but for Xerces-C++ 2 series.
-        //
-        parser = impl->createDOMBuilder(
-            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
-
-
-        parser->setFeature (XMLUni::fgDOMComments, false);
-        parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
-        parser->setFeature (XMLUni::fgDOMEntities, false);
-        parser->setFeature (XMLUni::fgDOMNamespaces, true);
-        parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
-        parser->setFeature (XMLUni::fgDOMValidation, true);
-        parser->setFeature (XMLUni::fgXercesSchema, true);
-        parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
-        parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
-        parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
-
-        //tree::error_handler<char> eh;
-//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
-        parser->setErrorHandler (&ehp);
-
-    #endif // _XERCES_VERSION >= 30000
-
-        // Parse XML documents.
-        //
-        
-    }
-    catch (const xml_schema::exception& e) {
-        cout << "schema exception" << endl;
-        cerr << e << endl;
-    } catch (const std::ios_base::failure&) {
-        cerr << ": unable to open or read failure" << endl;
-    }
-    
-}
-
-xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
-{
-    try {
-        std::ifstream ifs;
-        ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
-        ifs.open (url.c_str());
-        return parse(ifs, url);
-    } catch (const std::ios_base::failure&)
-    {
-        std::cerr << ": unable to open or read failure" << std::endl;
-    }
-    return xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument >();
-}
-
-xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
-{
-    std::istringstream is(s);
-    return parse(is, ""); //TODO set identifier?
-}
-
-
-xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::istream &ifs, const std::string &name)
-{
-    using namespace std;
-
-    try
-    {
-        using namespace xercesc;
-        namespace xml = xsd::cxx::xml;
-        namespace tree = xsd::cxx::tree;
-
-        // Parse XML documents.
-        //
-        {
-            // Wrap the standard input stream.
-            //
-            xml::sax::std_input_source isrc (ifs, name);
-            Wrapper4InputSource wrap (&isrc, false);
-
-            // Parse XML to DOM.
-            //
-        #if _XERCES_VERSION >= 30000
-            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
-        #else
-            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
-        #endif
-
-            eh.throw_if_failed<xml_schema::parsing> ();
-            return doc;
-        }
-    }
-    catch (const xml_schema::exception& e)
-    {
-        cerr << "schema exception" << endl;
-        cerr << e << endl;
-    }
-    catch (const std::ios_base::failure&)
-    {
-        cerr << ": unable to open or read failure" << endl;
-    }
-    catch (...)
-    {
-        cerr << ": unknown exception thrown" << endl;
-    }
-    eh.reset();
-    return xml_schema::dom::auto_ptr<xercesc::DOMDocument>();
-}
\ No newline at end of file
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
deleted file mode 100644
index 86a76c1..0000000
--- a/c++/compiled/XMLParserWrapper.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef XMLPARSER_WRAPPER_H
-#define XMLPARSER_WRAPPER_H
-
-#include <string>
-#include <memory>
-#include <bindings/kolabformat-xcal.hxx>
-#include <xsd/cxx/tree/error-handler.hxx>
-#include <boost/scoped_ptr.hpp>
-#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
-
-#if _XERCES_VERSION >= 30000
-#  include <xercesc/dom/DOMLSParser.hpp>
-#  include <xercesc/dom/DOMLSException.hpp>
-#else
-#  include <xercesc/dom/DOMBuilder.hpp>
-#endif
-
-#include <xercesc/framework/XMLGrammarPool.hpp>
-
-/**
- * This wrapper controls the lifetime of the parser object.
- * 
- * Initializing the parser is much more expensive than parsing a single XML document, therefore the parser should be reused if possible.
- * 
- * It might make sense to use a singleton internally to keep the parser alive between usages. Alternatively this object can be kept alive for as long as it makes sense.
- * 
- * This class also encapsulates the initialization of the whole parser, which must be done manually because precomiled schemas are used (which greatly improves the initialization performance).
- * 
- * Writing the document is static and doesn't need any initialization and is therefore not wrapped by this object.
- * 
- */
-
-class XMLParserWrapper {
-public:
-    XMLParserWrapper();
-    ~XMLParserWrapper();
-    
-    /**
-     * Threadsafe singleton. One Xerces instance is created per thread (threadlocal).
-     * Access via singleton to reuse parser.
-     */
-    static XMLParserWrapper &inst();
-    
-    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
-    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
-    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
-private:
-    void init();
-    xsd::cxx::tree::error_handler<char> eh;
-    xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
-
-    #if _XERCES_VERSION >= 30000
-        xercesc::DOMLSParser  *parser;
-    #else
-        xercesc::DOMBuilder  *parser;
-    #endif
-    xercesc::XMLGrammarPool *gp;
-};
-
-
-#endif
-
-
-
-
-
-
-
-
-
-
-
diff --git a/c++/compiled/grammar-input-stream.cxx b/c++/compiled/grammar-input-stream.cxx
deleted file mode 100644
index 0c94ea6..0000000
--- a/c++/compiled/grammar-input-stream.cxx
+++ /dev/null
@@ -1,115 +0,0 @@
-// file      : examples/cxx/tree/embedded/grammar-input-stream.cxx
-// author    : Boris Kolpackov <boris at codesynthesis.com>
-// copyright : not copyrighted - public domain
-
-#include <cassert>
-#include "grammar-input-stream.hxx"
-
-grammar_input_stream::
-grammar_input_stream (const XMLByte* data, std::size_t size)
-      : data_ (data),
-        size_ (size),
-        pos_ (0),
-        vpos_ (0),
-        cseq_ (0),
-        add_zero_ (false)
-{
-}
-
-#if _XERCES_VERSION >= 30000
-XMLFilePos grammar_input_stream::
-curPos () const
-{
-  return static_cast<XMLFilePos> (vpos_);
-}
-#else
-unsigned int grammar_input_stream::
-curPos () const
-{
-  return static_cast<unsigned int> (vpos_);
-}
-#endif
-
-#if _XERCES_VERSION >= 30000
-XMLSize_t grammar_input_stream::
-readBytes (XMLByte* const buf, const XMLSize_t size)
-#else
-unsigned int grammar_input_stream::
-readBytes (XMLByte* const buf, const unsigned int size)
-#endif
-{
-  std::size_t i (0);
-
-  // Add a zero from the alternating sequence if it didn't
-  // fit on the previous read.
-  //
-  if (add_zero_)
-  {
-    buf[i++] = 0;
-    add_zero_ = false;
-  }
-
-  // If have an unfinished sequential sequence, output it now.
-  //
-  if (cseq_ != 0 && !alt_)
-  {
-    for (; cseq_ != 0 && i < size; --cseq_)
-      buf[i++] = 0;
-  }
-
-  for (; i < size && pos_ < size_;)
-  {
-    XMLByte b = buf[i++] = data_[pos_++];
-
-    // See if we are in a compression sequence.
-    //
-    if (cseq_ != 0)
-    {
-      if (i < size)
-        buf[i++] = 0;
-      else
-        add_zero_ = true; // Add it on the next read.
-
-      cseq_--;
-      continue;
-    }
-
-    // If we are not in a compression sequence and this byte is
-    // not zero then we are done.
-    //
-    if (b != 0)
-      continue;
-
-    // We have a zero.
-    //
-    assert (pos_ < size_); // There has to be another byte.
-    unsigned char v (static_cast<unsigned char> (data_[pos_++]));
-    alt_ = (v & 128) != 0;
-    cseq_ = v & 127;
-
-    // If it is a sequential sequence, output as many zeros as
-    // we can.
-    //
-    if (!alt_)
-    {
-      for (; cseq_ != 0 && i < size; --cseq_)
-        buf[i++] = 0;
-    }
-  }
-
-  vpos_ += i;
-
-#if _XERCES_VERSION >= 30000
-  return static_cast<XMLSize_t> (i);
-#else
-  return static_cast<unsigned int> (i);
-#endif
-}
-
-#if _XERCES_VERSION >= 30000
-const XMLCh* grammar_input_stream::
-getContentType () const
-{
-  return 0;
-}
-#endif
diff --git a/c++/compiled/grammar-input-stream.hxx b/c++/compiled/grammar-input-stream.hxx
deleted file mode 100644
index a1b73c6..0000000
--- a/c++/compiled/grammar-input-stream.hxx
+++ /dev/null
@@ -1,53 +0,0 @@
-// file      : examples/cxx/tree/embedded/grammar-input-stream.hxx
-// author    : Boris Kolpackov <boris at codesynthesis.com>
-// copyright : not copyrighted - public domain
-
-#ifndef GRAMMAR_INPUT_STREAM_HXX
-#define GRAMMAR_INPUT_STREAM_HXX
-
-#include <cstddef>
-#include <xercesc/util/BinInputStream.hpp>
-
-// Memory buffer input stream with the special-purpose schema
-// grammar decompression.
-//
-class grammar_input_stream: public xercesc::BinInputStream
-{
-public :
-  grammar_input_stream (const XMLByte* data, std::size_t size);
-
-#if _XERCES_VERSION >= 30000
-
-  virtual XMLFilePos
-  curPos () const;
-
-  virtual XMLSize_t
-  readBytes (XMLByte* const buf, const XMLSize_t size);
-
-  virtual const XMLCh*
-  getContentType () const;
-
-#else
-
-  virtual unsigned int
-  curPos () const;
-
-  virtual unsigned int
-  readBytes (XMLByte* const buf, const unsigned int size);
-
-#endif
-
-private :
-  const XMLByte* data_;
-  std::size_t size_;
-  std::size_t pos_;
-  std::size_t vpos_;
-
-  // Compression data.
-  //
-  size_t cseq_;   // Number of bytes left in a compression sequence.
-  bool alt_;      // Alternating or sequential sequence.
-  bool add_zero_; // Add a zero on the next read.
-};
-
-#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/c++/compiled/xsdbin.cxx b/c++/compiled/xsdbin.cxx
deleted file mode 100644
index 53e2533..0000000
--- a/c++/compiled/xsdbin.cxx
+++ /dev/null
@@ -1,505 +0,0 @@
-// file      : examples/cxx/tree/embedded/xsdbin.cxx
-// author    : Boris Kolpackov <boris at codesynthesis.com>
-// copyright : not copyrighted - public domain
-
-// This program loads the XML Schema file(s) and converts them to
-// the Xerces-C++ binary schema format which can then be embedded
-// into C++ programs and used to validate XML documents. The output
-// is written as a C++ source file containing the array with the
-// binary data.
-//
-
-#include <string>
-#include <memory>   // std::auto_ptr
-#include <cstddef>  // std::size_t
-#include <fstream>
-#include <iostream>
-
-#include <xercesc/util/XMLUni.hpp>
-#include <xercesc/util/XMLString.hpp>
-#include <xercesc/util/PlatformUtils.hpp>
-#include <xercesc/util/XercesVersion.hpp>
-
-#include <xercesc/internal/BinMemOutputStream.hpp>
-#include <xercesc/validators/common/Grammar.hpp>
-
-#include <xercesc/sax/ErrorHandler.hpp>
-#include <xercesc/sax/SAXParseException.hpp>
-#include <xercesc/sax2/SAX2XMLReader.hpp>
-#include <xercesc/sax2/XMLReaderFactory.hpp>
-
-#if _XERCES_VERSION >= 30000
-#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
-#else
-#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
-#endif
-
-using namespace std;
-using namespace xercesc;
-
-class error_handler: public ErrorHandler
-{
-public:
-  error_handler ()
-      : failed_ (false)
-  {
-  }
-
-  bool
-  failed () const
-  {
-    return failed_;
-  }
-
-  enum severity {s_warning, s_error, s_fatal};
-
-  virtual void
-  warning (const SAXParseException&);
-
-  virtual void
-  error (const SAXParseException&);
-
-  virtual void
-  fatalError (const SAXParseException&);
-
-  virtual void
-  resetErrors ()
-  {
-    failed_ = false;
-  }
-
-  void
-  handle (const SAXParseException&, severity);
-
-private:
-  bool failed_;
-};
-
-void
-cxx_escape (string&);
-
-int
-main (int argc, char* argv[])
-{
-  const char* hxx_suffix = "-schema.hxx";
-  const char* cxx_suffix = "-schema.cxx";
-
-  string name;
-  string base;
-  string outdir;
-
-  class usage {};
-
-  int argi (1);
-  bool help (false);
-  bool multi_import (true);
-  bool verbose (false);
-
-  try
-  {
-    for (; argi < argc; ++argi)
-    {
-      string a (argv[argi]);
-
-      if (a == "--help")
-      {
-        help = true;
-        throw usage ();
-      }
-      else if (a == "--verbose")
-      {
-        verbose = true;
-      }
-      else if (a == "--hxx-suffix")
-      {
-        if (++argi >= argc)
-          throw usage ();
-
-        hxx_suffix = argv[argi];
-      }
-      else if (a == "--cxx-suffix")
-      {
-        if (++argi >= argc)
-          throw usage ();
-
-        cxx_suffix = argv[argi];
-      }
-      else if (a == "--output-dir")
-      {
-        if (++argi >= argc)
-          throw usage ();
-
-        outdir = argv[argi];
-      }
-      else if (a == "--array-name")
-      {
-        if (++argi >= argc)
-          throw usage ();
-
-        name = argv[argi];
-      }
-      else if (a == "--disable-multi-import")
-      {
-        multi_import = false;
-      }
-      else
-        break;
-    }
-
-    if (argi >= argc)
-    {
-      cerr << "no input file specified" << endl;
-      throw usage ();
-    }
-
-    base = argv[argi];
-  }
-  catch (usage const&)
-  {
-    cerr << "Usage: " << argv[0] << " [options] <files>" << endl
-         << "Options:" << endl
-         << "  --help                 Print usage information and exit." << endl
-         << "  --verbose              Print progress information." << endl
-         << "  --output-dir <dir>     Write generated files to <dir>." << endl
-         << "  --hxx-suffix <sfx>     Header file suffix instead of '-schema.hxx'." << endl
-         << "  --cxx-suffix <sfx>     Source file suffix instead of '-schema.cxx'." << endl
-         << "  --array-name <name>    Binary data array name." << endl
-         << "  --disable-multi-import Disable multiple import support." << endl
-         << endl;
-
-    return help ? 0 : 1;
-  }
-
-  XMLPlatformUtils::Initialize ();
-
-  {
-    MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
-
-    auto_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
-
-    // Load the schemas into grammar pool.
-    //
-    {
-      auto_ptr<SAX2XMLReader> parser (
-        XMLReaderFactory::createXMLReader (mm, gp.get ()));
-
-      parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
-      parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
-      parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
-      parser->setFeature (XMLUni::fgXercesSchema, true);
-      parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true);
-      parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
-
-      // Xerces-C++ 3.1.0 is the first version with working multi import
-      // support.
-      //
-#if _XERCES_VERSION >= 30100
-      parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import);
-#endif
-
-      error_handler eh;
-      parser->setErrorHandler (&eh);
-
-      for (; argi < argc; ++argi)
-      {
-        if (verbose)
-          cerr << "loading " << argv[argi] << endl;
-
-        if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true))
-        {
-          cerr << argv[argi] << ": error: unable to load" << endl;
-          return 1;
-        }
-
-        if (eh.failed ())
-          return 1;
-      }
-    }
-
-    // Get the binary representation.
-    //
-    BinMemOutputStream data;
-
-    try
-    {
-      gp->serializeGrammars (&data);
-    }
-    catch (const XSerializationException& e)
-    {
-      char* msg (XMLString::transcode (e.getMessage ()));
-      cerr << "error: " << msg << endl;
-      XMLString::release (&msg);
-      return 1;
-    }
-
-    size_t n (static_cast<size_t> (data.curPos ()));
-    const unsigned char* buf (
-      static_cast<const unsigned char*> (data.getRawBuffer ()));
-
-    if (verbose)
-      cerr << "uncomressed data size " << n << " bytes" << endl;
-
-    // Compress zeros.
-    //
-    size_t cn (0);
-    unsigned char* cbuf = new unsigned char[n];
-
-    size_t cseq (0);  // Number of bytes left in a compression sequence.
-    bool alt (false); // Alternating or sequential sequence.
-
-    for (size_t i (0); i < n;)
-    {
-      unsigned char v (buf[i++]);
-
-      // See if we are in a compression sequence.
-      //
-      if (cseq != 0)
-      {
-        // See if this byte needs to be copied.
-        //
-        if (alt && cseq % 2 == 0)
-          cbuf[cn++] = v;
-
-        cseq--;
-        continue;
-      }
-
-      // If we are not in a compression sequence and this byte is
-      // not zero then simply copy it.
-      //
-      if (v != 0)
-      {
-        cbuf[cn++] = v;
-        continue;
-      }
-
-      // We have a zero.
-      //
-      cbuf[cn++] = 0;
-
-      // See if we can start a new compression sequence.
-      //
-      if (i < n)
-      {
-        if (buf[i] == 0)
-        {
-          // Sequential sequence. See how far it runs.
-          //
-          alt = false;
-
-          for (cseq = 1; cseq < 127 && cseq + i < n; cseq++)
-            if (buf[cseq + i] != 0)
-              break;
-        }
-        else if (i + 1 < n && buf[i + 1] == 0)
-        {
-          // Alternating sequence. See how far it runs.
-          //
-          alt = true;
-
-          for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++)
-          {
-            if (buf[cseq * 2 + i + 1] != 0)
-              break;
-
-            // For longer sequences prefer sequential to alternating.
-            //
-            if (cseq > 2 &&
-                buf[cseq * 2 + i] == 0 &&
-                buf[(cseq - 1) * 2 + i] == 0 &&
-                buf[(cseq - 2) * 2 + i] == 0)
-            {
-              cseq -= 2;
-              break;
-            }
-          }
-
-          cseq *= 2;
-        }
-      }
-
-      if (cseq != 0)
-      {
-        cbuf[cn++] = static_cast<unsigned char> (
-          alt ? (128  | cseq / 2) : cseq);
-      }
-      else
-        cbuf[cn++] = 0;
-    }
-
-    if (verbose)
-      cerr << "comressed data size " << cn << " bytes" << endl;
-
-    buf = cbuf;
-    n = cn;
-
-    // Figure out the file names.
-    //
-    string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\'));
-
-    if (p1 != string::npos && p1 > p)
-      p = p1;
-
-    if (p != string::npos)
-      base = string (base, p + 1);
-
-    p = base.rfind ('.');
-
-    if (p != string::npos)
-      base.resize (p);
-
-    string hxx (base + hxx_suffix);
-    string cxx (base + cxx_suffix);
-
-    if (!outdir.empty ())
-    {
-#if defined (WIN32) || defined (__WIN32__)
-      hxx = outdir + '\\' + hxx;
-      cxx = outdir + '\\' + cxx;
-#else
-      hxx = outdir + '/' + hxx;
-      cxx = outdir + '/' + cxx;
-#endif
-    }
-
-    if (name.empty ())
-    {
-      name = base + "_schema";
-      cxx_escape (name);
-    }
-
-    // Write header.
-    //
-    {
-      ofstream os (hxx.c_str ());
-
-      if (!os.is_open ())
-      {
-        cerr << hxx << ": error: unable to open" << endl;
-        return 1;
-      }
-
-      os << "// Automatically generated. Do not edit." << endl
-         << "//" << endl
-         << endl
-         << "#include <xercesc/util/XercesDefs.hpp>" << endl
-         << endl
-         << "extern const XMLByte " << name << "[" << n << "UL];" << endl;
-    }
-
-    {
-      ofstream os (cxx.c_str ());
-
-      if (!os.is_open ())
-      {
-        cerr << cxx << ": error: unable to open" << endl;
-        return 1;
-      }
-
-      os << "// Automatically generated. Do not edit." << endl
-         << "//" << endl
-         << endl
-         << "#include <xercesc/util/XercesDefs.hpp>" << endl
-         << "#include <xercesc/util/XercesVersion.hpp>" << endl
-         << endl
-         << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " <<
-        XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl
-         << "#  error incompatible Xerces-C++ version detected" << endl
-         << "#endif" << endl
-         << endl
-         << "extern const XMLByte " << name << "[" << n << "UL] =" << endl
-         << "{";
-
-      for (size_t i (0); i < n; ++i)
-      {
-        if (i != 0)
-          os << ',';
-
-        os << (i % 12 == 0 ? "\n  " : " ") << "0x";
-        os.width (2);
-        os.fill ('0');
-        os << hex << static_cast<unsigned short> (buf[i]);
-      }
-
-      os << endl
-         << "};" << endl
-         << endl;
-    }
-
-    delete[] cbuf;
-  }
-
-  XMLPlatformUtils::Terminate ();
-}
-
-void
-cxx_escape (string& s)
-{
-  for (string::size_type i (0); i < s.size (); ++i)
-  {
-    char& c (s[i]);
-
-    if (i == 0)
-    {
-      if (!((c >= 'a' && c <= 'z') ||
-            (c >= 'A' && c <= 'Z') ||
-            c == '_'))
-        c = '_';
-    }
-    else
-    {
-      if (!((c >= 'a' && c <= 'z') ||
-            (c >= 'A' && c <= 'Z') ||
-            (c >= '0' && c <= '9') ||
-            c == '_'))
-        c = '_';
-    }
-  }
-}
-
-void error_handler::
-warning (const SAXParseException& e)
-{
-  handle (e, s_warning);
-}
-
-void error_handler::
-error (const SAXParseException& e)
-{
-  failed_ = true;
-  handle (e, s_error);
-}
-
-void error_handler::
-fatalError (const SAXParseException& e)
-{
-  failed_ = true;
-  handle (e, s_fatal);
-}
-
-void error_handler::
-handle (const SAXParseException& e, severity s)
-{
-  const XMLCh* xid (e.getPublicId ());
-
-  if (xid == 0)
-    xid = e.getSystemId ();
-
-  char* id (XMLString::transcode (xid));
-  char* msg (XMLString::transcode (e.getMessage ()));
-
-  cerr << id << ":";
-
-#if _XERCES_VERSION >= 30000
-  cerr << e.getLineNumber () << ":" << e.getColumnNumber () << " ";
-#else
-  XMLSSize_t l (e.getLineNumber ());
-  XMLSSize_t c (e.getColumnNumber ());
-  cerr << (l == -1 ? 0 : l) << ":" << (c == -1 ? 0 : c) << " ";
-#endif
-
-  cerr << (s == s_warning ? "warning: " : "error: ") << msg << endl;
-
-  XMLString::release (&id);
-  XMLString::release (&msg);
-}
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
deleted file mode 100644
index 90f31f0..0000000
--- a/c++/lib/CMakeLists.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-
-SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
-
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wp,-D_FORTIFY_SOURCE=2 -O2" ) #always generate shared libraries with -fPIC, -D_FORTIFY_SOURCE=2 enables some extra checking
-
-#Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabnote.cpp kolabevent.cpp kolabtodo.cpp kolabjournal.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-
-target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID})
-
-#For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
-set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wl,--no-undefined")
-set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
-
-install(TARGETS kolabxml ${KOLAB_INSTALL_DIRECTORIES})
-
-install( FILES
-    kolabformat.h
-    kolabevent.h
-    kolabtodo.h
-    kolabjournal.h
-    kolabcontact.h
-    kolabnote.h
-    kolabcontainers.h
-    global_definitions.h
-    DESTINATION ${KOLAB_HEADER_INSTALL_DIR} COMPONENT Devel)
-
-#----- The following makes sure libkolabxml is found in the install directory for installed files and not in the build directory (for libraries which link to libkolabxml)
-
-# use, i.e. don't skip the full RPATH for the build tree
-SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
-# when building, don't use the install RPATH already(but later on when installing)
-SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
-SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
-# add the automatically determined parts of the RPATH
-# which point to directories outside the build tree to the install RPATH
-SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-# the RPATH to be used when installing, but only if it's not a system directory
-LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${KOLAB_LIB_INSTALL_DIR}" isSystemDir)
-IF("${isSystemDir}" STREQUAL "-1")
-   SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
-ENDIF("${isSystemDir}" STREQUAL "-1")
-
-#-----------------------SWIG--------------------
-
-if (SWIG_FOUND)
-    add_subdirectory(python)
-    add_subdirectory(php)
-else()
-    message(WARNING "Could not build SWIG bindings, because SWIG is missing.")
-endif()
-
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
deleted file mode 100644
index d6730e1..0000000
--- a/c++/lib/DEVELOPMENT
+++ /dev/null
@@ -1,104 +0,0 @@
-== General Design Notes==
-
-* Although many values are optional, the library doesn't differentiate between set and not set values. The approach taken is to not write out values which are still on the default value in order to keep objects small.
-The downside of this is that an xml object could be modified although no values have been modified (because default values are not written out again).
-
-== Libraries ==
-
-=== libkolabxml ===
-Dependencies:
-* boost
-* xerces
-
-The core library providing the xml-serialization functions and containers for all types.
-
-=== libkolabkcal ===
-Dependencies:
-* libkolabxml
-* kcalcore
-* kdecore
-
-Library to provide converters to KCalCore containers as well as advanced functionality from KCalCore (such as expansion of recurrences) through SWIG bindings.
-
-=== kolabxmlkcal (deprecated) ===
-
-First approach which does a direct mapping from xml to KCalCore containers. 
-It turned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
-Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend.
-
-== Code architecture ==
-
-Care was taken to implement each conversion/mapping only once. The code makes heavy use of templates to achieve this.
-Due to the different formats the conversion functions were split up among formats (not much to share between those).
-
-xCal: genericxcalconversions.h, xcalconversions.h (genericxcalconversions are implementations which work for both Kolab Containers and KCalCore containers)
-xCard: kolabxcardconversions.h
-kolab: kolabconversions.h (TODO)
-
-All conversions are typesafe as far as possible (i.e. a conversion from uint to int is always done through a numeric cast), to make sure there are no hard-to-track-down edge cases (such as an overflow).
-
-== Kolab Containers ==
-
-While SWIG can handle all possible return values, the resulting code uses either a newly allocated object (return by value / or return by const reference), or passes back a pointer (return by reference/pointer).
-So return by const reference doesn't save anything for the bindings (it could potentially for c++ code).
-Returning references contains the danger of dangling pointers if the reference outlives the object.
-
-Datamembers are not directly exposed to provide binary compatibilty through the d-pointer.
-
-Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value).
-
-Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
-
-The containers do not use inheritance to ensure maximum compatibilty with SWIG (although SWIG provides inheritance for some languages).
-They were also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur.
-
-The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
-
-The validity of the containers can be checked using the isValid() function. This function is used to check if a value has been set, and does not really verifiy the validity of the values in terms of what ranges/combinations are allowed.
-
-=== Why KCalCore containers were not directly used ===
-
-KCalCore provides containers for all ical based functionality (events/todos/journals).
-
-They were not directly used because:
-- dependencies: depends on kdelibs and qt (event qt gui). Some serious work would be needed to be able to ship those containers with a minimum set of dependencies.
-- SWIG: It seems difficult to properly wrap those containers using SWIG (inheritance heavily used, Qt containers (for which we have no bindings), not easily copiable (special copy memberfucntion is needed due to internal use of pointers))
-- Consistency: because we anyways have containers out of the scope of KCalCore, we can provide this way a consistent interface, which represents exactly the Kolab defined functionality (while KCalCore would be a close, but not a perfect match).
-
-Overall using our own containers seems like the safer and more flexible approach. This way it's also possible to provide a reading/writing library with a minimum set of dependencies.
-
-== SWIG language bindings ==
-
-Bindings for PHP and Python are provided through SWIG.
-
-"make install" produces two directories with the necessary files in build/lib/pythonbindings and build/lib/phpbindings.
-The test script should show the usage of the bindings.
-
-== Performance ==
-
-The biggest performance hog is the initialization of the parser. First, when loading the schema from disk upon initialization, parsing a single file took ~16ms on my machine (just for comparison).
-After compiling the schema to a binary representation, it still took ~7ms. By reusing the parser it went down to ~0.35ms.
-
-Writing the files is not validating and therefore always fast (doesn't need a special parser or alike). Once the parser is initialized, reading is roughly as fast as writing.
-
-Currently the parser is kept in a singleton (XMLParserWrapper).
-Alternatively one could control the lifetime from the bindings through an initialization object which keeps the parser alive through a shared pointer. This way the parser could be initialized on demand and the memory used by the parser could be freed between runs. 
-
-For further performance improvements read this: http://xerces.apache.org/xerces2-j/faq-performance.html
-
-== Error Handling ==
-
-All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that.
-If an error occurs a message is printed to the standard error output and a default constructed value is returned.
-
-Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
-
-
-
-=== The XSD based development checklist ===
--Don't forget to add an element for each attribute in the style off: <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
- Otherwise you won't get the serialization/deserialization code (or respectively just wrong code), which still compiles though and looks correct from the outside.
-
--If you have modified the xsd's make sure to run "make clean && make" in the toplevel make directory, otherwise the schema is not recompiles => parsing errors
-
--Make sure you add new .xsd to the compiled schemas, otherwise you'll get "no declaration found" errors.
diff --git a/c++/lib/base64.cpp b/c++/lib/base64.cpp
deleted file mode 100644
index 071b05c..0000000
--- a/c++/lib/base64.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* 
-   base64.cpp and base64.h
-
-   Copyright (C) 2004-2008 René Nyffenegger
-
-   This source code is provided 'as-is', without any express or implied
-   warranty. In no event will the author be held liable for any damages
-   arising from the use of this software.
-
-   Permission is granted to anyone to use this software for any purpose,
-   including commercial applications, and to alter it and redistribute it
-   freely, subject to the following restrictions:
-
-   1. The origin of this source code must not be misrepresented; you must not
-      claim that you wrote the original source code. If you use this source code
-      in a product, an acknowledgment in the product documentation would be
-      appreciated but is not required.
-
-   2. Altered source versions must be plainly marked as such, and must not be
-      misrepresented as being the original source code.
-
-   3. This notice may not be removed or altered from any source distribution.
-
-   René Nyffenegger rene.nyffenegger at adp-gmbh.ch
-
-*/
-
-#include "base64.h"
-#include <iostream>
-
-static const std::string base64_chars = 
-             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-             "abcdefghijklmnopqrstuvwxyz"
-             "0123456789+/";
-
-
-static inline bool is_base64(unsigned char c) {
-  return (isalnum(c) || (c == '+') || (c == '/'));
-}
-
-std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
-  std::string ret;
-  int i = 0;
-  int j = 0;
-  unsigned char char_array_3[3];
-  unsigned char char_array_4[4];
-
-  while (in_len--) {
-    char_array_3[i++] = *(bytes_to_encode++);
-    if (i == 3) {
-      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-      char_array_4[3] = char_array_3[2] & 0x3f;
-
-      for(i = 0; (i <4) ; i++)
-        ret += base64_chars[char_array_4[i]];
-      i = 0;
-    }
-  }
-
-  if (i)
-  {
-    for(j = i; j < 3; j++)
-      char_array_3[j] = '\0';
-
-    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-    char_array_4[3] = char_array_3[2] & 0x3f;
-
-    for (j = 0; (j < i + 1); j++)
-      ret += base64_chars[char_array_4[j]];
-
-    while((i++ < 3))
-      ret += '=';
-
-  }
-
-  return ret;
-
-}
-
-std::string base64_decode(std::string const& encoded_string) {
-  int in_len = encoded_string.size();
-  int i = 0;
-  int j = 0;
-  int in_ = 0;
-  unsigned char char_array_4[4], char_array_3[3];
-  std::string ret;
-
-  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
-    char_array_4[i++] = encoded_string[in_]; in_++;
-    if (i ==4) {
-      for (i = 0; i <4; i++)
-        char_array_4[i] = base64_chars.find(char_array_4[i]);
-
-      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-      for (i = 0; (i < 3); i++)
-        ret += char_array_3[i];
-      i = 0;
-    }
-  }
-
-  if (i) {
-    for (j = i; j <4; j++)
-      char_array_4[j] = 0;
-
-    for (j = 0; j <4; j++)
-      char_array_4[j] = base64_chars.find(char_array_4[j]);
-
-    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
-  }
-
-  return ret;
-}
\ No newline at end of file
diff --git a/c++/lib/base64.h b/c++/lib/base64.h
deleted file mode 100644
index 5f87aec..0000000
--- a/c++/lib/base64.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <string>
-
-std::string base64_encode(unsigned char const* , unsigned int len);
-std::string base64_decode(std::string const& s);
-
diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
deleted file mode 100644
index 2aa36e8..0000000
--- a/c++/lib/global_definitions.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef GLOBAL_DEFINITIONS_H
-#define GLOBAL_DEFINITIONS_H
-#include <string>
-
-namespace Kolab {
-
-const char* const KOLAB_LIBNAME = "libkolabxml";
-const char* const KOLAB_LIB_VERSION = "0.1";
-const char* const KOLAB_FORMAT_VERSION = "3.0dev1";
-
-enum ErrorSeverity {
-    NoError,
-    Warning, //Warning, error could be corrected, object can be used without dataloss
-    Error, //Potentially corrupt object, writing the object back could result in dataloss. (Object could still be used to display the data readonly).
-    Critical //Ciritcal error, produced object cannot be used and should be thrown away (writing back will result in dataloss).
-};
-
-}
-
-#endif
diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
deleted file mode 100644
index 5f2dc12..0000000
--- a/c++/lib/incidence_p.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INCIDENCE_P
-#define INCIDENCE_P
-
-#include "kolabcontainers.h"
-
-namespace Kolab {
-    
-    struct PrivateIncidence
-    {
-        PrivateIncidence()
-        : sequence(0),
-        classification(ClassPublic),
-        thisAndFuture(false),
-        priority(0),
-        status(StatusUndefined){}
-        
-        std::string uid;
-        cDateTime created;
-        cDateTime lastModified;
-        int sequence;
-        Classification classification;
-        std::vector< std::string > categories;
-        std::vector< std::string > relatedTo;
-        cDateTime start;
-        
-        cDateTime recurrenceID;
-        bool thisAndFuture;
-        std::string summary;
-        std::string description;
-        std::string location;
-        int priority;
-        Status status;
-        RecurrenceRule rrule;
-        std::vector< cDateTime > recurrenceDates;
-        std::vector< cDateTime > exceptionDates;
-        ContactReference organizer;
-        Duration duration;
-        
-        std::vector<Attendee> attendees;
-        std::vector<Attachment> attachments;
-        std::vector<CustomProperty> customProperties;
-        
-        std::vector<Alarm> alarms;
-    };
-    
-}
-
-#endif
\ No newline at end of file
diff --git a/c++/lib/kolabcontact.cpp b/c++/lib/kolabcontact.cpp
deleted file mode 100644
index a959a2c..0000000
--- a/c++/lib/kolabcontact.cpp
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabcontact.h"
-
-namespace Kolab {
-    
-struct DistList::Private
-{
-    Private() {}
-    
-    std::string uid;
-    cDateTime lastModified;
-    std::vector< std::string > categories;
-    
-    std::string name;
-    std::vector<ContactReference> members;
-    std::vector<CustomProperty> customProperties;
-};
-    
-DistList::DistList()
-: d(new DistList::Private())
-{
-    
-}
-
-DistList::DistList(const DistList &other)
-: d(new DistList::Private())
-{
-    *d = *other.d;
-}
-
-DistList::~DistList()
-{
-    
-}
-
-void DistList::operator=(const Kolab::DistList &other)
-{
-    *d = *other.d;
-}
-
-bool DistList::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void DistList::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string DistList::uid() const
-{
-    return d->uid;
-}
-
-void DistList::setLastModified(const Kolab::cDateTime &dt)
-{
-    d->lastModified = dt;
-}
-
-cDateTime DistList::lastModified() const
-{
-    return d->lastModified;
-}
-
-void DistList::setName(const std::string &name)
-{
-    d->name = name;
-}
-
-std::string DistList::name() const
-{
-    return d->name;
-}
-
-void DistList::setMembers(const std::vector< ContactReference > &members)
-{
-    d->members = members;
-}
-
-std::vector< ContactReference > DistList::members() const
-{
-    return d->members;
-}
-
-void DistList::setCustomProperties(const std::vector< CustomProperty >& c)
-{
-    d->customProperties = c;
-}
-
-std::vector< CustomProperty > DistList::customProperties() const
-{
-    return d->customProperties;
-}
-
-
-
-
-
-    
-struct Contact::Private
-{
-    Private()
-    :  addressPreferredIndex(-1),
-    gender(NotSet),
-    telephonesPreferredIndex(-1),
-    imAddressPreferredIndex(-1),
-    emailAddressPreferredIndex(-1)
-    {}
-    
-    std::string uid;
-    cDateTime created;
-    cDateTime lastModified;
-    std::vector< std::string > categories;
-    
-    std::string name;
-    NameComponents nameComponents;
-    std::string note;
-    std::string freeBusyUrl;
-    std::vector< std::string > titles;
-    std::vector<Affiliation> affiliations;
-    std::vector<std::string> urls;
-    std::vector<Address> addresses;
-    int addressPreferredIndex;
-    std::vector<std::string> nickNames;
-    std::vector<Related> relateds;
-    cDateTime bDay;
-    cDateTime anniversary;
-    std::string photo;
-    std::string photoMimetype;
-    Gender gender;
-    std::vector<std::string> languages;
-    std::vector<Telephone> telephones;
-    int telephonesPreferredIndex;
-    std::vector<std::string> imAddresses;
-    int imAddressPreferredIndex;
-    std::vector<std::string> emailAddresses;
-    int emailAddressPreferredIndex;
-    std::vector<Geo> gpsPos;
-    Crypto crypto;
-    std::vector<CustomProperty> customProperties;
-};
-
-Contact::Contact()
-: d(new Contact::Private())
-{
-    
-}
-
-Contact::Contact(const Contact &other)
-: d(new Contact::Private())
-{
-    *d = *other.d;
-}
-
-Contact::~Contact()
-{
-    
-}
-
-void Contact::operator=(const Kolab::Contact &other)
-{
-    *d = *other.d;
-}
-
-bool Contact::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void Contact::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Contact::uid() const
-{
-    return d->uid;
-}
-
-void Contact::setLastModified(const Kolab::cDateTime &dt)
-{
-    d->lastModified = dt;
-}
-
-cDateTime Contact::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Contact::setCategories(const std::vector< std::string > &cat)
-{
- d->categories = cat;
-}
-
-void Contact::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Contact::categories() const
-{
-    return d->categories;
-}
-
-void Contact::setName(const std::string &name)
-{
-    d->name = name;
-}
-
-std::string Contact::name() const
-{
-    return d->name;
-}
-
-void Contact::setNameComponents(const Kolab::NameComponents &nc)
-{
-    d->nameComponents = nc;
-}
-
-NameComponents Contact::nameComponents() const
-{
-    return d->nameComponents;
-}
-
-void Contact::setNote(const std::string &note)
-{
-    d->note = note;
-}
-
-std::string Contact::note() const
-{
-    return d->note;
-}
-
-void Contact::setFreeBusyUrl(const std::string &url)
-{
-    d->freeBusyUrl = url;
-}
-
-std::string Contact::freeBusyUrl() const
-{
-    return d->freeBusyUrl;
-}
-
-void Contact::setTitles(const std::vector< std::string >& titles)
-{
-    d->titles = titles;
-}
-
-std::vector< std::string > Contact::titles() const
-{
-    return d->titles;
-}
-
-
-void Contact::setAffiliations(const std::vector< Affiliation > &a)
-{
-    d->affiliations = a;
-}
-
-std::vector< Affiliation > Contact::affiliations() const
-{
-    return d->affiliations;
-}
-
-void Contact::setUrls(const std::vector< std::string > &urls)
-{
-    d->urls = urls;
-}
-
-std::vector< std::string > Contact::urls() const
-{
-    return d->urls;
-}
-
-void Contact::setAddresses(const std::vector< Address > &ad, int preferred)
-{
-    d->addresses = ad;
-    d->addressPreferredIndex = preferred;
-}
-
-std::vector< Address > Contact::addresses() const
-{
-    return d->addresses;
-}
-
-int Contact::addressPreferredIndex() const
-{
-    return d->addressPreferredIndex;
-}
-
-
-void Contact::setNickNames(const std::vector< std::string > &n)
-{
-    d->nickNames = n;
-}
-
-std::vector< std::string > Contact::nickNames() const
-{
-    return d->nickNames;
-}
-
-void Contact::setRelateds(const std::vector< Related > &relateds)
-{
-    d->relateds = relateds;
-}
-
-std::vector< Related > Contact::relateds() const
-{
-    return d->relateds;
-}
-
-void Contact::setBDay(const Kolab::cDateTime &bday)
-{
-    d->bDay = bday;
-}
-
-cDateTime Contact::bDay() const
-{
-    return d->bDay;
-}
-
-void Contact::setAnniversary(const Kolab::cDateTime& dt)
-{
-    d->anniversary = dt;
-}
-
-cDateTime Contact::anniversary() const
-{
-    return d->anniversary;
-}
-
-void Contact::setPhoto(const std::string& data, const std::string& mimetype)
-{
-    d->photo = data;
-    d->photoMimetype = mimetype;
-}
-
-std::string Contact::photo() const
-{
-    return d->photo;
-}
-
-std::string Contact::photoMimetype() const
-{
-    return d->photoMimetype;
-}
-
-void Contact::setGender(Contact::Gender g)
-{
-    d->gender = g;
-}
-
-Contact::Gender Contact::gender() const
-{
-    return d->gender;
-}
-
-void Contact::setLanguages(const std::vector< std::string >& l)
-{
-    d->languages = l;
-}
-
-std::vector< std::string > Contact::languages() const
-{
-    return d->languages;
-}
-
-void Contact::setTelephones(const std::vector< Telephone >& tel, int preferredIndex)
-{
-    d->telephonesPreferredIndex = preferredIndex;
-    d->telephones = tel;
-}
-
-std::vector< Telephone > Contact::telephones() const
-{
-    return d->telephones;
-}
-
-int Contact::telephonesPreferredIndex() const
-{
-    return d->telephonesPreferredIndex;
-}
-
-void Contact::setIMaddresses(const std::vector< std::string > &adr, int preferredIndex)
-{
-    d->imAddresses = adr;
-    d->imAddressPreferredIndex = preferredIndex;
-}
-
-std::vector< std::string > Contact::imAddresses() const
-{
-    return d->imAddresses;
-}
-
-int Contact::imAddressPreferredIndex() const
-{
-    return d->imAddressPreferredIndex;
-}
-
-void Contact::setEmailAddresses(const std::vector< std::string >& email, int preferredIndex)
-{
-    d->emailAddresses = email;
-    d->emailAddressPreferredIndex = preferredIndex;
-}
-
-std::vector< std::string > Contact::emailAddresses() const
-{
-    return d->emailAddresses;
-}
-
-int Contact::emailAddressPreferredIndex() const
-{
-    return d->emailAddressPreferredIndex;
-}
-
-void Contact::setGPSpos(const std::vector< Geo >& pos)
-{
-    d->gpsPos = pos;
-}
-
-std::vector< Geo > Contact::gpsPos() const
-{
-    return d->gpsPos;
-}
-
-void Contact::setCrypto(const Kolab::Crypto& c)
-{
-    d->crypto = c;
-}
-
-Crypto Contact::crypto() const
-{
-    return d->crypto;
-}
-
-void Contact::setCustomProperties(const std::vector< CustomProperty >& c)
-{
-    d->customProperties = c;
-}
-
-std::vector< CustomProperty > Contact::customProperties() const
-{
-    return d->customProperties;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-} //Namespace
-
diff --git a/c++/lib/kolabcontact.h b/c++/lib/kolabcontact.h
deleted file mode 100644
index e4164dd..0000000
--- a/c++/lib/kolabcontact.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABCONTACT_H
-#define KOLABCONTACT_H
-
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-#include "kolabcontainers.h"
-
-namespace Kolab {
-    
-struct NameComponents {
-    bool operator==(const NameComponents &other) const { return mSurnames == other.mSurnames &&
-                                                        mGiven == other.mGiven &&
-                                                        mAdditional == other.mAdditional &&
-                                                        mPrefixes == other.mPrefixes &&
-                                                        mSuffixes == other.mSuffixes;
-                                                        };
-    void setSurnames(const std::vector<std::string> &s) { mSurnames = s; };
-    std::vector<std::string> surnames() const { return mSurnames; };
-    void setGiven(const std::vector<std::string> &s) { mGiven = s; };
-    std::vector<std::string> given() const { return mGiven; };
-    void setAdditional(const std::vector<std::string> &s) { mAdditional = s; };
-    std::vector<std::string> additional() const { return mAdditional; };
-    void setPrefixes(const std::vector<std::string> &s) { mPrefixes = s; };
-    std::vector<std::string> prefixes() const { return mPrefixes; };
-    void setSuffixes(const std::vector<std::string> &s) { mSuffixes = s; };
-    std::vector<std::string> suffixes() const { return mSuffixes; };
-    bool isValid() const { return !(mSurnames.empty() && mGiven.empty() && mAdditional.empty() && mPrefixes.empty() && mSuffixes.empty()); };
-private:
-    std::vector<std::string> mSurnames;
-    std::vector<std::string> mGiven;
-    std::vector<std::string> mAdditional;
-    std::vector<std::string> mPrefixes;
-    std::vector<std::string> mSuffixes;
-};
-
-struct Related {
-    
-    enum DescriptionType {
-        Invalid,
-        Text,
-        Uid
-    };
-    Related(): mType(Invalid), mRelationType(NoRelation) {};
-    Related(DescriptionType t, const std::string &textOrUri, int relationType = NoRelation)
-    :   mType(t), mRelationType(relationType)
-    {
-        if (t == Text) {
-            mText = textOrUri;
-        } else {
-            mUri = textOrUri;
-        }
-    };
-    bool operator==(const Related &other) const { return mType == other.mType &&
-    mUri == other.mUri &&
-    mText == other.mText &&
-    mRelationType == other.mRelationType;
-    };
-    DescriptionType type() const { return mType; };
-    std::string uri() const { return mUri; };
-    std::string text() const { return mText; };
-    enum RelationType {
-        NoRelation = 0,
-        Child = 0x01,
-        Spouse = 0x02,
-        Manager = 0x04,
-        Assistant = 0x08,
-    };
-    void setRelationTypes(int t) { mRelationType = t; };
-    int relationTypes() const { return mRelationType; };
-private:
-    DescriptionType mType;
-    std::string mUri;
-    std::string mText;
-    int mRelationType;
-};
-
-struct Address {
-    
-    Address(): mTypes(0) {};
-    enum Type {
-        Work = 0x01,
-        Home = 0x02
-    };
-    bool operator==(const Address &other) const { return mTypes == other.mTypes &&
-    mLabel == other.mLabel &&
-    mStreet == other.mStreet &&
-    mLocality == other.mLocality &&
-    mRegion == other.mRegion &&
-    mCode == other.mCode &&
-    mCountry == other.mCountry;
-    };
-    void setTypes(int t) { mTypes = t; };
-    int types() const { return mTypes; };
-    
-    void setLabel(const std::string &s) { mLabel = s; };
-    std::string label() const { return mLabel; }
-    
-    void setStreet(const std::string &s) { mStreet = s; };
-    std::string street() const { return mStreet; };
-    
-    void setLocality(const std::string &s) { mLocality = s; };
-    std::string locality() const { return mLocality; };
-    
-    void setRegion(const std::string &s) { mRegion = s; };
-    std::string region() const { return mRegion; };
-    
-    void setCode(const std::string &s) { mCode = s; };
-    std::string code() const { return mCode; };
-    
-    void setCountry(const std::string &s) { mCountry = s; };
-    std::string country() const { return mCountry; };
-private:
-    int mTypes;
-    std::string mLabel;
-    std::string mStreet;
-    std::string mLocality;
-    std::string mRegion;
-    std::string mCode;
-    std::string mCountry;
-};
-
-struct Affiliation {
-    bool operator==(const Affiliation &other) const { return mOrg == other.mOrg &&
-                                                    mOrgUnits == other.mOrgUnits &&
-                                                    mLogo == other.mLogo &&
-                                                    mLogoMimetype == other.mLogoMimetype &&
-                                                    mRoles == other.mRoles &&
-                                                    mRelateds == other.mRelateds &&
-                                                    mOffices == other.mOffices;
-                                                    };
-    void setOrganisation(const std::string &org) { mOrg = org; };
-    std::string organisation() const { return mOrg; };
-    void setOrganisationalUnits(const std::vector<std::string> &units) { mOrgUnits = units; };
-    std::vector<std::string> organisationalUnits() const { return mOrgUnits; };
-    void setLogo(const std::string &l, const std::string mimetype) { mLogo = l; mLogoMimetype = mimetype; };
-    std::string logo() const { return mLogo; };
-    std::string logoMimetype() const { return mLogoMimetype; };
-
-    void setRoles(const std::vector<std::string> &roles) { mRoles = roles; };
-    std::vector<std::string> roles() const { return mRoles; };
-    void setRelateds(const std::vector<Related> &relateds) { mRelateds = relateds; };
-    std::vector<Related> relateds() const { return mRelateds; };
-    void setAddresses(const std::vector<Address> &offices) { mOffices = offices; };
-    std::vector<Address> addresses() const { return mOffices; };
-private:
-    std::string mOrg;
-    std::vector<std::string> mOrgUnits;
-    std::string mLogo;
-    std::string mLogoMimetype;
-    std::vector<std::string> mRoles;
-    std::vector<Related> mRelateds;
-    std::vector<Address> mOffices;
-};
-
-struct Telephone {
-    enum Type {
-        Work = 0x01,
-        Home = 0x02,
-        Text = 0x04,
-        Voice = 0x08,
-        Fax = 0x10,
-        Cell = 0x20,
-        Video = 0x40,
-        Pager = 0x80,
-        Textphone = 0x100,
-        Car = 0x200
-    };
-    Telephone(): mType(0){};
-    bool operator==(const Telephone &other) const { return mNumber == other.mNumber &&
-                                                    mType == other.mType;
-                                                    };
-    void setTypes(int t) { mType = t; };
-    int types() const { return mType; };
-    void setNumber(const std::string &n) { mNumber = n; };
-    std::string number() const { return mNumber; };
-private:
-    std::string mNumber;
-    int mType;
-};
-
-struct Crypto {
-    enum CryptoTypes {
-        PGPinline = 0x01,
-        PGPmime = 0x02,
-        SMIME = 0x04,
-        SMIMEopaque = 0x08
-    };
-    
-    enum CryptoPref {
-        Ask,
-        Never,
-        Always,
-        IfPossible
-    };
-    Crypto(): mCryptoTypes(0), mSignPref(Ask), mEncryptPref(Ask){};
-    bool operator==(const Crypto &other) const { return mCryptoTypes == other.mCryptoTypes &&
-                                                    mPGPKey == other.mPGPKey &&
-                                                    mSMIMEKey == other.mSMIMEKey &&
-                                                    mSignPref == other.mSignPref &&
-                                                    mEncryptPref == other.mEncryptPref; };
-    bool isValid() const { return !(!mCryptoTypes && mPGPKey.empty() && mSMIMEKey.empty()); };
-
-    void setAllowed(int cryptoTypes) { mCryptoTypes = cryptoTypes; };
-    int allowed() const { return mCryptoTypes; };
-    void setPGPKey(const std::string &k) { mPGPKey = k; };
-    std::string pgpKey() const { return mPGPKey; };
-    void setSMIMEKey(const std::string &k) { mSMIMEKey = k; };
-    std::string smimeKey() const { return mSMIMEKey; };
-    void setSignPref(CryptoPref p) { mSignPref = p; };
-    CryptoPref signPref() const { return mSignPref; };
-    void setEncryptPref(CryptoPref p) { mEncryptPref = p; };
-    CryptoPref encryptPref() const { return mEncryptPref; };
-private:
-    int mCryptoTypes;
-    std::string mPGPKey;
-    std::string mSMIMEKey;
-    CryptoPref mSignPref;
-    CryptoPref mEncryptPref;
-};
-
-struct Geo {
-    Geo(): latitude(0.0), longitude(0.0) {};
-    Geo(double lat, double lon)
-    : latitude(lat), longitude(lon) {};
-    
-    bool operator==(const Geo &other) const{ return (longitude == other.longitude && latitude == other.latitude);};
-    double latitude;
-    double longitude;
-};
-
-
-class DistList {
-public:
-    DistList();
-    ~DistList();
-    DistList(const DistList &);
-    void operator=(const DistList &);
-
-    bool isValid() const;
-
-    void setUid(const std::string &);
-    std::string uid() const;
-
-    void setLastModified(const cDateTime &);
-    cDateTime lastModified() const;
-
-    void setName(const std::string &);
-    std::string name() const;
-
-    void setMembers(const std::vector<ContactReference> &);
-    std::vector<ContactReference> members() const;
-
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-class Contact {
-public:
-    Contact();
-    ~Contact();
-    Contact(const Contact &);
-    void operator=(const Contact &);
-
-    bool isValid() const;
-
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setLastModified(const cDateTime &);
-    cDateTime lastModified() const;
-    
-    void setCategories(const std::vector<std::string> &);
-    void addCategory(const std::string &);
-    std::vector<std::string> categories() const;
-    
-    void setName(const std::string &);
-    std::string name() const;
-    
-    void setNameComponents(const NameComponents &);
-    NameComponents nameComponents() const;
-    
-    void setNote(const std::string &);
-    std::string note() const;
-    
-    void setFreeBusyUrl(const std::string &);
-    std::string freeBusyUrl() const;
-    
-    void setTitles(const std::vector<std::string> &titles);
-    std::vector<std::string> titles() const;
-    
-    void setAffiliations(const std::vector<Affiliation> &);
-    std::vector<Affiliation> affiliations() const;
-    
-    void setUrls(const std::vector<std::string> &);
-    std::vector<std::string> urls() const;
-    
-    void setAddresses(const std::vector<Address> &, int preferred = -1);
-    std::vector<Address> addresses() const;
-    int addressPreferredIndex() const;
-    
-    void setNickNames(const std::vector< std::string > &);
-    std::vector< std::string > nickNames() const;
-    
-    void setRelateds(const std::vector<Related> &);
-    std::vector<Related> relateds() const;
-     
-    void setBDay(const cDateTime &);
-    cDateTime bDay() const;
-    
-    void setAnniversary(const cDateTime &);
-    cDateTime anniversary() const;
-    
-    void setPhoto(const std::string &data, const std::string &mimetype);
-    std::string photo() const;
-    std::string photoMimetype() const;
-    
-    enum Gender {
-        NotSet,
-        NotSpecified,
-        Male,
-        Female
-    };
-    
-    void setGender(Gender);
-    Gender gender() const;
-    
-    void setLanguages(const std::vector<std::string> &);
-    std::vector<std::string> languages() const;
-    
-    void setTelephones(const std::vector<Telephone> &, int preferredIndex = -1);
-    std::vector<Telephone> telephones() const;
-    int telephonesPreferredIndex() const;
-    
-    void setIMaddresses(const std::vector<std::string> &, int preferredIndex = -1);
-    std::vector<std::string> imAddresses() const;
-    int imAddressPreferredIndex() const;
-    
-    void setEmailAddresses(const std::vector<std::string> &, int preferredIndex = -1);
-    std::vector<std::string> emailAddresses() const;
-    int emailAddressPreferredIndex() const;
-    
-    void setGPSpos(const std::vector<Geo> &);
-    std::vector<Geo> gpsPos() const;
-    
-    void setCrypto(const Crypto &);
-    Crypto crypto() const;
-    
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-} //Namespace
-
-#endif // KOLABCONTACT_H
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
deleted file mode 100644
index 491f9d7..0000000
--- a/c++/lib/kolabcontainers.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabcontainers.h"
-#include "incidence_p.h"
-
-namespace Kolab {
-    
-struct cDateTime::Private {
-    Private()
-    : year(-1),
-    month(-1),
-    day(-1),
-    hour(-1),
-    minute(-1),
-    second(-1),
-    isUtc(false){}
-
-    int year;
-    int month;
-    int day;
-    int hour;
-    int minute;
-    int second;
-    bool isUtc;
-    std::string timezone;
-};
-
-cDateTime::cDateTime()
-: d(new cDateTime::Private())
-{
-
-}
-
-cDateTime::cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc)
-: d(new cDateTime::Private())
-{
-    d->year = year;
-    d->month = month;
-    d->day = day;
-    d->hour = hour;
-    d->minute = minute;
-    d->second = second;
-    d->isUtc = isUtc;
-}
-
-cDateTime::cDateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
-: d(new cDateTime::Private())
-{
-    d->year = year;
-    d->month = month;
-    d->day = day;
-    d->hour = hour;
-    d->minute = minute;
-    d->second = second;
-    d->timezone = timezone;
-}
-
-cDateTime::cDateTime(int year, int month, int day)
-: d(new cDateTime::Private())
-{
-    d->year = year;
-    d->month = month;
-    d->day = day;
-}
-
-cDateTime::cDateTime(const Kolab::cDateTime &other)
-: d(new cDateTime::Private())
-{
-    *d = *other.d;
-}
-
-cDateTime::~cDateTime()
-{
-
-}
-
-
-void cDateTime::operator=(const Kolab::cDateTime &other)
-{
-   *d = *other.d;
-}
-
-bool cDateTime::operator==(const Kolab::cDateTime &other) const
-{
-    if ( d->year == other.year() &&
-        d->month == other.month() &&
-        d->day == other.day() &&
-        d->hour == other.hour() &&
-        d->minute == other.minute() &&
-        d->second== other.second() &&
-        d->isUtc== other.isUTC() &&
-        d->timezone== other.timezone()) {
-        return true;
-    }
-    return false;
-}
-
-
-
-int cDateTime::year() const
-{
-    return d->year;
-}
-
-int cDateTime::month() const
-{
-    return d->month;
-}
-
-int cDateTime::day() const
-{
-    return d->day;
-}
-
-int cDateTime::hour() const
-{
-    return d->hour;
-}
-
-int cDateTime::minute() const
-{
-    return d->minute;
-}
-
-int cDateTime::second() const
-{
-    return d->second;
-}
-
-bool cDateTime::isDateOnly() const
-{
-    if ((d->hour < 0) && (d->minute < 0) && (d->second < 0)) {
-        return true;
-    }
-    return false;
-}
-
-void cDateTime::setDate(int year, int month, int day)
-{
-    d->year = year;
-    d->month = month;
-    d->day = day;
-}
-void cDateTime::setTime(int hour, int minute, int second)
-{
-    d->hour = hour;
-    d->minute = minute;
-    d->second = second;
-}
-void cDateTime::setTimezone(const std::string &tz)
-{
-    d->timezone = tz;
-}
-void cDateTime::setUTC(bool utc)
-{
-    d->isUtc = utc;
-}
-
-bool cDateTime::isUTC() const
-{
-    return d->isUtc;
-}
-
-std::string cDateTime::timezone() const
-{
-    return d->timezone;
-}
-
-bool cDateTime::isValid() const
-{
-    return (d->year >= 0 && d->month >= 0 && d->day >= 0);
-}
-
-struct RecurrenceRule::Private
-{
-    Private()
-    : freq(FreqNone),
-    weekstart(Monday),
-    count(-1),
-    interval(1){};
-    
-    Frequency freq;
-    Weekday weekstart;
-    cDateTime end;
-    int count;
-    int interval;
-    std::vector<int> bysecond;
-    std::vector<int> byminute;
-    std::vector<int> byhour;
-    std::vector<DayPos> byday;
-    std::vector<int> bymonthday;
-    std::vector<int> byyearday;
-    std::vector<int> byweekno;
-    std::vector<int> bymonth;
-};
-
-RecurrenceRule::RecurrenceRule()
-:   d(new RecurrenceRule::Private)
-{
-    
-}
-
-RecurrenceRule::RecurrenceRule(const Kolab::RecurrenceRule &other)
-:   d(new RecurrenceRule::Private)
-{
-    *d = *other.d;
-}
-
-void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
-{
-    *d = *other.d;
-}
-
-bool RecurrenceRule::operator==(const Kolab::RecurrenceRule &other) const
-{
-    if ( d->freq == other.frequency() &&
-        d->weekstart == other.weekStart() &&
-        d->end == other.end() &&
-        d->count == other.count() &&
-        d->interval == other.interval() &&
-        d->bysecond == other.bysecond() &&
-        d->byminute == other.byminute() &&
-        d->byhour == other.byhour() &&
-        d->byday == other.byday() &&
-        d->bymonthday == other.bymonthday() &&
-        d->byyearday == other.byyearday() &&
-        d->byweekno == other.byweekno() &&
-        d->bymonth == other.bymonth()) {
-            return true;
-        }
-        return false;
-}
-
-RecurrenceRule::~RecurrenceRule()
-{
-    
-}
-
-void RecurrenceRule::setFrequency(RecurrenceRule::Frequency freq)
-{
-    d->freq = freq;
-}
-
-RecurrenceRule::Frequency RecurrenceRule::frequency() const
-{
-    return d->freq;
-}
-
-void RecurrenceRule::setWeekStart(Kolab::Weekday weekstart)
-{
-    d->weekstart = weekstart;
-}
-
-Kolab::Weekday RecurrenceRule::weekStart() const
-{
-    return d->weekstart;
-}
-
-void RecurrenceRule::setEnd(const Kolab::cDateTime &end)
-{
-    d->end = end;
-}
-
-cDateTime RecurrenceRule::end() const
-{
-    return d->end;
-}
-
-void RecurrenceRule::setCount(int count)
-{
-    d->count = count;
-}
-
-int RecurrenceRule::count() const
-{
-    return d->count;
-}
-
-void RecurrenceRule::setInterval(int interval)
-{
-    d->interval = interval;
-}
-
-int RecurrenceRule::interval() const
-{
-    return d->interval;
-}
-
-void RecurrenceRule::setBysecond(const std::vector< int >&by)
-{
-    d->bysecond = by;
-}
-
-
-std::vector< int > RecurrenceRule::bysecond() const
-{
-    return d->bysecond;
-}
-
-void RecurrenceRule::setByminute(const std::vector< int > &by)
-{
-    d->byminute = by;
-}
-
-std::vector< int > RecurrenceRule::byminute() const
-{
-    return d->byminute;
-}
-
-void RecurrenceRule::setByhour(const std::vector< int > &by)
-{
-    d->byhour = by;
-}
-
-std::vector< int > RecurrenceRule::byhour() const
-{
-    return d->byhour;
-}
-
-void RecurrenceRule::setByday(const std::vector< DayPos > &by)
-{
-    d->byday = by;
-}
-
-std::vector< DayPos > RecurrenceRule::byday() const
-{
-    return d->byday;
-}
-
-void RecurrenceRule::setBymonthday(const std::vector< int > &by)
-{
-    d->bymonthday = by;
-}
-
-std::vector< int > RecurrenceRule::bymonthday() const
-{
-    return d->bymonthday;
-}
-
-void RecurrenceRule::setByyearday(const std::vector< int > &by)
-{
-    d->byyearday = by;
-}
-
-std::vector< int > RecurrenceRule::byyearday() const
-{
-    return d->byyearday;
-}
-
-void RecurrenceRule::setByweekno(const std::vector< int > &by)
-{
-    d->byweekno = by;
-}
-
-std::vector< int > RecurrenceRule::byweekno() const
-{
-    return d->byweekno;
-}
-
-void RecurrenceRule::setBymonth(const std::vector< int > &by)
-{
-    d->bymonth = by;
-}
-
-std::vector< int > RecurrenceRule::bymonth() const
-{
-    return d->bymonth;
-}
-
-bool RecurrenceRule::isValid() const
-{
-    if (d->freq == FreqNone) {
-        return false;
-    }
-    return true;
-}
-
-
-
-struct Attendee::Private
-{
-    Private()
-    : partStat(PartNeedsAction),
-    role(Required),
-    rsvp(false){};
-    
-    ContactReference contact;
-    PartStatus partStat;
-    Role role;
-    bool rsvp;
-};
-
-Attendee::Attendee()
-:   d(new Attendee::Private)
-{
-
-}
-
-Attendee::Attendee(const ContactReference& contact)
-:   d(new Attendee::Private)
-{
-    d->contact = contact; 
-}
-
-Attendee::Attendee(const Kolab::Attendee &other)
-:   d(new Attendee::Private)
-{
-    *d = *other.d;
-}
-
-void Attendee::operator=(const Kolab::Attendee &other)
-{
-    *d = *other.d;
-}
-
-Attendee::~Attendee()
-{
-
-}
-
-bool Attendee::operator==(const Kolab::Attendee &other) const
-{
-    if ( d->contact == other.contact() &&
-        d->partStat == other.partStat() &&
-        d->role == other.role() &&
-        d->rsvp== other.rsvp()) {
-        return true;
-    }
-    return false;
-}
-
-bool Attendee::isValid() const 
-{ 
-    return d->contact.isValid();
-};
-
-void Attendee::setContact(const ContactReference &c)
-{
-    d->contact = c;
-}
-
-ContactReference Attendee::contact() const
-{
-    return d->contact;
-}
-
-
-void Attendee::setPartStat(PartStatus partStat)
-{
-    d->partStat = partStat;
-}
-
-PartStatus Attendee::partStat() const
-{
-    return d->partStat;
-}
-
-void Attendee::setRole(Role role)
-{
-    d->role = role;
-}
-
-Role Attendee::role() const
-{
-    return d->role;
-}
-
-void Attendee::setRSVP(bool rsvp)
-{
-    d->rsvp = rsvp;
-}
-
-bool Attendee::rsvp() const
-{
-    return d->rsvp;
-}
-
-
-
-struct Attachment::Private
-{
-    std::string uri;
-    std::string data;
-    std::string mimetype;
-    std::string label;
-};
-
-Attachment::Attachment()
-:   d(new Attachment::Private)
-{
-}
-
-Attachment::Attachment(const Kolab::Attachment &other)
-:   d(new Attachment::Private)
-{
-    *d = *other.d;
-}
-
-void Attachment::operator=(const Kolab::Attachment &other)
-{
-    *d = *other.d;
-}
-
-Attachment::~Attachment()
-{
-}
-
-bool Attachment::operator==(const Kolab::Attachment &other) const
-{
-    return ( d->uri == other.uri() &&
-        d->data == other.data() &&
-        d->label == other.label() &&
-        d->mimetype == other.mimetype() );
-}
-
-void Attachment::setUri(const std::string &uri, const std::string& mimetype)
-{
-    d->uri = uri;
-    d->mimetype = mimetype;
-}
-
-std::string Attachment::uri() const
-{
-    return d->uri;
-}
-
-std::string Attachment::mimetype() const
-{
-    return d->mimetype;
-}
-
-void Attachment::setLabel(const std::string &label)
-{
-    d->label = label;
-}
-
-std::string Attachment::label() const
-{
-    return d->label;
-}
-
-void Attachment::setData(const std::string &data, const std::string& mimetype)
-{
-    d->data = data;
-    d->mimetype = mimetype;
-}
-
-std::string Attachment::data() const
-{
-    return d->data;
-}
-
-bool Attachment::isValid() const
-{
-    return !d->mimetype.empty(); //TODO use isValid variable
-}
-
-
-
-struct Alarm::Private
-{
-    Private(): relativeTo(Start),
-    numrepeat(0),
-    type(Alarm::InvalidAlarm) {};
-    std::string text;
-    Attachment audioFile;
-    std::string summary;
-    std::vector<ContactReference> attendees;
-    cDateTime start;
-    Duration relativeDuration;
-    Relative relativeTo;
-    Duration duration;
-    int numrepeat;
-    Type type;
-    
-};
-
-Alarm::Alarm()
-:   d(new Alarm::Private)
-{
-}
-
-Alarm::Alarm(const std::string &text)
-:   d(new Alarm::Private)
-{
-    d->text = text;
-    d->type = DisplayAlarm;
-}
-
-
-Alarm::Alarm(const Kolab::Attachment& audio)
-:   d(new Alarm::Private)
-{
-    d->audioFile = audio;
-    d->type = AudioAlarm;
-}
-
-Alarm::Alarm(const std::string& summary, const std::string& description, const std::vector<ContactReference> attendees)
-:   d(new Alarm::Private)
-{
-    d->summary = summary;
-    d->text = description;
-    d->attendees = attendees;
-    d->type = EMailAlarm;
-    
-}
-
-Alarm::Alarm(const Kolab::Alarm &other)
-:   d(new Alarm::Private)
-{
-    *d = *other.d;
-}
-
-void Alarm::operator=(const Kolab::Alarm &other)
-{
-    *d = *other.d;
-}
-
-Alarm::~Alarm()
-{
-}
-
-bool Alarm::operator==(const Kolab::Alarm &other) const
-{
-    return ( d->text == other.description() &&
-        d->text == other.description() &&
-        d->audioFile == other.audioFile() &&
-        d->summary == other.summary() &&
-        d->attendees == other.attendees() &&
-        d->start == other.start() &&
-        d->relativeDuration == other.relativeStart() &&
-        d->relativeTo == other.relativeTo() &&
-        d->duration == other.duration() &&
-        d->numrepeat == other.numrepeat() );
-}
-
-std::string Alarm::text() const
-{
-    return d->text;
-}
-
-Attachment Alarm::audioFile() const
-{
-    return d->audioFile;
-}
-
-std::string Alarm::summary() const
-{
-    return d->summary;
-}
-
-std::string Alarm::description() const
-{
-    return d->text;
-}
-
-std::vector<ContactReference> Alarm::attendees() const
-{
-    return d->attendees;
-}
-
-void Alarm::setStart(const Kolab::cDateTime &start)
-{
-    d->start = start;
-}
-
-cDateTime Alarm::start() const
-{
-    return d->start;
-}
-
-void Alarm::setRelativeStart(const Kolab::Duration &duration, Relative relativeTo)
-{
-    d->relativeDuration = duration;
-    d->relativeTo = relativeTo;
-}
-
-Duration Alarm::relativeStart() const
-{
-    return d->relativeDuration;
-}
-
-Relative Alarm::relativeTo() const
-{
-    return d->relativeTo;
-}
-
-void Alarm::setDuration(const Kolab::Duration &duration, int numrepeat)
-{
-    d->numrepeat = numrepeat;
-    d->duration = duration;
-}
-
-Duration Alarm::duration() const
-{
-    return d->duration;
-}
-
-int Alarm::numrepeat() const
-{
-    return d->numrepeat;
-}
-
-Alarm::Type Alarm::type() const
-{
-    return d->type;
-}
-
-
-
-
-
-
-}//Namespace
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
deleted file mode 100644
index 47dc5fc..0000000
--- a/c++/lib/kolabcontainers.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLAB_CONTAINERS_H
-#define KOLAB_CONTAINERS_H
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-
-namespace Kolab {
-
-class cDateTime {
-public:
-    cDateTime();
-    cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc=true);
-    cDateTime(const std::string &timezone, int year, int month, int day, int hour, int minute, int second);
-    cDateTime(int year, int month, int day);
-    ~cDateTime();
-    cDateTime(const cDateTime &);
-    void operator=(const cDateTime &);
-    bool operator==(const cDateTime &) const;
-   
-    
-    void setDate(int year, int month, int day);
-    int year() const;
-    int month() const;
-    int day() const;
-    
-    bool isDateOnly() const;
-    
-    void setTime(int hour, int minute, int second);
-    int hour() const;
-    int minute() const;
-    int second() const;
-    
-    void setUTC(bool);
-    bool isUTC() const;
-    void setTimezone(const std::string &);
-    std::string timezone() const;
-    
-    bool isValid() const;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-enum Classification {
-    ClassPublic,
-    ClassPrivate,
-    ClassConfidential
-};
-
-enum Status {
-    StatusUndefined,
-    StatusNeedsAction,
-    StatusCompleted,
-    StatusInProcess,
-    StatusCancelled,
-    StatusTentative,
-    StatusConfirmed,
-    StatusDraft,
-    StatusFinal
-};
-
-enum Weekday {
-    Monday,
-    Tuesday,
-    Wednesday,
-    Thursday,
-    Friday,
-    Saturday,
-    Sunday
-};
-
-struct DayPos {
-    DayPos(): mIsValid(false){};
-    DayPos(int occurrence, Weekday weekday): mOccurrence(occurrence), mWeekday(weekday), mIsValid(true){};
-    bool operator==(const DayPos &other) const { return mOccurrence == other.mOccurrence && mWeekday == other.mWeekday; };
-    int occurence() const { return mOccurrence; };
-    Weekday weekday() const { return mWeekday; };
-    bool isValid() { return mIsValid; };
-private:
-    int mOccurrence;
-    Weekday mWeekday;
-    bool mIsValid;
-};
-
-class Attachment {
-public:
-    Attachment();
-    Attachment(const Kolab::Attachment &);
-    ~Attachment();
-
-    void operator=(const Attachment &);
-    bool operator==(const Attachment &) const;
-
-    void setUri(const std::string &uri, const std::string &mimetype);
-    std::string uri() const;
-
-     ///Un-encoded binary content, Implies embedded, will be encoded
-     void setData(const std::string &, const std::string &mimetype);
-     ///Decoded binary content.
-     std::string data() const;
-     //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement?
-//     ///Base64 encoded binary content, Implies embedded
-//      void setEncodedData(const std::string &, const std::string &mimetype);
-
-    std::string mimetype() const;
-
-    ///User visible label
-    void setLabel(const std::string &);
-    std::string label() const;
-    
-    bool isValid() const;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-enum Relative {
-    Start,
-    End
-};
-
-struct Duration {
-    Duration():mWeeks(0), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(false), valid(false){};
-    Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){};
-    Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){};
-    bool operator==(const Duration &other) const{ return (/*mWeeks == other.mWeeks && 
-                                                            mDays == other.mDays &&
-                                                            mHours == other.mHours &&
-                                                            mMinutes == other.mMinutes &&
-                                                            mSeconds == other.mSeconds &&
-                                                            mNegative == other.mNegative &&*/
-                                                            ( ((((mWeeks * 7 + mDays) * 24 + mHours) * 60 + mMinutes) * 60 + mSeconds) ==
-                                                              ((((other.mWeeks * 7 + other.mDays) * 24 + other.mHours) * 60 + other.mMinutes) * 60 + other.mSeconds) ) &&
-                                                            valid == other.valid );};
-    int weeks() const { return mWeeks; };
-    int days() const { return mDays; };
-    int hours() const { return mHours; };
-    int minutes() const { return mMinutes; };
-    int seconds() const { return mSeconds; };
-
-    bool isNegative() const { return mNegative; };
-    bool isValid() const { return valid; };
-private:
-    int mWeeks;
-    int mDays;
-    int mHours;
-    int mMinutes;
-    int mSeconds;
-    bool mNegative;
-    bool valid;
-};
-
-struct ContactReference {
-    enum ReferenceType {
-        Invalid,
-        EmailReference,
-        UidReference,
-        EmailAndUidReference
-    };
-    ContactReference(): mType(Invalid) {};
-    ///For xCal
-    ContactReference(const std::string &email, const std::string &name = std::string(), const std::string &uid = std::string()): mType(EmailAndUidReference), mEmail(email), mUid(uid), mName(name) {};
-    ///For xCard
-    ContactReference(ReferenceType type, const std::string &emailOrUID, const std::string &name = std::string()): mType(type), mName(name) { 
-        if (type == EmailReference) {
-            mEmail = emailOrUID;
-        } else {
-            mUid = emailOrUID;
-        }
-    };
-    bool operator==(const ContactReference &other) const { return mType == other.mType &&
-                                                        mEmail == other.mEmail &&
-                                                        mName == other.mName &&
-                                                        mUid == mUid;
-    };
-
-    bool isValid() const { return mType != Invalid; };
-
-    void setName(const std::string &name) { mName = name; };
-
-    std::string email() const { return mEmail; };
-    std::string uid() const { return mUid; };
-    std::string name() const { return mName; };
-
-    ReferenceType type() const { return mType; };
-
-private:
-    ReferenceType mType;
-    std::string mEmail;
-    std::string mUid;
-    std::string mName;
-};
-
-class Alarm {
-public:
-    enum Type {
-        InvalidAlarm,
-        EMailAlarm,
-        DisplayAlarm,
-        AudioAlarm
-    };
-    
-    Alarm();
-    Alarm(const Alarm &);
-    ~Alarm();
-
-    void operator=(const Alarm &);
-    bool operator==(const Alarm &other) const;
-
-    ///EMail Alarm, @param attendees accepts only email + name and no uid
-    Alarm(const std::string &summary, const std::string &description, const std::vector<ContactReference> attendees);
-    std::string summary() const;
-    std::string description() const;
-    std::vector<ContactReference> attendees() const;
-
-    ///Display Alarm
-    Alarm(const std::string &text);
-    std::string text() const;
-
-    ///Audio Alarm
-    Alarm(const Attachment &audio);
-    Attachment audioFile() const;
-    
-    void setRelativeStart(const Duration &, Relative);
-    Duration relativeStart() const;
-    Relative relativeTo() const;
-    
-    void setStart(const cDateTime &);
-    cDateTime start() const;
-
-    void setDuration(const Duration &, int numrepeat);
-    Duration duration() const;
-    int numrepeat() const;
-    
-    Type type() const;
-
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-
-class RecurrenceRule {
-public:
-    
-    RecurrenceRule();
-    RecurrenceRule(const RecurrenceRule &);
-    ~RecurrenceRule();
-
-    void operator=(const RecurrenceRule &);
-    bool operator==(const RecurrenceRule &other) const;
-    
-    enum Frequency {
-        FreqNone,
-        Yearly,
-        Monthly,
-        Weekly,
-        Daily,
-        Hourly,
-        Minutely,
-        Secondly
-    };
-    
-    void setFrequency(Frequency);
-    Frequency frequency() const;
-    
-    void setWeekStart(Weekday);
-    Weekday weekStart() const;
-    
-    void setEnd(const cDateTime &);
-    cDateTime end() const;
-    
-    void setCount(int count);
-    int count() const;
-    
-    void setInterval(int);
-    int interval() const;
-    
-    void setBysecond(const std::vector<int> &);
-    std::vector<int> bysecond() const;
-    
-    void setByminute(const std::vector<int> &);
-    std::vector<int> byminute() const;
-    
-    void setByhour(const std::vector<int> &);
-    std::vector<int> byhour() const;
-    
-    void setByday(const std::vector<DayPos> &);
-    std::vector<DayPos> byday() const;
-    
-    void setBymonthday(const std::vector<int> &);
-    std::vector<int> bymonthday() const;
-    
-    void setByyearday(const std::vector<int> &);
-    std::vector<int> byyearday() const;
-    
-    void setByweekno(const std::vector<int> &);
-    std::vector<int> byweekno() const;
-    
-    void setBymonth(const std::vector<int> &);
-    std::vector<int> bymonth() const;
-    
-    bool isValid() const;
-    
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-
-enum PartStatus {
-    PartNeedsAction,
-    PartAccepted,
-    PartDeclined,
-    PartTentative,
-    PartDelegated
-};
-
-enum Role {
-    Required,
-    Chair,
-    Optional,
-    NonParticipant
-};
-
-class Attendee {
-public:
-    Attendee();
-    Attendee(const ContactReference &contact);
-    Attendee(const Attendee &);
-    ~Attendee();
-
-    void operator=(const Attendee &);
-    bool operator==(const Attendee &) const;
-
-    bool isValid() const;
-
-    void setContact(const ContactReference &);
-    ContactReference contact() const;
-
-    void setPartStat(PartStatus);
-    PartStatus partStat() const;
-
-    void setRole(Role);
-    Role role() const;
-
-    void setRSVP(bool);
-    bool rsvp() const;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-struct CustomProperty {
-    CustomProperty(){};
-    CustomProperty(const std::string &i, const std::string &v)
-    : identifier(i), value(v) {};
-
-    bool operator==(const CustomProperty &other) const{ return (identifier == other.identifier && value == other.value);};
-    std::string identifier;
-    std::string value;
-};
-
-template <typename T>
-std::vector<T> operator<< ( std::vector<T> v, const T &s)
-{
-    v.push_back(s);
-    return v;
-}
-
-
-//Prepared Kolab Objects
-
-
-class Configuration {
-    //TODO
-};
-
-
-    
-}
-
-#endif
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
deleted file mode 100644
index 4871acd..0000000
--- a/c++/lib/kolabconversions.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KOLABOBJECTCONVERSION_H
-#define KOLABOBJECTCONVERSION_H
-
-#include <bindings/kolabformat.hxx>
-#include "kolabcontainers.h"
-#include <XMLParserWrapper.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
-#include "global_definitions.h"
-#include "utils.h"
-#include "kolabnote.h"
-#include "shared_conversions.h"
-
-namespace Kolab {
-    namespace KolabObjects {
-        
-const char* const KOLAB_NAMESPACE = "http://kolab.org";
-    
-using namespace Kolab::Utils;
-using namespace Kolab::Shared;
-
-template <typename T>
-std::string serializeObject(const Kolab::Note &note, const std::string prod = std::string())
-{
-    clearErrors();
-    try {
-
-        const std::string &uid = getUID(note.uid());
-        setCreatedUid(uid);
-        
-        KolabXSD::Note::creation_date_type created = fromDateTime(note.created());
-        if (!note.created().isValid()) {
-            created = fromDateTime(getCurrentTime());
-        }
-
-        KolabXSD::Note n(getUID(note.uid()), prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION, created, fromDateTime(getCurrentTime()));
-
-        if (!note.categories().empty()) {
-            KolabXSD::Note::categories_sequence categories;
-            BOOST_FOREACH(const std::string &c, note.categories()) {
-                categories.push_back(c);
-            }
-            n.categories(categories);
-        }
-        switch (note.classification()) {
-            case Kolab::ClassPublic:
-                n.classification(KolabXSD::Note::classification_type::PUBLIC);
-                break;
-            case Kolab::ClassPrivate:
-                n.classification(KolabXSD::Note::classification_type::PRIVATE);
-                break;
-            case Kolab::ClassConfidential:
-                n.classification(KolabXSD::Note::classification_type::CONFIDENTIAL);
-                break;
-            default:
-                ERROR("unknown classification");
-        }
-        //TODO
-//         n.attachment();
-        n.summary(note.summary());
-        n.description(note.description());
-        n.color(note.color());
-
-        if (!note.customProperties().empty()) {
-            BOOST_FOREACH(const Kolab::CustomProperty &a, note.customProperties()) {
-                n.x_custom().push_back(KolabXSD::CustomType(a.identifier, a.value));
-            }
-        }
-
-        xml_schema::namespace_infomap map;
-        map[""].name = KOLAB_NAMESPACE;
-
-        std::ostringstream ostringstream;
-        KolabXSD::note(ostringstream, n, map);
-        return ostringstream.str();
-    } catch  (const xml_schema::exception& e) {
-        CRITICAL("Unknown Exception: failed to write Note");
-    }
-    return std::string();
-}
-
-template <typename T>
-boost::shared_ptr<Kolab::Note> deserializeObject(const std::string& s, bool isUrl)
-{
-    clearErrors();
-    try {
-        std::auto_ptr<KolabXSD::Note> note;
-        if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
-            if (doc.get()) {
-                note = KolabXSD::note(doc);
-            }
-        } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
-            if (doc.get()) {
-                note = KolabXSD::note(doc);
-            }
-        }
-
-        if (!note.get()) {
-            CRITICAL("failed to parse note!");
-            return boost::shared_ptr<Kolab::Note>();
-        }
-
-        boost::shared_ptr<Kolab::Note> n = boost::shared_ptr<Kolab::Note>(new Kolab::Note);
-        n->setUid(note->uid());
-        n->setCreated(*toDate(note->creation_date()));
-        n->setLastModified(*toDate(note->last_modification_date()));
-        std::vector<std::string> categories;
-        std::copy(note->categories().begin(), note->categories().end(), std::back_inserter(categories));
-        n->setCategories(categories);
-        if (note->classification()) {
-            switch (*note->classification()) {
-                case KolabXSD::Note::classification_type::PUBLIC:
-                    n->setClassification(Kolab::ClassPublic);
-                    break;
-                case KolabXSD::Note::classification_type::PRIVATE:
-                    n->setClassification(Kolab::ClassPrivate);
-                    break;
-                case KolabXSD::Note::classification_type::CONFIDENTIAL:
-                    n->setClassification(Kolab::ClassConfidential);
-                    break;
-                default:
-                    ERROR("unknown classification");
-            }
-        }
-        //TODO
-//             n->setAttachments();
-        if (note->summary()) {
-            n->setSummary(*note->summary());
-        }
-        if (note->description()) {
-            n->setDescription(*note->description());
-        }
-        if (note->color()) {
-            n->setColor(*note->color());
-        }
-        
-        setProductId( note->prodid() );
-        //         setFormatVersion( vcards->vcard().version().text() );
-        //         global_xCardVersion = vcalendar.properties().version().text();
-        setKolabVersion( note->version() );
-        
-        if (!note->x_custom().empty()) {
-            std::vector<Kolab::CustomProperty> customProperties;
-            BOOST_FOREACH(const KolabXSD::CustomType &p, note->x_custom()) {
-                customProperties.push_back(CustomProperty(p.identifier(), p.value()));
-            }
-            n->setCustomProperties(customProperties);
-        }
-        return n;
-    } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        CRITICAL("Failed to read note!");
-    }
-    
-    return boost::shared_ptr<T>();
-}
-    
-    }//Namespace
-} //Namespace
-
-#endif
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
deleted file mode 100644
index 07b4bb0..0000000
--- a/c++/lib/kolabevent.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabevent.h"
-#include "incidence_p.h"
-
-namespace Kolab {
-
-struct Event::Private: public PrivateIncidence
-{
-    Private()
-    : PrivateIncidence(), 
-    isTransparent(false){}
-
-    cDateTime end;
-    bool isTransparent;
-    Duration duration;
-    std::vector< Event > exceptions;
-};
-
-Event::Event()
-: d(new Event::Private())
-{
-//     std::cout << "ctor" << std::endl;
-}
-
-Event::Event(const Event &other)
-: d(new Event::Private())
-{
-    *d = *other.d;
-//     std::cout << "cctor" << std::endl;
-}
-
-Event::~Event()
-{
-//     std::cout << "dtor" << std::endl;
-}
-
-void Event::operator=(const Kolab::Event &other)
-{
-    *d = *other.d;
-}
-
-bool Event::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void Event::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Event::uid() const
-{
-    return d->uid;
-}
-
-void Event::setCreated(const Kolab::cDateTime &created)
-{
-    d->created = created;
-}
-
-cDateTime Event::created() const
-{
-    return d->created;
-}
-
-void Event::setLastModified(const Kolab::cDateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-cDateTime Event::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Event::setSequence(int sequence)
-{
-    d->sequence = sequence;
-}
-
-int Event::sequence() const
-{
-    return d->sequence;
-}
-
-void Event::setClassification(Classification class_)
-{
-    d->classification = class_;
-}
-
-Classification Event::classification() const
-{
-    return d->classification;
-}
-
-void Event::setCategories(const std::vector< std::string > &categories)
-{
-    d->categories = categories;
-}
-
-void Event::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Event::categories() const
-{
-    return d->categories;
-}
-
-void Event::setStart(const Kolab::cDateTime &start)
-{
-    d->start = start;
-}
-
-cDateTime Event::start() const
-{
-    return d->start;
-}
-
-void Event::setEnd(const Kolab::cDateTime &end)
-{
-    d->end = end;
-}
-
-cDateTime Event::end() const
-{
-    return d->end;
-}
-
-void Event::setDuration(const Duration &duration)
-{
-    d->duration = duration;
-}
-
-Duration Event::duration() const
-{
-    return d->duration;
-}
-
-
-void Event::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture)
-{
-    d->recurrenceID = rID;
-    d->thisAndFuture = thisandfuture;
-}
-
-cDateTime Event::recurrenceID() const
-{
-    return d->recurrenceID;
-}
-
-bool Event::thisAndFuture() const
-{
-    return d->thisAndFuture;
-}
-
-void Event::setSummary(const std::string &summary)
-{
-    d->summary = summary;
-}
-
-std::string Event::summary() const
-{
-    return d->summary;
-}
-
-void Event::setDescription(const std::string &description)
-{
-    d->description = description;
-}
-
-std::string Event::description() const
-{
-    return d->description;
-}
-
-void Event::setPriority(int priority)
-{
-    d->priority = priority;
-}
-
-int Event::priority() const
-{
-    return d->priority;
-}
-
-void Event::setStatus(Status status)
-{
-    d->status = status;
-}
-
-Status Event::status() const
-{
-    return d->status;
-}
-
-void Event::setLocation(const std::string &location)
-{
-    d->location = location;
-}
-
-std::string Event::location() const
-{
-    return d->location;
-}
-
-void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
-{
-    d->rrule = rrule;
-}
-
-RecurrenceRule Event::recurrenceRule() const
-{
-    return d->rrule;
-}
-
-void Event::setRecurrenceDates(const std::vector< cDateTime > &dates)
-{
-    d->recurrenceDates = dates;
-}
-
-void Event::addRecurrenceDate(const Kolab::cDateTime &dt)
-{
-    d->recurrenceDates.push_back(dt);
-}
-
-std::vector< cDateTime > Event::recurrenceDates() const
-{
-    return d->recurrenceDates;
-}
-
-void Event::setExceptionDates(const std::vector< cDateTime > &dates)
-{
-    d->exceptionDates = dates;
-}
-
-void Event::addExceptionDate(const Kolab::cDateTime &dt)
-{
-    d->exceptionDates.push_back(dt);
-}
-
-std::vector< cDateTime > Event::exceptionDates() const
-{
-    return d->exceptionDates;
-}
-
-void Event::setTransparency(bool isTransparent)
-{
-    d->isTransparent = isTransparent;
-}
-
-bool Event::transparency() const
-{
-    return d->isTransparent;
-}
-
-void Event::setOrganizer(const ContactReference &organizer)
-{
-    d->organizer = organizer;
-}
-
-ContactReference Event::organizer() const
-{
-    return d->organizer;
-}
-
-void Event::setAttendees(const std::vector< Attendee > &attendees)
-{
-    d->attendees = attendees;
-}
-
-std::vector< Attendee > Event::attendees() const
-{
-    return d->attendees;
-}
-
-void Event::setAttachments(const std::vector< Attachment > &attach)
-{
-    d->attachments = attach;
-}
-
-std::vector< Attachment > Event::attachments() const
-{
-    return d->attachments;
-}
-
-void Event::setCustomProperties(const std::vector< CustomProperty > &prop)
-{
-    d->customProperties = prop;
-}
-
-std::vector< CustomProperty > Event::customProperties() const
-{
-    return d->customProperties;
-}
-
-// void Event::setExceptions(const std::vector< Event > &exceptions)
-// {
-//     d->exceptions = exceptions;
-// }
-// 
-// std::vector< Event > Event::exceptions() const
-// {
-//     return d->exceptions;
-// }
-
-void Event::setAlarms(const std::vector< Alarm > &alarms)
-{
-    d->alarms = alarms;
-}
-
-std::vector< Alarm > Event::alarms() const
-{
-    return d->alarms;
-}
-
-
-
-
-}
\ No newline at end of file
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
deleted file mode 100644
index 415a1e9..0000000
--- a/c++/lib/kolabevent.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLAB_EVENT_H
-#define KOLAB_EVENT_H
-
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-#include "kolabcontainers.h"
-namespace Kolab {
-
-class Event {
-public:
-    Event();
-    ~Event();
-    Event(const Event &);
-    void operator=(const Event &);
-    
-    bool isValid() const;
-    
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setCreated(const cDateTime &);
-    cDateTime created() const;
-    
-    void setLastModified(const cDateTime &);
-    cDateTime lastModified() const;
-    
-    void setSequence(int);
-    int sequence() const;
-    
-    void setClassification(Classification);
-    Classification classification() const;
-
-    void setCategories(const std::vector<std::string> &);
-    void addCategory(const std::string &);
-    std::vector<std::string> categories() const;
-    
-    void setStart(const cDateTime &);
-    cDateTime start() const;
-    
-    void setEnd(const cDateTime &);
-    cDateTime end() const;
-    
-    void setDuration(const Duration &);
-    Duration duration() const;
-    
-    void setTransparency(bool isTransparent);
-    bool transparency() const;
-    
-    void setRecurrenceRule(const RecurrenceRule &);
-    RecurrenceRule recurrenceRule() const;
-    
-    void setRecurrenceDates(const std::vector<cDateTime> &);
-    void addRecurrenceDate(const cDateTime &);
-    std::vector<cDateTime> recurrenceDates() const;
-    
-    void setExceptionDates(const std::vector<cDateTime> &);
-    void addExceptionDate(const cDateTime &);
-    std::vector<cDateTime> exceptionDates() const;
-    
-    void setRecurrenceID(const cDateTime &, bool thisandfuture);
-    cDateTime recurrenceID() const;
-    bool thisAndFuture() const;
-    
-    void setSummary(const std::string &);
-    std::string summary() const;
-    
-    void setDescription(const std::string &);
-    std::string description() const;
-    
-    void setPriority(int);
-    int priority() const;
-    
-    void setStatus(Status);
-    Status status() const;
-    
-    void setLocation(const std::string &);
-    std::string location() const;
-    
-    void setOrganizer(const ContactReference &);
-    ContactReference organizer() const;
-    
-    void setAttendees(const std::vector<Attendee> &);
-    std::vector<Attendee> attendees() const;
-    
-    void setAttachments(const std::vector<Attachment> &);
-    std::vector<Attachment> attachments() const;
-    
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-/*    TODO what is this? Exceptions it is
-    void setExceptions(const std::vector<Event> &);
-    std::vector<Event> exceptions() const;*/
-    
-    void setAlarms(const std::vector<Alarm> &);
-    std::vector<Alarm> alarms() const;
-
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-
-}
-
-#endif
-
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
deleted file mode 100644
index 98a42a2..0000000
--- a/c++/lib/kolabformat.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabformat.h"
-
-#include <iostream>
-#include "xcalconversions.h"
-
-#include "xcardconversions.h"
-#include "utils.h"
-#include "kolabconversions.h"
-
-namespace Kolab {
-    
-ErrorSeverity error()
-{
-    return Utils::getError();
-}
-
-std::string errorMessage()
-{
-    return Utils::getErrorMessage();
-}
-
-std::string productId()
-{
-    return Utils::productId();
-}
-
-std::string xCalVersion()
-{
-    return XCAL::global_xCalVersion;
-}
-
-std::string xKolabVersion()
-{
-    return Utils::kolabVersion();
-}
-
-std::string getSerializedUID()
-{
-    return Utils::createdUid();
-}
-
-Kolab::Event readEvent(const std::string& s, bool isUrl)
-{
-    Kolab::XCAL::IncidenceTrait <Kolab::Event >::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::Event();
-    }
-    return *ptr;
-}
-
-std::string writeEvent(const Kolab::Event &event)
-{
-    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(event);
-}
-
-Kolab::Todo readTodo(const std::string& s, bool isUrl)
-{
-    XCAL::IncidenceTrait<Kolab::Todo>::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::Todo();
-    }
-    return *ptr;
-}
-
-std::string writeTodo(const Kolab::Todo &event)
-{
-    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(event);
-}
-
-Journal readJournal(const std::string& s, bool isUrl)
-{
-    XCAL::IncidenceTrait<Kolab::Journal>::IncidencePtr ptr = XCAL::deserializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::Journal();
-    }
-    return *ptr;
-}
-
-std::string writeJournal(const Kolab::Journal &j)
-{
-    return XCAL::serializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(j);
-}
-
-
-Kolab::Contact readContact(const std::string& s, bool isUrl)
-{
-    boost::shared_ptr <Kolab::Contact > ptr = XCARD::deserializeCard<Kolab::Contact>(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::Contact();
-    }
-    return *ptr;
-}
-
-std::string writeContact(const Contact &contact)
-{
-    return XCARD::serializeCard(contact);
-}
-
-DistList readDistlist(const std::string& s, bool isUrl)
-{
-    boost::shared_ptr <Kolab::DistList> ptr = XCARD::deserializeCard<Kolab::DistList>(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::DistList();
-    }
-    return *ptr;
-}
-
-std::string writeDistlist(const DistList &list)
-{
-    return XCARD::serializeCard(list);
-}
-
-Note readNote(const std::string& s, bool isUrl)
-{
-    boost::shared_ptr <Kolab::Note> ptr = Kolab::KolabObjects::deserializeObject<Kolab::Note>(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::Note();
-    }
-    return *ptr;
-    return Note();
-}
-
-std::string writeNote(const Note &note)
-{
-    return Kolab::KolabObjects::serializeObject<Kolab::Note>(note);
-}
-
-Configuration readConfiguration(const std::string& /*s*/, bool /*isUrl*/)
-{
-//     boost::shared_ptr <Kolab::Configuration> ptr = deserializeConfiguration(s, isUrl);
-//     if (!ptr.get()) {
-//         return Kolab::Configuration();
-//     }
-//     return *ptr;
-    return Configuration();
-}
-
-std::string writeConfiguration(const Configuration &/*config*/)
-{
-//     return serializeConfiguration(config);
-return std::string();
-}
-
-
-}
-
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
deleted file mode 100644
index 090650c..0000000
--- a/c++/lib/kolabformat.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABFORMAT_H
-#define KOLABFORMAT_H
-
-#include <string>
-#include "kolabcontainers.h"
-#include "kolabtodo.h"
-#include "kolabevent.h"
-#include "kolabjournal.h"
-#include "kolabcontact.h"
-#include "kolabnote.h"
-#include "global_definitions.h"
-
-namespace Kolab {
-
-/**
- * Check to see if serialization/deserialization was successful.
- */
-Kolab::ErrorSeverity error();
-std::string errorMessage();
-
-/**
- * Returns productId string of the last deserialized object.
- * Updated during deserialization of object.
- */
-std::string productId();
-/**
- * Returns KolabFormat version of the last deserialized object.
- * Updated during deserialization of object.
- */
-std::string xKolabVersion();
-/**
- * Returns xCal version of the last deserialized xCal object.
- * Updated during deserialization of object.
- */
-std::string xCalVersion();
-
-/**
- * Returns the UID of the last serialized  object.
- * Updated during serialization of the object.
- */
-std::string getSerializedUID();
-
-Kolab::Event readEvent(const std::string& s, bool isUrl);
-std::string writeEvent(const Kolab::Event &);
-
-Kolab::Todo readTodo(const std::string& s, bool isUrl);
-std::string writeTodo(const Kolab::Todo &);
-
-Kolab::Journal readJournal(const std::string& s, bool isUrl);
-std::string writeJournal(const Kolab::Journal &);
-
-Kolab::Contact readContact(const std::string& s, bool isUrl);
-std::string writeContact(const Kolab::Contact &);
-
-Kolab::DistList readDistlist(const std::string& s, bool isUrl);
-std::string writeDistlist(const Kolab::DistList &);
-
-Kolab::Note readNote(const std::string& s, bool isUrl);
-std::string writeNote(const Kolab::Note &);
-
-Kolab::Configuration readConfiguration(const std::string& s, bool isUrl);
-std::string writeConfiguration(const Kolab::Configuration &);
-
-}
-
-#endif // KOLABFORMAT_H
-
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
deleted file mode 100644
index 30726f3..0000000
--- a/c++/lib/kolabformat.i
+++ /dev/null
@@ -1,42 +0,0 @@
-/* kolabformat.i */
-%module kolabformat
-%{
-
-    /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
-    #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
-
-    #include "global_definitions.h"
-    #include "kolabformat.h"
-    #include "kolabcontainers.h"
-    #include "kolabevent.h"
-    #include "kolabtodo.h"
-    #include "kolabjournal.h"
-    #include "kolabcontact.h"
-%}
-
-%include "std_string.i"
-%include "std_vector.i"
-
-namespace std {
-    %template(vectori) vector<int>;
-    %template(vectors) vector<string>;
-    %template(vectordaypos) vector<Kolab::DayPos>;
-    %template(vectorcs) vector<Kolab::CustomProperty>;
-    %template(vectoraddress) vector<Kolab::Address>;
-    %template(vectoraffiliation) vector<Kolab::Affiliation>;
-    %template(vectoralarm) vector<Kolab::Alarm>;
-    %template(vectorattachment) vector<Kolab::Attachment>;
-    %template(vectorattendee) vector<Kolab::Attendee>;
-    %template(vectorcontactref) vector<Kolab::ContactReference>;
-    %template(vectorrelated) vector<Kolab::Related>;
-    %template(vectortelephone) vector<Kolab::Telephone>;
-    %template(vectordatetime) vector<Kolab::cDateTime>;
-};
-
-%include "global_definitions.h"
-%include "kolabcontainers.h"
-%include "kolabevent.h"
-%include "kolabtodo.h"
-%include "kolabjournal.h"
-%include "kolabcontact.h"
-%include "kolabformat.h"
diff --git a/c++/lib/kolabjournal.cpp b/c++/lib/kolabjournal.cpp
deleted file mode 100644
index f13633b..0000000
--- a/c++/lib/kolabjournal.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabjournal.h"
-#include "incidence_p.h"
-
-namespace Kolab {
-
-struct Journal::Private: public PrivateIncidence
-{
-    Private()
-    : PrivateIncidence() {}
-};
-
-Journal::Journal()
-: d(new Journal::Private())
-{
-}
-
-Journal::Journal(const Journal &other)
-: d(new Journal::Private())
-{
-    *d = *other.d;
-}
-
-Journal::~Journal()
-{
-}
-
-void Journal::operator=(const Kolab::Journal &other)
-{
-    *d = *other.d;
-}
-
-bool Journal::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void Journal::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Journal::uid() const
-{
-    return d->uid;
-}
-
-void Journal::setCreated(const Kolab::cDateTime &created)
-{
-    d->created = created;
-}
-
-cDateTime Journal::created() const
-{
-    return d->created;
-}
-
-void Journal::setLastModified(const Kolab::cDateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-cDateTime Journal::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Journal::setSequence(int sequence)
-{
-    d->sequence = sequence;
-}
-
-int Journal::sequence() const
-{
-    return d->sequence;
-}
-
-void Journal::setClassification(Classification class_)
-{
-    d->classification = class_;
-}
-
-Classification Journal::classification() const
-{
-    return d->classification;
-}
-
-void Journal::setCategories(const std::vector< std::string > &categories)
-{
-    d->categories = categories;
-}
-
-void Journal::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Journal::categories() const
-{
-    return d->categories;
-}
-
-void Journal::setStart(const Kolab::cDateTime &start)
-{
-    d->start = start;
-}
-
-cDateTime Journal::start() const
-{
-    return d->start;
-}
-
-void Journal::setSummary(const std::string &summary)
-{
-    d->summary = summary;
-}
-
-std::string Journal::summary() const
-{
-    return d->summary;
-}
-
-void Journal::setDescription(const std::string &description)
-{
-    d->description = description;
-}
-
-std::string Journal::description() const
-{
-    return d->description;
-}
-
-
-void Journal::setStatus(Status status)
-{
-    d->status = status;
-}
-
-Status Journal::status() const
-{
-    return d->status;
-}
-
-void Journal::setAttendees(const std::vector< Attendee > &attendees)
-{
-    d->attendees = attendees;
-}
-
-std::vector< Attendee > Journal::attendees() const
-{
-    return d->attendees;
-}
-
-void Journal::setAttachments(const std::vector< Attachment > &attach)
-{
-    d->attachments = attach;
-}
-
-std::vector< Attachment > Journal::attachments() const
-{
-    return d->attachments;
-}
-
-void Journal::setCustomProperties(const std::vector< CustomProperty > &prop)
-{
-    d->customProperties = prop;
-}
-
-std::vector< CustomProperty > Journal::customProperties() const
-{
-    return d->customProperties;
-}
-
-
-}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabjournal.h b/c++/lib/kolabjournal.h
deleted file mode 100644
index 9a904d3..0000000
--- a/c++/lib/kolabjournal.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABJOURNAL_H
-#define KOLABJOURNAL_H
-
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-#include "kolabcontainers.h"
-namespace Kolab {
-
-class Journal {
-public:
-    Journal();
-    ~Journal();
-    Journal(const Journal &);
-    void operator=(const Journal &);
-    
-    bool isValid() const;
-    
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setCreated(const cDateTime &);
-    cDateTime created() const;
-    
-    void setLastModified(const cDateTime &);
-    cDateTime lastModified() const;
-    
-    void setSequence(int);
-    int sequence() const;
-    
-    void setClassification(Classification);
-    Classification classification() const;
-
-    void setCategories(const std::vector<std::string> &);
-    void addCategory(const std::string &);
-    std::vector<std::string> categories() const;
-    
-    void setStart(const cDateTime &);
-    cDateTime start() const;
-    
-    void setSummary(const std::string &);
-    std::string summary() const;
-    
-    void setDescription(const std::string &);
-    std::string description() const;
-    
-    void setStatus(Status);
-    Status status() const;
-    
-    //TODO Contacts
-    
-    void setAttendees(const std::vector<Attendee> &);
-    std::vector<Attendee> attendees() const;
-    
-    void setAttachments(const std::vector<Attachment> &);
-    std::vector<Attachment> attachments() const;
-    
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-
-
-}
-
-#endif
-
diff --git a/c++/lib/kolabnote.cpp b/c++/lib/kolabnote.cpp
deleted file mode 100644
index c7931bb..0000000
--- a/c++/lib/kolabnote.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "kolabnote.h"
-
-namespace Kolab {
-
-struct Note::Private
-{
-    Private()
-    : classification(ClassPublic){}
-    
-    std::string uid;
-    cDateTime created;
-    cDateTime lastModified;
-    std::vector< std::string > categories;
-    Classification classification;
-    
-    std::string summary;
-    std::string description;
-    std::string color;
-    
-    std::vector<Attachment> attachments;
-    std::vector<CustomProperty> customProperties;
-};
-
-Note::Note()
-: d(new Note::Private())
-{
-}
-
-Note::Note(const Note &other)
-: d(new Note::Private())
-{
-    *d = *other.d;
-}
-
-Note::~Note()
-{
-}
-
-void Note::operator=(const Kolab::Note &other)
-{
-    *d = *other.d;
-}
-
-bool Note::operator==(const Kolab::Note& other) const
-{
-    return ( d->uid == other.uid() &&
-    d->created == other.created() &&
-    d->lastModified == other.lastModified() &&
-    d->categories == other.categories() &&
-    d->classification == other.classification() &&
-    d->summary == other.summary() &&
-    d->description == other.description() &&
-    d->color == other.color() &&
-    d->attachments == other.attachments() &&
-    d->customProperties == other.customProperties());
-}
-
-bool Note::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void Note::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Note::uid() const
-{
-    return d->uid;
-}
-
-void Note::setCreated(const Kolab::cDateTime &created)
-{
-    d->created = created;
-}
-
-cDateTime Note::created() const
-{
-    return d->created;
-}
-
-void Note::setLastModified(const Kolab::cDateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-cDateTime Note::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Note::setClassification(Classification class_)
-{
-    d->classification = class_;
-}
-
-Classification Note::classification() const
-{
-    return d->classification;
-}
-
-void Note::setCategories(const std::vector< std::string > &categories)
-{
-    d->categories = categories;
-}
-
-void Note::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Note::categories() const
-{
-    return d->categories;
-}
-
-void Note::setSummary(const std::string &summary)
-{
-    d->summary = summary;
-}
-
-std::string Note::summary() const
-{
-    return d->summary;
-}
-
-void Note::setDescription(const std::string &description)
-{
-    d->description = description;
-}
-
-std::string Note::description() const
-{
-    return d->description;
-}
-
-void Note::setColor(const std::string &color)
-{
-    d->color = color;
-}
-
-std::string Note::color() const
-{
-    return d->color;
-}
-
-void Note::setAttachments(const std::vector< Attachment > &attach)
-{
-    d->attachments = attach;
-}
-
-std::vector< Attachment > Note::attachments() const
-{
-    return d->attachments;
-}
-
-void Note::setCustomProperties(const std::vector< CustomProperty > &prop)
-{
-    d->customProperties = prop;
-}
-
-std::vector< CustomProperty > Note::customProperties() const
-{
-    return d->customProperties;
-}
-
-} //Note
diff --git a/c++/lib/kolabnote.h b/c++/lib/kolabnote.h
deleted file mode 100644
index 6edffb6..0000000
--- a/c++/lib/kolabnote.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KOLABNOTE_H
-#define KOLABNOTE_H
-
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-#include "kolabcontainers.h"
-namespace Kolab {
-    
-    class Note {
-    public:
-        Note();
-        ~Note();
-        Note(const Note &);
-        void operator=(const Note &);
-        bool operator==(const Note &) const;
-        
-        bool isValid() const;
-        
-        void setUid(const std::string &);
-        std::string uid() const;
-        
-        void setCreated(const cDateTime &);
-        cDateTime created() const;
-        
-        void setLastModified(const cDateTime &);
-        cDateTime lastModified() const;
-        
-        void setClassification(Classification);
-        Classification classification() const;
-        
-        void setCategories(const std::vector<std::string> &);
-        void addCategory(const std::string &);
-        std::vector<std::string> categories() const;
-        
-        void setSummary(const std::string &);
-        std::string summary() const;
-        
-        void setDescription(const std::string &);
-        std::string description() const;
-        
-        void setColor(const std::string &);
-        std::string color() const;
-        
-        void setAttachments(const std::vector<Attachment> &);
-        std::vector<Attachment> attachments() const;
-        
-        void setCustomProperties(const std::vector<CustomProperty> &);
-        std::vector<CustomProperty> customProperties() const;
-    private:
-        struct Private;
-        boost::scoped_ptr<Private> d;
-    };
-
-}
-
-#endif
-
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
deleted file mode 100644
index 97d2e03..0000000
--- a/c++/lib/kolabtodo.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabtodo.h"
-#include "incidence_p.h"
-
-namespace Kolab {
-    
-    
-struct Todo::Private: public PrivateIncidence
-{
-    Private()
-    : PrivateIncidence(),
-    percentComplete(0){}
-    
-    cDateTime due;
-    int percentComplete;
-};
-
-Todo::Todo()
-: d(new Todo::Private())
-{
-    
-}
-
-Todo::Todo(const Todo &other)
-: d(new Todo::Private())
-{
-    *d = *other.d;
-}
-
-Todo::~Todo()
-{
-    
-}
-
-void Todo::operator=(const Kolab::Todo &other)
-{
-    *d = *other.d;
-}
-
-bool Todo::isValid() const
-{
-    return !d->uid.empty();
-}
-
-void Todo::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Todo::uid() const
-{
-    return d->uid;
-}
-
-void Todo::setCreated(const Kolab::cDateTime &created)
-{
-    d->created = created;
-}
-
-cDateTime Todo::created() const
-{
-    return d->created;
-}
-
-void Todo::setLastModified(const Kolab::cDateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-cDateTime Todo::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Todo::setSequence(int sequence)
-{
-    d->sequence = sequence;
-}
-
-int Todo::sequence() const
-{
-    return d->sequence;
-}
-
-void Todo::setClassification(Classification class_)
-{
-    d->classification = class_;
-}
-
-Classification Todo::classification() const
-{
-    return d->classification;
-}
-
-void Todo::setCategories(const std::vector< std::string > &categories)
-{
-    d->categories = categories;
-}
-
-void Todo::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Todo::categories() const
-{
-    return d->categories;
-}
-
-void Todo::setRelatedTo(const std::vector< std::string > &related)
-{
-    d->relatedTo = related;
-}
-
-void Todo::addRelatedTo(const std::string &related)
-{
-    d->relatedTo.push_back(related);
-}
-
-std::vector< std::string > Todo::relatedTo() const
-{
-    return d->relatedTo;
-}
-
-void Todo::setStart(const Kolab::cDateTime &start)
-{
-    d->start = start;
-}
-
-cDateTime Todo::start() const
-{
-    return d->start;
-}
-
-void Todo::setDue(const Kolab::cDateTime &due)
-{
-    d->due = due;
-}
-
-cDateTime Todo::due() const
-{
-    return d->due;
-}
-
-void Todo::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture)
-{
-    d->recurrenceID = rID;
-    d->thisAndFuture = thisandfuture;
-}
-
-cDateTime Todo::recurrenceID() const
-{
-    return d->recurrenceID;
-}
-
-bool Todo::thisAndFuture() const
-{
-    return d->thisAndFuture;
-}
-
-void Todo::setSummary(const std::string &summary)
-{
-    d->summary = summary;
-}
-
-std::string Todo::summary() const
-{
-    return d->summary;
-}
-
-void Todo::setDescription(const std::string &description)
-{
-    d->description = description;
-}
-
-std::string Todo::description() const
-{
-    return d->description;
-}
-
-void Todo::setPriority(int priority)
-{
-    d->priority = priority;
-}
-
-int Todo::priority() const
-{
-    return d->priority;
-}
-
-void Todo::setStatus(Status status)
-{
-    d->status = status;
-}
-
-Status Todo::status() const
-{
-    return d->status;
-}
-
-void Todo::setPercentComplete(int complete)
-{
-    d->percentComplete = complete;
-}
-    
-int Todo::percentComplete() const
-{
-    return d->percentComplete;
-}
-
-void Todo::setLocation(const std::string &location)
-{
-    d->location = location;
-}
-
-std::string Todo::location() const
-{
-    return d->location;
-}
-
-void Todo::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
-{
-    d->rrule = rrule;
-}
-
-RecurrenceRule Todo::recurrenceRule() const
-{
-    return d->rrule;
-}
-
-void Todo::setRecurrenceDates(const std::vector< cDateTime > &dates)
-{
-    d->recurrenceDates = dates;
-}
-
-void Todo::addRecurrenceDate(const Kolab::cDateTime &dt)
-{
-    d->recurrenceDates.push_back(dt);
-}
-
-std::vector< cDateTime > Todo::recurrenceDates() const
-{
-    return d->recurrenceDates;
-}
-
-void Todo::setExceptionDates(const std::vector< cDateTime > &dates)
-{
-    d->exceptionDates = dates;
-}
-
-void Todo::addExceptionDate(const Kolab::cDateTime &dt)
-{
-    d->exceptionDates.push_back(dt);
-}
-
-std::vector< cDateTime > Todo::exceptionDates() const
-{
-    return d->exceptionDates;
-}
-
-void Todo::setOrganizer(const ContactReference &organizer)
-{
-    d->organizer = organizer;
-}
-
-ContactReference Todo::organizer() const
-{
-    return d->organizer;
-}
-
-void Todo::setAttendees(const std::vector< Attendee > &attendees)
-{
-    d->attendees = attendees;
-}
-
-std::vector< Attendee > Todo::attendees() const
-{
-    return d->attendees;
-}
-
-void Todo::setAttachments(const std::vector< Attachment > &attach)
-{
-    d->attachments = attach;
-}
-
-std::vector< Attachment > Todo::attachments() const
-{
-    return d->attachments;
-}
-
-void Todo::setCustomProperties(const std::vector< CustomProperty > &prop)
-{
-    d->customProperties = prop;
-}
-
-std::vector< CustomProperty > Todo::customProperties() const
-{
-    return d->customProperties;
-}
-
-void Todo::setAlarms(const std::vector< Alarm > &alarms)
-{
-    d->alarms = alarms;
-}
-
-std::vector< Alarm > Todo::alarms() const
-{
-    return d->alarms;
-}
-
-}
\ No newline at end of file
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
deleted file mode 100644
index ce547e3..0000000
--- a/c++/lib/kolabtodo.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLAB_TODO_H
-#define KOLAB_TODO_H
-
-#include <string>
-#include <vector>
-#include <boost/scoped_ptr.hpp>
-#include "kolabcontainers.h"
-namespace Kolab {
-    
-
-class Todo {
-public:
-    Todo();
-    ~Todo();
-    Todo(const Todo &);
-    void operator=(const Todo &);
-    
-    bool isValid() const;
-
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setCreated(const cDateTime &);
-    cDateTime created() const;
-    
-    void setLastModified(const cDateTime &);
-    cDateTime lastModified() const;
-    
-    void setSequence(int);
-    int sequence() const;
-    
-    void setClassification(Classification);
-    Classification classification() const;
-
-    void setCategories(const std::vector<std::string> &);
-    void addCategory(const std::string &);
-    std::vector<std::string> categories() const;
-    
-    void setRelatedTo(const std::vector<std::string> &);
-    void addRelatedTo(const std::string &);
-    std::vector<std::string> relatedTo() const;
-    
-    void setStart(const cDateTime &);
-    cDateTime start() const;
-    
-    void setDue(const cDateTime &);
-    cDateTime due() const;
-
-    void setRecurrenceRule(const RecurrenceRule &);
-    RecurrenceRule recurrenceRule() const;
-    
-    void setRecurrenceDates(const std::vector<cDateTime> &);
-    void addRecurrenceDate(const cDateTime &);
-    std::vector<cDateTime> recurrenceDates() const;
-    
-    void setExceptionDates(const std::vector<cDateTime> &);
-    void addExceptionDate(const cDateTime &);
-    std::vector<cDateTime> exceptionDates() const;
-    
-    void setRecurrenceID(const cDateTime &, bool thisandfuture);
-    cDateTime recurrenceID() const;
-    bool thisAndFuture() const;
-    
-    void setSummary(const std::string &);
-    std::string summary() const;
-    
-    void setDescription(const std::string &);
-    std::string description() const;
-    
-    void setPriority(int);
-    int priority() const;
-    
-    void setStatus(Status);
-    Status status() const;
-    
-    void setPercentComplete(int);
-    int percentComplete() const;
-    
-    void setLocation(const std::string &);
-    std::string location() const;
-    
-    void setOrganizer(const ContactReference &);
-    ContactReference organizer() const;
-    
-    void setAttendees(const std::vector<Attendee> &);
-    std::vector<Attendee> attendees() const;
-    
-    void setAttachments(const std::vector<Attachment> &);
-    std::vector<Attachment> attachments() const;
-    
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-    
-    void setAlarms(const std::vector<Alarm> &);
-    std::vector<Alarm> alarms() const;
-    
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
-}
-
-#endif
-
diff --git a/c++/lib/php/CMakeLists.txt b/c++/lib/php/CMakeLists.txt
deleted file mode 100644
index 2d95c36..0000000
--- a/c++/lib/php/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-#Generate PHP wrapper
-include_directories(../)
-
-set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp)
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
-    COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  ../kolabformat.i
-    COMMENT "Generating php bindings"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS ../kolabformat.i kolabxml
-    VERBATIM
-    )
-SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
-ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
-
-
-#Compile PHP Bindings
-# Since there is no php library we can't compile with -Wl,--no-undefined
-if (APPLE)
-    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flat_namespace -undefined suppress" )
-endif()
-
-find_package(PHP4)
-include_directories(${PHP4_INCLUDE_PATH})
-add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
-target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
-
-configure_file(test.php ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
-
-install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
-
-install( FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php
-  test.php
-  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
\ No newline at end of file
diff --git a/c++/lib/php/test.php b/c++/lib/php/test.php
deleted file mode 100755
index 48c3304..0000000
--- a/c++/lib/php/test.php
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-//run using "php -d enable_dl=On -d extension=./kolabformat.so  test.php"
-
-include("kolabformat.php");
-
-function assertequal($got, $expect, $name) {
-	if ($got == $expect) {
-		print "OK - $name\n";
-		return true;
-	}
-	else {
-		print "FAIL - $name\n";
-		print "-- Expected " . var_export($expect, true) . ", got " . var_export($got, true) . " --\n";
-		return false;
-	}
-}
-
-function assertcontains($haystack, $needle, $name) {
-	// remove whitespace
-	$haystack = preg_replace('/\n\s*/ims', '', $haystack);
-	$needle = preg_replace('/\n\s*/ims', '', $needle);
-
-	return assertequal(substr(strstr($haystack, $needle), 0, strlen($needle)), $needle, $name);
-}
-
-function asserttrue($arg, $name) {
-	return assertequal($arg, true, $name);
-}
-
-function assertfalse($arg, $name) {
-	return assertequal($arg, false, $name);
-}
-
-function array2vector($arr) {
-	$vec = new vectors;
-	foreach ((array)$arr as $val)
-		$vec->push($val);
-	return $vec;
-}
-
-
-/////// Test Event
-
-$e = new Event();
-$e->setCreated(new cDateTime(2012,3,14, 9,5,30));
-$e->setStart(new cDateTime(2012,7,31));
-$d = new cDateTime(2009,10,12);
-assertequal($e->exceptionDates()->size(), 0, "Event::exceptionDates()");
-$e->addExceptionDate($d);
-assertequal($e->exceptionDates()->size(), 1, "Event::addExceptionDate()");
-
-$r = new RecurrenceRule();
-$r->setFrequency(RecurrenceRule::Minutely);
-
-$bysec = new vectori();
-$bysec->push(1);
-$bysec->push(3);
-
-$r->setBySecond($bysec);
-$e->setRecurrenceRule($r);
-
-$xml = kolabformat::writeEvent($e);
-#print $xml;
-assertcontains($xml, '<dtstart><date>2012-07-31</date></dtstart>', "Event::setStart() with date only");
-assertcontains($xml, '<created><date-time>2012-03-14T09:05:30Z</date-time></created>', "Event::setCreated() with date-time");
-assertcontains($xml, '<rrule><recur><freq>MINUTELY</freq>', "RecurrenceRule::setFrequency()");
-assertcontains($xml, '<rrule><recur><freq>MINUTELY</freq><bysecond>1</bysecond><bysecond>3</bysecond></recur></rrule>', "RecurrenceRule::setBySecond()");
-assertcontains($xml, '<exdate><date>2009-10-12</date></exdate>', "Event Recurrence Exceptions");
-
-$e1 = kolabformat::readEvent($xml, false);
-assertequal($xml, kolabformat::writeEvent($e1), "kolabformat::readEvent() => kolabformat::writeEvent()");
-
-$s = $e1->start();
-assertequal(sprintf('%d-%d-%d', $s->year(), $s->month(), $s->day()), '2012-7-31', "Event::start()");
-
-$r = $e1->recurrenceRule();
-assertequal($r->frequency(), RecurrenceRule::Minutely, "RecurrenceRule::frequency()");
-assertequal($r->bysecond()->size(), 2, "RecurrenceRule::bysecond()");
-assertequal($e1->exceptionDates()->size(), 1, "Read Event::exceptionDates()");
-
-
-/////// Test Contact
-
-$c = new Contact;
-$c->setName("Contact-FN");
-
-$nc = new NameComponents;
-$nc->setSurnames(array2vector("Surname"));
-$nc->setGiven(array2vector("Given"));
-$nc->setAdditional(array2vector(array("Middle1", "Middle2")));
-$nc->setPrefixes(array2vector("Prefix"));
-#$nc->setSuffixes(new vectors);
-
-assertcontains($nc->surnames()->size(),    1, "NameComponents::setSurnames()");
-assertcontains($nc->given()->size(),       1, "NameComponents::setGiven()");
-assertcontains($nc->additional()->size(),  2, "NameComponents::setAdditional()");
-assertcontains($nc->prefixes()->size(),    1, "NameComponents::setPrefixes()");
-assertcontains($nc->suffixes()->size(),    0, "NameComponents::suffixes()");
-
-$c->setNameComponents($nc);
-$c->setTitles(array2vector("MyProfession"));
-
-$pic = "R0lGODlhEgASAIAAAMDAwAAAACH5BAEAAAAALAAAAAASABIAQAIPhI+py+0Po5y02ouz3pwXADs=";
-$c->setPhoto(base64_decode($pic), 'image/gif');
-$c->setGPSpos(array2vector("geo:46.952585,7.43766"));
-
-$bd = new cDateTime(1980,8,1);
-$c->setBDay($bd);
-
-$vcs = new vectorcs;
-$vcs->push(new CustomProperty("initials", "KF"));
-$c->setCustomProperties($vcs);
-
-$xml = kolabformat::writeContact($c);
-#print $xml;
-assertcontains($xml, "<uid><uri>urn:uuid:", "Generate Contact UID as urn::uuid");
-assertcontains($xml, "<n><surname>Surname</surname><given>Given</given><additional>Middle1</additional><additional>Middle2</additional><prefix>Prefix</prefix></n>", "Contact::setNameComponents()");
-assertcontains($xml, "<title><text>MyProfession</text></title>", "Contact::setTitles()");
-assertcontains($xml, "<photo><uri>data:image/gif;base64,$pic</uri></photo>", "Contact::setPhoto()");
-assertcontains($xml, "<bday><date>19800801</date></bday>", "Contact::setBDay()");
-assertcontains($xml, "<geo><uri>geo:46.952585,7.43766</uri></geo>", "Contact::setGPSpos()");
-
-$c1 = kolabformat::readContact($xml, false);
-assertequal($xml, kolabformat::writeContact($c1), "kolabformat::readContact() => kolabformat::writeContact()");
-assertequal($c1->photoMimetype(), "image/gif", "Contact::photoMimetype()");
-assertequal($c1->uid(), kolabformat::getSerializedUID(), "kolabformat::getSerializedUID()");
-
-$c1->setBDay(new cDateTime);
-$xml = kolabformat::writeContact($c);
-assertfalse(strpos($xml, '<bday><date>'), "Unset BDay with empty cDateTime");
-
-
-/////// Test DistList
-
-$dl = new DistList;
-$dl->setName("DalistÄÖŸ");
-
-$m = new vectorcontactref;
-$a = new ContactReference(ContactReference::EmailReference, "a at localhost", "Member-A");
-$m->push($a);
-
-$b = new ContactReference(ContactReference::UidReference, "x-member-b-fff");
-$b->setName("Member-B");
-$m->push($b);
-
-#$c = new ContactReference(ContactReference::EmailAndUidReference, "c at localhost", "dddaab06-0000-0000-eeb5-cc64ff7f0000");
-#$c->setName("Member-C");
-#$m->push($c);
-
-assertequal($m->size(), 2, "vectorcontactref::size()");
-$dl->setMembers($m);
-
-$xml = kolabformat::writeDistlist($dl);
-#print $xml;
-assertcontains($xml, '<fn><text>DalistÄÖŸ</text></fn>', "kolabformat::writeDistlist(): FN (UTF-8)");
-assertcontains($xml, '<uri>mailto:Member%2DA%3Ca%40localhost%3E</uri>', "kolabformat::writeDistlist(): mailto uri");
-assertcontains($xml, '<member><uri>urn:uuid:x-member-b-fff</uri>', "kolabformat::writeDistlist(): member urn::uuid");
-
-?>
-
-
-
diff --git a/c++/lib/python/CMakeLists.txt b/c++/lib/python/CMakeLists.txt
deleted file mode 100644
index 397405c..0000000
--- a/c++/lib/python/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-#Generate Python wrapper
-include_directories(../)
-
-set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
-    COMMAND ${SWIG} -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} ../kolabformat.i
-    COMMENT "Generating python bindings"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS ../kolabformat.i kolabxml
-    VERBATIM
-    )
-
-SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
-ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-
-#Compile Python Bindings
-find_package(PythonLibs)
-include_directories(${PYTHON_INCLUDE_DIRS})
-
-# python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-
-add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
-SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
-SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
-
-configure_file(test.py ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
-
-install(TARGETS pythonbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
-
-install( FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.py
-  test.py
-  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
\ No newline at end of file
diff --git a/c++/lib/python/test.py b/c++/lib/python/test.py
deleted file mode 100644
index f7a306e..0000000
--- a/c++/lib/python/test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import kolabformat
-e = kolabformat.Event()
-
-ex = e.exceptionDates()
-ex.size()
-ex.push_back(kolabformat.cDateTime(1,1,1))
-ex.size()
-e.exceptionDates().size()
-e.setExceptionDates(ex)
-e.exceptionDates().size()
-
-string = kolabformat.writeEvent(e);
-print string;
-e1 = kolabformat.readEvent(string, False);
-string = kolabformat.writeEvent(e1);
-print string;
\ No newline at end of file
diff --git a/c++/lib/shared_conversions.h b/c++/lib/shared_conversions.h
deleted file mode 100644
index fd64ae5..0000000
--- a/c++/lib/shared_conversions.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SHAREDCONVERSIONS_H
-#define SHAREDCONVERSIONS_H
-
-#include <xsd/cxx/tree/date-time.hxx>
-#include "kolabcontainers.h"
-#include <boost/shared_ptr.hpp>
-#include "utils.h"
-#include <bindings/iCalendar-params.hxx>
-
-namespace Kolab {
-    namespace Shared {
-typedef boost::shared_ptr<cDateTime> cDateTimePtr;
-
-typedef ::xsd::cxx::tree::type type;
-typedef ::xsd::cxx::tree::simple_type< type > simple_type;
-typedef ::xsd::cxx::tree::date< char, simple_type > date;
-typedef ::xsd::cxx::tree::date_time< char, simple_type > date_time;
-
-using namespace Utils;
-
-cDateTimePtr toDate(const date &dt)
-{
-    cDateTimePtr date(new cDateTime());
-    date->setDate(dt.year(), dt.month(), dt.day());
-    return date;
-}
-
-cDateTimePtr toDate(const date_time &dt)
-{
-    cDateTimePtr date(new cDateTime());
-    date->setDate(dt.year(), dt.month(), dt.day());
-    date->setTime(dt.hours(), dt.minutes(), dt.seconds());
-    if (dt.zone_present()) {
-        date->setUTC(true);
-    }
-    return date;
-}
-
-date_time fromDateTime(const cDateTime &d)
-{
-    date_time date(d.year(), d.month(), d.day(), d.hour(), d.minute(), d.second());
-    if (d.isUTC()) {
-        //Setting both zone hours/and zone minutes to zero results in a Z being appended to indicate UTC
-        date.zone_hours(0);
-        date.zone_minutes(0);
-    }
-    return date;
-}
-
-date fromDate(const cDateTime &d)
-{
-    date de(d.year(), d.month(), d.day());
-    return de;
-}
-
-std::string toURN(const std::string &uid)
-{
-    if (uid.substr(0, 9) == std::string("urn:uuid:")) {
-        return uid;
-    }
-    return std::string("urn:uuid:")+uid;
-}
-
-std::string fromURN(const std::string &uri)
-{
-    if (uri.substr(0, 9) != std::string("urn:uuid:")) {
-        WARNING("not a urn");
-        return uri;
-    }
-    return uri.substr(9);
-}
-
-Kolab::ContactReference toContactReference(const std::string &uri) {
-    std::string name;
-    if (uri.substr(0, 9) == std::string("urn:uuid:")) {
-        return Kolab::ContactReference(Kolab::ContactReference::UidReference, fromURN(uri));
-    }
-    const std::string &email = fromMailto(uri, name);
-    return Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name);
-}
-
-std::string fromContactReference(const Kolab::ContactReference &c, bool embeddName = true) {
-    switch (c.type()) {
-        case ContactReference::UidReference:
-            return toURN(c.uid());
-        case ContactReference::EmailReference:
-        case ContactReference::EmailAndUidReference:
-            if (embeddName) {
-                return toMailto(c.email(), c.name());
-            }
-            return toMailto(c.email());
-        case ContactReference::Invalid:
-        default:
-            WARNING("Tried serializing invalid ContactReference");
-    }
-    return std::string();
-}
-
-
-
-
-    } //Namespace
-} //Namespace
-
-#endif
\ No newline at end of file
diff --git a/c++/lib/uricode.h b/c++/lib/uricode.h
deleted file mode 100644
index 54bf542..0000000
--- a/c++/lib/uricode.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Uri encode and decode.
-// RFC1630, RFC1738, RFC2396
-
-#include <string>
-#include <assert.h>
-
-const char HEX2DEC[256] = 
-{
-    /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
-    /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
-    
-    /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    
-    /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    
-    /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
-};
-
-std::string UriDecode(const std::string & sSrc)
-{
-    // Note from RFC1630:  "Sequences which start with a percent sign
-    // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
-    // for future extension"
-    
-    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
-    const int SRC_LEN = sSrc.length();
-    const unsigned char * const SRC_END = pSrc + SRC_LEN;
-    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
-    
-    char * const pStart = new char[SRC_LEN];
-    char * pEnd = pStart;
-    
-    while (pSrc < SRC_LAST_DEC)
-    {
-        if (*pSrc == '%')
-        {
-            char dec1, dec2;
-            if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
-                && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))
-            {
-                *pEnd++ = (dec1 << 4) + dec2;
-                pSrc += 3;
-                continue;
-            }
-        }
-        
-        *pEnd++ = *pSrc++;
-    }
-    
-    // the last 2- chars
-    while (pSrc < SRC_END)
-        *pEnd++ = *pSrc++;
-    
-    std::string sResult(pStart, pEnd);
-    delete [] pStart;
-    return sResult;
-}
-
-// Only alphanum is safe.
-const char SAFE[256] =
-{
-    /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */
-    /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
-    
-    /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
-    /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
-    /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
-    /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
-    
-    /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    
-    /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-    /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
-};
-
-std::string UriEncode(const std::string & sSrc)
-{
-    const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
-    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
-    const int SRC_LEN = sSrc.length();
-    unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
-    unsigned char * pEnd = pStart;
-    const unsigned char * const SRC_END = pSrc + SRC_LEN;
-    
-    for (; pSrc < SRC_END; ++pSrc)
-    {
-        if (SAFE[*pSrc]) 
-            *pEnd++ = *pSrc;
-        else
-        {
-            // escape this char
-            *pEnd++ = '%';
-            *pEnd++ = DEC2HEX[*pSrc >> 4];
-            *pEnd++ = DEC2HEX[*pSrc & 0x0F];
-        }
-    }
-    
-    std::string sResult((char *)pStart, (char *)pEnd);
-    delete [] pStart;
-    return sResult;
-}
-
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
deleted file mode 100644
index 8096f54..0000000
--- a/c++/lib/utils.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "utils.h"
-#include <string>
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 104200
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_io.hpp>
-#else
-#include <uuid/uuid.h>
-#endif
-
-#include <boost/lexical_cast.hpp>
-#include <boost/thread.hpp>
-#include <time.h>
-#include "base64.h"
-#include "uricode.h"
-
-namespace Kolab {
-    
-namespace Utils {
-
-/**
- * We have to store our global variables thread-local to ensure thread-safety.
- */
-struct Global {
-    std::string createdUID;
-    std::string productId;
-    std::string xKolabVersion;
-    
-    ErrorSeverity errorBit;
-    std::string errorMessage;
-};
-
-boost::thread_specific_ptr<Global> ptr;
-class ThreadLocal
-{
-public:
-    static Global &inst()
-    {
-        Global *t = ptr.get();
-//         std::cout << "inst " << boost::this_thread::get_id() << std::endl;
-        if (!t) {
-//             std::cout << "initialize Global" << std::endl;
-            t = new Global();
-            ptr.reset(t);
-        }
-        return *t;
-    }
-};
-
-void setKolabVersion(const std::string &s)
-{
-    ThreadLocal::inst().xKolabVersion = s;
-}
-
-std::string kolabVersion()
-{
-    return ThreadLocal::inst().xKolabVersion;
-}
-
-void setProductId(const std::string &s)
-{
-    ThreadLocal::inst().productId = s;
-}
-
-std::string productId()
-{
-    return ThreadLocal::inst().productId;
-}
-
-
-void setCreatedUid(const std::string &s)
-{
-    ThreadLocal::inst().createdUID = s;
-}
-
-std::string createdUid()
-{
-    return ThreadLocal::inst().createdUID;
-}
-
-
-std::string getUID(const std::string &s)
-{
-    if (s.empty()) {
-#if BOOST_VERSION >= 104200
-        boost::uuids::uuid u; // initialize uuid
-        return boost::uuids::to_string(u);
-#else
-        uuid_t u;
-        uuid_generate(u);
-        char out[37];
-        uuid_unparse(u,out);
-        return std::string(out, 36); //We don't need the terminating \0
-#endif
-    }
-    return s;
-}
-
-cDateTime getCurrentTime()
-{
-    time_t rawtime;
-    struct tm * ptm;
-    time(&rawtime);
-    ptm = gmtime(&rawtime);
-    return cDateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
-}
-
-
-void logMessage(const std::string &m, ErrorSeverity s)
-{
-    switch (s) {
-        case NoError:
-            std::cout << "Debug: " << m << std::endl;
-            break;
-        case Warning:
-            std::cerr << "Warning: " << m << std::endl;
-            break;
-        case Error:
-            std::cerr << "Error: " << m << std::endl;
-            if (ThreadLocal::inst().errorBit < Error) {
-                ThreadLocal::inst().errorBit = Error;
-                ThreadLocal::inst().errorMessage = m;
-            }
-            break;
-        case Critical:
-        default:
-            std::cerr << "Critical: " << m << std::endl;
-            if (ThreadLocal::inst().errorBit < Critical) {
-                ThreadLocal::inst().errorBit = Critical;
-                ThreadLocal::inst().errorMessage = m;
-            }
-    }
-}
-
-void logMessage(const std::string &message, const std::string &file, int line, ErrorSeverity s)
-{
-   logMessage(file+" "+boost::lexical_cast<std::string>(line)+": " + "  " + message, s);
-}
-
-void clearErrors()
-{
-    ThreadLocal::inst().errorBit = NoError;
-    ThreadLocal::inst().errorMessage.clear();
-}
-
-ErrorSeverity getError()
-{
-    return ThreadLocal::inst().errorBit;
-}
-
-std::string getErrorMessage()
-{
-    return ThreadLocal::inst().errorMessage;
-}
-
-
-std::string uriInlineEncoding(const std::string &s, const std::string &mimetype)
-{
-    return std::string("data:")+mimetype+std::string(";base64,")+base64_encode(reinterpret_cast<const unsigned char*>(s.c_str()), s.length());
-}
-
-std::string uriInlineDecoding(const std::string &s, std::string &mimetype)
-{
-    if (s.substr(0, 5) != std::string("data:")) {
-        ERROR("wrong picture encoding");
-        std::cout << s <<  "      " << s.substr(0, 5) << std::endl;
-        return std::string();
-    }
-    std::size_t pos = s.find(";",5);
-    if (pos == std::string::npos) {
-        ERROR("wrong picture encoding");
-        std::cout << s <<  "      " << s.substr(0, 5) << std::endl;
-        return std::string();
-    }
-    mimetype = s.substr(5, pos-5);
-    if (s.substr(pos+1, 6) != std::string("base64")) {
-        ERROR("wrong picture encoding");
-        std::cout << s <<  "      " << s.substr(pos+1, 6) << std::endl;
-        return std::string();
-    }
-    return base64_decode(s.substr(pos+8, s.size()-(pos+8)));
-}
-
-std::string toMailto(const std::string &email, const std::string &name)
-{
-    std::string mailto;
-    if (!name.empty()) {
-        mailto.append(name);
-    }
-    mailto.append("<");
-    mailto.append(email);
-    mailto.append(">");
-    return std::string("mailto:")+UriEncode(mailto);
-}
-
-std::string fromMailto(const std::string &mailtoUri, std::string &name)
-{
-    const std::string &decoded = UriDecode(mailtoUri);
-    if (decoded.substr(0, 7).compare("mailto:")) {
-        WARNING("no mailto address");
-        std::cout << decoded << std::endl;
-        return mailtoUri;
-    }
-    std::size_t begin = decoded.find('<',7);
-    if (begin == std::string::npos) {
-        WARNING("no mailto address");
-        std::cout << decoded << std::endl;
-        return mailtoUri;
-    }
-    std::size_t end = decoded.find('>', begin);
-    if (end == std::string::npos) {
-        WARNING("no mailto address");
-        std::cout << decoded << std::endl;
-        return mailtoUri;
-    }
-    name = decoded.substr(7, begin-7);
-    const std::string &email = decoded.substr(begin+1, end-begin-1);
-    return email;
-}
-
-std::string fromMailto(const std::string &mailtoUri)
-{
-    std::string n;
-    return fromMailto(mailtoUri, n);
-}
-
-} //Namespace
-
-} //Namespace
\ No newline at end of file
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
deleted file mode 100644
index 15bf376..0000000
--- a/c++/lib/utils.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <string>
-#include "kolabcontainers.h"
-#include "global_definitions.h"
-#include <boost/numeric/conversion/cast.hpp>
-
-namespace Kolab {
-
-    namespace Utils {
-/**
- * Returns a new globally unique UID if the parameter is empty
- */
-std::string getUID(const std::string & = std::string());
-
-cDateTime getCurrentTime();
-
-void logMessage(const std::string &,const std::string &, int, ErrorSeverity s);
-     
-#define LOG(message) logMessage(message,__FILE__, __LINE__, NoError);
-#define WARNING(message) logMessage(message,__FILE__, __LINE__, Warning);
-#define ERROR(message) logMessage(message,__FILE__, __LINE__, Error);
-#define CRITICAL(message) logMessage(message,__FILE__, __LINE__, Critical);
-
-void logMessage(const std::string &, ErrorSeverity s = Warning);
-
-
-/**
- * The following values must be updated by the serialization/deserialization functinos
- */
-
-
-/**
- * The error state after serialization/deserialization
- */
-void clearErrors();
-ErrorSeverity getError();
-std::string getErrorMessage();
-
-/**
- * The uid of the last serialized object
- */
-void setCreatedUid(const std::string &);
-std::string createdUid();
-
-/**
- * The productId of the last deserialized object
- */
-void setProductId(const std::string &);
-std::string productId();
-
-/**
- * The Kolab Format Version of the last deserialized object
- */
-void setKolabVersion(const std::string &);
-std::string kolabVersion();
-
-/**
- * Helper functions for save conversion of integer types (so we can catch overflows)
- */
-
-template <typename T>
-int convertToInt(T integer)
-{
-    try {
-        return boost::numeric_cast<int>(integer);
-    } catch(boost::numeric::negative_overflow& e) {
-        ERROR(e.what());
-    } catch(boost::numeric::positive_overflow& e) {
-        ERROR(e.what());
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        ERROR(e.what());
-    }
-    return 0;
-}
-
-template <typename T> 
-T fromInt(int integer)
-{
-    try {
-        return boost::numeric_cast<T>(integer);
-    } catch(boost::numeric::negative_overflow& e) {
-        ERROR(e.what());
-    } catch(boost::numeric::positive_overflow& e) {
-        ERROR(e.what());
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        ERROR(e.what());
-    }
-    return 0;
-}
-
-std::string uriInlineEncoding(const std::string &, const std::string &mime);
-std::string uriInlineDecoding(const std::string &s, std::string &mimetype);
-
-std::string toMailto(const std::string &email, const std::string &name = std::string());
-std::string fromMailto(const std::string &mailtoUri, std::string &name);
-std::string fromMailto(const std::string &mailtoUri);
-
-    } //Namespace
-
-} //Namespace
-
-#endif
-
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
deleted file mode 100644
index 601acea..0000000
--- a/c++/lib/xcalconversions.h
+++ /dev/null
@@ -1,1701 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef XCALCONVERSIONS_H
-#define XCALCONVERSIONS_H
-
-#include "global_definitions.h"
-
-#include <bindings/kolabformat-xcal.hxx>
-#include <bindings/iCalendar-props.hxx>
-#include <compiled/XMLParserWrapper.h>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/numeric/conversion/converter_policies.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/foreach.hpp>
-
-#include <fstream>
-#include <iostream>
-
-#include <boost/lexical_cast.hpp>
-
-#include "kolabcontainers.h"
-#include "kolabtodo.h"
-#include "kolabevent.h"
-#include "kolabjournal.h"
-#include "utils.h"
-#include "base64.h"
-#include "shared_conversions.h"
-
-namespace Kolab {
-    namespace XCAL {
-        
-std::string global_xCalVersion;
-
-const char* const XCAL_VERSION = "2.0";
-const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
-
-const char* const TZ_PREFIX = "/kolab.org/";
-
-const char* const THISANDFUTURE = "THISANDFUTURE";
-
-const char* const BASE64 = "BASE64";
-
-const char* const NEEDSACTION = "NEEDS-ACTION";
-const char* const COMPLETED = "OPAQUE";
-const char* const INPROCESS = "IN-PROCESS";
-const char* const CANCELLED = "CANCELLED";
-const char* const TENTATIVE = "TENTATIVE";
-const char* const CONFIRMED = "CONFIRMED";
-const char* const DRAFT = "DRAFT";
-const char* const FINAL = "FINAL";
-
-const char* const CONFIDENTIAL = "CONFIDENTIAL";
-const char* const PRIVATE = "PRIVATE";
-const char* const PUBLIC = "PUBLIC";
-
-const char* const PARTACCEPTED = "ACCEPTED";
-const char* const PARTDECLINED = "DECLINED";
-const char* const PARTDELEGATED = "DELEGATED";
-const char* const PARTNEEDSACTION = "NEEDS-ACTION";
-const char* const PARTTENTATIVE = "TENTATIVE";
-
-const char* const CHAIR = "CHAIR";
-const char* const NONPARTICIPANT = "NON-PARTICIPANT";
-const char* const OPTIONAL = "OPT-PARTICIPANT";
-const char* const REQUIRED = "REQ-PARTICIPANT";
-
-const char* const DISPLAYALARM = "DISPLAY";
-const char* const EMAILALARM = "EMAIL";
-const char* const AUDIOALARM = "AUDIO";
-
-const char* const TRANSPARENT = "TRANSPARENT";
-const char* const OPAQUE = "OPAQUE";
-
-const char* const MO = "MO";
-const char* const TU = "TU";
-const char* const WE = "WE";
-const char* const TH = "TH";
-const char* const FR = "FR";
-const char* const SA = "SA";
-const char* const SU = "SU";
-
-//Alarms
-const char* const START = "START";
-const char* const END = "END";
-
-using namespace Kolab::Utils;
-using namespace Kolab::Shared;
-
-//=== Generic Conversions ===
-    
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
-    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
-}
-
-std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
-{
-    std::vector<std::string> d;
-    std::copy(s.text().begin(), s.text().end(), std::back_inserter(d));
-    return d;
-}
-
-template <typename T>
-std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
-{
-    std::auto_ptr<T> ptr(new T());
-    std::copy(list.begin(), list.end(), std::back_inserter(ptr->text()));
-    return ptr;
-}
-
-//TODO doesn't seem very useful after all, remove
-std::string toString(const icalendar_2_0::TextPropertyType &s)
-{
-    return s.text();
-}
-
-
-
-
-std::string fromDayPos(const Kolab::DayPos &d)
-{   
-    std::string s;
-    if (d.occurence() != 0) {
-        s.append(boost::lexical_cast<std::string>(d.occurence()));
-    }
-    switch (d.weekday()) {
-        case Kolab::Monday:
-            s.append(MO);
-            break;
-        case Kolab::Tuesday:
-            s.append(TU);
-            break;
-        case Kolab::Wednesday:
-            s.append(WE);
-            break;
-        case Kolab::Thursday:
-            s.append(TH);
-            break;
-        case Kolab::Friday:
-            s.append(FR);
-            break;
-        case Kolab::Saturday:
-            s.append(SA);
-            break;
-        case Kolab::Sunday:
-            s.append(SU);
-            break;
-    }
-    return s;
-}
-
-Kolab::DayPos toDayPos(const std::string &s)
-{
-    std::string number;
-    bool gotOccurrence = false;
-    int occurrence = 0;
-    for (std::string::const_iterator it = s.begin(); it != s.end(); it++) {
-        switch(*it) {
-            case '0':
-            case '1':
-            case '2':
-            case '3':
-            case '4':
-            case '5':
-            case '6':
-            case '7':
-            case '8':
-            case '9':
-            case '+':
-            case '-':
-                number.push_back(*it);
-                break;
-            default:
-                if (!gotOccurrence && !number.empty()) {
-                    try {
-                        occurrence = boost::lexical_cast<int>(number);
-                    } catch(boost::bad_lexical_cast &) {
-                        ERROR("failed to convert: " + number);
-                        return DayPos();
-                    }
-                    number.clear();
-                }
-                gotOccurrence = true;
-                number.push_back(*it);
-                break;
-        }
-    }
-
-    if (number == MO) {
-        return DayPos(occurrence, Kolab::Monday);
-    } else if (number == TU) {
-        return DayPos(occurrence, Kolab::Tuesday);
-    } else if (number == WE) {
-        return DayPos(occurrence, Kolab::Wednesday);
-    } else if (number == TH) {
-        return DayPos(occurrence, Kolab::Thursday);
-    } else if (number == FR) {
-        return DayPos(occurrence, Kolab::Friday);
-    } else if (number == SA) {
-        return DayPos(occurrence, Kolab::Saturday);
-    } else if (number == SU) {
-        return DayPos(occurrence, Kolab::Sunday);
-    }
-    return DayPos();
-}
-
-std::string fromDuration(const Kolab::Duration &d)
-{
-    std::string s;
-    if (!d.isValid()) {
-        return s;
-    }
-    if (d.isNegative()) {
-        s.push_back('-');
-    }
-    s.push_back('P');
-    try {
-        if (d.weeks() > 0) {
-            s.append(boost::lexical_cast<std::string>(d.weeks()));
-            s.push_back('W');
-        }
-        if (d.days() > 0) {
-            s.append(boost::lexical_cast<std::string>(d.days()));
-            s.push_back('D');
-        }
-        if (d.hours() > 0 || d.minutes() > 0 || d.seconds() > 0) {
-            s.push_back('T');
-            if (d.hours() > 0) {
-                s.append(boost::lexical_cast<std::string>(d.hours()));
-                s.push_back('H');
-            }
-            if (d.minutes() > 0) {
-                s.append(boost::lexical_cast<std::string>(d.minutes()));
-                s.push_back('M');
-            }
-            if (d.seconds() > 0) {
-                s.append(boost::lexical_cast<std::string>(d.seconds()));
-                s.push_back('S');
-            }
-        }
-        
-    } catch(boost::bad_lexical_cast &) { 
-        ERROR("failed to convert duration");
-        return std::string();
-    }
-    return s;
-}
-
-Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
-{
-    int weeks = 0;
-    int days = 0;
-    int hours = 0;
-    int minutes = 0;
-    int seconds = 0;
-    bool negative = false;
-
-    std::string number;
-
-    for (std::string::const_iterator it = d.begin(); it != d.end(); it++) {
-        switch(*it) {
-            case '0':
-            case '1':
-            case '2':
-            case '3':
-            case '4':
-            case '5':
-            case '6':
-            case '7':
-            case '8':
-            case '9':
-                number.push_back(*it);
-                break;
-            case 'H':
-                try {
-                    hours = boost::lexical_cast<int>(number);
-                } catch(boost::bad_lexical_cast &) {
-                    ERROR("failed to convert: " +  number);
-                    return Duration();
-                }
-                number.clear();
-                break;
-            case 'M':
-                try {
-                    minutes = boost::lexical_cast<int>(number);
-                } catch(boost::bad_lexical_cast &) {
-                    ERROR("failed to convert: " + number);
-                    return Duration();
-                }
-                number.clear();
-                break;
-            case 'S':
-                try {
-                    seconds = boost::lexical_cast<int>(number);
-                } catch(boost::bad_lexical_cast &) { 
-                    ERROR("failed to convert: " + number);
-                    return Duration();
-                }
-                number.clear();
-                break;
-            case 'T':
-                break;
-            case 'W':
-                try {
-                    weeks = boost::lexical_cast<int>(number);
-                } catch(boost::bad_lexical_cast &) { 
-                    ERROR("failed to convert: " + number);
-                    return Duration();
-                }
-                return Duration(weeks, negative);
-            case 'D':
-                try {
-                    days = boost::lexical_cast<int>(number);
-                } catch(boost::bad_lexical_cast &) { 
-                    ERROR("failed to convert: " + number);
-                    return Duration();
-                }
-                number.clear();
-                break;
-            case '+':
-                break;
-            case '-':
-                negative = true;
-                break;
-            case 'P':
-                break;
-            default:
-                ERROR("failed to convert duration: " + *it);
-                return Duration();
-        }
-    }
-    return Duration(days, hours, minutes, seconds, negative);
-}
-
-template <typename T>
-T fromContactReference(const Kolab::ContactReference &c) {
-    T organizer(toMailto(c.email()));
-    
-    typename T::parameters_type p;
-    if (!c.name().empty()) {
-        icalendar_2_0::CnParamType name(c.name());
-        p.baseParameter().push_back(name);
-    }
-    if (!c.uid().empty()) {
-        icalendar_2_0::DirParamType dir(toURN(c.uid()));
-        p.baseParameter().push_back(dir);
-    }
-    organizer.parameters(p);
-    return organizer;
-}
-
-Kolab::ContactReference toContactReference(const icalendar_2_0::CalAddressPropertyType &cal)
-{
-    const std::string &email = fromMailto(cal.cal_address());;
-    std::string name;
-    std::string uid;
-    if (cal.parameters()) {
-        for (icalendar_2_0::ArrayOfParameters::baseParameter_const_iterator it((*cal.parameters()).baseParameter().begin()); it != (*cal.parameters()).baseParameter().end(); it++) {
-            if (const icalendar_2_0::CnParamType * tz = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
-                name = tz->text();
-                continue;
-            }
-            if (const icalendar_2_0::DirParamType * tz = dynamic_cast<const icalendar_2_0::DirParamType*> (&*it)) {
-                uid = tz->uri();
-                continue;
-            }
-        }
-    }
-    return Kolab::ContactReference(email, name, uid);
-}
-
-
-template <typename T>
-Kolab::Attachment toAttachment(T aProp)
-{
-    Kolab::Attachment a;
-    std::string mimetype;
-    if (aProp.parameters()) {
-        const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
-        for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-            if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
-                mimetype = p->text();
-            }
-            if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
-                if (p->text() != BASE64) {
-                    ERROR("wrong encoding");
-                    return Kolab::Attachment();
-                }
-            }
-            if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
-                a.setLabel(p->text());
-            }
-        }
-    }
-    if (mimetype.empty()) {
-        ERROR("no mimetype");
-    }
-
-    if (aProp.uri()) {
-        a.setUri(*aProp.uri(), mimetype);
-    } else if (aProp.binary()) {
-        a.setData(base64_decode(*aProp.binary()), mimetype);
-    } else {
-        ERROR("not uri and no data available");
-    }
-    return a;
-}
-
-icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
-{
-    icalendar_2_0::AttachPropType attachment;
-    icalendar_2_0::AttachPropType::parameters_type p;
-    p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
-    if (!a.label().empty()) {
-        p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
-    }
-    
-    if (!a.uri().empty()) {
-        attachment.uri(a.uri());
-    } else  if (!a.data().empty()) {
-        attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
-        p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
-    } else {
-        ERROR("no uri and no data");
-    }
-    
-    attachment.parameters(p);
-    return attachment;
-}
-
-//==== cDateTime ====
-
-
-std::string getTimezone(const icalendar_2_0::ArrayOfParameters &parameters) {
-    for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-        if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
-            std::string tzid = tz->text();
-            if (tzid.find(TZ_PREFIX) != std::string::npos) {
-                tzid.erase(0, strlen(TZ_PREFIX));
-            } else {
-                WARNING("/kolab.org/ timezone prefix is missing");
-            }
-            return tzid;
-        }
-    }
-    return std::string();
-}
-
-cDateTimePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
-    cDateTimePtr date;
-    if (dtProperty.date_time()) {
-        date = Shared::toDate(*dtProperty.date_time());
-    } else if (dtProperty.date()) {
-        date = Shared::toDate(*dtProperty.date());
-    }
-
-    if (dtProperty.parameters()) {
-        const std::string &tzid = getTimezone(*dtProperty.parameters());
-        if (tzid.size()) {
-            date->setTimezone(tzid);
-        }
-    }
-    return date;
-}
-
-
-cDateTimePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
-    cDateTimePtr date;
-    if (dtProperty.date_time()) {
-        date = Shared::toDate(*dtProperty.date_time());
-    } else { //The utc-date-time element shouldn't even exist
-        date = cDateTimePtr(new cDateTime());
-        ERROR("This element shouldn't even be existing");
-        //TODO Implement anyways?
-        return date;
-    }
-    date->setUTC(true);
-    return date;
-}
-
-template <typename I>
-std::auto_ptr<I> fromDate(const cDateTime &dt)
-{
-    std::auto_ptr<I> ptr(new I);
-    if (dt.isDateOnly()) {
-        ptr->date(Shared::fromDate(dt));
-    } else {
-        ptr->date_time(Shared::fromDateTime(dt));
-
-        const std::string &timezone = dt.timezone();
-        if (timezone.size() != 0) {
-            std::string tz(TZ_PREFIX);
-            tz.append(timezone);
-            icalendar_2_0::TzidParamType tzidParam(tz);
-            icalendar_2_0::ArrayOfParameters parameters;
-            parameters.baseParameter().push_back(tzidParam);
-            ptr->parameters(parameters);
-        }
-    }
-    return ptr;
-}
-
-
-template <typename I>
-std::vector<cDateTime> toDateTimeList(I datelistProperty)
-{
-    std::vector<cDateTime>  list;
-    
-    std::string tzid;
-    if (datelistProperty.parameters()) {
-        tzid = getTimezone(*datelistProperty.parameters());
-    }
-    if (!datelistProperty.date().empty()) {
-        BOOST_FOREACH(const xml_schema::date &d, datelistProperty.date()) {
-            list.push_back(*Shared::toDate(d));
-        }
-    } else if (!datelistProperty.date_time().empty()) {
-        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
-            cDateTimePtr date = Shared::toDate(d);
-            if (tzid.size()) {
-                date->setTimezone(tzid);
-            }
-            list.push_back(*date);
-        }
-    }
-    return list;
-}
-
-template <typename I>
-std::auto_ptr<I> fromDateTimeList(const std::vector<cDateTime> &dtlist)
-{
-    
-    std::auto_ptr<I> ptr(new I);
-    BOOST_FOREACH(const cDateTime &dt, dtlist) {
-        if (dt.isDateOnly()) {
-            ptr->date().push_back(Shared::fromDate(dt));
-        } else {
-            ptr->date_time().push_back(Shared::fromDateTime(dt));
-        }
-        //TODO handle utc
-        //TODO check for equality of timezones?
-    }
-    
-    if (!dtlist.empty() && !dtlist.at(0).timezone().empty()) {
-        const std::string &timezone = dtlist.at(0).timezone();
-        if (timezone.size() != 0) {
-            std::string tz(TZ_PREFIX);
-            tz.append(timezone);
-            icalendar_2_0::TzidParamType tzidParam(tz);
-            icalendar_2_0::ArrayOfParameters parameters;
-            parameters.baseParameter().push_back(tzidParam);
-            ptr->parameters(parameters);
-        }
-    }
-    
-    return ptr;
-}
-
-
-//---- cDateTime ----
-
-
-
-//=== Attendee ===
-
-std::string mapPartStat(PartStatus status)
-{
-    switch (status) {
-        case PartAccepted:
-            return PARTACCEPTED;
-        case PartDeclined:
-            return PARTDECLINED;
-        case PartDelegated:
-            return PARTDELEGATED;
-        case PartNeedsAction:
-            return PARTNEEDSACTION;
-        case PartTentative:
-            return PARTTENTATIVE;
-    }
-    ERROR("PartStat not handled: " + status);
-    return std::string();
-}
-
-PartStatus mapPartStat(const std::string &status)
-{
-    if (status == PARTACCEPTED) {
-        return PartAccepted;
-    } else if (status == PARTDECLINED) {
-        return PartDeclined;
-    } else if (status == PARTDELEGATED) {
-        return PartDelegated;
-    } else if (status == PARTNEEDSACTION) {
-        return PartNeedsAction;
-    } else if (status == PARTTENTATIVE) {
-        return PartTentative;
-    }
-    ERROR("PartStat not handled: " + status);
-    return PartNeedsAction;
-}
-
-std::string mapRole(Role status)
-{
-    switch (status) {
-        case Chair:
-            return std::string(CHAIR);
-        case NonParticipant:
-            return NONPARTICIPANT;
-        case Optional:
-            return OPTIONAL;
-        case Required:
-            return REQUIRED;
-    }
-    ERROR("PartStat not handled: " + status);
-    return std::string();
-}
-
-Role mapRole(const std::string &status)
-{
-    if (status == CHAIR) {
-        return Chair;
-    } else if (status == NONPARTICIPANT) {
-        return NonParticipant;
-    } else if (status == OPTIONAL) {
-        return Optional;
-    } else if (status == REQUIRED) {
-        return Required;
-    }
-    ERROR("Unhandled Role " + status);
-    return Required;
-}
-
-
-
-
-
-//----------------
-
-//=== Recurrence Rule ===
-
-    typedef std::auto_ptr<RecurrenceRule> RecurrencePtr;
-
-
-    RecurrenceRule::Frequency mapRecurrenceFrequency(const icalendar_2_0::RecurType::freq_type &freq)
-    {
-        using namespace icalendar_2_0;
-        
-        switch (freq) {
-            case FreqRecurType::YEARLY:
-                return RecurrenceRule::Yearly;
-            case FreqRecurType::MONTHLY:
-                return RecurrenceRule::Monthly;
-            case FreqRecurType::WEEKLY:
-                return RecurrenceRule::Weekly;
-            case FreqRecurType::DAILY:
-                return RecurrenceRule::Daily;
-            case FreqRecurType::HOURLY:
-                return RecurrenceRule::Hourly;
-            case FreqRecurType::MINUTELY:
-                return RecurrenceRule::Minutely;
-            case FreqRecurType::SECONDLY:
-                return RecurrenceRule::Secondly;
-            default:
-                ERROR("invalid unhandled recurrenc type" + freq);
-        }
-        return RecurrenceRule::FreqNone;
-    }
-    
-    icalendar_2_0::RecurType::freq_type mapRecurrenceFrequency(RecurrenceRule::Frequency freq)
-    {
-        using namespace icalendar_2_0;
-
-        switch (freq) {
-            case RecurrenceRule::Yearly:
-                return FreqRecurType::YEARLY;
-            case RecurrenceRule::Monthly:
-                return FreqRecurType::MONTHLY;
-            case RecurrenceRule::Weekly:
-                return FreqRecurType::WEEKLY;
-            case RecurrenceRule::Daily:
-                return FreqRecurType::DAILY;
-            case RecurrenceRule::Hourly:
-                return FreqRecurType::HOURLY;
-            case RecurrenceRule::Minutely:
-                return FreqRecurType::MINUTELY;
-            case RecurrenceRule::Secondly:
-                return FreqRecurType::SECONDLY;
-            default:
-                ERROR("invalid unhandled recurrenc type");
-        }
-        return 0;
-    }
-    
-    static void setWeekStart(RecurrencePtr &r, const icalendar_2_0::RecurType::wkst_type &wkst)
-    {
-        using namespace icalendar_2_0;
-
-        switch (wkst) {
-            case WeekdayRecurType::MO:
-                r->setWeekStart(Kolab::Monday);
-                break;
-            case WeekdayRecurType::TU:
-                r->setWeekStart(Kolab::Tuesday);
-                break;
-            case WeekdayRecurType::WE:
-                r->setWeekStart(Kolab::Wednesday);
-                break;
-            case WeekdayRecurType::TH:
-                r->setWeekStart(Kolab::Thursday);
-                break;
-            case WeekdayRecurType::FR:
-                r->setWeekStart(Kolab::Friday);
-                break;
-            case WeekdayRecurType::SA:
-                r->setWeekStart(Kolab::Saturday);
-                break;
-            case WeekdayRecurType::SU:
-                r->setWeekStart(Kolab::Sunday);
-                break;
-            default:
-                ERROR("invalid unhandled weekday" + wkst);
-        }
-    }
-
-    
-    static void setByday(RecurrencePtr &r, const icalendar_2_0::RecurType::byday_sequence &list)
-    {
-        std::vector<DayPos> by;
-        for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(toDayPos(*it));
-        }
-        r->setByday(by);
-    }
-
-    template <typename T, typename I>
-    std::vector<int> bylist(const xsd::cxx::tree::sequence <T> &list)
-    { 
-        std::vector<int> by;
-        BOOST_FOREACH(const T i, list) {
-            by.push_back(convertToInt<I>(i));
-        }
-        return by;
-    }
-    
-RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-{
-    using namespace icalendar_2_0;
-
-    RecurrencePtr r(new RecurrenceRule());
-    r->setFrequency(mapRecurrenceFrequency(rrule.freq()));
-    if (rrule.until()) {
-        cDateTimePtr date;
-        if ((*rrule.until()).date_time()) {
-            date = Shared::toDate(*(*rrule.until()).date_time());
-        } else if ((*rrule.until()).date()) {
-            date = Shared::toDate(*(*rrule.until()).date());
-        }
-        r->setEnd(*date);
-    } else if (rrule.count()) {
-        r->setCount(toInt(*rrule.count()));
-    }
-    if (rrule.interval()) {
-        r->setInterval(toInt(*rrule.interval()));
-    } else {
-        r->setInterval(1);
-    }
-    r->setBysecond(bylist<RecurType::bysecond_type, xml_schema::non_negative_integer>(rrule.bysecond()));
-    r->setByminute(bylist<RecurType::byminute_type, xml_schema::non_negative_integer>(rrule.byminute()));
-    r->setByhour(bylist<RecurType::byhour_type, xml_schema::non_negative_integer>(rrule.byhour()));
-    setByday(r, rrule.byday());
-    r->setBymonthday(bylist<RecurType::bymonthday_type, xml_schema::integer>(rrule.bymonthday()));
-    r->setByyearday(bylist<RecurType::byyearday_type, xml_schema::integer>(rrule.byyearday()));
-    r->setByweekno(bylist<RecurType::byweekno_type, xml_schema::integer>(rrule.byweekno()));
-    r->setBymonth(bylist<RecurType::bymonth_type, xml_schema::integer>(rrule.bymonth()));
-    if (rrule.wkst()) {
-        setWeekStart(r, *rrule.wkst());
-    }
-    return r;
-}
-    
-//--- Recurrence Rule ---
-
-template <typename I, typename T>
-void setIncidenceProperties(I &inc, const T &prop)
-{    
-    inc.setUid(toString(prop.uid()));
-    inc.setCreated(*toDate(prop.created()));
-    inc.setLastModified(*toDate(prop.dtstamp()));
-
-    if (prop.sequence()) {
-        inc.setSequence(toInt(*prop.sequence()));
-    }
-    
-    if (prop.class_()) {
-        std::string string(toString(*prop.class_()));
-        Kolab::Classification sec = ClassPublic;
-        if (string == PRIVATE) {
-            sec = ClassPrivate;
-        } else if (string == CONFIDENTIAL) {
-            sec = ClassConfidential;
-        }
-        inc.setClassification(sec);
-    }
-    
-    if (prop.categories()) {
-        inc.setCategories(toStringList(*prop.categories()));
-    }
-    
-    if (prop.dtstart()) {
-        const cDateTimePtr date = toDate(*prop.dtstart());
-        inc.setStart(*date);
-    }
-
-    if (prop.summary()) {
-        inc.setSummary(toString(*prop.summary()));
-    }
-
-    if (prop.description()) {
-        inc.setDescription(toString(*prop.description()));
-    }
-
-    if (prop.status()) {
-        const std::string &status =  toString(*prop.status());
-        if (status == NEEDSACTION) {
-            inc.setStatus(StatusNeedsAction);
-        } else if (status == COMPLETED) {
-            inc.setStatus(StatusCompleted);
-        } else if (status == INPROCESS) {
-            inc.setStatus(StatusInProcess);
-        } else if (status == CANCELLED) {
-            inc.setStatus(StatusCancelled);
-        } else if (status == TENTATIVE) {
-            inc.setStatus(StatusTentative);
-        } else if (status == CONFIRMED) {
-            inc.setStatus(StatusConfirmed);
-        } else if (status == DRAFT) {
-            inc.setStatus(StatusDraft);
-        } else if (status == FINAL) {
-            inc.setStatus(StatusFinal);
-        } else {
-            ERROR("Unhandled status");
-        }
-    }
-    
-    if (prop.attendee().size()) {
-        std::vector<Kolab::Attendee> attendees;
-        BOOST_FOREACH(typename T::attendee_type aProp, prop.attendee()) {
-            Kolab::Attendee a;
-            std::string name;
-            if (aProp.parameters()) {
-                const icalendar_2_0::AttendeePropType::parameters_type &parameters = *aProp.parameters();
-                for (icalendar_2_0::AttendeePropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-                    if (const icalendar_2_0::CnParamType * p = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
-                        name = p->text();
-                    }
-                    if (const icalendar_2_0::PartstatParamType * p = dynamic_cast<const icalendar_2_0::PartstatParamType*> (&*it)) {
-                        PartStatus s = mapPartStat(p->text());
-                        if (s != PartNeedsAction) {
-                            a.setPartStat(s);
-                        }
-                    }
-                    if (const icalendar_2_0::RoleParamType * p = dynamic_cast<const icalendar_2_0::RoleParamType*> (&*it)) {
-                        Role s = mapRole(p->text());
-                        if (s != Required) {
-                            a.setRole(s);
-                        }
-                    }
-                    if (const icalendar_2_0::RsvpParamType * p = dynamic_cast<const icalendar_2_0::RsvpParamType*> (&*it)) {
-                        a.setRSVP(p->boolean());
-                    }
-                }
-            }
-            Kolab::ContactReference ref = toContactReference(aProp);
-            a.setContact(ref);
-            attendees.push_back(a);
-        }
-        inc.setAttendees(attendees);
-    }
-    
-    if (prop.attach().size()) {
-        std::vector<Kolab::Attachment> attachments;
-        BOOST_FOREACH(typename T::attach_type aProp, prop.attach()) {
-            const Kolab::Attachment &a = toAttachment<typename T::attach_type>(aProp);
-            if (!a.isValid()) {
-                ERROR("invalid attachment");
-                continue;
-            }
-            attachments.push_back(a);
-        }
-        inc.setAttachments(attachments);
-    }
-    
-    if (prop.x_custom().size()) {
-        std::vector<Kolab::CustomProperty> customProperties;
-        BOOST_FOREACH(typename T::x_custom_type p, prop.x_custom()) {
-            customProperties.push_back(CustomProperty(p.identifier(), p.value()));
-        }
-        inc.setCustomProperties(customProperties);
-    }
-
-}
-
-template <typename I, typename T>
-void setTodoEventProperties(I &inc, const T &prop)
-{
-
-    if (prop.rrule()) {
-       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
-       inc.setRecurrenceRule(*rrule);
-    }
-
-    if (prop.rdate()) {
-        inc.setRecurrenceDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
-        if (!prop.rdate()->period().empty()) {
-            ERROR("the period element must not be used, ignored.");
-        }
-    }
-
-    if (prop.exdate()) {
-       inc.setExceptionDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
-    }
-    
-    if (prop.recurrence_id()) {
-        bool thisandfuture = false;
-        if (prop.recurrence_id()->parameters()) {
-            const icalendar_2_0::RecurrenceIdPropType::parameters_type &parameters = *prop.recurrence_id()->parameters();
-            for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-                if (dynamic_cast<const icalendar_2_0::RangeParamType*> (&*it)) {
-                    thisandfuture = true;
-                }
-            }
-        }
-        inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture);
-    }
-
-    if (prop.priority()) {
-        inc.setPriority(toInt(*prop.priority()));
-    }
-
-    if (prop.location()) {
-        inc.setLocation(toString(*prop.location()));
-    }
-    
-    if (prop.organizer()) {
-        inc.setOrganizer(toContactReference(*prop.organizer()));
-    }
-    
-}
-
-
-template <typename T, typename I>
-T fromList(const std::vector<int> &input) {
-    T list;
-    BOOST_FOREACH(int i, input) {
-        list.push_back(convertToInt<I>(i));
-    }
-    return list;
-}
-
-std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r)
-{
-    using namespace icalendar_2_0;
-        
-    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(mapRecurrenceFrequency(r.frequency())));
-    
-    RecurPropertyType::recur_type &recur = rruleProp->recur();
-    const cDateTime &endDate = r.end();
-    if (endDate.isValid()) {
-        RecurPropertyType::recur_type::until_type until;
-        if (endDate.isDateOnly()) {
-            until.date(Shared::fromDate(endDate));
-        } else {
-            until.date_time(Shared::fromDateTime(endDate));
-        }
-        recur.until(until);
-    } else if (r.count() > 0) {
-        recur.count(fromInt<RecurType::count_type>(r.count()));
-    }
-    
-    if (r.interval() > 1) {
-        recur.interval(fromInt<RecurType::interval_type>(r.interval()));
-    }
-    
-    if (!r.bysecond().empty()) {
-        recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
-    }
-    
-    if (!r.byminute().empty()) {
-        recur.byminute(fromList<RecurType::byminute_sequence, xml_schema::non_negative_integer>(r.byminute()));
-    }
-    
-    if (!r.byhour().empty()) {
-        recur.byhour(fromList<RecurType::byhour_sequence, xml_schema::non_negative_integer>(r.byhour()));
-    }
-    
-    if (!r.byday().empty()) {
-        RecurType::byday_sequence byday;
-        BOOST_FOREACH(const Kolab::DayPos &daypos, r.byday()) {
-            byday.push_back(fromDayPos(daypos));
-        }
-        recur.byday(byday);
-    }
-    
-    if (!r.bymonthday().empty()) {
-        recur.bymonthday(fromList<RecurType::bymonthday_sequence, xml_schema::integer>(r.bymonthday()));
-    }
-    
-    if (!r.byyearday().empty()) {
-        recur.byyearday(fromList<RecurType::byyearday_sequence, xml_schema::integer>(r.byyearday()));
-    }
-    
-    if (!r.byweekno().empty()) {
-        recur.byweekno(fromList<RecurType::byweekno_sequence, xml_schema::integer>(r.byweekno()));
-    }
-    
-    if (!r.bymonth().empty()) {
-        recur.bymonth(fromList<RecurType::bymonth_sequence, xml_schema::integer>(r.bymonth()));
-    }
-
-    return rruleProp;
-}
-
-
-
-
-template <typename T, typename I>
-void getIncidenceProperties(T &prop, const I &inc)
-{
-    using namespace icalendar_2_0;
-    
-    typedef T properties; 
-    
-    prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
-    
-    switch (inc.classification()) {
-        case Kolab::ClassConfidential:
-            prop.class_(typename properties::class_type(CONFIDENTIAL));
-            break;
-        case Kolab::ClassPrivate:
-            prop.class_(typename properties::class_type(PRIVATE));
-            break;
-        default:
-            prop.class_(typename properties::class_type(PUBLIC));
-            break;
-    }
-    
-    if (!inc.categories().empty()) {
-        prop.categories(*fromStringList<typename properties::categories_type>(inc.categories()));
-    }
-
-    if (inc.start().isValid()) {
-        prop.dtstart(fromDate<typename properties::dtstart_type>(inc.start()));
-    }
-
-    if (!inc.summary().empty()) {
-        prop.summary(typename properties::summary_type(inc.summary()));
-    }
-    
-    if (!inc.description().empty()) {
-        prop.description(typename properties::description_type(inc.description()));
-    }
-
-    if (inc.status() != StatusUndefined) {
-        switch (inc.status()) {
-            case StatusNeedsAction:
-                prop.status(typename properties::status_type(NEEDSACTION));
-                break;
-            case StatusCompleted:
-                prop.status(typename properties::status_type(COMPLETED));
-                break;
-            case StatusInProcess:
-                prop.status(typename properties::status_type(INPROCESS));
-                break;
-            case StatusCancelled:
-                prop.status(typename properties::status_type(CANCELLED));
-                break;
-            case StatusTentative:
-                prop.status(typename properties::status_type(TENTATIVE));
-                break;
-            case StatusConfirmed:
-                prop.status(typename properties::status_type(CONFIRMED));
-                break;
-            case StatusDraft:
-                prop.status(typename properties::status_type(DRAFT));
-                break;
-            case StatusFinal:
-                prop.status(typename properties::status_type(FINAL));
-                break;
-            default:
-                ERROR("unhandled status " + inc.status());
-        }
-
-    }
-
-    if (!inc.attendees().empty()) {        
-        
-        BOOST_FOREACH(const Kolab::Attendee &a, inc.attendees()) {
-            const Kolab::ContactReference &c = a.contact();
-            
-            typename properties::attendee_type attendee = fromContactReference<typename properties::attendee_type>(c);
-            
-            typename properties::attendee_type::parameters_type &p = *attendee.parameters();
-            
-            std::string stat = mapPartStat(a.partStat());
-            if (!stat.empty()) {
-                p.baseParameter().push_back(icalendar_2_0::PartstatParamType(stat));
-            }
-            
-            std::string r = mapRole(a.role());
-            if (!r.empty()) {
-                p.baseParameter().push_back(icalendar_2_0::RoleParamType(r));
-            }
-            
-            if (a.rsvp()) {
-                p.baseParameter().push_back(icalendar_2_0::RsvpParamType(true));
-            }
-
-            prop.attendee().push_back(attendee);
-
-        }
-    }
-    
-    if (!inc.attachments().empty()) {
-        BOOST_FOREACH(const Kolab::Attachment &a, inc.attachments()) {
-            prop.attach().push_back(fromAttachment(a));
-        }
-    }
-    
-    if (!inc.customProperties().empty()) {
-        BOOST_FOREACH(const Kolab::CustomProperty &a, inc.customProperties()) {
-            prop.x_custom().push_back(typename properties::x_custom_type(a.identifier, a.value));
-        }
-    }
-
-}
-
-template <typename T, typename I>
-void getTodoEventProperties(T &prop, const I &inc)
-{
-    using namespace icalendar_2_0;
-    typedef T properties; 
-    
-    if (inc.recurrenceRule().isValid()) {
-        const RecurrenceRule &r = inc.recurrenceRule();
-        prop.rrule(recurrenceProperty(r));
-        //TODO check if startdate is allDay if recurrence is allDay
-        //TODO check if startdate matches the one of the event (it MUST)
-    }
-    
-    if (!inc.recurrenceDates().empty()) {
-        prop.rdate(fromDateTimeList<typename properties::rdate_type>(inc.recurrenceDates()));
-    }
-    
-    if (!inc.exceptionDates().empty()) {
-        prop.exdate(fromDateTimeList<typename properties::exdate_type>(inc.exceptionDates()));
-    }
-    
-    if (inc.recurrenceID().isValid()) {
-        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<typename properties::recurrence_id_type>(inc.recurrenceID());
-        if (inc.thisAndFuture()) {
-            if (!recurrenceId->parameters()) {
-                recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
-            }
-            typename properties::recurrence_id_type::parameters_type &parameters = *recurrenceId->parameters(); //There is maybe already a timezone set
-            icalendar_2_0::RangeParamType range(THISANDFUTURE);
-            parameters.baseParameter().push_back(range);
-        }
-        
-        prop.recurrence_id(recurrenceId);
-    }
-    
-    if (inc.priority() != 0) {
-        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
-    }
-    
-    if (!inc.location().empty()) {
-        prop.location(typename properties::location_type(inc.location()));
-    }
-    
-    if (inc.organizer().isValid()) {
-        prop.organizer(fromContactReference<typename properties::organizer_type>(inc.organizer()));
-    }
-}
-
-//=== Alarms ===
-
-template <typename KolabType, typename IncidenceType>
-void setAlarms(typename KolabType::components_type& components, const IncidenceType &incidence)
-{
-    BOOST_FOREACH(const Kolab::Alarm &alarm, incidence.alarms()) {
-        typedef icalendar_2_0::ValarmType::properties_type PropType;
-        
-        PropType::trigger_type trigger;
-        if (alarm.start().isValid()) {
-            
-            trigger.date_time(fromDateTime(alarm.start()));
-        } else {
-            if (!alarm.relativeStart().isValid()) {
-                ERROR("no start and no relativeStart");
-                continue;
-            }
-            trigger.duration(PropType::trigger_type::duration_type(fromDuration(alarm.relativeStart())));
-            icalendar_2_0::ArrayOfParameters parameters;
-            if (alarm.relativeTo() == Kolab::End) {
-                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(END));
-            } else {
-                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(START));
-            }
-            trigger.parameters(parameters);
-        }
-
-        std::auto_ptr<PropType> p;
-        switch(alarm.type()) {
-            case Kolab::Alarm::DisplayAlarm:
-                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(DISPLAYALARM), trigger));
-                p->description(PropType::description_type(alarm.description()));
-                break;
-            case Kolab::Alarm::EMailAlarm:
-                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(EMAILALARM), trigger));
-                p->summary(PropType::summary_type(alarm.summary()));
-                p->description(PropType::description_type(alarm.description()));
-                BOOST_FOREACH(const Kolab::ContactReference &attendee, alarm.attendees()) {
-                    p->attendee().push_back(icalendar_2_0::ContactType(toMailto(attendee.email(), attendee.name())));
-                }
-                break;
-            case Kolab::Alarm::AudioAlarm:
-                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(AUDIOALARM), trigger));
-                p->description(PropType::description_type(alarm.description()));
-                p->attach(fromAttachment(alarm.audioFile()));
-                break;
-            default:
-                ERROR("invalid alarm");
-                continue;
-        }
-        if (alarm.duration().isValid()) {
-            p->duration(PropType::duration_type(fromDuration(alarm.duration())));
-            p->repeat(PropType::repeat_type(fromInt<PropType::repeat_type::integer_type>(alarm.numrepeat())));
-        }
-
-        components.valarm().push_back(icalendar_2_0::ValarmType(p));
-    }
-}
-
-
-
-template <typename IncidenceType, typename KolabType>
-void getAlarms(IncidenceType &incidence, const typename KolabType::components_type &components)
-{
-    typedef icalendar_2_0::ValarmType::properties_type PropType;
-    std::vector<Kolab::Alarm> alarms;
-    BOOST_FOREACH(const typename KolabType::components_type::valarm_type &valarm, components.valarm()) {
-        const icalendar_2_0::ValarmType::properties_type &prop = valarm.properties();
-
-        Kolab::Alarm alarm;
-        if (prop.action().text() == DISPLAYALARM) {
-            if (!prop.description()) {
-                ERROR("description is missing");
-                continue;
-            }
-            alarm = Kolab::Alarm((*prop.description()).text());
-        } else if (prop.action().text() == EMAILALARM) {
-            std::vector<Kolab::ContactReference> attendees;
-            if (prop.attendee().empty()) {
-                WARNING("No receipents for email alarm");
-            }
-            for (typename PropType::attendee_const_iterator at(prop.attendee().begin()); at != prop.attendee().end(); at++) {
-                std::string name;
-                const std::string &email = fromMailto((*at).cal_address(), name);
-                attendees.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name));
-            }
-            if (!prop.description() || !prop.summary()) {
-                ERROR("description or summary is missing");
-                continue;
-            }
-            alarm = Kolab::Alarm((*prop.summary()).text(), (*prop.description()).text(), attendees);
-        } else if (prop.action().text() == AUDIOALARM) {
-            if (!prop.attach()) {
-                ERROR("audio file is missing");
-                continue;
-            }
-            const Kolab::Attachment &attach = toAttachment<icalendar_2_0::properties::attach_type>(*prop.attach());
-            if (!attach.isValid()) {
-                ERROR("audio file is invalid");
-                continue;
-            }
-            alarm = Kolab::Alarm(attach);
-        } else {
-            ERROR("unknown alarm type " + prop.action().text());
-            continue;
-        }
-        
-        if (prop.trigger().date_time()) {
-            alarm.setStart(*Shared::toDate(*prop.trigger().date_time()));
-            if (!alarm.start().isUTC()) {
-                ERROR("The start date time must be in UTC ");
-                continue;
-            }
-        } else if (prop.trigger().duration()) {
-            Kolab::Relative relativeTo = Kolab::Start;
-            if (prop.trigger().parameters()) {
-                BOOST_FOREACH(const icalendar_2_0::ArrayOfParameters::baseParameter_type &param, (*prop.trigger().parameters()).baseParameter()) {
-                    if (const icalendar_2_0::RelatedParamType *rel = dynamic_cast<const icalendar_2_0::RelatedParamType*> (&param)) {
-                        if (rel->text() == START) {
-                            relativeTo = Kolab::Start;
-                        } else if (rel->text() == END) {
-                            relativeTo = Kolab::End;
-                        } else {
-                            LOG("relativeTo not specified, default to start ");
-                        }
-                    }
-                }
-            }
-            
-            alarm.setRelativeStart(toDuration(*prop.trigger().duration()), relativeTo);
-        } else {
-            ERROR("no duration and not starttime ");
-            continue;
-        }
-        if (prop.duration()) {
-            int repeat = 0;
-            if (prop.repeat()) {
-                repeat = toInt(*prop.repeat());
-            }
-            alarm.setDuration(toDuration((*prop.duration()).duration()), repeat); //TODO check duration?
-        }
-        alarms.push_back(alarm);
-    }
-    incidence.setAlarms(alarms);
-}
-
-//--- Alarms ---
-
-class Incidence; //Just for Trait
-
-///Trait for Incidence object
-template <typename T, typename I> 
-struct IncidenceConverter;
-
-template <typename T> struct IncidenceConverter < Incidence, T >
-{
-    static std::string uid(const T &inc) {
-        if (inc.uid().empty()) { //generate new UID
-            return getUID();
-        }
-        return inc.uid();
-    }
-    
-    static xml_schema::date_time dtstamp() {
-        return fromDateTime(getCurrentTime());
-    }
-    
-    static xml_schema::date_time created(const T &inc) {
-        if (inc.created().isValid()) {
-            return fromDateTime(inc.created());
-        }
-        return fromDateTime(getCurrentTime());
-    }
-
-};
-
-
-///Trait for incidence properties specialized for Event/Todo/Journal
-template <typename T> struct IncidenceTrait;
-
-template < > struct IncidenceTrait <Kolab::Event>
-{
-    typedef icalendar_2_0::KolabEvent KolabType;
-    typedef Kolab::Event IncidenceType;
-    typedef boost::shared_ptr<Kolab::Event> IncidencePtr;
-
-    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
-    {
-        KolabType::components_type eventComponents;
-        setAlarms<icalendar_2_0::KolabEvent, IncidenceType>(eventComponents, event);
-        if (!eventComponents.valarm().empty()) {
-            vevent.components(eventComponents);
-        }
-        
-        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
-        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
-        getTodoEventProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
-
-        if (!event.start().isValid()) {
-            ERROR("Start date is missing, but is mandatory for events");
-        }
-
-        if (event.end().isValid()) {
-            prop.dtend(fromDate<icalendar_2_0::KolabEvent::properties_type::dtend_type>(event.end()));
-        } else if (event.duration().isValid()) {
-            prop.duration(icalendar_2_0::KolabEvent::properties_type::duration_type(fromDuration(event.duration())));
-        }
-        
-        if (event.transparency()) {
-            prop.transp( icalendar_2_0::KolabEvent::properties_type::transp_type(TRANSPARENT));
-        }
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabEvent inc) //TODO to base trait
-    {
-        components.vevent().push_back(inc);
-    }
-
-    static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
-    {
-        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
-        if (!prop.dtstart()) {
-            ERROR("Start date is missing, but is mandatory for events");
-        }
-
-        setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
-        setTodoEventProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
-
-        if (prop.dtend()) {
-            event.setEnd(*toDate(*prop.dtend()));
-            if (event.end().isUTC() != event.end().isUTC() && 
-                event.end().timezone() != event.end().timezone() &&
-                event.end().isDateOnly() != event.end().isDateOnly()) {
-                ERROR("dtEnd has wrong timespec");
-            }
-        } else if (prop.duration()) {
-            event.setDuration(toDuration((*prop.duration()).duration()));
-        }
-
-        if (prop.transp()) {
-            if (toString(*prop.transp()) == TRANSPARENT) {
-                event.setTransparency(true);
-            } else {
-                event.setTransparency(false);
-                if (toString(*prop.transp()) != OPAQUE) {
-                    ERROR("wrong transparency value " + toString(*prop.transp()));
-                }
-            }
-        }
-        if (vevent.components()) {
-            getAlarms<Kolab::Event, icalendar_2_0::KolabEvent>(event, *vevent.components());
-        }
-    }
-
-    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vevent().begin();
-    }
-    
-    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vevent().end();
-    }
-    
-};
-
-template < > struct IncidenceTrait <Kolab::Todo>
-{
-    typedef icalendar_2_0::KolabTodo KolabType;
-    typedef Kolab::Todo IncidenceType;
-    typedef boost::shared_ptr<Kolab::Todo> IncidencePtr;
-
-    static void writeIncidence(icalendar_2_0::KolabTodo& vevent, const Kolab::Todo &todo)
-    {
-        KolabType::components_type eventComponents;
-        setAlarms<icalendar_2_0::KolabTodo, IncidenceType>(eventComponents, todo);
-        if (!eventComponents.valarm().empty()) {
-            vevent.components(eventComponents);
-        }
-
-        icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
-
-        getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
-        getTodoEventProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
-
-        if (!todo.relatedTo().empty()) {
-            icalendar_2_0::KolabTodo::properties_type::related_to_sequence list;
-            BOOST_FOREACH(std::string relatedTo, todo.relatedTo()) {
-                list.push_back(icalendar_2_0::KolabTodo::properties_type::related_to_type(relatedTo));
-            }
-            prop.related_to(list);
-        }
-        if (todo.due().isValid()) {
-            prop.due(fromDate<icalendar_2_0::KolabTodo::properties_type::due_type>(todo.due()));
-        }
-        if (todo.percentComplete() > 0) {
-            prop.percent_complete(icalendar_2_0::KolabTodo::properties_type::percent_complete_type(fromInt<icalendar_2_0::IntegerPropertyType::integer_type>(todo.percentComplete())));
-        }
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabTodo inc) //TODO to base trait
-    {
-        components.vtodo().push_back(inc);
-    }
-
-    static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
-    {
-        const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
-
-        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
-        setTodoEventProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
-
-        if (!prop.related_to().empty()) {
-            BOOST_FOREACH(icalendar_2_0::KolabTodo::properties_type::related_to_type p, prop.related_to()) {
-                todo.addRelatedTo(p.text());
-            }
-        }
-        if (prop.due()) {
-            todo.setDue(*toDate(*prop.due()));
-        }
-        if (prop.percent_complete()) {
-            todo.setPercentComplete(toInt(*prop.percent_complete()));
-        }
-        if (vevent.components()) {
-            getAlarms<Kolab::Todo, icalendar_2_0::KolabTodo>(todo, *vevent.components());
-        }
-    }
-
-    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vtodo().begin();
-    }
-    
-    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vtodo().end();
-    }
-    
-};
-
-template < > struct IncidenceTrait <Kolab::Journal>
-{
-    typedef icalendar_2_0::KolabJournal KolabType;
-    typedef Kolab::Journal IncidenceType;
-    typedef boost::shared_ptr<Kolab::Journal> IncidencePtr;
-
-    static void writeIncidence(icalendar_2_0::KolabJournal& vjournal, const Kolab::Journal &journal)
-    {
-        icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
-        getIncidenceProperties<icalendar_2_0::KolabJournal::properties_type>(prop, journal);
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabJournal inc)
-    {
-        components.vjournal().push_back(inc);
-    }
-
-    static void readIncidence(Kolab::Journal &journal, const icalendar_2_0::KolabJournal& vjournal)
-    {
-        const icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
-        setIncidenceProperties<Kolab::Journal, icalendar_2_0::KolabJournal::properties_type>(journal, prop);
-    }
-
-    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vjournal().begin();
-    }
-    
-    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
-    {
-        return components.vjournal().end();
-    }
-    
-};
-
-
-//////////////////////////////////=========================================
-
-
-template <typename T>
-std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
-    
-    using namespace icalendar_2_0;
-    typedef IncidenceConverter< Incidence, typename T::IncidenceType > IC;
-    typedef typename T::KolabType KolabType;
-    
-    clearErrors();
-
-    try {
-
-        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
-        setCreatedUid(uid.text());
-        typename KolabType::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(IC::dtstamp());
-        typename KolabType::properties_type::created_type created;
-        created.date_time(IC::created(incidence));
-        typename KolabType::properties_type eventProps(uid, created, dtstamp);
-        
-        KolabType inc(eventProps);
-        
-        T::writeIncidence(inc, incidence);
-
-        VcalendarType::components_type components;
-        T::addIncidence(components, inc);
-        
-        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME+KOLAB_LIB_VERSION); //FIXME own version field for lib version
-        VcalendarType::properties_type::version_type version(XCAL_VERSION);
-        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION);
-        
-        VcalendarType::properties_type properties(prodid, version, x_kolab_version);
-        
-        VcalendarType vcalendar(properties, components);
-        
-        IcalendarType icalendar(vcalendar);
-
-        xml_schema::namespace_infomap map;
-        map[""].name = XCAL_NAMESPACE;
-        
-        std::ostringstream ostringstream;
-        icalendar_2_0::icalendar(ostringstream, icalendar, map);
-        return ostringstream.str();
-    } catch  (const xml_schema::exception& e) {
-        CRITICAL("failed to write Incidence");
-    } catch (...) {
-        CRITICAL("Unhandled exception");
-    }
-    return std::string();
-}
-
-
-template <typename T>
-typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
-{
-    using namespace icalendar_2_0;
-    typedef typename T::IncidencePtr IncidencePtr;
-    typedef typename T::IncidenceType IncidenceType;
-    typedef typename T::KolabType KolabType;
-    
-    clearErrors();
-    try {
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
-        if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-        } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-        }
-        
-        if (!icalendar.get()) {
-            CRITICAL("Failed to parse calendar!");
-            return IncidencePtr();
-        }
-
-        const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
-
-        std::vector < IncidencePtr > incidences;
-        for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
-            IncidencePtr e = IncidencePtr(new IncidenceType);
-            const KolabType &event = *it;
-            T::readIncidence(*e, event);
-            incidences.push_back(e);
-        }
-        
-        setProductId( vcalendar.properties().prodid().text() );
-        global_xCalVersion = vcalendar.properties().version().text();
-        setKolabVersion( vcalendar.properties().x_kolab_version().text() );
-
-
-        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
-//         foreach (KCalCore::Event * event, events) {
-//             if (!event->hasRecurrenceId()) {
-//                 return event;
-//             }
-//         }
-        if (incidences.size() != 1) {
-            WARNING("wrong number of incidences: "+ incidences.size());
-        }
-        return *incidences.begin();
-    } catch  (const xml_schema::exception& e) {
-        std::cout <<  e << std::endl;
-        CRITICAL("Failed to read incidence!");
-    } catch (...) {
-        CRITICAL("Unhandled exception");
-    }
-    return IncidencePtr();
-}
-
-    }
-}//Namespace
-
-#endif
-
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
deleted file mode 100644
index 0be6f0a..0000000
--- a/c++/lib/xcardconversions.h
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABXCARDCONVERSION_H
-#define KOLABXCARDCONVERSION_H
-
-#include <bindings/kolabformat-xcard.hxx>
-#include "kolabcontainers.h"
-#include <XMLParserWrapper.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
-#include <iomanip>
-#include "global_definitions.h"
-#include "utils.h"
-#include "kolabcontact.h"
-#include "shared_conversions.h"
-
-namespace Kolab {
-    namespace XCARD {
-        
-    const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
-    const char* const INDIVIDUAL = "individual";
-    const char* const GROUP = "group";
-    const char* const MIME_PGP_KEYS = "application/pgp-keys";
-    const char* const MIME_PKCS7_MIME = "application/pkcs7-mime";
-
-using namespace Kolab::Utils;
-    
-template <typename T> 
-std::string getType();
-
-template <> 
-std::string getType<Kolab::Contact>()
-{
-    return INDIVIDUAL;
-}
-
-template <> 
-std::string getType<Kolab::DistList>()
-{
-    return GROUP;
-}
-
-template <typename T>
-xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input)
-{
-    xsd::cxx::tree::sequence<T> list;
-    BOOST_FOREACH(const std::string &s, input) {
-        list.push_back(T(s));
-    }
-    return list;
-}
-
-template <typename T>
-xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input, int preferredIndex)
-{
-    xsd::cxx::tree::sequence<T> list;
-    int index = 0;
-    BOOST_FOREACH(const std::string &s, input) {
-        T im(s);
-        if(preferredIndex == index) {
-            typename T::parameters_type parameters;
-            parameters.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
-            im.parameters(parameters);
-        }
-        index++;
-        list.push_back(im);
-    }
-    return list;
-}
-
-template <typename T>
-std::vector<std::string> toUriList(const xsd::cxx::tree::sequence<T> &input)
-{
-    std::vector<std::string> list;
-    BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, input) {
-        list.push_back(s.uri());
-    }
-    return list;
-}
-
-template <typename T>
-std::vector<std::string> toTextList(const xsd::cxx::tree::sequence<T> &input)
-{
-    std::vector<std::string> list;
-    BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, input) {
-        list.push_back(s.text());
-    }
-    return list;
-}
-
-std::vector<std::string> toStringList(const ::xsd::cxx::tree::sequence< ::xml_schema::string > &s)
-{
-    std::vector<std::string> d;
-    std::copy(s.begin(), s.end(), std::back_inserter(d));
-    return d;
-}
-
-::xsd::cxx::tree::sequence< ::xml_schema::string > fromStringList(const std::vector<std::string> &s)
-{
-    ::xsd::cxx::tree::sequence< ::xml_schema::string > d;
-    std::copy(s.begin(), s.end(), std::back_inserter(d));
-    return d;
-}
-
-std::string fromDate(const cDateTime &dt)
-{
-    if (!dt.isDateOnly()) {
-        WARNING("fromDate called on date time value");
-    }
-    std::stringstream s;
-    s.fill('0');
-    s.width(4);
-    s << dt.year();
-    s.width(2);
-    s << dt.month();
-    s.width(2);
-    s << dt.day();
-    return s.str();
-}
-
-std::string fromDateTime(const cDateTime &dt)
-{
-    std::stringstream s;
-    s.fill('0');
-    s << std::right; 
-    s.width(4);
-    s << dt.year();
-    s.width(2);
-    s << dt.month();
-    s.width(2);
-    s << dt.day();
-    s.width(1);
-    if (dt.isDateOnly()) {
-        return s.str();
-    }
-    s << "T";
-    s.width(2);
-    s << dt.hour();
-    s.width(2);
-    s << dt.minute();
-    s.width(2);
-    s << dt.second();
-    if (dt.isUTC()) {
-        s << "Z";
-    }
-    return s.str();
-}
-
-cDateTime toDateTime(const std::string &input)
-{
-    int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
-    bool isUtc = false;
-    try {
-        year = boost::lexical_cast<int>(input.substr(0, 4));
-        month = boost::lexical_cast<int>(input.substr(4, 2));
-        day = boost::lexical_cast<int>(input.substr(6, 2));
-        if (input.size() >= 15) { //Minimum for time
-            if (input.at(8) != 'T') {
-                ERROR("Wrong demiliter");
-                return cDateTime();
-            }
-            hour = boost::lexical_cast<int>(input.substr(9, 2));
-            minute = boost::lexical_cast<int>(input.substr(11, 2));
-            second = boost::lexical_cast<int>(input.substr(13, 2));
-        } else {
-            if (input.size() >= 9) {
-                ERROR("Invalid dt " + input);
-                return cDateTime();
-            }
-            return cDateTime(year, month, day);
-        }
-        if (input.size() >= 16) {
-            if (input.at(15) == 'Z') {
-                isUtc = true;
-            } else {
-                ERROR("wrong utc char? " + input.at(15));
-                return cDateTime();
-            }
-        }
-    } catch (boost::bad_lexical_cast &c) {
-        ERROR("failed to convert: "+std::string(c.what()));
-        return cDateTime();
-    } catch (...) {
-        ERROR("failed to convert: unkown exception");
-        return cDateTime();
-    }
-    return cDateTime(year, month, day, hour, minute, second, isUtc);
-}
-
-cDateTime toDateTime(const vcard_4_0::DateDatetimePropertyType &prop)
-{
-    if (prop.date_time()) {
-        return toDateTime(*prop.date_time());
-    } else if (prop.date()) {
-        return toDateTime(*prop.date());
-    }
-    ERROR("no date and no datetime");
-    return cDateTime();
-}
-
-template <typename T>
-T fromDateTime(const Kolab::cDateTime &dt)
-{
-    T prop;
-
-    if (dt.isDateOnly()) {
-        prop.date(fromDate(dt));
-    } else {
-        prop.date_time(fromDateTime(dt));
-    }
-    return prop;
-}
-
-vcard_4_0::PrefTypeValueType fromCryptoPref(Kolab::Crypto::CryptoPref pref)
-{
-    switch (pref) {
-        case Kolab::Crypto::Always:
-            return vcard_4_0::CryptoType::encryptpref_type::text_type::Always;
-        case Kolab::Crypto::Ask:
-            return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
-        case Kolab::Crypto::IfPossible:
-            return vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible;
-        case Kolab::Crypto::Never:
-            return vcard_4_0::CryptoType::encryptpref_type::text_type::Never;
-        default:
-            WARNING("unknown encrypt pref");
-    }
-    return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
-}
-
-Kolab::Crypto::CryptoPref toCryptoPref(vcard_4_0::PrefTypeValueType pref)
-{
-    switch (pref) {
-        case vcard_4_0::CryptoType::encryptpref_type::text_type::Always:
-            return Kolab::Crypto::Always;
-        case vcard_4_0::CryptoType::encryptpref_type::text_type::Ask:
-            return Kolab::Crypto::Ask;
-        case vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible:
-            return Kolab::Crypto::IfPossible;
-        case vcard_4_0::CryptoType::encryptpref_type::text_type::Never:
-            return Kolab::Crypto::Never;
-        default:
-            WARNING("unknown encrypt pref");
-    }
-    return Kolab::Crypto::Ask;
-}
-
-vcard_4_0::relatedPropType fromRelated(const Kolab::Related &r)
-{
-    using namespace vcard_4_0;
-    vcard_4_0::relatedPropType related;
-    if (r.type() == Kolab::Related::Uid) {
-        related.uri(r.uri());
-    } else {
-        related.text(r.text());
-    }
-    if (r.relationTypes() != Kolab::Related::NoRelation) {
-        
-        vcard::adr_type::parameters_type::baseParameter_sequence base;
-        vcard::adr_type::parameters_type b;
-        
-        vcard_4_0::typeParamType::text_sequence seq;
-        if (r.relationTypes() & Kolab::Related::Child) {
-            seq.push_back(TypeValueType::child);
-        }
-        if (r.relationTypes() & Kolab::Related::Spouse) {
-            seq.push_back(TypeValueType::spouse);
-        }
-        if (r.relationTypes() & Kolab::Related::Assistant) {
-            seq.push_back(TypeValueType::x_assistant);
-        }
-        if (r.relationTypes() & Kolab::Related::Manager) {
-            seq.push_back(TypeValueType::x_manager);
-        }
-        if (!seq.empty()) {
-            vcard_4_0::typeParamType type;
-            type.text(seq);
-            b.baseParameter().push_back(type);
-        }
-        
-        related.parameters(b);
-    }
-    
-    return related;
-}
-
-Kolab::Related toRelated(const vcard_4_0::relatedPropType &r)
-{
-    Kolab::Related::DescriptionType type = Kolab::Related::Invalid;
-    std::string textOrUri;
-    if (r.uri()) {
-        type = Kolab::Related::Uid;
-        textOrUri = *r.uri();
-    } else if (r.text()) {
-        type = Kolab::Related::Text;
-        textOrUri = *r.text();
-    } else {
-        ERROR("no text and no uri");
-        return Kolab::Related();
-    }
-    Kolab::Related related(type, textOrUri);
-    if (r.parameters()) {
-        BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*r.parameters()).baseParameter()) {
-            if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
-                int types = 0;
-                BOOST_FOREACH(const std::string &s, rel->text()) {
-                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::child)) {
-                        types |= Kolab::Related::Child;
-                    }
-                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::spouse)) {
-                        types |= Kolab::Related::Spouse;
-                    }
-                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_assistant)) {
-                        types |= Kolab::Related::Assistant;
-                    }
-                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_manager)) {
-                        types |= Kolab::Related::Manager;
-                    }
-                }
-                related.setRelationTypes(types);
-            } 
-        }
-    }
-    return related;
-}
-
-vcard_4_0::vcard::adr_type fromAddress(const Kolab::Address &address)
-{
-    using namespace vcard_4_0;
-    vcard::adr_type a(vcard::adr_type::pobox_type(std::string()/*address.pobox()*/), 
-                      vcard::adr_type::ext_type(std::string()/*address.ext()*/),
-                                                vcard::adr_type::street_type(address.street()),
-                                                vcard::adr_type::locality_type(address.locality()),
-                                                vcard::adr_type::region_type(address.region()),
-                                                address.code(),
-                                                vcard::adr_type::country_type(address.country())
-                      );
-    vcard::adr_type::parameters_type b;
-    if (address.types()) {
-        vcard_4_0::typeParamType::text_sequence seq;
-        if (address.types() & Kolab::Address::Home) {
-            seq.push_back(TypeValueType::home);
-        }
-        if (address.types() & Kolab::Address::Work) {
-            seq.push_back(TypeValueType::work);
-        }
-        if (!seq.empty()) {
-            vcard_4_0::typeParamType type;
-            type.text(seq);
-            b.baseParameter().push_back(type);
-        }
-    }
-    if (!address.label().empty()) {
-        b.baseParameter().push_back(vcard_4_0::labelParamType(address.label()));
-    }
-    a.parameters(b);
-    return a;
-}
-
-Kolab::Address toAddress(const vcard_4_0::vcard::adr_type &adr, bool *isPreferred = 0)
-{
-    using namespace vcard_4_0;
-    Address address;
-    if (adr.parameters()) {
-        BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*adr.parameters()).baseParameter()) {
-            if (const vcard_4_0::labelParamType *rel = dynamic_cast<const vcard_4_0::labelParamType*> (&param)) {
-                address.setLabel(rel->text());
-            } else if (isPreferred && dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
-                *isPreferred = true;
-            } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
-                int types = 0;
-                BOOST_FOREACH(const std::string &s, rel->text()) {
-                    if (s == TypeValueType(TypeValueType::work)) {
-                        types |= Kolab::Telephone::Work;
-                    }
-                    if (s == TypeValueType(TypeValueType::home)) {
-                        types |= Kolab::Telephone::Home;
-                    }
-                }
-                address.setTypes(types);
-            } 
-        }
-    }
-    
-    address.setCode(adr.code());
-    address.setCountry(adr.country());
-    address.setLocality(adr.locality());
-    address.setRegion(adr.region());
-    address.setStreet(adr.street());
-    return address;
-}
-
-std::string toGeoUri(double lat, double lon)
-{
-    //lexical_cast doesn't work, so we're using stringstream
-    std::stringstream s;
-    s << "geo:";
-    s.precision(15); //can't use std::numeric_limits<double>::max_digits10 because that's c++ 0x, it should be 17, but that seems to cause rounding problems... no idea why.
-    s << lat << ",";
-    s.precision(15); //Needed to get the right precision somehow...
-    s << lon;
-    return s.str();
-}
-
-bool fromGeoUri(const std::string &uri, double &lat, double &lon)
-{
-    if (uri.substr(0,4) != std::string("geo:")) {
-        WARNING("not a geo uri");
-        return false;
-    }
-    std::size_t pos1 = uri.find(",");
-    if (pos1 == std::string::npos) {
-        WARNING("not a valid geo uri");
-        return false;
-    }
-    lat = boost::lexical_cast<double>(uri.substr(4, pos1-4));
-    lon = boost::lexical_cast<double>(uri.substr(pos1+1, uri.size()-pos1-1));
-    return true;
-}
-
-template <typename T> 
-void writeCard(vcard_4_0::vcard &vcard, const T &);
-
-template <> 
-void writeCard<Kolab::Contact>(vcard_4_0::vcard &vcard, const Kolab::Contact &contact)
-{
-    using namespace vcard_4_0;
-    
-    if (!contact.categories().empty()) {
-        vcard_4_0::vcard::categories_type cat;
-        vcard_4_0::vcard::categories_type::text_sequence seq;
-        BOOST_FOREACH(const std::string &s, contact.categories()) {
-            seq.push_back(s);
-        }
-        cat.text(seq);
-        vcard.categories(cat);
-    }
-    
-    if (contact.nameComponents().isValid()) {
-        const NameComponents &nc = contact.nameComponents();
-        vcard::n_type n;
-        n.surname(fromStringList(nc.surnames()));
-        n.given(fromStringList(nc.given()));
-        n.additional(fromStringList(nc.additional()));
-        n.prefix(fromStringList(nc.prefixes()));
-        n.suffix(fromStringList(nc.suffixes()));
-        vcard.n(n);
-    }
-    
-    if (!contact.note().empty()) {
-        vcard.note(vcard::note_type(contact.note()));
-    }
-    
-    if (!contact.freeBusyUrl().empty()) {
-        vcard.fburl(vcard::fburl_type(contact.freeBusyUrl()));
-    }
-    
-    if (!contact.titles().empty()) {
-        vcard.title(fromList<vcard::title_type>(contact.titles()));
-    }
-    
-    if (!contact.affiliations().empty()) {
-        vcard::group_sequence affiliations;
-        BOOST_FOREACH(const Affiliation &a, contact.affiliations()) {
-            affiliationPropType::org_type org;
-            org.text().push_back(a.organisation());
-            BOOST_FOREACH(const std::string &unit, a.organisationalUnits()) {
-                org.text().push_back(unit);
-            }
-            vcard::group_type group(org);
-            if (!a.logo().empty()) {
-                group.logo(affiliationPropType::logo_type(uriInlineEncoding(a.logo(), a.logoMimetype())));
-            }
-            group.role(fromList<affiliationPropType::role_type>(a.roles()));
-            BOOST_FOREACH(const Related &rel, a.relateds()) {
-                group.related().push_back(fromRelated(rel));
-            }
-            BOOST_FOREACH(const Address &adr, a.addresses()) {
-                group.adr().push_back(fromAddress(adr));
-            }
-
-            affiliations.push_back(group);
-        }
-        vcard.group(affiliations);
-    }
-    
-    if (!contact.urls().empty()) {
-        vcard.url(fromList<vcard::url_type>(contact.urls()));
-    }
-    
-    if (!contact.addresses().empty()) {
-        vcard::adr_sequence adrs;
-        int index = 0;
-        BOOST_FOREACH(const Kolab::Address &address, contact.addresses()) {
-            vcard::adr_type a = fromAddress(address);
-            if(contact.addressPreferredIndex() == index) {
-                if (a.parameters()) {
-                    (*a.parameters()).baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
-                } else {
-                    vcard::adr_type::parameters_type b;
-                    b.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
-                    a.parameters(b);
-                }
-            }
-            index++;
-            adrs.push_back(a);
-        }
-        vcard.adr(adrs);
-    }
-    
-    if (!contact.nickNames().empty()) {
-        vcard::nickname_type::text_sequence textsequence;
-        BOOST_FOREACH(const std::string &s, contact.nickNames()) {
-            textsequence.push_back(s);
-        }
-        vcard::nickname_type nickName;
-        nickName.text(textsequence);
-        vcard.nickname(nickName);
-    }
-    
-    if (!contact.relateds().empty()) {
-        vcard::related_sequence seq;
-        BOOST_FOREACH(const Kolab::Related &r, contact.relateds()) {
-            seq.push_back(fromRelated(r));
-        }
-        vcard.related(seq);
-    }
-    
-    if (contact.bDay().isValid()) {
-        Kolab::cDateTime dt = contact.bDay();
-        if (dt.isUTC() || !dt.timezone().empty()) {
-            WARNING("Must be local time, local time assumed");
-            dt.setUTC(false);
-        }
-        vcard.bday(fromDateTime<vcard::bday_type>(dt));
-    }
-    
-    if (contact.anniversary().isValid()) {
-        Kolab::cDateTime dt = contact.anniversary();
-        if (dt.isUTC() || !dt.timezone().empty()) {
-            WARNING("Must be local time, local time assumed");
-            dt.setUTC(false);
-        }
-        vcard.anniversary(fromDateTime<vcard::anniversary_type>(dt));
-    }
-    
-    if (!contact.photo().empty()) {
-        vcard::photo_type photo(vcard_4_0::UriPropertyType::uri_type(uriInlineEncoding(contact.photo(), contact.photoMimetype())));
-        vcard.photo(photo);
-    }
-    
-    if (contact.gender() != Contact::NotSet) {
-        switch (contact.gender()) {
-            case Contact::NotSpecified:
-                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::empty));
-                break;
-            case Contact::Male:
-                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::M));
-                break;
-            case Contact::Female:
-                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::F));
-                break;
-            default:
-                ERROR("Unhandled gender");
-        }
-    }
-    
-    if (!contact.languages().empty()) {
-        vcard.lang(fromList<vcard::lang_type>(contact.languages()));
-    }
-    
-    if (!contact.telephones().empty()) {
-        vcard::tel_sequence seq;
-        int index = 0;
-        BOOST_FOREACH(const Kolab::Telephone &t, contact.telephones()) {
-            vcard::tel_type tel(t.number());
-            vcard_4_0::typeParamType telTypeParam;
-            if (t.types() & Kolab::Telephone::Car) {
-                telTypeParam.text().push_back(TypeValueType::x_car);
-            } 
-            if (t.types() & Kolab::Telephone::Cell) {
-                telTypeParam.text().push_back(TypeValueType::cell);
-            } 
-            if (t.types() & Kolab::Telephone::Fax) {
-                telTypeParam.text().push_back(TypeValueType::fax);
-            } 
-            if (t.types() & Kolab::Telephone::Home) {
-                telTypeParam.text().push_back(TypeValueType::home);
-            } 
-            if (t.types() & Kolab::Telephone::Work) {
-                telTypeParam.text().push_back(TypeValueType::work);
-            } 
-            if (t.types() & Kolab::Telephone::Text) {
-                telTypeParam.text().push_back(TypeValueType::text);
-            } 
-            if (t.types() & Kolab::Telephone::Voice) {
-                telTypeParam.text().push_back(TypeValueType::voice);
-            } 
-            if (t.types() & Kolab::Telephone::Video) {
-                telTypeParam.text().push_back(TypeValueType::video);
-            } 
-            if (t.types() & Kolab::Telephone::Textphone) {
-                telTypeParam.text().push_back(TypeValueType::textphone);
-            } 
-            if (t.types() & Kolab::Telephone::Pager) {
-                telTypeParam.text().push_back(TypeValueType::pager);
-            }
-            vcard::tel_type::parameters_type params;
-            if(contact.telephonesPreferredIndex() == index) {
-                params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
-            }
-            index++;
-
-            if (!telTypeParam.text().empty()) {
-                params.baseParameter().push_back(telTypeParam);
-                tel.parameters(params);
-            }
-            seq.push_back(tel);
-        }
-        vcard.tel(seq);
-    }
-    
-    if (!contact.imAddresses().empty()) {
-        vcard.impp(fromList<vcard::impp_type>(contact.imAddresses(), contact.imAddressPreferredIndex()));
-    }
-    
-    if (!contact.emailAddresses().empty()) {
-        vcard.email(fromList<vcard::email_type>(contact.emailAddresses(), contact.emailAddressPreferredIndex()));
-    }
-    
-    if (!contact.gpsPos().empty()) {
-        vcard_4_0::vcard::geo_sequence list;
-        BOOST_FOREACH(const Kolab::Geo &g ,contact.gpsPos()) {
-            list.push_back(vcard_4_0::vcard::geo_type(toGeoUri(g.latitude, g.longitude)));
-        }
-        vcard.geo(list);
-    }
-    
-    if (contact.crypto().isValid()) {
-        vcard::x_crypto_type crypto;
-        const Kolab::Crypto &c = contact.crypto();
-        if (c.allowed()) {
-            vcard::x_crypto_type::allowed_type::text_sequence seq;
-            if (c.allowed() & Kolab::Crypto::PGPinline) {
-                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE);
-            }
-            if (c.allowed() & Kolab::Crypto::PGPmime) {
-                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_MIME);
-            }
-            if (c.allowed() & Kolab::Crypto::SMIME) {
-                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIME);
-            }
-            if (c.allowed() & Kolab::Crypto::SMIMEopaque) {
-                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque);
-            }
-            vcard::x_crypto_type::allowed_type allowed;
-            allowed.text(seq);
-            crypto.allowed(allowed);
-        }
-        vcard_4_0::vcard::key_sequence keys;
-        if (!c.pgpKey().empty()) {
-            keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.pgpKey(), MIME_PGP_KEYS)));
-        }
-        if (!c.smimeKey().empty()) {
-            keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.smimeKey(), MIME_PKCS7_MIME)));
-        }
-        if (!keys.empty()) {
-            vcard.key(keys);
-        }
-        crypto.encryptpref(fromCryptoPref(c.encryptPref()));
-        crypto.signpref(fromCryptoPref(c.signPref()));
-
-        vcard.x_crypto(crypto);
-    }
-
-
-}
-
-template <> 
-void writeCard<Kolab::DistList>(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist)
-{
-    if (!distlist.members().empty()) {
-        vcard_4_0::vcard::member_sequence members;
-        BOOST_FOREACH (const Kolab::ContactReference &m, distlist.members()) {
-            members.push_back(vcard_4_0::vcard::member_type(Shared::fromContactReference(m)));
-        }
-        vcard.member(members);
-    } else {
-        WARNING("empty distlist");
-    }
-}
-
-
-
-template <typename T>
-std::string serializeCard(const T &card, const std::string prod = std::string()) {
-
-    using namespace vcard_4_0;
-    
-    clearErrors();
-
-    try {
-        vcard_4_0::vcard::uid_type uid(Shared::toURN(getUID(card.uid())));
-        setCreatedUid(Shared::fromURN(uid.uri()));
-        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
-        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
-        vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
-        vcard_4_0::vcard::kind_type kind(getType<T>());
-        vcard_4_0::vcard::fn_type fn(card.name());
-
-        vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
-        
-        writeCard<T>(vcard, card);
-        
-        if (!card.customProperties().empty()) {
-            BOOST_FOREACH(const Kolab::CustomProperty &a, card.customProperties()) {
-                vcard.x_custom().push_back(vcard_4_0::CustomType(a.identifier, a.value));
-            }
-        }
-        
-        VcardsType vcards(vcard);
-
-        xml_schema::namespace_infomap map;
-        map[""].name = XCARD_NAMESPACE;
-        
-        std::ostringstream ostringstream;
-        vcard_4_0::vcards(ostringstream, vcards, map);
-        return ostringstream.str();
-    } catch  (const xml_schema::exception& e) {
-        CRITICAL("Unknown Exception: failed to write Contact");
-    }
-    return std::string();
-}
-
-template <typename T>
-boost::shared_ptr<T> readCard(const vcard_4_0::VcardsType::vcard_type &vcard);
-
-template <>
-boost::shared_ptr<Kolab::Contact> readCard <Kolab::Contact> (const vcard_4_0::VcardsType::vcard_type &vcard)
-{
-    using namespace vcard_4_0;
-    boost::shared_ptr<Kolab::Contact> contact(new Kolab::Contact);
-    
-    if (vcard.categories()) {
-        contact->setCategories(toStringList((*vcard.categories()).text()));
-    }
-    
-    if (vcard.n()) {
-        NameComponents nc;
-        nc.setSurnames(toStringList((*vcard.n()).surname()));
-        nc.setGiven(toStringList((*vcard.n()).given()));
-        nc.setPrefixes(toStringList((*vcard.n()).prefix()));
-        nc.setSuffixes(toStringList((*vcard.n()).suffix()));
-        nc.setAdditional(toStringList((*vcard.n()).additional()));
-        contact->setNameComponents(nc);
-    }
-    if (vcard.note()) {
-        contact->setNote((*vcard.note()).text());
-    }
-    if (vcard.fburl()) {
-        contact->setFreeBusyUrl((*vcard.fburl()).uri());
-    }
-    if (!vcard.title().empty()) {
-        contact->setTitles(toTextList<vcard::title_type >(vcard.title()));
-    }
-    if (!vcard.group().empty()) {
-        std::vector<Kolab::Affiliation> list;
-        BOOST_FOREACH (const vcard::group_type &group, vcard.group()) {
-            Kolab::Affiliation aff;
-            if (!group.org().text().empty()) {
-                aff.setOrganisation(*group.org().text().begin());
-                std::vector<std::string> units;
-                for ( vcard_4_0::NonEmptyTextListPropertyType::text_const_iterator it = ++group.org().text().begin(); it != group.org().text().end(); it++) {
-                    units.push_back(*it);
-                }
-                aff.setOrganisationalUnits(units);
-            } else {
-                WARNING("No org present");
-            }
-            std::string mimetype;
-            if (group.logo()) {
-                const std::string &logo = uriInlineDecoding((*group.logo()).uri(), mimetype);
-                aff.setLogo(logo, mimetype);
-            }
-            aff.setRoles(toTextList<vcard::group_type::role_type>(group.role()));
-            std::vector<Related> relateds;
-            BOOST_FOREACH(const vcard::group_type::related_type &rel, group.related()) {
-                relateds.push_back(toRelated(rel));
-            }
-            aff.setRelateds(relateds);
-            std::vector<Address> addresses;
-            BOOST_FOREACH(const vcard::group_type::adr_type &adr, group.adr()) {
-                addresses.push_back(toAddress(adr));
-            }
-            aff.setAddresses(addresses);
-            list.push_back(aff);
-        }
-        contact->setAffiliations(list);
-    }
-    if (!vcard.url().empty()) {
-        contact->setUrls(toUriList<vcard::url_type >(vcard.url()));
-    }
-    if (!vcard.adr().empty()) {
-        std::vector<Kolab::Address> list;
-        int preferredIndex = -1;
-        int index = 0;
-        BOOST_FOREACH(const vcard::adr_type &adr, vcard.adr()) {
-            bool isPreferred = false;
-            const Kolab::Address &address = toAddress(adr, &isPreferred);
-            if (isPreferred) {
-                preferredIndex = index;
-            }
-            index++;
-            list.push_back(address);
-        }
-        contact->setAddresses(list, preferredIndex);
-    }
-    if (vcard.nickname()) {
-        contact->setNickNames(toTextList<TextListPropertyType::text_type>((*vcard.nickname()).text()));
-    }
-    if (!vcard.related().empty()) {
-        std::vector<Related> list;
-        BOOST_FOREACH(const vcard_4_0::vcard::related_type &r, vcard.related()) {
-            list.push_back(toRelated(r));
-        }
-        contact->setRelateds(list);
-    }
-    if (vcard.bday()) {
-        contact->setBDay(toDateTime(*vcard.bday()));
-    }
-    if (vcard.anniversary()) {
-        contact->setAnniversary(toDateTime(*vcard.anniversary()));
-    }
-    if (vcard.photo()) {
-        std::string mimetype;
-        const std::string decodedPhoto =  uriInlineDecoding((*vcard.photo()).uri(), mimetype);
-        contact->setPhoto(decodedPhoto, mimetype);
-    }
-    if (vcard.gender()) {
-        if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::empty) {
-            contact->setGender(Kolab::Contact::NotSpecified);
-        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::M) {
-            contact->setGender(Kolab::Contact::Male);
-        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::F) {
-            contact->setGender(Kolab::Contact::Female);
-        }
-    }
-    if (!vcard.lang().empty()) {
-        std::vector<std::string> list;
-        BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) {
-            list.push_back(l.language_tag());
-        }
-        contact->setLanguages(list);
-    }
-    if (!vcard.tel().empty()) {
-        std::vector<Kolab::Telephone> list;
-        int preferredIndex = -1;
-        int index = 0;
-        BOOST_FOREACH(const vcard::tel_type &tel, vcard.tel()) {
-            Kolab::Telephone telephone;
-            if (tel.parameters()) {
-                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*tel.parameters()).baseParameter()) {
-                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
-                        preferredIndex = index;
-                    } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
-                        int types = 0;
-                        BOOST_FOREACH(const std::string &s, rel->text()) {
-                            if (s == TypeValueType(TypeValueType::work)) {
-                                types |= Kolab::Telephone::Work;
-                            }
-                            if (s == TypeValueType(TypeValueType::home)) {
-                                types |= Kolab::Telephone::Home;
-                            }
-                            if (s == TypeValueType(TypeValueType::text)) {
-                                types |= Kolab::Telephone::Text;
-                            }
-                            if (s == TypeValueType(TypeValueType::voice)) {
-                                types |= Kolab::Telephone::Voice;
-                            }
-                            if (s == TypeValueType(TypeValueType::fax)) {
-                                types |= Kolab::Telephone::Fax;
-                            }
-                            if (s == TypeValueType(TypeValueType::cell)) {
-                                types |= Kolab::Telephone::Cell;
-                            }
-                            if (s == TypeValueType(TypeValueType::video)) {
-                                types |= Kolab::Telephone::Video;
-                            }
-                            if (s == TypeValueType(TypeValueType::pager)) {
-                                types |= Kolab::Telephone::Pager;
-                            }
-                            if (s == TypeValueType(TypeValueType::textphone)) {
-                                types |= Kolab::Telephone::Textphone;
-                            }
-                            if (s == TypeValueType(TypeValueType::x_car)) {
-                                types |= Kolab::Telephone::Car;
-                            }
-                        }
-                        telephone.setTypes(types);
-                    } 
-                }
-            }
-            index++;
-
-            telephone.setNumber(tel.text());
-            list.push_back(telephone);
-        }
-        contact->setTelephones(list, preferredIndex);
-    }
-    
-    if (!vcard.impp().empty()) {
-        int preferredIndex = -1;
-        
-        std::vector<std::string> list;
-        int i = 0;
-        BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, vcard.impp()) {
-            if (s.parameters()) {
-                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
-                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
-                        preferredIndex = i;
-                    } 
-                }
-            }
-            i++;
-            list.push_back(s.uri());
-        }
-        
-        contact->setIMaddresses(list, preferredIndex);
-    }
-    if (!vcard.email().empty()) {
-        int preferredIndex = -1;
-        
-        std::vector<std::string> list;
-        int i = 0;
-        BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, vcard.email()) {
-            if (s.parameters()) {
-                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
-                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
-                        preferredIndex = i;
-                    } 
-                }
-            }
-            i++;
-            list.push_back(s.text());
-        }
-        
-        contact->setEmailAddresses(list, preferredIndex);
-    }
-    if (!vcard.geo().empty()) {
-        std::vector<Geo> list;
-        BOOST_FOREACH(const vcard_4_0::geoPropType &s, vcard.geo()) {
-            double lon = 0.0;
-            double lat = 0.0;
-            if (fromGeoUri(s.uri(), lat, lon)) {
-                list.push_back(Kolab::Geo(lat, lon));
-            }
-        }
-        contact->setGPSpos(list);
-    }
-    if (vcard.x_crypto()) {
-        const vcard_4_0::vcard::x_crypto_type &crypto = *vcard.x_crypto();
-        Kolab::Crypto c;
-        if (crypto.allowed()) {
-            int allowed = 0;
-            BOOST_FOREACH(const vcard_4_0::vcard::x_crypto_type::allowed_type::text_type &m, crypto.allowed()->text()) {
-                if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE) {
-                    allowed |= Kolab::Crypto::PGPinline;
-                } else if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_MIME) {
-                    allowed |= Kolab::Crypto::PGPmime;
-                } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIME) {
-                    allowed |= Kolab::Crypto::SMIME;
-                } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque) {
-                    allowed |= Kolab::Crypto::SMIMEopaque;
-                } else {
-                    WARNING("unknown allowed property");
-                }
-            }
-            c.setAllowed(allowed);
-        }
-        if (!vcard.key().empty()) {
-            BOOST_FOREACH(const vcard_4_0::keyPropType &k, vcard.key()) {
-                std::string mimetype;
-                const std::string &key = uriInlineDecoding(k.uri(), mimetype);
-                if (mimetype == MIME_PGP_KEYS) {
-                    c.setPGPKey(key);
-                } else if (mimetype == MIME_PKCS7_MIME) {
-                    c.setSMIMEKey(key);
-                } else {
-                    WARNING("wrong mimetype on key");
-                }
-            }
-        }
-        if (crypto.encryptpref()) {
-            c.setEncryptPref(toCryptoPref(crypto.encryptpref()->text()));
-        }
-        if (crypto.signpref()) {
-            c.setSignPref(toCryptoPref(crypto.signpref()->text()));
-        }
-        contact->setCrypto(c);
-    }
-    return contact;
-}
-
-template <>
-boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
-{
-    using namespace vcard_4_0;
-    boost::shared_ptr<Kolab::DistList> distlist(new Kolab::DistList);
-
-    if (!vcard.member().empty()) {
-        std::vector<Kolab::ContactReference> members;
-
-        BOOST_FOREACH(const vcard_4_0::vcard::member_type & m, vcard.member()) {
-            members.push_back(Shared::toContactReference(m.uri()));
-        }
-        distlist->setMembers(members);
-    } else {
-        WARNING("empty distlist");
-    }
-    return distlist;
-}
-
-template <typename T>
-boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
-{
-    clearErrors();
-    try {
-        std::auto_ptr<vcard_4_0::VcardsType> vcards;
-        if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
-            if (doc.get()) {
-                vcards = vcard_4_0::vcards(doc);
-            }
-        } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
-            if (doc.get()) {
-                vcards = vcard_4_0::vcards(doc);
-            }
-        }
-
-        if (!vcards.get()) {
-            CRITICAL("failed to parse card!");
-            return boost::shared_ptr<T>();
-        }
-        
-        boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
-        card->setUid(Shared::fromURN(vcards->vcard().uid().uri()));
-        card->setName(vcards->vcard().fn().text());
-        
-        setProductId( vcards->vcard().prodid().text() );
-//         setFormatVersion( vcards->vcard().version().text() );
-//         global_xCardVersion = vcalendar.properties().version().text();
-        setKolabVersion( vcards->vcard().x_kolab_version().text() );
-        
-        if (!vcards->vcard().x_custom().empty()) {
-            std::vector<Kolab::CustomProperty> customProperties;
-            BOOST_FOREACH(const vcard_4_0::CustomType &p, vcards->vcard().x_custom()) {
-                customProperties.push_back(CustomProperty(p.identifier(), p.value()));
-            }
-            card->setCustomProperties(customProperties);
-        }
-        
-        return card;
-    } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        CRITICAL("Failed to read card!");
-    }
-
-    return boost::shared_ptr<T>();
-}
-
-    }
-    
-} //Namespace
-
-#endif
\ No newline at end of file
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
deleted file mode 100644
index ecaa0ae..0000000
--- a/c++/tests/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
-if (QT4_FOUND)
-    message("Buildings tests")
-    QT4_AUTOMOC(bindingstest.cpp)
-    add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
-
-    QT4_AUTOMOC(conversiontest.cpp)
-    add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC})
-    target_link_libraries(conversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
-else()
-    message(WARNING "Could not build tests because qt is missing")
-endif()
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
deleted file mode 100644
index 75eec5e..0000000
--- a/c++/tests/bindingstest.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-#include "bindingstest.h"
-
-#include <QObject>
-#include <QtTest/QtTest>
-
-#include "bindings/iCalendar-props.hxx"
-#include "bindings/iCalendar-valtypes.hxx"
-#include "bindings/kolabformat.hxx"
-
-#include <iostream>
-
-#include <xercesc/dom/DOMException.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <lib/kolabformat.h>
-#include <kdebug.h>
-// #include <kolab/kolabkcalconversion.h>
-#include <iostream>
-#include <fstream>
-#include "serializers.h"
-#include <lib/utils.h>
-#include <lib/kolabjournal.h>
-
-
-
-
-void BindingsTest::noteCompletness()
-{
-    Kolab::Note note;
-    note.setUid("UID");
-    note.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
-    note.setClassification(Kolab::ClassConfidential);
-    note.addCategory("Category");
-    note.setSummary("summary");
-    note.setDescription("description");
-    note.setColor("color");
-    const std::string &result = Kolab::writeNote(note);
-//     std::cout << result << std::endl;
-    
-    const Kolab::Note &re = Kolab::readNote(result, false);
-    QCOMPARE(re.uid(), note.uid());
-    QCOMPARE(re.created(), note.created());
-    QCOMPARE(re.classification(), note.classification());
-    QCOMPARE(re.categories(), note.categories());
-    QCOMPARE(re.summary(), note.summary());
-    QCOMPARE(re.description(), note.description());
-    QCOMPARE(re.color(), note.color());
-}
-
-
-// void BindingsTest::eventCompletness_data()
-template <typename T>
-void setIncidence(T &ev)
-{
-    ev.setUid("UID");
-    ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
-    ev.setSequence(1);
-    ev.setClassification(Kolab::ClassConfidential);
-    ev.addCategory("Category");
-    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
-    
-    Kolab::RecurrenceRule rule;
-    rule.setFrequency(Kolab::RecurrenceRule::Daily);
-    rule.setCount(5);
-    std::vector<int> list;
-    list.push_back(1);
-    list.push_back(3);
-    rule.setBysecond(list);
-    rule.setByminute(list);
-    rule.setByhour(list);
-    std::vector<Kolab::DayPos> byday;
-    byday.push_back(Kolab::DayPos(15, Kolab::Friday));
-    byday.push_back(Kolab::DayPos(0, Kolab::Monday));
-    byday.push_back(Kolab::DayPos(-3, Kolab::Monday));
-    rule.setByday(byday);
-    rule.setBymonthday(list);
-    rule.setByyearday(list);
-    rule.setByweekno(list);
-    rule.setBymonth(list);
-    
-    ev.setRecurrenceRule(rule);
-    ev.addRecurrenceDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
-    ev.addExceptionDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
-    ev.setRecurrenceID(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0), true);
-    ev.setSummary("summary");
-    ev.setDescription("description");
-    ev.setPriority(3);
-    ev.setStatus(Kolab::StatusConfirmed);
-    ev.setLocation("location");
-    ev.setOrganizer(Kolab::ContactReference("mail", "name", "uid"));
-    
-    Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid"));
-    attendee.setPartStat(Kolab::PartDelegated);
-    attendee.setRole(Kolab::Chair);
-    attendee.setRSVP(true);
-    
-    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
-    
-    std::vector<Kolab::Attachment> attachments;
-    
-    Kolab::Attachment attach;
-    attach.setData("data????*?*?*?*?*?", "mimetype");
-    attach.setLabel("label");
-    attachments.push_back(attach);
-    
-    Kolab::Attachment attach2;
-    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
-    attach2.setLabel("labe2l");
-    attachments.push_back(attach2);
-    
-    Kolab::Attachment attach3;
-    using namespace std;
-    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
-    if (file.is_open()) {
-        int size = file.tellg();
-        char *memblock = new char [size];
-        file.seekg (0, ios::beg);
-        file.read (memblock, size);
-        file.close();
-
-        attach3.setData(string(memblock, size), "mimetype");
-
-        delete[] memblock;
-    }
-    attach3.setLabel("labe3l");
-    attachments.push_back(attach3);
-    
-    ev.setAttachments(attachments);
-    std::vector<Kolab::CustomProperty> properties;
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    ev.setCustomProperties(properties);
-    
-    std::vector<Kolab::Alarm> alarms;
-//     Kolab::Alarm dispAlarm("ident");
-//     dispAlarm.setRelativeStart(Kolab::Duration(3, true), Kolab::Start);
-//     alarms.push_back(dispAlarm);
-    std::vector<Kolab::ContactReference> att;
-    att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
-    att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
-    Kolab::Alarm emailAlarm("ident", "value", att);
-    emailAlarm.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true));
-    alarms.push_back(emailAlarm);
-//     Kolab::Attachment audiofile;
-//     audiofile.setUri("ksdjlksdflj", "sdkljdfl");
-//     Kolab::Alarm audio(audiofile);
-//     audio.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true));
-//     alarms.push_back(audio);
-    ev.setAlarms(alarms);
-}
-
-template <typename T>
-void checkIncidence(const T &ev, const T &re)
-{
-    //Common to all
-    
-    QCOMPARE(ev.uid(), re.uid());
-    QCOMPARE(ev.created(), re.created());
-    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
-    QCOMPARE(ev.sequence(), re.sequence());
-    QCOMPARE(ev.classification(), re.classification());
-    QCOMPARE(ev.categories(), re.categories());
-    QCOMPARE(ev.start(), re.start());
-    
-    //Recurrence
-    const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
-    const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
-    QCOMPARE(r1.isValid(), r2.isValid());
-    QCOMPARE(r1.frequency(), r2.frequency());
-    QCOMPARE(r1.interval(), r2.interval());
-    QCOMPARE(r1.weekStart(), r2.weekStart());
-    QCOMPARE(r1.count(), r2.count());
-    QCOMPARE(r1.end(), r2.end());
-    QCOMPARE(r1.bysecond(), r2.bysecond());
-    QCOMPARE(r1.byminute(), r2.byminute());
-    QCOMPARE(r1.byhour(), r2.byhour());
-    QCOMPARE(r1.byday(), r2.byday());
-    QCOMPARE(r1.bymonthday(), r2.bymonthday());
-    QCOMPARE(r1.byyearday(), r2.byyearday());
-    QCOMPARE(r1.byweekno(), r2.byweekno());
-    QCOMPARE(r1.bymonth(), r2.bymonth());
-        
-    //Rest
-    QCOMPARE(ev.recurrenceDates(), re.recurrenceDates());
-    QCOMPARE(ev.exceptionDates(), re.exceptionDates());
-    QCOMPARE(ev.recurrenceID(), re.recurrenceID());
-    QCOMPARE(ev.thisAndFuture(), re.thisAndFuture());
-    QCOMPARE(ev.summary(), re.summary());
-    QCOMPARE(ev.description(), re.description());
-    QCOMPARE(ev.priority(), re.priority());
-    QCOMPARE(ev.status(), re.status());
-    QCOMPARE(ev.location(), re.location());
-    QCOMPARE(ev.organizer(), re.organizer());
-    QCOMPARE(ev.attendees(), re.attendees());
-    QCOMPARE(ev.attachments(), re.attachments());
-    QCOMPARE(ev.customProperties(), re.customProperties());
-    QCOMPARE(ev.alarms(), re.alarms());
-}
-
-
-
-void BindingsTest::eventCompletness()
-{
-    Kolab::Event ev;
-    setIncidence(ev);
-    ev.setEnd(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
-    ev.setTransparency(true);
-    
-    std::string result = Kolab::writeEvent(ev);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-//     std::cout << result << endl;
-    Kolab::Event e = Kolab::readEvent(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    checkIncidence(ev, e);
-    QCOMPARE(ev.end(), e.end());
-    QCOMPARE(ev.transparency(), e.transparency());
-    
-}
-
-void BindingsTest::eventDuration()
-{
-    Kolab::Event ev;
-    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
-    ev.setDuration(Kolab::Duration(11,22,33,44, true));
-
-    const std::string result = Kolab::writeEvent(ev);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-//     std::cout << result << endl;
-    const Kolab::Event e = Kolab::readEvent(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    QVERIFY(ev.duration().isValid());
-    QCOMPARE(ev.duration(), e.duration());
-}
-
-void BindingsTest::todoCompletness()
-{
-    Kolab::Todo ev;
-    setIncidence(ev);
-    ev.setDue(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
-    ev.addRelatedTo("rel1");
-    ev.addRelatedTo("rel2");
-    ev.setPercentComplete(50);
-    
-    std::string result = Kolab::writeTodo(ev);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-//     std::cout << result << endl;
-    Kolab::Todo e = Kolab::readTodo(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    checkIncidence(ev, e);
-    QCOMPARE(ev.due(), e.due());
-    QCOMPARE(ev.relatedTo(), e.relatedTo());
-    QCOMPARE(ev.percentComplete(), e.percentComplete());
-}
-
-void BindingsTest::journalCompletness()
-{
-    Kolab::Journal ev;
-    
-    
-    ev.setUid("UID");
-    ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
-    ev.setSequence(1);
-    ev.setClassification(Kolab::ClassConfidential);
-    ev.addCategory("Category");
-    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
-    Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid"));
-    attendee.setPartStat(Kolab::PartDelegated);
-    attendee.setRole(Kolab::Chair);
-    attendee.setRSVP(true);
-    
-    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
-    
-    std::vector<Kolab::Attachment> attachments;
-    
-    Kolab::Attachment attach;
-    attach.setData("data????*?*?*?*?*?", "mimetype");
-    attach.setLabel("label");
-    attachments.push_back(attach);
-    
-    Kolab::Attachment attach2;
-    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
-    attach2.setLabel("labe2l");
-    attachments.push_back(attach2);
-    
-    Kolab::Attachment attach3;
-    using namespace std;
-    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
-    if (file.is_open()) {
-        int size = file.tellg();
-        char *memblock = new char [size];
-        file.seekg (0, ios::beg);
-        file.read (memblock, size);
-        file.close();
-
-        attach3.setData(string(memblock, size), "mimetype");
-
-        delete[] memblock;
-    }
-    attach3.setLabel("labe3l");
-    attachments.push_back(attach3);
-    
-    ev.setAttachments(attachments);
-    std::vector<Kolab::CustomProperty> properties;
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    ev.setCustomProperties(properties);
-    
-    
-    
-    std::string result = Kolab::writeJournal(ev);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-//     std::cout << result << endl;
-    Kolab::Journal re = Kolab::readJournal(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    
-    
-    QCOMPARE(ev.uid(), re.uid());
-    QCOMPARE(ev.created(), re.created());
-    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
-    QCOMPARE(ev.sequence(), re.sequence());
-    QCOMPARE(ev.classification(), re.classification());
-    QCOMPARE(ev.categories(), re.categories());
-    QCOMPARE(ev.start(), re.start());
-    QCOMPARE(ev.summary(), re.summary());
-    QCOMPARE(ev.description(), re.description());
-    QCOMPARE(ev.status(), re.status());
-    QCOMPARE(ev.attendees(), re.attendees());
-    QCOMPARE(ev.attachments(), re.attachments());
-    QCOMPARE(ev.customProperties(), re.customProperties());
-    
-}
-
-void BindingsTest::contactCompletness()
-{
-    std::vector<std::string> stringlist;
-    stringlist.push_back("lbksdfbklsd");
-    stringlist.push_back("sdf");
-
-    Kolab::Contact c;
-    c.setUid("1045b57d-ff7f-0000-d814-867b4d7f0000");
-    c.setCategories(stringlist);
-    c.setName("name");
-    Kolab::NameComponents nc;
-    nc.setSurnames(stringlist);
-    nc.setGiven(stringlist);
-    nc.setAdditional(stringlist);
-    nc.setPrefixes(stringlist);
-    nc.setSuffixes(stringlist);
-    c.setNameComponents(nc);
-    c.setNote("note");
-    c.setFreeBusyUrl("freebusy");
-    c.setUrls(stringlist);
-    c.setNickNames(stringlist);
-    
-    std::vector <Kolab::Related> relateds;
-    Kolab::Related r1(Kolab::Related::Text, "text");
-    r1.setRelationTypes(Kolab::Related::Child);
-    relateds.push_back(r1);
-    Kolab::Related r2(Kolab::Related::Uid, "urn");
-    r2.setRelationTypes(Kolab::Related::Child|Kolab::Related::Spouse);
-    relateds.push_back(r2);
-    c.setRelateds(relateds);
-    
-    c.setBDay(Kolab::cDateTime(2001,12,10,12,12,12,false));
-    c.setAnniversary(Kolab::cDateTime(2001,3,2,1,1,1,false));
-    c.setPhoto("photo", "mimetype");
-    c.setGender(Kolab::Contact::Male);
-    c.setLanguages(stringlist);
-    c.setIMaddresses(stringlist,1);
-    c.setEmailAddresses(stringlist,1);
-    c.setTitles(stringlist);
-    
-    std::vector<Kolab::Affiliation> list;
-    Kolab::Affiliation aff;
-    aff.setOrganisation("org");
-    aff.setOrganisationalUnits(stringlist);
-    aff.setLogo("logo", "mime/miem");
-    aff.setRoles(stringlist);
-    std::vector<Kolab::Related> relateds2;
-    relateds2.push_back(Kolab::Related(Kolab::Related::Text, "textRelation", Kolab::Related::Assistant));
-    relateds2.push_back(Kolab::Related(Kolab::Related::Uid, "textRelation", Kolab::Related::Manager));
-    aff.setRelateds(relateds2);
-    std::vector<Kolab::Address> adrs;
-    Kolab::Address adr1;
-    adr1.setLabel("label");
-    adrs.push_back(adr1);
-    Kolab::Address adr2;
-    adr2.setStreet("street");
-    adr2.setTypes(Kolab::Address::Work);
-    adrs.push_back(adr2);
-    aff.setAddresses(adrs);
-    list.push_back(aff);
-    Kolab::Affiliation aff2;
-    list.push_back(aff2);
-    c.setAffiliations(list);
-    Kolab::Address address;
-    address.setCode("oiuoiu");
-    address.setCountry("werwer");
-    address.setLabel("lkjlkj");
-    address.setLocality("alla");
-    address.setRegion("skjdfkd");
-    address.setStreet("sldkflsdfj");
-    address.setTypes( Kolab::Address::Work | Kolab::Address::Home );
-    std::vector<Kolab::Address> addresses;
-    addresses.push_back(address);
-    addresses.push_back(address);
-    c.setAddresses(addresses);
-    Kolab::Telephone phone;
-    phone.setNumber("lkjsdflkjfds");
-    phone.setTypes(Kolab::Telephone::Work|
-                    Kolab::Telephone::Home|
-                    Kolab::Telephone::Text|
-                    Kolab::Telephone::Voice|
-                    Kolab::Telephone::Fax|
-                    Kolab::Telephone::Cell|
-                    Kolab::Telephone::Video|
-                    Kolab::Telephone::Pager|
-                    Kolab::Telephone::Textphone|
-                    Kolab::Telephone::Car
-    );
-
-    std::vector<Kolab::Telephone> telephones;
-    telephones.push_back(phone);
-    telephones.push_back(phone);
-    c.setTelephones(telephones, 1);
-    std::vector<Kolab::Geo> geo;
-    geo << Kolab::Geo(1.3, -40.3);
-    c.setGPSpos(geo);
-    Kolab::Crypto crypto;
-    crypto.setAllowed(Kolab::Crypto::PGPinline | Kolab::Crypto::SMIMEopaque);
-    crypto.setPGPKey("pgp");
-    crypto.setSignPref(Kolab::Crypto::IfPossible);
-    crypto.setEncryptPref(Kolab::Crypto::Never);
-    crypto.setSMIMEKey("smime");
-    c.setCrypto(crypto);
-    
-    std::vector<Kolab::CustomProperty> properties;
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    c.setCustomProperties(properties);
-    
-    const std::string result = Kolab::writeContact(c);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    std::cout << result << endl;
-    Kolab::Contact e = Kolab::readContact(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    QCOMPARE(e.uid(), c.uid());
-    QCOMPARE(e.categories(), c.categories());
-    QCOMPARE(e.name(), c.name());
-    QCOMPARE(e.nameComponents(), c.nameComponents());
-    QCOMPARE(e.note(), c.note());
-    QCOMPARE(e.freeBusyUrl(), c.freeBusyUrl());
-    QCOMPARE(e.titles(), c.titles());
-    QCOMPARE(e.affiliations(), c.affiliations());
-    QCOMPARE(e.urls(), c.urls());
-    QCOMPARE(e.addresses(), c.addresses());
-    QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex());
-    QCOMPARE(e.nickNames(), c.nickNames());
-    QCOMPARE(e.relateds(), c.relateds());
-    QCOMPARE(e.bDay(), c.bDay());
-    QCOMPARE(e.anniversary(), c.anniversary());
-    QCOMPARE(e.photo(), c.photo());
-    QCOMPARE(e.photoMimetype(), c.photoMimetype());
-    QCOMPARE(e.gender(), c.gender());
-    QCOMPARE(e.languages(), c.languages());
-    QCOMPARE(e.telephones(), c.telephones());
-    QCOMPARE(e.telephonesPreferredIndex(), c.telephonesPreferredIndex());
-    QCOMPARE(e.imAddresses(), c.imAddresses());
-    QCOMPARE(e.imAddressPreferredIndex(), c.imAddressPreferredIndex());
-    QCOMPARE(e.emailAddresses(), c.emailAddresses());
-    QCOMPARE(e.emailAddressPreferredIndex(), c.emailAddressPreferredIndex());
-    QCOMPARE(e.gpsPos(), c.gpsPos());
-    QCOMPARE(e.crypto(), c.crypto());
-    QCOMPARE(e.customProperties(), c.customProperties());
-}
-
-void BindingsTest::distlistCompletness()
-{
-    std::vector<std::string> stringlist;
-    stringlist.push_back("lbksdfbklsd");
-    stringlist.push_back("sdf");
-
-    Kolab::DistList c;
-    c.setName("name");
-    c.setUid("uid");
-    std::vector<Kolab::ContactReference> members;
-    members.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
-    members.push_back(Kolab::ContactReference(Kolab::ContactReference::UidReference, "urn"));
-    c.setMembers(members);
-    std::vector<Kolab::CustomProperty> properties;
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    properties.push_back(Kolab::CustomProperty("ident", "value"));
-    c.setCustomProperties(properties);
-    
-    const std::string result = Kolab::writeDistlist(c);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-//     std::cout << result << endl;
-    Kolab::DistList e = Kolab::readDistlist(result, false);
-    QVERIFY(Kolab::error() == Kolab::NoError);
-    QCOMPARE(e.uid(), c.uid());
-    QCOMPARE(e.name(), c.name());
-    QCOMPARE(e.members(), c.members());
-    QCOMPARE(e.customProperties(), c.customProperties());
-}
-
-
-void BindingsTest::versionTest()
-{
-    Kolab::Todo ev;
-    setIncidence(ev);
-    
-    std::string result = Kolab::writeTodo(ev);
-    Kolab::Todo e = Kolab::readTodo(result, false);
-    QCOMPARE(Kolab::productId(), std::string(Kolab::KOLAB_LIBNAME) + std::string(Kolab::KOLAB_LIB_VERSION));
-    QCOMPARE(Kolab::xKolabVersion(), std::string(Kolab::KOLAB_FORMAT_VERSION));
-    QCOMPARE(Kolab::xCalVersion(), std::string("2.0"));
-}
-
-void BindingsTest::errorTest()
-{
-    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
-    QCOMPARE(Kolab::error(), Kolab::Critical);
-    QVERIFY(!Kolab::errorMessage().empty());
-}
-
-//Don't break due to an error
-void BindingsTest::errorRecoveryTest()
-{
-    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
-    QCOMPARE(Kolab::error(), Kolab::Critical);
-
-    Kolab::Todo ev;
-    setIncidence(ev);
-    
-    const std::string result = Kolab::writeTodo(ev);
-    Kolab::readTodo(result, false);
-    QCOMPARE(Kolab::error(), Kolab::NoError);
-}
-
-void BindingsTest::BenchmarkRoundtripKolab()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeEvent(event);
-    QBENCHMARK {
-        Kolab::readEvent(result, false);
-    }
-}
-
-void BindingsTest::BenchmarkRoundtrip()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result;
-    QBENCHMARK {
-        result = Kolab::writeEvent(event);
-        Kolab::readEvent(result, false);
-    }
-}
-
-QTEST_MAIN( BindingsTest )
-
-#include "bindingstest.moc"
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
deleted file mode 100644
index 16c933c..0000000
--- a/c++/tests/bindingstest.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef BINDINGSTEST_H
-#define BINDINGSTEST_H
-
-#include <QtCore/QObject>
-#include <QtTest/QtTest>
-
-/*
- * The test are roundtrip tests, which simply write an object out and read it again. The two objects are then compared for equality.
- * This assumes that containers are working (comparison operators and adding/removing values).
- * 
- * Testing it properly would mean to add loads of testfiles in text so we could:
- * serialize => compare to text representation
- * deserialize => check values
- * 
- * If we would do this ideally for every property on every type that would result in a lot of work.
- *
- */ 
-
-class BindingsTest : public QObject
-{
-  Q_OBJECT
-  private slots:
-
-    //Kolabformat
-    void noteCompletness();
-    void eventCompletness();
-    void eventDuration();
-    void todoCompletness();
-    void journalCompletness();
-    
-    void contactCompletness();
-    void distlistCompletness();
-
-    void versionTest();
-    void errorTest();
-    void errorRecoveryTest();
-
-    void BenchmarkRoundtripKolab();
-    void BenchmarkRoundtrip();
-
-};
-
-#endif
\ No newline at end of file
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
deleted file mode 100644
index 0bed229..0000000
--- a/c++/tests/conversiontest.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "conversiontest.h"
-
-#include <QtTest/QtTest>
-#include <lib/xcalconversions.h>
-#include <lib/xcardconversions.h>
-#include <lib/utils.h>
-
-#include "serializers.h"
-#include <boost/thread.hpp>
-
-Q_DECLARE_METATYPE(Kolab::Duration);
-Q_DECLARE_METATYPE(Kolab::DayPos);
-Q_DECLARE_METATYPE(Kolab::cDateTime);
-Q_DECLARE_METATYPE(Kolab::ErrorSeverity);
-Q_DECLARE_METATYPE(std::string);
-
-using namespace Kolab::XCAL;
-
-void ConversionTest::dateComparatorTest()
-{
-    QVERIFY( !(Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime()));
-    QVERIFY( Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false));
-}
-
- 
-void ConversionTest::durationParserTest_data()
-{
-    QTest::addColumn<Kolab::Duration>("expected");
-    QTest::addColumn<QString>("string");
-
-    QTest::newRow("Time") << Kolab::Duration(0,2,3,4, false) << "+PT2H3M4S";
-    QTest::newRow("Day") << Kolab::Duration(1,2,3,4, false) << "+P1DT2H3M4S";
-    QTest::newRow("Week") << Kolab::Duration(1, false) << "+P1W";
-    QTest::newRow("Week Multidigit, negative") << Kolab::Duration(23, true) << "-P23W";
-    Kolab::Utils::clearErrors();
-}
-
-void ConversionTest::durationParserTest()
-{
-    QFETCH(QString, string);
-    QFETCH(Kolab::Duration, expected);
-    const Kolab::Duration result = toDuration(string.toStdString());
-    QCOMPARE(result, expected);
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::durationSerializerTest_data()
-{
-    QTest::addColumn<QString>("expected");
-    QTest::addColumn<Kolab::Duration>("duration");
-
-    QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false);
-    QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false);
-    QTest::newRow("Week positive") << "P1W" << Kolab::Duration(1, false);
-    QTest::newRow("Week negative") << "-P3W" << Kolab::Duration(3, true);
-    QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true);
-    Kolab::Utils::clearErrors();
-}
-
-void ConversionTest::durationSerializerTest()
-{
-    QFETCH(Kolab::Duration, duration);
-    QFETCH(QString, expected);
-    const std::string result = fromDuration(duration);
-    QCOMPARE(QString::fromStdString(result), expected);
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-
-void ConversionTest::dayPosParserTest_data()
-{
-    QTest::addColumn<Kolab::DayPos>("expected");
-    QTest::addColumn<QString>("string");
-
-    QTest::newRow("positive") << Kolab::DayPos(15, Kolab::Wednesday) << "15WE";
-    QTest::newRow("positive with +") << Kolab::DayPos(15, Kolab::Wednesday) << "+15WE";
-    QTest::newRow("negative") << Kolab::DayPos(-15, Kolab::Wednesday) << "-15WE";
-    QTest::newRow("all occurrences") << Kolab::DayPos(0, Kolab::Wednesday) << "WE";
-    Kolab::Utils::clearErrors();
-}
-
-void ConversionTest::dayPosParserTest()
-{
-    QFETCH(QString, string);
-    QFETCH(Kolab::DayPos, expected);
-    const Kolab::DayPos result = toDayPos(string.toStdString());
-    QCOMPARE(result, expected);
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::dayPosSerializerTest_data()
-{
-    QTest::addColumn<QString>("expected");
-    QTest::addColumn<Kolab::DayPos>("daypos");
-
-    QTest::newRow("pos") << "15WE" << Kolab::DayPos(15, Kolab::Wednesday);
-    QTest::newRow("negative") << "-15WE" << Kolab::DayPos(-15, Kolab::Wednesday);
-    QTest::newRow("all occurrences") << "WE" << Kolab::DayPos(0, Kolab::Wednesday);
-    Kolab::Utils::clearErrors();
-
-}
-
-void ConversionTest::dayPosSerializerTest()
-{
-    QFETCH(Kolab::DayPos, daypos);
-    QFETCH(QString, expected);
-    const std::string result = fromDayPos(daypos);
-    QCOMPARE(QString::fromStdString(result), expected);
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::xcardDateParserTest_data()
-{
-    QTest::addColumn<QString>("input");
-    QTest::addColumn<Kolab::cDateTime>("expected");
-    QTest::addColumn<Kolab::ErrorSeverity>("errorState");
-
-    QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) << Kolab::NoError;
-    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true) << Kolab::NoError;
-    QTest::newRow("date only") << "20010102" << Kolab::cDateTime(2001, 01, 02) << Kolab::NoError;
-    QTest::newRow("fail 1 short") << "20010102T03040" << Kolab::cDateTime() << Kolab::Error;
-    QTest::newRow("fail non utc") << "20010102T030401s" << Kolab::cDateTime() << Kolab::Error;
-    QTest::newRow("fail no time") << "20010102T" << Kolab::cDateTime() << Kolab::Error;
-    Kolab::Utils::clearErrors();
-}
-
-
-void ConversionTest::xcardDateParserTest()
-{
-    QFETCH(QString, input);
-    QFETCH(Kolab::cDateTime, expected);
-    QFETCH(Kolab::ErrorSeverity, errorState);
-    const Kolab::cDateTime &dt = Kolab::XCARD::toDateTime(input.toStdString());
-    QCOMPARE(dt, expected);
-    QCOMPARE(Kolab::Utils::getError(), errorState);
-}
-
-void ConversionTest::xCardSerializerTest_data()
-{
-    QTest::addColumn<QString>("expected");
-    QTest::addColumn<Kolab::cDateTime>("dt");
-
-    QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false);
-    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true);
-    QTest::newRow("dateonly") << "20010102" << Kolab::cDateTime(2001, 01, 02);
-    Kolab::Utils::clearErrors();
-}
-
-void ConversionTest::xCardSerializerTest()
-{
-    QFETCH(QString, expected);
-    QFETCH(Kolab::cDateTime, dt);
-    const std::string &s = Kolab::XCARD::fromDateTime(dt);
-    QCOMPARE(QString::fromStdString(s), expected);
-    if (dt.isDateOnly()) {
-        const std::string &s2 = Kolab::XCARD::fromDate(dt);
-        QCOMPARE(QString::fromStdString(s2), expected);
-    }
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::uriInlineEncodingTest()
-{
-    const std::string &s = Kolab::Utils::uriInlineEncoding("data", "mimetype/mime");
-    QCOMPARE(s, std::string("data:mimetype/mime;base64,ZGF0YQ=="));
-    std::string mimetype;
-    const std::string &d = Kolab::Utils::uriInlineDecoding(s, mimetype);
-    QCOMPARE(mimetype, std::string("mimetype/mime"));
-    QCOMPARE(d, std::string("data"));
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::mailtoUriEncodingTest_data()
-{
-    QTest::addColumn<QString>("email");
-    QTest::addColumn<QString>("name");
-    QTest::addColumn<QString>("result");
-    QTest::addColumn<QString>("resultEncoded");
-    
-    QTest::newRow("1") << "email_1 at email.com" << "John Doe" << "mailto:John Doe<email_1 at email.com>" << "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E";
-    
-    Kolab::Utils::clearErrors();
-}
-
-void ConversionTest::mailtoUriEncodingTest()
-{
-    QFETCH(QString, email);
-    QFETCH(QString, name);
-    QFETCH(QString, result);
-    QFETCH(QString, resultEncoded);
-    const std::string &mailto = Kolab::XCARD::toMailto(email.toStdString(), name.toStdString());
-    std::cout << mailto << std::endl;
-    QCOMPARE(QString::fromStdString(mailto), resultEncoded);
-    std::string n;
-    const std::string &e = Kolab::XCARD::fromMailto(mailto, n);
-    QCOMPARE(QString::fromStdString(n), name);
-    QCOMPARE(QString::fromStdString(e), email);
-    
-}
-
-void ConversionTest::urnTest()
-{
-    QCOMPARE(Kolab::Shared::toURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"));
-    QCOMPARE(Kolab::Shared::toURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"));
-    QCOMPARE(Kolab::Shared::fromURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000"));
-    QCOMPARE(Kolab::Shared::fromURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000"));
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-void ConversionTest::geoUriTest()
-{
-    QCOMPARE(Kolab::XCARD::toGeoUri(-34.056, 179.3453), std::string("geo:-34.056,179.3453"));
-    QCOMPARE(Kolab::XCARD::toGeoUri(-34.1, 179.5), std::string("geo:-34.1,179.5"));
-    QCOMPARE(Kolab::XCARD::toGeoUri(-34.0, 179.0), std::string("geo:-34,179"));
-    QCOMPARE(Kolab::XCARD::toGeoUri(-34, 179), std::string("geo:-34,179"));
-    QCOMPARE(Kolab::XCARD::toGeoUri(-34.012342356, 179.3451234553), std::string("geo:-34.012342356,179.3451234553"));
-    
-    double lat, lon;
-    QVERIFY(Kolab::XCARD::fromGeoUri(std::string("geo:-34.056,179.3453"), lat, lon));
-    QCOMPARE(lat, -34.056);
-    QCOMPARE(lon, 179.3453);
-    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
-}
-
-
-void ConversionTest::contactReferenceTest()
-{
-    Kolab::ContactReference email(Kolab::ContactReference::EmailReference, "mail", "name");
-    QCOMPARE(Kolab::Shared::fromContactReference(email), std::string("mailto:name%3Cmail%3E"));
-    Kolab::ContactReference urn(Kolab::ContactReference::UidReference, "urn");
-    QCOMPARE(Kolab::Shared::fromContactReference(urn), std::string("urn:uuid:urn"));
-    
-    QCOMPARE(Kolab::Shared::toContactReference("urn:uuid:urn"), urn);
-    QCOMPARE(Kolab::Shared::toContactReference("mailto:name%3Cmail%3E"), email);
-}
-
-
-void threadF() 
-{
-    for (int i = 0; i < 5; ++i)
-    {
-        std::stringstream s;
-//         s << boost::this_thread::get_id();
-        std::string uid = s.str();
-//         std::cout << uid << std::endl;
-        Kolab::Utils::setCreatedUid(uid);
-        boost::this_thread::sleep(boost::posix_time::seconds(1));
-        QCOMPARE(Kolab::Utils::createdUid(), uid);
-    }
-}
-
-void ConversionTest::threadLocalTest()
-{
-    //Ensure global variables are not mixed between threads and therefore threadsafe.
-    boost::thread t(threadF);
-    boost::thread t2(threadF);
-    t.join();
-    t2.join();
-}
-
-void ConversionTest::uuidGeneratorTest()
-{
-    const std::string &s = getUID();
-    std::cout << s << std::endl;
-    QVERIFY(!s.empty());
-    QCOMPARE(s.size(), (std::size_t)36ul);
-}
-
-
-
-QTEST_MAIN( ConversionTest )
-
-#include "conversiontest.moc"
-
-
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
deleted file mode 100644
index b586ed6..0000000
--- a/c++/tests/conversiontest.h
+++ /dev/null
@@ -1,47 +0,0 @@
-
-#ifndef CONVERSIONTEST_H
-#define CONVERSIONTEST_H
-
-#include <QObject>
-
-class ConversionTest : public QObject
-{
-  Q_OBJECT
-  private slots:
-    void dateComparatorTest();
-
-    void durationParserTest_data();
-    void durationParserTest();
-    
-    void durationSerializerTest_data();
-    void durationSerializerTest();
-    
-    void dayPosParserTest_data();
-    void dayPosParserTest();
-    
-    void dayPosSerializerTest_data();
-    void dayPosSerializerTest();
-    
-    void xcardDateParserTest_data();
-    void xcardDateParserTest();
-    
-    void xCardSerializerTest_data();
-    void xCardSerializerTest();
-    
-    void uriInlineEncodingTest();
-    
-    void mailtoUriEncodingTest_data();
-    void mailtoUriEncodingTest();
-    
-    void urnTest();
-    
-    void contactReferenceTest();
-    
-    void geoUriTest();
-    
-    void threadLocalTest();
-    
-    void uuidGeneratorTest();
-};
-
-#endif // CONVERSIONTEST_H
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
deleted file mode 100644
index 39d904f..0000000
--- a/c++/tests/serializers.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifndef SERIALIZERS_H
-#define SERIALIZERS_H
-
-#include <QByteArray>
-#include <QString>
-#include <lib/kolabformat.h>
-
-namespace QTest {
-    template<>
-    char *toString(const Kolab::cDateTime &dt)
-    {
-        QByteArray ba = "Kolab::cDateTime(";
-        ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", ";
-        ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", ";
-        ba += QString(dt.isUTC()?QString("UTC"):QString("TZ: "+QString::fromStdString(dt.timezone()))).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-
-    template<>
-    char *toString(const std::vector<Kolab::cDateTime> &v)
-    {
-        QByteArray ba = "vector<Kolab::cDateTime>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ "\n";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Attendee &a)
-    {
-        QByteArray ba = "Kolab::Attendee(";
-        ba += QString::fromStdString(a.contact().email()).toAscii() + ", " + QString::fromStdString(a.contact().name()).toAscii()+ ", " + 
-        QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role())  + ", " + QByteArray::number(a.rsvp())  + ", " + 
-        QString::fromStdString(a.contact().uid()).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Attendee> &v)
-    {
-        QByteArray ba = "vector<Kolab::Attendee>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-     
-    template<>
-    char *toString(const std::string &s)
-    {
-        QByteArray ba = "string(";
-        ba += QString::fromStdString(s).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<std::string> &v)
-    {
-        QByteArray ba = "vector<std::string>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<int> &v)
-    {
-        QByteArray ba = "vector<int>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QString::number(v.at(i)).toAscii()+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Duration &dt)
-    {
-        QByteArray ba = "Kolab::Duration(";
-        ba += QByteArray::number(dt.weeks()) + ", " + QByteArray::number(dt.days())+ ", " + QByteArray::number(dt.hours()) + ", ";
-        ba += QByteArray::number(dt.minutes()) + ", " + QByteArray::number(dt.seconds()) + ", " + QByteArray::number(dt.isNegative());
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::DayPos &dt)
-    {
-        QByteArray ba = "Kolab::DayPos(";
-        ba += QByteArray::number(dt.occurence()) + ", " + QByteArray::number(dt.weekday());
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Attachment &a)
-    {
-        QByteArray ba = "Kolab::Attachment(";
-        ba += QString::fromStdString(a.uri()).toAscii() + ", " + QString::fromStdString(a.mimetype()).toAscii()+ ", " + 
-        QString::fromStdString(a.label()).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Attachment> &v)
-    {
-        QByteArray ba = "vector<Kolab::Attachment>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ "\n";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::ContactReference &a)
-    {
-        QByteArray ba = "Kolab::ContactReference(";
-        ba += QString::fromStdString(a.email()).toAscii()+ ", ";
-        ba += QString::fromStdString(a.name()).toAscii()+ ", ";
-        ba += QString::fromStdString(a.uid()).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::ContactReference> &v)
-    {
-        QByteArray ba = "vector<Kolab::ContactReference>(";
-        for (int i = 0; i < v.size(); i++) {
-                ba += QByteArray(toString(v.at(i)))+ "\n";
-            }
-            ba += ")";
-            return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Alarm &a)
-    {
-        QByteArray ba = "Kolab::Alarm(";
-        ba += QByteArray::number(a.type()) + "\n " + QString::fromStdString(a.summary()).toAscii()+ "\n " + 
-        QString::fromStdString(a.text()).toAscii()+"\n " +toString(a.duration()) + "\n " + QByteArray::number(a.numrepeat())+  "\n " + toString(a.start()) + "\n " +
-        toString(a.relativeStart())  + "\n " +  QByteArray::number(a.relativeTo()) + "\n " + toString(a.audioFile()) +  "\n " + toString(a.attendees()) + "\n ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Alarm> &v)
-    {
-        QByteArray ba = "vector<Kolab::Alarm>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ "\n";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Related &a)
-    {
-        QByteArray ba = "Kolab::Related(";
-        ba += QString::fromStdString(a.text()).toAscii()+ "\n " + 
-        QString::fromStdString(a.uri()).toAscii()+"\n " +
-        QByteArray::number(a.relationTypes()) + "\n " +
-        QByteArray::number(a.type()) + "\n ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Related> &v)
-    {
-        QByteArray ba = "vector<Kolab::Related>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ "\n";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Affiliation &a)
-    {
-        QByteArray ba = "Kolab::Affiliation(";
-        ba += QString::fromStdString(a.organisation()).toAscii()+ "\n " + 
-        QString::fromStdString(a.logo()).toAscii()+"\n " + "\n " + toString(a.roles())+  "\n " + toString(a.relateds()) + "\n " +
-        toString(a.addresses())  + "\n ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Affiliation> &v)
-    {
-        QByteArray ba = "vector<Kolab::Affiliation>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ "\n";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-
-
- }
- 
-#endif
- 
\ No newline at end of file
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
deleted file mode 100644
index 89f99a5..0000000
--- a/c++/tests/testfiles/icalEvent.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!--Copy of an example event from the xCal RFC-->
-<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0" >
-     <vcalendar>
-       <properties>
-         <prodid>
-           <text>-//Example Inc.//Example Client//EN</text>
-         </prodid>
-         <version>
-           <text>2.0</text>
-         </version>
-         <x-kolab-version > <!--xmlns="http://kolab.org"-->
-             <text>3.0dev1</text>
-         </x-kolab-version>
-       </properties>
-       <components>
-         <vevent>
-           <properties>
-             <uid>
-               <text>00959BC664CA650E933C892C at example.com</text>
-             </uid>
-             <created>
-               <date-time>2006-02-06T00:11:21Z</date-time>
-             </created>
-             <dtstamp>
-               <date-time>2006-02-06T00:11:21Z</date-time>
-             </dtstamp>
-             <dtstart>
-               <parameters>
-                 <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
-               </parameters>
-               <date-time>2006-01-02T12:00:00</date-time>
-             </dtstart>
-             <duration>
-               <duration>PT1H</duration>
-             </duration>
-             <rrule>
-               <recur>
-                 <freq>DAILY</freq>
-                 <count>5</count>
-               </recur>
-             </rrule>
-             <rdate>
-               <parameters>
-                 <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
-               </parameters>
-               <date-time>2007-02-06T00:11:21</date-time>
-       <!--        <period>
-                 <start>2006-01-02T15:00:00</start>
-                 <duration>PT2H</duration>
-               </period>-->
-             </rdate>
-             <summary>
-               <text>Event #2</text>
-             </summary>
-             <description>
-               <text>Test.&#x0a;Test.
-Test.</text>
-             </description>
-
-           </properties>
-         </vevent>
-<!--         <vevent>
-           <properties>
-             <dtstamp>
-               <date-time>2006-02-06T00:11:21Z</date-time>
-             </dtstamp>
-             <dtstart>
-               <parameters>
-                 <tzid><text>Europe/Zurich</text></tzid>
-               </parameters>
-               <date-time>2006-01-04T14:00:00</date-time>
-             </dtstart>
-             <duration>
-               <duration>PT1H</duration>
-             </duration>
-             <recurrence-id>
-               <parameters>
-                 <tzid><text>Europe/Zurich</text></tzid>
-               </parameters>
-               <date-time>2006-01-04T12:00:00</date-time>
-             </recurrence-id>
-             <summary>
-               <text>Event #2 bis</text>
-             </summary>
-
-           </properties>
-           <components/>
-         </vevent>-->
-       </components>
-     </vcalendar>
-</icalendar>
diff --git a/c++/tests/testfiles/testevent.xml b/c++/tests/testfiles/testevent.xml
deleted file mode 100644
index dd59990..0000000
--- a/c++/tests/testfiles/testevent.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<vevent xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
-
-  <properties>
-    <dtstart>
-      <date>2011-11-10+10:10</date>
-    </dtstart>
-    <rrule>
-      <recur>
-        <freq>DAILY</freq>
-        <count>2</count>
-        <byhour>3</byhour>
-      </recur>
-    </rrule>
-    <x-prop>
-        <parameters>
-        <pref><integer>1</integer></pref>
-        </parameters>                 <!-- Core vCard elements  -->
-        <text>value goes here</text>  <!-- are still accessible -->
-    </x-prop>
-
-  </properties>
-
-  <components/>
-
-</vevent>
diff --git a/c++/tests/testfiles/testkolabevent.xml b/c++/tests/testfiles/testkolabevent.xml
deleted file mode 100644
index e991846..0000000
--- a/c++/tests/testfiles/testkolabevent.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<kolab:event xmlns:kolab="http://kolab.org" xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
-
-  <vevent>
-    <properties>
-      <dtstart>
-        <date>2011-11-10+10:10</date>
-      </dtstart>
-      <rrule>
-        <recur>
-           <count>2</count>
-          <byhour>3</byhour>
-          <freq>DAILY</freq>
-          
-        </recur>
-      </rrule>
-      <x-custom-property>
-         <unknown>blabla</unknown>
-      </x-custom-property>       
-      <x-unknown-property>
-         <unknown>blibla</unknown>
-      </x-unknown-property>       
-    </properties>
-    <components>
-      <valarm/>
-    </components>
-  </vevent>
-
-</kolab:event>
diff --git a/libkolabxml/.gitignore b/libkolabxml/.gitignore
new file mode 100644
index 0000000..a007fea
--- /dev/null
+++ b/libkolabxml/.gitignore
@@ -0,0 +1 @@
+build/*
diff --git a/libkolabxml/CMakeLists.txt b/libkolabxml/CMakeLists.txt
new file mode 100644
index 0000000..c76f992
--- /dev/null
+++ b/libkolabxml/CMakeLists.txt
@@ -0,0 +1,127 @@
+project(kolabxmlbindings)
+
+cmake_minimum_required(VERSION 2.6)
+
+# only available from cmake-2.8.0
+if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7)
+    cmake_policy(SET CMP0012 NEW)
+endif()
+
+# only available from cmake-2.8.4
+if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND
+    ${CMAKE_PATCH_VERSION} GREATER 3)
+    cmake_policy(SET CMP0017 NEW)
+endif()
+
+include( ../cmake/modules/FindKolabInternal.cmake )
+
+find_package(Boost COMPONENTS thread REQUIRED)
+
+if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
+    find_library(UUID NAMES uuid)
+    if(UUID)
+        message("uuid found")
+    else (UUID)
+        message(FATAL_ERROR "uuid NOT found!")
+    endif(UUID)
+endif()
+
+find_package(Qt4)
+find_program( XSDCXX xsdcxx /usr/bin/)
+if(XSDCXX)
+    message("xsd code generator found")
+else (XSDCXX)
+    message(FATAL_ERROR
+    "xsd code generator NOT found!")
+endif(XSDCXX)
+
+find_library(XERCES_C NAMES xerces-c xerces-c_2)
+if(XERCES_C)
+    message("xerces found")
+else (XERCES_C)
+    message(FATAL_ERROR
+    "xerces NOT found!")
+endif(XERCES_C)
+
+find_program(SWIG swig /usr/bin/)
+if(SWIG)
+    set(SWIG_FOUND ON)
+    message("SWIG found")
+endif(SWIG)
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
+
+# set( CMAKE_VERBOSE_MAKEFILE on )
+
+set(CMAKE_BUILD_TYPE Debug)
+
+set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
+file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
+
+set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
+
+# Generate bindings
+
+set( SCHEMAS
+    ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd
+    ${SCHEMA_DIR}/ical/iCalendar-params.xsd
+    ${SCHEMA_DIR}/ical/iCalendar-props.xsd
+    ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+    ${SCHEMA_DIR}/xCard.xsd
+    ${SCHEMA_DIR}/kolabformat-xcard.xsd
+    ${SCHEMA_DIR}/kolabformat.xsd
+)
+
+set( SCHEMA_SOURCEFILES  
+    ${CMAKE_BUILD_DIR}/bindings/kolabformat.cxx
+    ${CMAKE_BUILD_DIR}/bindings/xCard.cxx
+    ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcal.cxx
+    ${CMAKE_BUILD_DIR}/bindings/kolabformat-xcard.cxx
+    ${CMAKE_BUILD_DIR}/bindings/iCalendar-params.cxx
+    ${CMAKE_BUILD_DIR}/bindings/iCalendar-props.cxx
+    ${CMAKE_BUILD_DIR}/bindings/iCalendar-valtypes.cxx
+#     bindings/iCalendar-link-extension.cxx
+#     bindings/iCalendar-bw-extensions.cxx
+#     bindings/iCalendar-ms-extensions.cxx
+)
+
+#xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd
+# --generate-inline --extern-xml-schema xml-schema.xsd
+# --cxx-suffix .cpp --hxx-suffix .h   
+add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
+    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization  --namespace-map http://kolab.org=KolabXSD --root-element icalendar --root-element vcards --root-element note --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
+    COMMENT "Generating XSD bindings"
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    DEPENDS ${SCHEMAS}
+    VERBATIM
+    )
+
+# Compile Schemas
+add_executable(xsdbin compiled/xsdbin.cxx)
+target_link_libraries(xsdbin ${XERCES_C})
+
+
+
+add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
+    COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR} ${SCHEMAS}
+    COMMENT "Compiling Kolab XSD schema"
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    DEPENDS ${SCHEMAS} xsdbin
+    VERBATIM
+    )
+set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BUILD_DIR}/kolabformat-xcal-schema.cxx)
+
+# ---------
+
+SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
+
+include_directories( ./ )
+include_directories( compiled )
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+
+add_subdirectory(lib)
+if (${QT_FOUND})
+    add_subdirectory(tests)
+endif()
+
diff --git a/libkolabxml/Makefile.am b/libkolabxml/Makefile.am
new file mode 100644
index 0000000..be0206b
--- /dev/null
+++ b/libkolabxml/Makefile.am
@@ -0,0 +1,36 @@
+EXTRA_DIST = \
+	autogen.sh \
+	CMakeLists.txt \
+	Makefile.am \
+	README \
+	compiled/ \
+	compiled/grammar-input-stream.cxx \
+	compiled/grammar-input-stream.hxx \
+	compiled/README \
+	compiled/XMLParserWrapper.cpp \
+	compiled/XMLParserWrapper.h \
+	compiled/xsdbin.cxx \
+	lib/ \
+	$(wildcard lib/*.cpp) \
+	$(wildcard lib/*.h) \
+	lib/CMakeLists.txt \
+	lib/DEVELOPMENT \
+	lib/kolabcontainers.i \
+	lib/kolabformat.i \
+	lib/php/ \
+	lib/php/CMakeLists.txt \
+	lib/php/test.php \
+	lib/python/ \
+	lib/python/CMakeLists.txt \
+	lib/python/test.py \
+	tests/ \
+	$(wildcard tests/*.cpp) \
+	$(wildcard tests/*.h) \
+	tests/CMakeLists.txt \
+	tests/testfiles/ \
+	$(wildcard tests/testfiles/*.xml)
+
+all:
+	@rm -rf build/
+	@mkdir -p build/
+	@cd build/; cmake ..; make
diff --git a/libkolabxml/README b/libkolabxml/README
new file mode 100644
index 0000000..88b9c36
--- /dev/null
+++ b/libkolabxml/README
@@ -0,0 +1,22 @@
+Build with:
+
+$mkdir build
+$cd build
+$cmake ..
+$make
+
+
+Minimum requirements are:
+-cmake 2.6
+-boost >= 1.47
+-xerces-c >= 3.0
+-cxx >= 3.0 (http://www.codesynthesis.com/products/xsd/)
+
+For further features:
+-SWIG >= 2.0
+-QT >= 4.7
+-KCalCore/KDECore >= 4.7
+
+
+For further information see lib/DEVELOPMENT.
+
diff --git a/libkolabxml/autogen.sh b/libkolabxml/autogen.sh
new file mode 100755
index 0000000..8ed1fd5
--- /dev/null
+++ b/libkolabxml/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Rebuilds the entire foo in one go. One shot, one kill.
+
+rm -rf build/
+mkdir -p build
+cd build
+cmake ..
+make
diff --git a/libkolabxml/compiled/README b/libkolabxml/compiled/README
new file mode 100644
index 0000000..c2ff791
--- /dev/null
+++ b/libkolabxml/compiled/README
@@ -0,0 +1,20 @@
+Code needed to compile schemas so they can be embeeded into the binary.
+
+According to the xsd example in xsd/examples/cxx/tree/embedded/
+
+xsdbin.cxx
+  Tool for converting one or more XML Schema files to the compressed binary
+  representation. The output is written as a pair of C++ source files 
+  containing the array with the binary data. Use the --help option to see
+  the tool's usage information.
+
+library-schema.hxx
+library-schema.cxx
+  Binary representation of the library.xsd schema. These files are generated
+  by the xsdbin tool.
+
+grammar-input-stream.hxx
+grammar-input-stream.cxx
+  Input stream implementation with the special-purpose schema grammar 
+  decompression algorithm. It is used to load the binary schema representation
+  produced by the xsdbin tool.
diff --git a/libkolabxml/compiled/XMLParserWrapper.cpp b/libkolabxml/compiled/XMLParserWrapper.cpp
new file mode 100644
index 0000000..dffff8d
--- /dev/null
+++ b/libkolabxml/compiled/XMLParserWrapper.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "XMLParserWrapper.h"
+
+#include <memory>   // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include <boost/thread.hpp>
+
+#include "kolabformat-xcal-schema.hxx"
+#include "grammar-input-stream.hxx"
+
+XMLParserWrapper::XMLParserWrapper()
+:   ehp(eh),
+    parser(0),
+    gp(0)
+{
+    // We need to initialize the Xerces-C++ runtime because we
+    // are doing the XML-to-DOM parsing ourselves.
+    //
+    xercesc::XMLPlatformUtils::Initialize ();
+    init();
+}
+
+
+XMLParserWrapper::~XMLParserWrapper()
+{
+    delete parser;
+    delete gp;
+    xercesc::XMLPlatformUtils::Terminate ();
+
+}
+
+boost::thread_specific_ptr<XMLParserWrapper> ptr;
+
+XMLParserWrapper& XMLParserWrapper::inst()
+{
+    XMLParserWrapper *t = ptr.get();
+    if (!t) {
+        t = new XMLParserWrapper();
+        ptr.reset(t);
+    }
+    return *t;
+}
+
+
+void XMLParserWrapper::init()
+{
+    using namespace std;
+    
+    if (parser) {
+        return;
+    }
+    try
+    {
+        using namespace xercesc;
+        namespace xml = xsd::cxx::xml;
+        namespace tree = xsd::cxx::tree;
+        // Create and load the grammar pool.
+        //
+        MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+        gp = new XMLGrammarPoolImpl (mm);
+
+        try
+        {
+            grammar_input_stream is (iCalendar_schema, sizeof (iCalendar_schema));
+            gp->deserializeGrammars(&is);
+        }
+        catch(const XSerializationException& e)
+        {
+            cerr << "unable to load schema: " << xml::transcode<char> (e.getMessage ()) << endl;
+            return;
+        }
+
+        // Lock the grammar pool. This is necessary if we plan to use the
+        // same grammar pool in multiple threads (this way we can reuse the
+        // same grammar in multiple parsers). Locking the pool disallows any
+        // modifications to the pool, such as an attempt by one of the threads
+        // to cache additional schemas.
+        //
+        gp->lockPool ();
+
+        // Get an implementation of the Load-Store (LS) interface.
+        //
+        const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+        DOMImplementation* impl (
+        DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+    #if _XERCES_VERSION >= 30000
+
+        // Xerces-C++ 3.0.0 and later.
+        //
+        parser = impl->createLSParser (
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
+
+        DOMConfiguration* conf (parser->getDomConfig ());
+
+        // Discard comment nodes in the document.
+        //
+        conf->setParameter (XMLUni::fgDOMComments, false);
+
+        // Enable datatype normalization.
+        //
+        conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+        // Do not create EntityReference nodes in the DOM tree. No
+        // EntityReference nodes will be created, only the nodes
+        // corresponding to their fully expanded substitution text
+        // will be created.
+        //
+        conf->setParameter (XMLUni::fgDOMEntities, false);
+
+        // Perform namespace processing.
+        //
+        conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+        // Do not include ignorable whitespace in the DOM tree.
+        //
+        conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+        // Enable validation.
+        //
+        conf->setParameter (XMLUni::fgDOMValidate, true);
+        conf->setParameter (XMLUni::fgXercesSchema, true);
+        conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+        // Xerces-C++ 3.1.0 is the first version with working multi import
+        // support.
+        //
+    #if _XERCES_VERSION >= 30100
+        conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+    #endif
+
+        // Use the loaded grammar during parsing.
+        //
+        conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+        // Disable loading schemas via other means (e.g., schemaLocation).
+        //
+        conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+        // We will release the DOM document ourselves.
+        //
+        conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+        
+        
+
+        // Set error handler.
+        //
+//         tree::error_handler<char> eh;
+//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
+        conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
+
+    #else // _XERCES_VERSION >= 30000
+
+        // Same as above but for Xerces-C++ 2 series.
+        //
+        parser = impl->createDOMBuilder(
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
+
+
+        parser->setFeature (XMLUni::fgDOMComments, false);
+        parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+        parser->setFeature (XMLUni::fgDOMEntities, false);
+        parser->setFeature (XMLUni::fgDOMNamespaces, true);
+        parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+        parser->setFeature (XMLUni::fgDOMValidation, true);
+        parser->setFeature (XMLUni::fgXercesSchema, true);
+        parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+        parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+        parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+        //tree::error_handler<char> eh;
+//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
+        parser->setErrorHandler (&ehp);
+
+    #endif // _XERCES_VERSION >= 30000
+
+        // Parse XML documents.
+        //
+        
+    }
+    catch (const xml_schema::exception& e) {
+        cout << "schema exception" << endl;
+        cerr << e << endl;
+    } catch (const std::ios_base::failure&) {
+        cerr << ": unable to open or read failure" << endl;
+    }
+    
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
+{
+    try {
+        std::ifstream ifs;
+        ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
+        ifs.open (url.c_str());
+        return parse(ifs, url);
+    } catch (const std::ios_base::failure&)
+    {
+        std::cerr << ": unable to open or read failure" << std::endl;
+    }
+    return xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument >();
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
+{
+    std::istringstream is(s);
+    return parse(is, ""); //TODO set identifier?
+}
+
+
+xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::istream &ifs, const std::string &name)
+{
+    using namespace std;
+
+    try
+    {
+        using namespace xercesc;
+        namespace xml = xsd::cxx::xml;
+        namespace tree = xsd::cxx::tree;
+
+        // Parse XML documents.
+        //
+        {
+            // Wrap the standard input stream.
+            //
+            xml::sax::std_input_source isrc (ifs, name);
+            Wrapper4InputSource wrap (&isrc, false);
+
+            // Parse XML to DOM.
+            //
+        #if _XERCES_VERSION >= 30000
+            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+        #else
+            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+        #endif
+
+            eh.throw_if_failed<xml_schema::parsing> ();
+            return doc;
+        }
+    }
+    catch (const xml_schema::exception& e)
+    {
+        cerr << "schema exception" << endl;
+        cerr << e << endl;
+    }
+    catch (const std::ios_base::failure&)
+    {
+        cerr << ": unable to open or read failure" << endl;
+    }
+    catch (...)
+    {
+        cerr << ": unknown exception thrown" << endl;
+    }
+    eh.reset();
+    return xml_schema::dom::auto_ptr<xercesc::DOMDocument>();
+}
\ No newline at end of file
diff --git a/libkolabxml/compiled/XMLParserWrapper.h b/libkolabxml/compiled/XMLParserWrapper.h
new file mode 100644
index 0000000..86a76c1
--- /dev/null
+++ b/libkolabxml/compiled/XMLParserWrapper.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef XMLPARSER_WRAPPER_H
+#define XMLPARSER_WRAPPER_H
+
+#include <string>
+#include <memory>
+#include <bindings/kolabformat-xcal.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+#include <boost/scoped_ptr.hpp>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/dom/DOMLSParser.hpp>
+#  include <xercesc/dom/DOMLSException.hpp>
+#else
+#  include <xercesc/dom/DOMBuilder.hpp>
+#endif
+
+#include <xercesc/framework/XMLGrammarPool.hpp>
+
+/**
+ * This wrapper controls the lifetime of the parser object.
+ * 
+ * Initializing the parser is much more expensive than parsing a single XML document, therefore the parser should be reused if possible.
+ * 
+ * It might make sense to use a singleton internally to keep the parser alive between usages. Alternatively this object can be kept alive for as long as it makes sense.
+ * 
+ * This class also encapsulates the initialization of the whole parser, which must be done manually because precomiled schemas are used (which greatly improves the initialization performance).
+ * 
+ * Writing the document is static and doesn't need any initialization and is therefore not wrapped by this object.
+ * 
+ */
+
+class XMLParserWrapper {
+public:
+    XMLParserWrapper();
+    ~XMLParserWrapper();
+    
+    /**
+     * Threadsafe singleton. One Xerces instance is created per thread (threadlocal).
+     * Access via singleton to reuse parser.
+     */
+    static XMLParserWrapper &inst();
+    
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
+private:
+    void init();
+    xsd::cxx::tree::error_handler<char> eh;
+    xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
+
+    #if _XERCES_VERSION >= 30000
+        xercesc::DOMLSParser  *parser;
+    #else
+        xercesc::DOMBuilder  *parser;
+    #endif
+    xercesc::XMLGrammarPool *gp;
+};
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libkolabxml/compiled/grammar-input-stream.cxx b/libkolabxml/compiled/grammar-input-stream.cxx
new file mode 100644
index 0000000..0c94ea6
--- /dev/null
+++ b/libkolabxml/compiled/grammar-input-stream.cxx
@@ -0,0 +1,115 @@
+// file      : examples/cxx/tree/embedded/grammar-input-stream.cxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+      : data_ (data),
+        size_ (size),
+        pos_ (0),
+        vpos_ (0),
+        cseq_ (0),
+        add_zero_ (false)
+{
+}
+
+#if _XERCES_VERSION >= 30000
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+  return static_cast<XMLFilePos> (vpos_);
+}
+#else
+unsigned int grammar_input_stream::
+curPos () const
+{
+  return static_cast<unsigned int> (vpos_);
+}
+#endif
+
+#if _XERCES_VERSION >= 30000
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+#else
+unsigned int grammar_input_stream::
+readBytes (XMLByte* const buf, const unsigned int size)
+#endif
+{
+  std::size_t i (0);
+
+  // Add a zero from the alternating sequence if it didn't
+  // fit on the previous read.
+  //
+  if (add_zero_)
+  {
+    buf[i++] = 0;
+    add_zero_ = false;
+  }
+
+  // If have an unfinished sequential sequence, output it now.
+  //
+  if (cseq_ != 0 && !alt_)
+  {
+    for (; cseq_ != 0 && i < size; --cseq_)
+      buf[i++] = 0;
+  }
+
+  for (; i < size && pos_ < size_;)
+  {
+    XMLByte b = buf[i++] = data_[pos_++];
+
+    // See if we are in a compression sequence.
+    //
+    if (cseq_ != 0)
+    {
+      if (i < size)
+        buf[i++] = 0;
+      else
+        add_zero_ = true; // Add it on the next read.
+
+      cseq_--;
+      continue;
+    }
+
+    // If we are not in a compression sequence and this byte is
+    // not zero then we are done.
+    //
+    if (b != 0)
+      continue;
+
+    // We have a zero.
+    //
+    assert (pos_ < size_); // There has to be another byte.
+    unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+    alt_ = (v & 128) != 0;
+    cseq_ = v & 127;
+
+    // If it is a sequential sequence, output as many zeros as
+    // we can.
+    //
+    if (!alt_)
+    {
+      for (; cseq_ != 0 && i < size; --cseq_)
+        buf[i++] = 0;
+    }
+  }
+
+  vpos_ += i;
+
+#if _XERCES_VERSION >= 30000
+  return static_cast<XMLSize_t> (i);
+#else
+  return static_cast<unsigned int> (i);
+#endif
+}
+
+#if _XERCES_VERSION >= 30000
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+  return 0;
+}
+#endif
diff --git a/libkolabxml/compiled/grammar-input-stream.hxx b/libkolabxml/compiled/grammar-input-stream.hxx
new file mode 100644
index 0000000..a1b73c6
--- /dev/null
+++ b/libkolabxml/compiled/grammar-input-stream.hxx
@@ -0,0 +1,53 @@
+// file      : examples/cxx/tree/embedded/grammar-input-stream.hxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef GRAMMAR_INPUT_STREAM_HXX
+#define GRAMMAR_INPUT_STREAM_HXX
+
+#include <cstddef>
+#include <xercesc/util/BinInputStream.hpp>
+
+// Memory buffer input stream with the special-purpose schema
+// grammar decompression.
+//
+class grammar_input_stream: public xercesc::BinInputStream
+{
+public :
+  grammar_input_stream (const XMLByte* data, std::size_t size);
+
+#if _XERCES_VERSION >= 30000
+
+  virtual XMLFilePos
+  curPos () const;
+
+  virtual XMLSize_t
+  readBytes (XMLByte* const buf, const XMLSize_t size);
+
+  virtual const XMLCh*
+  getContentType () const;
+
+#else
+
+  virtual unsigned int
+  curPos () const;
+
+  virtual unsigned int
+  readBytes (XMLByte* const buf, const unsigned int size);
+
+#endif
+
+private :
+  const XMLByte* data_;
+  std::size_t size_;
+  std::size_t pos_;
+  std::size_t vpos_;
+
+  // Compression data.
+  //
+  size_t cseq_;   // Number of bytes left in a compression sequence.
+  bool alt_;      // Alternating or sequential sequence.
+  bool add_zero_; // Add a zero on the next read.
+};
+
+#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/libkolabxml/compiled/xsdbin.cxx b/libkolabxml/compiled/xsdbin.cxx
new file mode 100644
index 0000000..53e2533
--- /dev/null
+++ b/libkolabxml/compiled/xsdbin.cxx
@@ -0,0 +1,505 @@
+// file      : examples/cxx/tree/embedded/xsdbin.cxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// This program loads the XML Schema file(s) and converts them to
+// the Xerces-C++ binary schema format which can then be embedded
+// into C++ programs and used to validate XML documents. The output
+// is written as a C++ source file containing the array with the
+// binary data.
+//
+
+#include <string>
+#include <memory>   // std::auto_ptr
+#include <cstddef>  // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XercesVersion.hpp>
+
+#include <xercesc/internal/BinMemOutputStream.hpp>
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+using namespace std;
+using namespace xercesc;
+
+class error_handler: public ErrorHandler
+{
+public:
+  error_handler ()
+      : failed_ (false)
+  {
+  }
+
+  bool
+  failed () const
+  {
+    return failed_;
+  }
+
+  enum severity {s_warning, s_error, s_fatal};
+
+  virtual void
+  warning (const SAXParseException&);
+
+  virtual void
+  error (const SAXParseException&);
+
+  virtual void
+  fatalError (const SAXParseException&);
+
+  virtual void
+  resetErrors ()
+  {
+    failed_ = false;
+  }
+
+  void
+  handle (const SAXParseException&, severity);
+
+private:
+  bool failed_;
+};
+
+void
+cxx_escape (string&);
+
+int
+main (int argc, char* argv[])
+{
+  const char* hxx_suffix = "-schema.hxx";
+  const char* cxx_suffix = "-schema.cxx";
+
+  string name;
+  string base;
+  string outdir;
+
+  class usage {};
+
+  int argi (1);
+  bool help (false);
+  bool multi_import (true);
+  bool verbose (false);
+
+  try
+  {
+    for (; argi < argc; ++argi)
+    {
+      string a (argv[argi]);
+
+      if (a == "--help")
+      {
+        help = true;
+        throw usage ();
+      }
+      else if (a == "--verbose")
+      {
+        verbose = true;
+      }
+      else if (a == "--hxx-suffix")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        hxx_suffix = argv[argi];
+      }
+      else if (a == "--cxx-suffix")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        cxx_suffix = argv[argi];
+      }
+      else if (a == "--output-dir")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        outdir = argv[argi];
+      }
+      else if (a == "--array-name")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        name = argv[argi];
+      }
+      else if (a == "--disable-multi-import")
+      {
+        multi_import = false;
+      }
+      else
+        break;
+    }
+
+    if (argi >= argc)
+    {
+      cerr << "no input file specified" << endl;
+      throw usage ();
+    }
+
+    base = argv[argi];
+  }
+  catch (usage const&)
+  {
+    cerr << "Usage: " << argv[0] << " [options] <files>" << endl
+         << "Options:" << endl
+         << "  --help                 Print usage information and exit." << endl
+         << "  --verbose              Print progress information." << endl
+         << "  --output-dir <dir>     Write generated files to <dir>." << endl
+         << "  --hxx-suffix <sfx>     Header file suffix instead of '-schema.hxx'." << endl
+         << "  --cxx-suffix <sfx>     Source file suffix instead of '-schema.cxx'." << endl
+         << "  --array-name <name>    Binary data array name." << endl
+         << "  --disable-multi-import Disable multiple import support." << endl
+         << endl;
+
+    return help ? 0 : 1;
+  }
+
+  XMLPlatformUtils::Initialize ();
+
+  {
+    MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+    auto_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
+
+    // Load the schemas into grammar pool.
+    //
+    {
+      auto_ptr<SAX2XMLReader> parser (
+        XMLReaderFactory::createXMLReader (mm, gp.get ()));
+
+      parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+      parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+      parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
+      parser->setFeature (XMLUni::fgXercesSchema, true);
+      parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true);
+      parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+      // Xerces-C++ 3.1.0 is the first version with working multi import
+      // support.
+      //
+#if _XERCES_VERSION >= 30100
+      parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import);
+#endif
+
+      error_handler eh;
+      parser->setErrorHandler (&eh);
+
+      for (; argi < argc; ++argi)
+      {
+        if (verbose)
+          cerr << "loading " << argv[argi] << endl;
+
+        if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true))
+        {
+          cerr << argv[argi] << ": error: unable to load" << endl;
+          return 1;
+        }
+
+        if (eh.failed ())
+          return 1;
+      }
+    }
+
+    // Get the binary representation.
+    //
+    BinMemOutputStream data;
+
+    try
+    {
+      gp->serializeGrammars (&data);
+    }
+    catch (const XSerializationException& e)
+    {
+      char* msg (XMLString::transcode (e.getMessage ()));
+      cerr << "error: " << msg << endl;
+      XMLString::release (&msg);
+      return 1;
+    }
+
+    size_t n (static_cast<size_t> (data.curPos ()));
+    const unsigned char* buf (
+      static_cast<const unsigned char*> (data.getRawBuffer ()));
+
+    if (verbose)
+      cerr << "uncomressed data size " << n << " bytes" << endl;
+
+    // Compress zeros.
+    //
+    size_t cn (0);
+    unsigned char* cbuf = new unsigned char[n];
+
+    size_t cseq (0);  // Number of bytes left in a compression sequence.
+    bool alt (false); // Alternating or sequential sequence.
+
+    for (size_t i (0); i < n;)
+    {
+      unsigned char v (buf[i++]);
+
+      // See if we are in a compression sequence.
+      //
+      if (cseq != 0)
+      {
+        // See if this byte needs to be copied.
+        //
+        if (alt && cseq % 2 == 0)
+          cbuf[cn++] = v;
+
+        cseq--;
+        continue;
+      }
+
+      // If we are not in a compression sequence and this byte is
+      // not zero then simply copy it.
+      //
+      if (v != 0)
+      {
+        cbuf[cn++] = v;
+        continue;
+      }
+
+      // We have a zero.
+      //
+      cbuf[cn++] = 0;
+
+      // See if we can start a new compression sequence.
+      //
+      if (i < n)
+      {
+        if (buf[i] == 0)
+        {
+          // Sequential sequence. See how far it runs.
+          //
+          alt = false;
+
+          for (cseq = 1; cseq < 127 && cseq + i < n; cseq++)
+            if (buf[cseq + i] != 0)
+              break;
+        }
+        else if (i + 1 < n && buf[i + 1] == 0)
+        {
+          // Alternating sequence. See how far it runs.
+          //
+          alt = true;
+
+          for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++)
+          {
+            if (buf[cseq * 2 + i + 1] != 0)
+              break;
+
+            // For longer sequences prefer sequential to alternating.
+            //
+            if (cseq > 2 &&
+                buf[cseq * 2 + i] == 0 &&
+                buf[(cseq - 1) * 2 + i] == 0 &&
+                buf[(cseq - 2) * 2 + i] == 0)
+            {
+              cseq -= 2;
+              break;
+            }
+          }
+
+          cseq *= 2;
+        }
+      }
+
+      if (cseq != 0)
+      {
+        cbuf[cn++] = static_cast<unsigned char> (
+          alt ? (128  | cseq / 2) : cseq);
+      }
+      else
+        cbuf[cn++] = 0;
+    }
+
+    if (verbose)
+      cerr << "comressed data size " << cn << " bytes" << endl;
+
+    buf = cbuf;
+    n = cn;
+
+    // Figure out the file names.
+    //
+    string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\'));
+
+    if (p1 != string::npos && p1 > p)
+      p = p1;
+
+    if (p != string::npos)
+      base = string (base, p + 1);
+
+    p = base.rfind ('.');
+
+    if (p != string::npos)
+      base.resize (p);
+
+    string hxx (base + hxx_suffix);
+    string cxx (base + cxx_suffix);
+
+    if (!outdir.empty ())
+    {
+#if defined (WIN32) || defined (__WIN32__)
+      hxx = outdir + '\\' + hxx;
+      cxx = outdir + '\\' + cxx;
+#else
+      hxx = outdir + '/' + hxx;
+      cxx = outdir + '/' + cxx;
+#endif
+    }
+
+    if (name.empty ())
+    {
+      name = base + "_schema";
+      cxx_escape (name);
+    }
+
+    // Write header.
+    //
+    {
+      ofstream os (hxx.c_str ());
+
+      if (!os.is_open ())
+      {
+        cerr << hxx << ": error: unable to open" << endl;
+        return 1;
+      }
+
+      os << "// Automatically generated. Do not edit." << endl
+         << "//" << endl
+         << endl
+         << "#include <xercesc/util/XercesDefs.hpp>" << endl
+         << endl
+         << "extern const XMLByte " << name << "[" << n << "UL];" << endl;
+    }
+
+    {
+      ofstream os (cxx.c_str ());
+
+      if (!os.is_open ())
+      {
+        cerr << cxx << ": error: unable to open" << endl;
+        return 1;
+      }
+
+      os << "// Automatically generated. Do not edit." << endl
+         << "//" << endl
+         << endl
+         << "#include <xercesc/util/XercesDefs.hpp>" << endl
+         << "#include <xercesc/util/XercesVersion.hpp>" << endl
+         << endl
+         << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " <<
+        XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl
+         << "#  error incompatible Xerces-C++ version detected" << endl
+         << "#endif" << endl
+         << endl
+         << "extern const XMLByte " << name << "[" << n << "UL] =" << endl
+         << "{";
+
+      for (size_t i (0); i < n; ++i)
+      {
+        if (i != 0)
+          os << ',';
+
+        os << (i % 12 == 0 ? "\n  " : " ") << "0x";
+        os.width (2);
+        os.fill ('0');
+        os << hex << static_cast<unsigned short> (buf[i]);
+      }
+
+      os << endl
+         << "};" << endl
+         << endl;
+    }
+
+    delete[] cbuf;
+  }
+
+  XMLPlatformUtils::Terminate ();
+}
+
+void
+cxx_escape (string& s)
+{
+  for (string::size_type i (0); i < s.size (); ++i)
+  {
+    char& c (s[i]);
+
+    if (i == 0)
+    {
+      if (!((c >= 'a' && c <= 'z') ||
+            (c >= 'A' && c <= 'Z') ||
+            c == '_'))
+        c = '_';
+    }
+    else
+    {
+      if (!((c >= 'a' && c <= 'z') ||
+            (c >= 'A' && c <= 'Z') ||
+            (c >= '0' && c <= '9') ||
+            c == '_'))
+        c = '_';
+    }
+  }
+}
+
+void error_handler::
+warning (const SAXParseException& e)
+{
+  handle (e, s_warning);
+}
+
+void error_handler::
+error (const SAXParseException& e)
+{
+  failed_ = true;
+  handle (e, s_error);
+}
+
+void error_handler::
+fatalError (const SAXParseException& e)
+{
+  failed_ = true;
+  handle (e, s_fatal);
+}
+
+void error_handler::
+handle (const SAXParseException& e, severity s)
+{
+  const XMLCh* xid (e.getPublicId ());
+
+  if (xid == 0)
+    xid = e.getSystemId ();
+
+  char* id (XMLString::transcode (xid));
+  char* msg (XMLString::transcode (e.getMessage ()));
+
+  cerr << id << ":";
+
+#if _XERCES_VERSION >= 30000
+  cerr << e.getLineNumber () << ":" << e.getColumnNumber () << " ";
+#else
+  XMLSSize_t l (e.getLineNumber ());
+  XMLSSize_t c (e.getColumnNumber ());
+  cerr << (l == -1 ? 0 : l) << ":" << (c == -1 ? 0 : c) << " ";
+#endif
+
+  cerr << (s == s_warning ? "warning: " : "error: ") << msg << endl;
+
+  XMLString::release (&id);
+  XMLString::release (&msg);
+}
diff --git a/libkolabxml/lib/CMakeLists.txt b/libkolabxml/lib/CMakeLists.txt
new file mode 100644
index 0000000..90f31f0
--- /dev/null
+++ b/libkolabxml/lib/CMakeLists.txt
@@ -0,0 +1,52 @@
+
+SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wp,-D_FORTIFY_SOURCE=2 -O2" ) #always generate shared libraries with -fPIC, -D_FORTIFY_SOURCE=2 enables some extra checking
+
+#Library with serialization/deserialization code and kolab-containers
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabnote.cpp kolabevent.cpp kolabtodo.cpp kolabjournal.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+
+target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID})
+
+#For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
+set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wl,--no-undefined")
+set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
+
+install(TARGETS kolabxml ${KOLAB_INSTALL_DIRECTORIES})
+
+install( FILES
+    kolabformat.h
+    kolabevent.h
+    kolabtodo.h
+    kolabjournal.h
+    kolabcontact.h
+    kolabnote.h
+    kolabcontainers.h
+    global_definitions.h
+    DESTINATION ${KOLAB_HEADER_INSTALL_DIR} COMPONENT Devel)
+
+#----- The following makes sure libkolabxml is found in the install directory for installed files and not in the build directory (for libraries which link to libkolabxml)
+
+# use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
+# when building, don't use the install RPATH already(but later on when installing)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
+SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
+# add the automatically determined parts of the RPATH
+# which point to directories outside the build tree to the install RPATH
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+# the RPATH to be used when installing, but only if it's not a system directory
+LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${KOLAB_LIB_INSTALL_DIR}" isSystemDir)
+IF("${isSystemDir}" STREQUAL "-1")
+   SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
+ENDIF("${isSystemDir}" STREQUAL "-1")
+
+#-----------------------SWIG--------------------
+
+if (SWIG_FOUND)
+    add_subdirectory(python)
+    add_subdirectory(php)
+else()
+    message(WARNING "Could not build SWIG bindings, because SWIG is missing.")
+endif()
+
diff --git a/libkolabxml/lib/DEVELOPMENT b/libkolabxml/lib/DEVELOPMENT
new file mode 100644
index 0000000..d6730e1
--- /dev/null
+++ b/libkolabxml/lib/DEVELOPMENT
@@ -0,0 +1,104 @@
+== General Design Notes==
+
+* Although many values are optional, the library doesn't differentiate between set and not set values. The approach taken is to not write out values which are still on the default value in order to keep objects small.
+The downside of this is that an xml object could be modified although no values have been modified (because default values are not written out again).
+
+== Libraries ==
+
+=== libkolabxml ===
+Dependencies:
+* boost
+* xerces
+
+The core library providing the xml-serialization functions and containers for all types.
+
+=== libkolabkcal ===
+Dependencies:
+* libkolabxml
+* kcalcore
+* kdecore
+
+Library to provide converters to KCalCore containers as well as advanced functionality from KCalCore (such as expansion of recurrences) through SWIG bindings.
+
+=== kolabxmlkcal (deprecated) ===
+
+First approach which does a direct mapping from xml to KCalCore containers. 
+It turned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
+Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend.
+
+== Code architecture ==
+
+Care was taken to implement each conversion/mapping only once. The code makes heavy use of templates to achieve this.
+Due to the different formats the conversion functions were split up among formats (not much to share between those).
+
+xCal: genericxcalconversions.h, xcalconversions.h (genericxcalconversions are implementations which work for both Kolab Containers and KCalCore containers)
+xCard: kolabxcardconversions.h
+kolab: kolabconversions.h (TODO)
+
+All conversions are typesafe as far as possible (i.e. a conversion from uint to int is always done through a numeric cast), to make sure there are no hard-to-track-down edge cases (such as an overflow).
+
+== Kolab Containers ==
+
+While SWIG can handle all possible return values, the resulting code uses either a newly allocated object (return by value / or return by const reference), or passes back a pointer (return by reference/pointer).
+So return by const reference doesn't save anything for the bindings (it could potentially for c++ code).
+Returning references contains the danger of dangling pointers if the reference outlives the object.
+
+Datamembers are not directly exposed to provide binary compatibilty through the d-pointer.
+
+Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value).
+
+Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
+
+The containers do not use inheritance to ensure maximum compatibilty with SWIG (although SWIG provides inheritance for some languages).
+They were also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur.
+
+The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
+
+The validity of the containers can be checked using the isValid() function. This function is used to check if a value has been set, and does not really verifiy the validity of the values in terms of what ranges/combinations are allowed.
+
+=== Why KCalCore containers were not directly used ===
+
+KCalCore provides containers for all ical based functionality (events/todos/journals).
+
+They were not directly used because:
+- dependencies: depends on kdelibs and qt (event qt gui). Some serious work would be needed to be able to ship those containers with a minimum set of dependencies.
+- SWIG: It seems difficult to properly wrap those containers using SWIG (inheritance heavily used, Qt containers (for which we have no bindings), not easily copiable (special copy memberfucntion is needed due to internal use of pointers))
+- Consistency: because we anyways have containers out of the scope of KCalCore, we can provide this way a consistent interface, which represents exactly the Kolab defined functionality (while KCalCore would be a close, but not a perfect match).
+
+Overall using our own containers seems like the safer and more flexible approach. This way it's also possible to provide a reading/writing library with a minimum set of dependencies.
+
+== SWIG language bindings ==
+
+Bindings for PHP and Python are provided through SWIG.
+
+"make install" produces two directories with the necessary files in build/lib/pythonbindings and build/lib/phpbindings.
+The test script should show the usage of the bindings.
+
+== Performance ==
+
+The biggest performance hog is the initialization of the parser. First, when loading the schema from disk upon initialization, parsing a single file took ~16ms on my machine (just for comparison).
+After compiling the schema to a binary representation, it still took ~7ms. By reusing the parser it went down to ~0.35ms.
+
+Writing the files is not validating and therefore always fast (doesn't need a special parser or alike). Once the parser is initialized, reading is roughly as fast as writing.
+
+Currently the parser is kept in a singleton (XMLParserWrapper).
+Alternatively one could control the lifetime from the bindings through an initialization object which keeps the parser alive through a shared pointer. This way the parser could be initialized on demand and the memory used by the parser could be freed between runs. 
+
+For further performance improvements read this: http://xerces.apache.org/xerces2-j/faq-performance.html
+
+== Error Handling ==
+
+All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that.
+If an error occurs a message is printed to the standard error output and a default constructed value is returned.
+
+Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
+
+
+
+=== The XSD based development checklist ===
+-Don't forget to add an element for each attribute in the style off: <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
+ Otherwise you won't get the serialization/deserialization code (or respectively just wrong code), which still compiles though and looks correct from the outside.
+
+-If you have modified the xsd's make sure to run "make clean && make" in the toplevel make directory, otherwise the schema is not recompiles => parsing errors
+
+-Make sure you add new .xsd to the compiled schemas, otherwise you'll get "no declaration found" errors.
diff --git a/libkolabxml/lib/base64.cpp b/libkolabxml/lib/base64.cpp
new file mode 100644
index 0000000..071b05c
--- /dev/null
+++ b/libkolabxml/lib/base64.cpp
@@ -0,0 +1,123 @@
+/* 
+   base64.cpp and base64.h
+
+   Copyright (C) 2004-2008 René Nyffenegger
+
+   This source code is provided 'as-is', without any express or implied
+   warranty. In no event will the author be held liable for any damages
+   arising from the use of this software.
+
+   Permission is granted to anyone to use this software for any purpose,
+   including commercial applications, and to alter it and redistribute it
+   freely, subject to the following restrictions:
+
+   1. The origin of this source code must not be misrepresented; you must not
+      claim that you wrote the original source code. If you use this source code
+      in a product, an acknowledgment in the product documentation would be
+      appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+      misrepresented as being the original source code.
+
+   3. This notice may not be removed or altered from any source distribution.
+
+   René Nyffenegger rene.nyffenegger at adp-gmbh.ch
+
+*/
+
+#include "base64.h"
+#include <iostream>
+
+static const std::string base64_chars = 
+             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+             "abcdefghijklmnopqrstuvwxyz"
+             "0123456789+/";
+
+
+static inline bool is_base64(unsigned char c) {
+  return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
+  std::string ret;
+  int i = 0;
+  int j = 0;
+  unsigned char char_array_3[3];
+  unsigned char char_array_4[4];
+
+  while (in_len--) {
+    char_array_3[i++] = *(bytes_to_encode++);
+    if (i == 3) {
+      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+      char_array_4[3] = char_array_3[2] & 0x3f;
+
+      for(i = 0; (i <4) ; i++)
+        ret += base64_chars[char_array_4[i]];
+      i = 0;
+    }
+  }
+
+  if (i)
+  {
+    for(j = i; j < 3; j++)
+      char_array_3[j] = '\0';
+
+    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+    char_array_4[3] = char_array_3[2] & 0x3f;
+
+    for (j = 0; (j < i + 1); j++)
+      ret += base64_chars[char_array_4[j]];
+
+    while((i++ < 3))
+      ret += '=';
+
+  }
+
+  return ret;
+
+}
+
+std::string base64_decode(std::string const& encoded_string) {
+  int in_len = encoded_string.size();
+  int i = 0;
+  int j = 0;
+  int in_ = 0;
+  unsigned char char_array_4[4], char_array_3[3];
+  std::string ret;
+
+  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
+    char_array_4[i++] = encoded_string[in_]; in_++;
+    if (i ==4) {
+      for (i = 0; i <4; i++)
+        char_array_4[i] = base64_chars.find(char_array_4[i]);
+
+      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+      for (i = 0; (i < 3); i++)
+        ret += char_array_3[i];
+      i = 0;
+    }
+  }
+
+  if (i) {
+    for (j = i; j <4; j++)
+      char_array_4[j] = 0;
+
+    for (j = 0; j <4; j++)
+      char_array_4[j] = base64_chars.find(char_array_4[j]);
+
+    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
+  }
+
+  return ret;
+}
\ No newline at end of file
diff --git a/libkolabxml/lib/base64.h b/libkolabxml/lib/base64.h
new file mode 100644
index 0000000..5f87aec
--- /dev/null
+++ b/libkolabxml/lib/base64.h
@@ -0,0 +1,5 @@
+#include <string>
+
+std::string base64_encode(unsigned char const* , unsigned int len);
+std::string base64_decode(std::string const& s);
+
diff --git a/libkolabxml/lib/global_definitions.h b/libkolabxml/lib/global_definitions.h
new file mode 100644
index 0000000..2aa36e8
--- /dev/null
+++ b/libkolabxml/lib/global_definitions.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GLOBAL_DEFINITIONS_H
+#define GLOBAL_DEFINITIONS_H
+#include <string>
+
+namespace Kolab {
+
+const char* const KOLAB_LIBNAME = "libkolabxml";
+const char* const KOLAB_LIB_VERSION = "0.1";
+const char* const KOLAB_FORMAT_VERSION = "3.0dev1";
+
+enum ErrorSeverity {
+    NoError,
+    Warning, //Warning, error could be corrected, object can be used without dataloss
+    Error, //Potentially corrupt object, writing the object back could result in dataloss. (Object could still be used to display the data readonly).
+    Critical //Ciritcal error, produced object cannot be used and should be thrown away (writing back will result in dataloss).
+};
+
+}
+
+#endif
diff --git a/libkolabxml/lib/incidence_p.h b/libkolabxml/lib/incidence_p.h
new file mode 100644
index 0000000..5f2dc12
--- /dev/null
+++ b/libkolabxml/lib/incidence_p.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef INCIDENCE_P
+#define INCIDENCE_P
+
+#include "kolabcontainers.h"
+
+namespace Kolab {
+    
+    struct PrivateIncidence
+    {
+        PrivateIncidence()
+        : sequence(0),
+        classification(ClassPublic),
+        thisAndFuture(false),
+        priority(0),
+        status(StatusUndefined){}
+        
+        std::string uid;
+        cDateTime created;
+        cDateTime lastModified;
+        int sequence;
+        Classification classification;
+        std::vector< std::string > categories;
+        std::vector< std::string > relatedTo;
+        cDateTime start;
+        
+        cDateTime recurrenceID;
+        bool thisAndFuture;
+        std::string summary;
+        std::string description;
+        std::string location;
+        int priority;
+        Status status;
+        RecurrenceRule rrule;
+        std::vector< cDateTime > recurrenceDates;
+        std::vector< cDateTime > exceptionDates;
+        ContactReference organizer;
+        Duration duration;
+        
+        std::vector<Attendee> attendees;
+        std::vector<Attachment> attachments;
+        std::vector<CustomProperty> customProperties;
+        
+        std::vector<Alarm> alarms;
+    };
+    
+}
+
+#endif
\ No newline at end of file
diff --git a/libkolabxml/lib/kolabcontact.cpp b/libkolabxml/lib/kolabcontact.cpp
new file mode 100644
index 0000000..a959a2c
--- /dev/null
+++ b/libkolabxml/lib/kolabcontact.cpp
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabcontact.h"
+
+namespace Kolab {
+    
+struct DistList::Private
+{
+    Private() {}
+    
+    std::string uid;
+    cDateTime lastModified;
+    std::vector< std::string > categories;
+    
+    std::string name;
+    std::vector<ContactReference> members;
+    std::vector<CustomProperty> customProperties;
+};
+    
+DistList::DistList()
+: d(new DistList::Private())
+{
+    
+}
+
+DistList::DistList(const DistList &other)
+: d(new DistList::Private())
+{
+    *d = *other.d;
+}
+
+DistList::~DistList()
+{
+    
+}
+
+void DistList::operator=(const Kolab::DistList &other)
+{
+    *d = *other.d;
+}
+
+bool DistList::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void DistList::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string DistList::uid() const
+{
+    return d->uid;
+}
+
+void DistList::setLastModified(const Kolab::cDateTime &dt)
+{
+    d->lastModified = dt;
+}
+
+cDateTime DistList::lastModified() const
+{
+    return d->lastModified;
+}
+
+void DistList::setName(const std::string &name)
+{
+    d->name = name;
+}
+
+std::string DistList::name() const
+{
+    return d->name;
+}
+
+void DistList::setMembers(const std::vector< ContactReference > &members)
+{
+    d->members = members;
+}
+
+std::vector< ContactReference > DistList::members() const
+{
+    return d->members;
+}
+
+void DistList::setCustomProperties(const std::vector< CustomProperty >& c)
+{
+    d->customProperties = c;
+}
+
+std::vector< CustomProperty > DistList::customProperties() const
+{
+    return d->customProperties;
+}
+
+
+
+
+
+    
+struct Contact::Private
+{
+    Private()
+    :  addressPreferredIndex(-1),
+    gender(NotSet),
+    telephonesPreferredIndex(-1),
+    imAddressPreferredIndex(-1),
+    emailAddressPreferredIndex(-1)
+    {}
+    
+    std::string uid;
+    cDateTime created;
+    cDateTime lastModified;
+    std::vector< std::string > categories;
+    
+    std::string name;
+    NameComponents nameComponents;
+    std::string note;
+    std::string freeBusyUrl;
+    std::vector< std::string > titles;
+    std::vector<Affiliation> affiliations;
+    std::vector<std::string> urls;
+    std::vector<Address> addresses;
+    int addressPreferredIndex;
+    std::vector<std::string> nickNames;
+    std::vector<Related> relateds;
+    cDateTime bDay;
+    cDateTime anniversary;
+    std::string photo;
+    std::string photoMimetype;
+    Gender gender;
+    std::vector<std::string> languages;
+    std::vector<Telephone> telephones;
+    int telephonesPreferredIndex;
+    std::vector<std::string> imAddresses;
+    int imAddressPreferredIndex;
+    std::vector<std::string> emailAddresses;
+    int emailAddressPreferredIndex;
+    std::vector<Geo> gpsPos;
+    Crypto crypto;
+    std::vector<CustomProperty> customProperties;
+};
+
+Contact::Contact()
+: d(new Contact::Private())
+{
+    
+}
+
+Contact::Contact(const Contact &other)
+: d(new Contact::Private())
+{
+    *d = *other.d;
+}
+
+Contact::~Contact()
+{
+    
+}
+
+void Contact::operator=(const Kolab::Contact &other)
+{
+    *d = *other.d;
+}
+
+bool Contact::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void Contact::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Contact::uid() const
+{
+    return d->uid;
+}
+
+void Contact::setLastModified(const Kolab::cDateTime &dt)
+{
+    d->lastModified = dt;
+}
+
+cDateTime Contact::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Contact::setCategories(const std::vector< std::string > &cat)
+{
+ d->categories = cat;
+}
+
+void Contact::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Contact::categories() const
+{
+    return d->categories;
+}
+
+void Contact::setName(const std::string &name)
+{
+    d->name = name;
+}
+
+std::string Contact::name() const
+{
+    return d->name;
+}
+
+void Contact::setNameComponents(const Kolab::NameComponents &nc)
+{
+    d->nameComponents = nc;
+}
+
+NameComponents Contact::nameComponents() const
+{
+    return d->nameComponents;
+}
+
+void Contact::setNote(const std::string &note)
+{
+    d->note = note;
+}
+
+std::string Contact::note() const
+{
+    return d->note;
+}
+
+void Contact::setFreeBusyUrl(const std::string &url)
+{
+    d->freeBusyUrl = url;
+}
+
+std::string Contact::freeBusyUrl() const
+{
+    return d->freeBusyUrl;
+}
+
+void Contact::setTitles(const std::vector< std::string >& titles)
+{
+    d->titles = titles;
+}
+
+std::vector< std::string > Contact::titles() const
+{
+    return d->titles;
+}
+
+
+void Contact::setAffiliations(const std::vector< Affiliation > &a)
+{
+    d->affiliations = a;
+}
+
+std::vector< Affiliation > Contact::affiliations() const
+{
+    return d->affiliations;
+}
+
+void Contact::setUrls(const std::vector< std::string > &urls)
+{
+    d->urls = urls;
+}
+
+std::vector< std::string > Contact::urls() const
+{
+    return d->urls;
+}
+
+void Contact::setAddresses(const std::vector< Address > &ad, int preferred)
+{
+    d->addresses = ad;
+    d->addressPreferredIndex = preferred;
+}
+
+std::vector< Address > Contact::addresses() const
+{
+    return d->addresses;
+}
+
+int Contact::addressPreferredIndex() const
+{
+    return d->addressPreferredIndex;
+}
+
+
+void Contact::setNickNames(const std::vector< std::string > &n)
+{
+    d->nickNames = n;
+}
+
+std::vector< std::string > Contact::nickNames() const
+{
+    return d->nickNames;
+}
+
+void Contact::setRelateds(const std::vector< Related > &relateds)
+{
+    d->relateds = relateds;
+}
+
+std::vector< Related > Contact::relateds() const
+{
+    return d->relateds;
+}
+
+void Contact::setBDay(const Kolab::cDateTime &bday)
+{
+    d->bDay = bday;
+}
+
+cDateTime Contact::bDay() const
+{
+    return d->bDay;
+}
+
+void Contact::setAnniversary(const Kolab::cDateTime& dt)
+{
+    d->anniversary = dt;
+}
+
+cDateTime Contact::anniversary() const
+{
+    return d->anniversary;
+}
+
+void Contact::setPhoto(const std::string& data, const std::string& mimetype)
+{
+    d->photo = data;
+    d->photoMimetype = mimetype;
+}
+
+std::string Contact::photo() const
+{
+    return d->photo;
+}
+
+std::string Contact::photoMimetype() const
+{
+    return d->photoMimetype;
+}
+
+void Contact::setGender(Contact::Gender g)
+{
+    d->gender = g;
+}
+
+Contact::Gender Contact::gender() const
+{
+    return d->gender;
+}
+
+void Contact::setLanguages(const std::vector< std::string >& l)
+{
+    d->languages = l;
+}
+
+std::vector< std::string > Contact::languages() const
+{
+    return d->languages;
+}
+
+void Contact::setTelephones(const std::vector< Telephone >& tel, int preferredIndex)
+{
+    d->telephonesPreferredIndex = preferredIndex;
+    d->telephones = tel;
+}
+
+std::vector< Telephone > Contact::telephones() const
+{
+    return d->telephones;
+}
+
+int Contact::telephonesPreferredIndex() const
+{
+    return d->telephonesPreferredIndex;
+}
+
+void Contact::setIMaddresses(const std::vector< std::string > &adr, int preferredIndex)
+{
+    d->imAddresses = adr;
+    d->imAddressPreferredIndex = preferredIndex;
+}
+
+std::vector< std::string > Contact::imAddresses() const
+{
+    return d->imAddresses;
+}
+
+int Contact::imAddressPreferredIndex() const
+{
+    return d->imAddressPreferredIndex;
+}
+
+void Contact::setEmailAddresses(const std::vector< std::string >& email, int preferredIndex)
+{
+    d->emailAddresses = email;
+    d->emailAddressPreferredIndex = preferredIndex;
+}
+
+std::vector< std::string > Contact::emailAddresses() const
+{
+    return d->emailAddresses;
+}
+
+int Contact::emailAddressPreferredIndex() const
+{
+    return d->emailAddressPreferredIndex;
+}
+
+void Contact::setGPSpos(const std::vector< Geo >& pos)
+{
+    d->gpsPos = pos;
+}
+
+std::vector< Geo > Contact::gpsPos() const
+{
+    return d->gpsPos;
+}
+
+void Contact::setCrypto(const Kolab::Crypto& c)
+{
+    d->crypto = c;
+}
+
+Crypto Contact::crypto() const
+{
+    return d->crypto;
+}
+
+void Contact::setCustomProperties(const std::vector< CustomProperty >& c)
+{
+    d->customProperties = c;
+}
+
+std::vector< CustomProperty > Contact::customProperties() const
+{
+    return d->customProperties;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+} //Namespace
+
diff --git a/libkolabxml/lib/kolabcontact.h b/libkolabxml/lib/kolabcontact.h
new file mode 100644
index 0000000..e4164dd
--- /dev/null
+++ b/libkolabxml/lib/kolabcontact.h
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABCONTACT_H
+#define KOLABCONTACT_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+
+namespace Kolab {
+    
+struct NameComponents {
+    bool operator==(const NameComponents &other) const { return mSurnames == other.mSurnames &&
+                                                        mGiven == other.mGiven &&
+                                                        mAdditional == other.mAdditional &&
+                                                        mPrefixes == other.mPrefixes &&
+                                                        mSuffixes == other.mSuffixes;
+                                                        };
+    void setSurnames(const std::vector<std::string> &s) { mSurnames = s; };
+    std::vector<std::string> surnames() const { return mSurnames; };
+    void setGiven(const std::vector<std::string> &s) { mGiven = s; };
+    std::vector<std::string> given() const { return mGiven; };
+    void setAdditional(const std::vector<std::string> &s) { mAdditional = s; };
+    std::vector<std::string> additional() const { return mAdditional; };
+    void setPrefixes(const std::vector<std::string> &s) { mPrefixes = s; };
+    std::vector<std::string> prefixes() const { return mPrefixes; };
+    void setSuffixes(const std::vector<std::string> &s) { mSuffixes = s; };
+    std::vector<std::string> suffixes() const { return mSuffixes; };
+    bool isValid() const { return !(mSurnames.empty() && mGiven.empty() && mAdditional.empty() && mPrefixes.empty() && mSuffixes.empty()); };
+private:
+    std::vector<std::string> mSurnames;
+    std::vector<std::string> mGiven;
+    std::vector<std::string> mAdditional;
+    std::vector<std::string> mPrefixes;
+    std::vector<std::string> mSuffixes;
+};
+
+struct Related {
+    
+    enum DescriptionType {
+        Invalid,
+        Text,
+        Uid
+    };
+    Related(): mType(Invalid), mRelationType(NoRelation) {};
+    Related(DescriptionType t, const std::string &textOrUri, int relationType = NoRelation)
+    :   mType(t), mRelationType(relationType)
+    {
+        if (t == Text) {
+            mText = textOrUri;
+        } else {
+            mUri = textOrUri;
+        }
+    };
+    bool operator==(const Related &other) const { return mType == other.mType &&
+    mUri == other.mUri &&
+    mText == other.mText &&
+    mRelationType == other.mRelationType;
+    };
+    DescriptionType type() const { return mType; };
+    std::string uri() const { return mUri; };
+    std::string text() const { return mText; };
+    enum RelationType {
+        NoRelation = 0,
+        Child = 0x01,
+        Spouse = 0x02,
+        Manager = 0x04,
+        Assistant = 0x08,
+    };
+    void setRelationTypes(int t) { mRelationType = t; };
+    int relationTypes() const { return mRelationType; };
+private:
+    DescriptionType mType;
+    std::string mUri;
+    std::string mText;
+    int mRelationType;
+};
+
+struct Address {
+    
+    Address(): mTypes(0) {};
+    enum Type {
+        Work = 0x01,
+        Home = 0x02
+    };
+    bool operator==(const Address &other) const { return mTypes == other.mTypes &&
+    mLabel == other.mLabel &&
+    mStreet == other.mStreet &&
+    mLocality == other.mLocality &&
+    mRegion == other.mRegion &&
+    mCode == other.mCode &&
+    mCountry == other.mCountry;
+    };
+    void setTypes(int t) { mTypes = t; };
+    int types() const { return mTypes; };
+    
+    void setLabel(const std::string &s) { mLabel = s; };
+    std::string label() const { return mLabel; }
+    
+    void setStreet(const std::string &s) { mStreet = s; };
+    std::string street() const { return mStreet; };
+    
+    void setLocality(const std::string &s) { mLocality = s; };
+    std::string locality() const { return mLocality; };
+    
+    void setRegion(const std::string &s) { mRegion = s; };
+    std::string region() const { return mRegion; };
+    
+    void setCode(const std::string &s) { mCode = s; };
+    std::string code() const { return mCode; };
+    
+    void setCountry(const std::string &s) { mCountry = s; };
+    std::string country() const { return mCountry; };
+private:
+    int mTypes;
+    std::string mLabel;
+    std::string mStreet;
+    std::string mLocality;
+    std::string mRegion;
+    std::string mCode;
+    std::string mCountry;
+};
+
+struct Affiliation {
+    bool operator==(const Affiliation &other) const { return mOrg == other.mOrg &&
+                                                    mOrgUnits == other.mOrgUnits &&
+                                                    mLogo == other.mLogo &&
+                                                    mLogoMimetype == other.mLogoMimetype &&
+                                                    mRoles == other.mRoles &&
+                                                    mRelateds == other.mRelateds &&
+                                                    mOffices == other.mOffices;
+                                                    };
+    void setOrganisation(const std::string &org) { mOrg = org; };
+    std::string organisation() const { return mOrg; };
+    void setOrganisationalUnits(const std::vector<std::string> &units) { mOrgUnits = units; };
+    std::vector<std::string> organisationalUnits() const { return mOrgUnits; };
+    void setLogo(const std::string &l, const std::string mimetype) { mLogo = l; mLogoMimetype = mimetype; };
+    std::string logo() const { return mLogo; };
+    std::string logoMimetype() const { return mLogoMimetype; };
+
+    void setRoles(const std::vector<std::string> &roles) { mRoles = roles; };
+    std::vector<std::string> roles() const { return mRoles; };
+    void setRelateds(const std::vector<Related> &relateds) { mRelateds = relateds; };
+    std::vector<Related> relateds() const { return mRelateds; };
+    void setAddresses(const std::vector<Address> &offices) { mOffices = offices; };
+    std::vector<Address> addresses() const { return mOffices; };
+private:
+    std::string mOrg;
+    std::vector<std::string> mOrgUnits;
+    std::string mLogo;
+    std::string mLogoMimetype;
+    std::vector<std::string> mRoles;
+    std::vector<Related> mRelateds;
+    std::vector<Address> mOffices;
+};
+
+struct Telephone {
+    enum Type {
+        Work = 0x01,
+        Home = 0x02,
+        Text = 0x04,
+        Voice = 0x08,
+        Fax = 0x10,
+        Cell = 0x20,
+        Video = 0x40,
+        Pager = 0x80,
+        Textphone = 0x100,
+        Car = 0x200
+    };
+    Telephone(): mType(0){};
+    bool operator==(const Telephone &other) const { return mNumber == other.mNumber &&
+                                                    mType == other.mType;
+                                                    };
+    void setTypes(int t) { mType = t; };
+    int types() const { return mType; };
+    void setNumber(const std::string &n) { mNumber = n; };
+    std::string number() const { return mNumber; };
+private:
+    std::string mNumber;
+    int mType;
+};
+
+struct Crypto {
+    enum CryptoTypes {
+        PGPinline = 0x01,
+        PGPmime = 0x02,
+        SMIME = 0x04,
+        SMIMEopaque = 0x08
+    };
+    
+    enum CryptoPref {
+        Ask,
+        Never,
+        Always,
+        IfPossible
+    };
+    Crypto(): mCryptoTypes(0), mSignPref(Ask), mEncryptPref(Ask){};
+    bool operator==(const Crypto &other) const { return mCryptoTypes == other.mCryptoTypes &&
+                                                    mPGPKey == other.mPGPKey &&
+                                                    mSMIMEKey == other.mSMIMEKey &&
+                                                    mSignPref == other.mSignPref &&
+                                                    mEncryptPref == other.mEncryptPref; };
+    bool isValid() const { return !(!mCryptoTypes && mPGPKey.empty() && mSMIMEKey.empty()); };
+
+    void setAllowed(int cryptoTypes) { mCryptoTypes = cryptoTypes; };
+    int allowed() const { return mCryptoTypes; };
+    void setPGPKey(const std::string &k) { mPGPKey = k; };
+    std::string pgpKey() const { return mPGPKey; };
+    void setSMIMEKey(const std::string &k) { mSMIMEKey = k; };
+    std::string smimeKey() const { return mSMIMEKey; };
+    void setSignPref(CryptoPref p) { mSignPref = p; };
+    CryptoPref signPref() const { return mSignPref; };
+    void setEncryptPref(CryptoPref p) { mEncryptPref = p; };
+    CryptoPref encryptPref() const { return mEncryptPref; };
+private:
+    int mCryptoTypes;
+    std::string mPGPKey;
+    std::string mSMIMEKey;
+    CryptoPref mSignPref;
+    CryptoPref mEncryptPref;
+};
+
+struct Geo {
+    Geo(): latitude(0.0), longitude(0.0) {};
+    Geo(double lat, double lon)
+    : latitude(lat), longitude(lon) {};
+    
+    bool operator==(const Geo &other) const{ return (longitude == other.longitude && latitude == other.latitude);};
+    double latitude;
+    double longitude;
+};
+
+
+class DistList {
+public:
+    DistList();
+    ~DistList();
+    DistList(const DistList &);
+    void operator=(const DistList &);
+
+    bool isValid() const;
+
+    void setUid(const std::string &);
+    std::string uid() const;
+
+    void setLastModified(const cDateTime &);
+    cDateTime lastModified() const;
+
+    void setName(const std::string &);
+    std::string name() const;
+
+    void setMembers(const std::vector<ContactReference> &);
+    std::vector<ContactReference> members() const;
+
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+class Contact {
+public:
+    Contact();
+    ~Contact();
+    Contact(const Contact &);
+    void operator=(const Contact &);
+
+    bool isValid() const;
+
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setLastModified(const cDateTime &);
+    cDateTime lastModified() const;
+    
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setName(const std::string &);
+    std::string name() const;
+    
+    void setNameComponents(const NameComponents &);
+    NameComponents nameComponents() const;
+    
+    void setNote(const std::string &);
+    std::string note() const;
+    
+    void setFreeBusyUrl(const std::string &);
+    std::string freeBusyUrl() const;
+    
+    void setTitles(const std::vector<std::string> &titles);
+    std::vector<std::string> titles() const;
+    
+    void setAffiliations(const std::vector<Affiliation> &);
+    std::vector<Affiliation> affiliations() const;
+    
+    void setUrls(const std::vector<std::string> &);
+    std::vector<std::string> urls() const;
+    
+    void setAddresses(const std::vector<Address> &, int preferred = -1);
+    std::vector<Address> addresses() const;
+    int addressPreferredIndex() const;
+    
+    void setNickNames(const std::vector< std::string > &);
+    std::vector< std::string > nickNames() const;
+    
+    void setRelateds(const std::vector<Related> &);
+    std::vector<Related> relateds() const;
+     
+    void setBDay(const cDateTime &);
+    cDateTime bDay() const;
+    
+    void setAnniversary(const cDateTime &);
+    cDateTime anniversary() const;
+    
+    void setPhoto(const std::string &data, const std::string &mimetype);
+    std::string photo() const;
+    std::string photoMimetype() const;
+    
+    enum Gender {
+        NotSet,
+        NotSpecified,
+        Male,
+        Female
+    };
+    
+    void setGender(Gender);
+    Gender gender() const;
+    
+    void setLanguages(const std::vector<std::string> &);
+    std::vector<std::string> languages() const;
+    
+    void setTelephones(const std::vector<Telephone> &, int preferredIndex = -1);
+    std::vector<Telephone> telephones() const;
+    int telephonesPreferredIndex() const;
+    
+    void setIMaddresses(const std::vector<std::string> &, int preferredIndex = -1);
+    std::vector<std::string> imAddresses() const;
+    int imAddressPreferredIndex() const;
+    
+    void setEmailAddresses(const std::vector<std::string> &, int preferredIndex = -1);
+    std::vector<std::string> emailAddresses() const;
+    int emailAddressPreferredIndex() const;
+    
+    void setGPSpos(const std::vector<Geo> &);
+    std::vector<Geo> gpsPos() const;
+    
+    void setCrypto(const Crypto &);
+    Crypto crypto() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+} //Namespace
+
+#endif // KOLABCONTACT_H
diff --git a/libkolabxml/lib/kolabcontainers.cpp b/libkolabxml/lib/kolabcontainers.cpp
new file mode 100644
index 0000000..491f9d7
--- /dev/null
+++ b/libkolabxml/lib/kolabcontainers.cpp
@@ -0,0 +1,729 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabcontainers.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+    
+struct cDateTime::Private {
+    Private()
+    : year(-1),
+    month(-1),
+    day(-1),
+    hour(-1),
+    minute(-1),
+    second(-1),
+    isUtc(false){}
+
+    int year;
+    int month;
+    int day;
+    int hour;
+    int minute;
+    int second;
+    bool isUtc;
+    std::string timezone;
+};
+
+cDateTime::cDateTime()
+: d(new cDateTime::Private())
+{
+
+}
+
+cDateTime::cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc)
+: d(new cDateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+    d->isUtc = isUtc;
+}
+
+cDateTime::cDateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
+: d(new cDateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+    d->timezone = timezone;
+}
+
+cDateTime::cDateTime(int year, int month, int day)
+: d(new cDateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+}
+
+cDateTime::cDateTime(const Kolab::cDateTime &other)
+: d(new cDateTime::Private())
+{
+    *d = *other.d;
+}
+
+cDateTime::~cDateTime()
+{
+
+}
+
+
+void cDateTime::operator=(const Kolab::cDateTime &other)
+{
+   *d = *other.d;
+}
+
+bool cDateTime::operator==(const Kolab::cDateTime &other) const
+{
+    if ( d->year == other.year() &&
+        d->month == other.month() &&
+        d->day == other.day() &&
+        d->hour == other.hour() &&
+        d->minute == other.minute() &&
+        d->second== other.second() &&
+        d->isUtc== other.isUTC() &&
+        d->timezone== other.timezone()) {
+        return true;
+    }
+    return false;
+}
+
+
+
+int cDateTime::year() const
+{
+    return d->year;
+}
+
+int cDateTime::month() const
+{
+    return d->month;
+}
+
+int cDateTime::day() const
+{
+    return d->day;
+}
+
+int cDateTime::hour() const
+{
+    return d->hour;
+}
+
+int cDateTime::minute() const
+{
+    return d->minute;
+}
+
+int cDateTime::second() const
+{
+    return d->second;
+}
+
+bool cDateTime::isDateOnly() const
+{
+    if ((d->hour < 0) && (d->minute < 0) && (d->second < 0)) {
+        return true;
+    }
+    return false;
+}
+
+void cDateTime::setDate(int year, int month, int day)
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+}
+void cDateTime::setTime(int hour, int minute, int second)
+{
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+}
+void cDateTime::setTimezone(const std::string &tz)
+{
+    d->timezone = tz;
+}
+void cDateTime::setUTC(bool utc)
+{
+    d->isUtc = utc;
+}
+
+bool cDateTime::isUTC() const
+{
+    return d->isUtc;
+}
+
+std::string cDateTime::timezone() const
+{
+    return d->timezone;
+}
+
+bool cDateTime::isValid() const
+{
+    return (d->year >= 0 && d->month >= 0 && d->day >= 0);
+}
+
+struct RecurrenceRule::Private
+{
+    Private()
+    : freq(FreqNone),
+    weekstart(Monday),
+    count(-1),
+    interval(1){};
+    
+    Frequency freq;
+    Weekday weekstart;
+    cDateTime end;
+    int count;
+    int interval;
+    std::vector<int> bysecond;
+    std::vector<int> byminute;
+    std::vector<int> byhour;
+    std::vector<DayPos> byday;
+    std::vector<int> bymonthday;
+    std::vector<int> byyearday;
+    std::vector<int> byweekno;
+    std::vector<int> bymonth;
+};
+
+RecurrenceRule::RecurrenceRule()
+:   d(new RecurrenceRule::Private)
+{
+    
+}
+
+RecurrenceRule::RecurrenceRule(const Kolab::RecurrenceRule &other)
+:   d(new RecurrenceRule::Private)
+{
+    *d = *other.d;
+}
+
+void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
+{
+    *d = *other.d;
+}
+
+bool RecurrenceRule::operator==(const Kolab::RecurrenceRule &other) const
+{
+    if ( d->freq == other.frequency() &&
+        d->weekstart == other.weekStart() &&
+        d->end == other.end() &&
+        d->count == other.count() &&
+        d->interval == other.interval() &&
+        d->bysecond == other.bysecond() &&
+        d->byminute == other.byminute() &&
+        d->byhour == other.byhour() &&
+        d->byday == other.byday() &&
+        d->bymonthday == other.bymonthday() &&
+        d->byyearday == other.byyearday() &&
+        d->byweekno == other.byweekno() &&
+        d->bymonth == other.bymonth()) {
+            return true;
+        }
+        return false;
+}
+
+RecurrenceRule::~RecurrenceRule()
+{
+    
+}
+
+void RecurrenceRule::setFrequency(RecurrenceRule::Frequency freq)
+{
+    d->freq = freq;
+}
+
+RecurrenceRule::Frequency RecurrenceRule::frequency() const
+{
+    return d->freq;
+}
+
+void RecurrenceRule::setWeekStart(Kolab::Weekday weekstart)
+{
+    d->weekstart = weekstart;
+}
+
+Kolab::Weekday RecurrenceRule::weekStart() const
+{
+    return d->weekstart;
+}
+
+void RecurrenceRule::setEnd(const Kolab::cDateTime &end)
+{
+    d->end = end;
+}
+
+cDateTime RecurrenceRule::end() const
+{
+    return d->end;
+}
+
+void RecurrenceRule::setCount(int count)
+{
+    d->count = count;
+}
+
+int RecurrenceRule::count() const
+{
+    return d->count;
+}
+
+void RecurrenceRule::setInterval(int interval)
+{
+    d->interval = interval;
+}
+
+int RecurrenceRule::interval() const
+{
+    return d->interval;
+}
+
+void RecurrenceRule::setBysecond(const std::vector< int >&by)
+{
+    d->bysecond = by;
+}
+
+
+std::vector< int > RecurrenceRule::bysecond() const
+{
+    return d->bysecond;
+}
+
+void RecurrenceRule::setByminute(const std::vector< int > &by)
+{
+    d->byminute = by;
+}
+
+std::vector< int > RecurrenceRule::byminute() const
+{
+    return d->byminute;
+}
+
+void RecurrenceRule::setByhour(const std::vector< int > &by)
+{
+    d->byhour = by;
+}
+
+std::vector< int > RecurrenceRule::byhour() const
+{
+    return d->byhour;
+}
+
+void RecurrenceRule::setByday(const std::vector< DayPos > &by)
+{
+    d->byday = by;
+}
+
+std::vector< DayPos > RecurrenceRule::byday() const
+{
+    return d->byday;
+}
+
+void RecurrenceRule::setBymonthday(const std::vector< int > &by)
+{
+    d->bymonthday = by;
+}
+
+std::vector< int > RecurrenceRule::bymonthday() const
+{
+    return d->bymonthday;
+}
+
+void RecurrenceRule::setByyearday(const std::vector< int > &by)
+{
+    d->byyearday = by;
+}
+
+std::vector< int > RecurrenceRule::byyearday() const
+{
+    return d->byyearday;
+}
+
+void RecurrenceRule::setByweekno(const std::vector< int > &by)
+{
+    d->byweekno = by;
+}
+
+std::vector< int > RecurrenceRule::byweekno() const
+{
+    return d->byweekno;
+}
+
+void RecurrenceRule::setBymonth(const std::vector< int > &by)
+{
+    d->bymonth = by;
+}
+
+std::vector< int > RecurrenceRule::bymonth() const
+{
+    return d->bymonth;
+}
+
+bool RecurrenceRule::isValid() const
+{
+    if (d->freq == FreqNone) {
+        return false;
+    }
+    return true;
+}
+
+
+
+struct Attendee::Private
+{
+    Private()
+    : partStat(PartNeedsAction),
+    role(Required),
+    rsvp(false){};
+    
+    ContactReference contact;
+    PartStatus partStat;
+    Role role;
+    bool rsvp;
+};
+
+Attendee::Attendee()
+:   d(new Attendee::Private)
+{
+
+}
+
+Attendee::Attendee(const ContactReference& contact)
+:   d(new Attendee::Private)
+{
+    d->contact = contact; 
+}
+
+Attendee::Attendee(const Kolab::Attendee &other)
+:   d(new Attendee::Private)
+{
+    *d = *other.d;
+}
+
+void Attendee::operator=(const Kolab::Attendee &other)
+{
+    *d = *other.d;
+}
+
+Attendee::~Attendee()
+{
+
+}
+
+bool Attendee::operator==(const Kolab::Attendee &other) const
+{
+    if ( d->contact == other.contact() &&
+        d->partStat == other.partStat() &&
+        d->role == other.role() &&
+        d->rsvp== other.rsvp()) {
+        return true;
+    }
+    return false;
+}
+
+bool Attendee::isValid() const 
+{ 
+    return d->contact.isValid();
+};
+
+void Attendee::setContact(const ContactReference &c)
+{
+    d->contact = c;
+}
+
+ContactReference Attendee::contact() const
+{
+    return d->contact;
+}
+
+
+void Attendee::setPartStat(PartStatus partStat)
+{
+    d->partStat = partStat;
+}
+
+PartStatus Attendee::partStat() const
+{
+    return d->partStat;
+}
+
+void Attendee::setRole(Role role)
+{
+    d->role = role;
+}
+
+Role Attendee::role() const
+{
+    return d->role;
+}
+
+void Attendee::setRSVP(bool rsvp)
+{
+    d->rsvp = rsvp;
+}
+
+bool Attendee::rsvp() const
+{
+    return d->rsvp;
+}
+
+
+
+struct Attachment::Private
+{
+    std::string uri;
+    std::string data;
+    std::string mimetype;
+    std::string label;
+};
+
+Attachment::Attachment()
+:   d(new Attachment::Private)
+{
+}
+
+Attachment::Attachment(const Kolab::Attachment &other)
+:   d(new Attachment::Private)
+{
+    *d = *other.d;
+}
+
+void Attachment::operator=(const Kolab::Attachment &other)
+{
+    *d = *other.d;
+}
+
+Attachment::~Attachment()
+{
+}
+
+bool Attachment::operator==(const Kolab::Attachment &other) const
+{
+    return ( d->uri == other.uri() &&
+        d->data == other.data() &&
+        d->label == other.label() &&
+        d->mimetype == other.mimetype() );
+}
+
+void Attachment::setUri(const std::string &uri, const std::string& mimetype)
+{
+    d->uri = uri;
+    d->mimetype = mimetype;
+}
+
+std::string Attachment::uri() const
+{
+    return d->uri;
+}
+
+std::string Attachment::mimetype() const
+{
+    return d->mimetype;
+}
+
+void Attachment::setLabel(const std::string &label)
+{
+    d->label = label;
+}
+
+std::string Attachment::label() const
+{
+    return d->label;
+}
+
+void Attachment::setData(const std::string &data, const std::string& mimetype)
+{
+    d->data = data;
+    d->mimetype = mimetype;
+}
+
+std::string Attachment::data() const
+{
+    return d->data;
+}
+
+bool Attachment::isValid() const
+{
+    return !d->mimetype.empty(); //TODO use isValid variable
+}
+
+
+
+struct Alarm::Private
+{
+    Private(): relativeTo(Start),
+    numrepeat(0),
+    type(Alarm::InvalidAlarm) {};
+    std::string text;
+    Attachment audioFile;
+    std::string summary;
+    std::vector<ContactReference> attendees;
+    cDateTime start;
+    Duration relativeDuration;
+    Relative relativeTo;
+    Duration duration;
+    int numrepeat;
+    Type type;
+    
+};
+
+Alarm::Alarm()
+:   d(new Alarm::Private)
+{
+}
+
+Alarm::Alarm(const std::string &text)
+:   d(new Alarm::Private)
+{
+    d->text = text;
+    d->type = DisplayAlarm;
+}
+
+
+Alarm::Alarm(const Kolab::Attachment& audio)
+:   d(new Alarm::Private)
+{
+    d->audioFile = audio;
+    d->type = AudioAlarm;
+}
+
+Alarm::Alarm(const std::string& summary, const std::string& description, const std::vector<ContactReference> attendees)
+:   d(new Alarm::Private)
+{
+    d->summary = summary;
+    d->text = description;
+    d->attendees = attendees;
+    d->type = EMailAlarm;
+    
+}
+
+Alarm::Alarm(const Kolab::Alarm &other)
+:   d(new Alarm::Private)
+{
+    *d = *other.d;
+}
+
+void Alarm::operator=(const Kolab::Alarm &other)
+{
+    *d = *other.d;
+}
+
+Alarm::~Alarm()
+{
+}
+
+bool Alarm::operator==(const Kolab::Alarm &other) const
+{
+    return ( d->text == other.description() &&
+        d->text == other.description() &&
+        d->audioFile == other.audioFile() &&
+        d->summary == other.summary() &&
+        d->attendees == other.attendees() &&
+        d->start == other.start() &&
+        d->relativeDuration == other.relativeStart() &&
+        d->relativeTo == other.relativeTo() &&
+        d->duration == other.duration() &&
+        d->numrepeat == other.numrepeat() );
+}
+
+std::string Alarm::text() const
+{
+    return d->text;
+}
+
+Attachment Alarm::audioFile() const
+{
+    return d->audioFile;
+}
+
+std::string Alarm::summary() const
+{
+    return d->summary;
+}
+
+std::string Alarm::description() const
+{
+    return d->text;
+}
+
+std::vector<ContactReference> Alarm::attendees() const
+{
+    return d->attendees;
+}
+
+void Alarm::setStart(const Kolab::cDateTime &start)
+{
+    d->start = start;
+}
+
+cDateTime Alarm::start() const
+{
+    return d->start;
+}
+
+void Alarm::setRelativeStart(const Kolab::Duration &duration, Relative relativeTo)
+{
+    d->relativeDuration = duration;
+    d->relativeTo = relativeTo;
+}
+
+Duration Alarm::relativeStart() const
+{
+    return d->relativeDuration;
+}
+
+Relative Alarm::relativeTo() const
+{
+    return d->relativeTo;
+}
+
+void Alarm::setDuration(const Kolab::Duration &duration, int numrepeat)
+{
+    d->numrepeat = numrepeat;
+    d->duration = duration;
+}
+
+Duration Alarm::duration() const
+{
+    return d->duration;
+}
+
+int Alarm::numrepeat() const
+{
+    return d->numrepeat;
+}
+
+Alarm::Type Alarm::type() const
+{
+    return d->type;
+}
+
+
+
+
+
+
+}//Namespace
diff --git a/libkolabxml/lib/kolabcontainers.h b/libkolabxml/lib/kolabcontainers.h
new file mode 100644
index 0000000..47dc5fc
--- /dev/null
+++ b/libkolabxml/lib/kolabcontainers.h
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLAB_CONTAINERS_H
+#define KOLAB_CONTAINERS_H
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+
+namespace Kolab {
+
+class cDateTime {
+public:
+    cDateTime();
+    cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc=true);
+    cDateTime(const std::string &timezone, int year, int month, int day, int hour, int minute, int second);
+    cDateTime(int year, int month, int day);
+    ~cDateTime();
+    cDateTime(const cDateTime &);
+    void operator=(const cDateTime &);
+    bool operator==(const cDateTime &) const;
+   
+    
+    void setDate(int year, int month, int day);
+    int year() const;
+    int month() const;
+    int day() const;
+    
+    bool isDateOnly() const;
+    
+    void setTime(int hour, int minute, int second);
+    int hour() const;
+    int minute() const;
+    int second() const;
+    
+    void setUTC(bool);
+    bool isUTC() const;
+    void setTimezone(const std::string &);
+    std::string timezone() const;
+    
+    bool isValid() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+enum Classification {
+    ClassPublic,
+    ClassPrivate,
+    ClassConfidential
+};
+
+enum Status {
+    StatusUndefined,
+    StatusNeedsAction,
+    StatusCompleted,
+    StatusInProcess,
+    StatusCancelled,
+    StatusTentative,
+    StatusConfirmed,
+    StatusDraft,
+    StatusFinal
+};
+
+enum Weekday {
+    Monday,
+    Tuesday,
+    Wednesday,
+    Thursday,
+    Friday,
+    Saturday,
+    Sunday
+};
+
+struct DayPos {
+    DayPos(): mIsValid(false){};
+    DayPos(int occurrence, Weekday weekday): mOccurrence(occurrence), mWeekday(weekday), mIsValid(true){};
+    bool operator==(const DayPos &other) const { return mOccurrence == other.mOccurrence && mWeekday == other.mWeekday; };
+    int occurence() const { return mOccurrence; };
+    Weekday weekday() const { return mWeekday; };
+    bool isValid() { return mIsValid; };
+private:
+    int mOccurrence;
+    Weekday mWeekday;
+    bool mIsValid;
+};
+
+class Attachment {
+public:
+    Attachment();
+    Attachment(const Kolab::Attachment &);
+    ~Attachment();
+
+    void operator=(const Attachment &);
+    bool operator==(const Attachment &) const;
+
+    void setUri(const std::string &uri, const std::string &mimetype);
+    std::string uri() const;
+
+     ///Un-encoded binary content, Implies embedded, will be encoded
+     void setData(const std::string &, const std::string &mimetype);
+     ///Decoded binary content.
+     std::string data() const;
+     //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement?
+//     ///Base64 encoded binary content, Implies embedded
+//      void setEncodedData(const std::string &, const std::string &mimetype);
+
+    std::string mimetype() const;
+
+    ///User visible label
+    void setLabel(const std::string &);
+    std::string label() const;
+    
+    bool isValid() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+enum Relative {
+    Start,
+    End
+};
+
+struct Duration {
+    Duration():mWeeks(0), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(false), valid(false){};
+    Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){};
+    Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){};
+    bool operator==(const Duration &other) const{ return (/*mWeeks == other.mWeeks && 
+                                                            mDays == other.mDays &&
+                                                            mHours == other.mHours &&
+                                                            mMinutes == other.mMinutes &&
+                                                            mSeconds == other.mSeconds &&
+                                                            mNegative == other.mNegative &&*/
+                                                            ( ((((mWeeks * 7 + mDays) * 24 + mHours) * 60 + mMinutes) * 60 + mSeconds) ==
+                                                              ((((other.mWeeks * 7 + other.mDays) * 24 + other.mHours) * 60 + other.mMinutes) * 60 + other.mSeconds) ) &&
+                                                            valid == other.valid );};
+    int weeks() const { return mWeeks; };
+    int days() const { return mDays; };
+    int hours() const { return mHours; };
+    int minutes() const { return mMinutes; };
+    int seconds() const { return mSeconds; };
+
+    bool isNegative() const { return mNegative; };
+    bool isValid() const { return valid; };
+private:
+    int mWeeks;
+    int mDays;
+    int mHours;
+    int mMinutes;
+    int mSeconds;
+    bool mNegative;
+    bool valid;
+};
+
+struct ContactReference {
+    enum ReferenceType {
+        Invalid,
+        EmailReference,
+        UidReference,
+        EmailAndUidReference
+    };
+    ContactReference(): mType(Invalid) {};
+    ///For xCal
+    ContactReference(const std::string &email, const std::string &name = std::string(), const std::string &uid = std::string()): mType(EmailAndUidReference), mEmail(email), mUid(uid), mName(name) {};
+    ///For xCard
+    ContactReference(ReferenceType type, const std::string &emailOrUID, const std::string &name = std::string()): mType(type), mName(name) { 
+        if (type == EmailReference) {
+            mEmail = emailOrUID;
+        } else {
+            mUid = emailOrUID;
+        }
+    };
+    bool operator==(const ContactReference &other) const { return mType == other.mType &&
+                                                        mEmail == other.mEmail &&
+                                                        mName == other.mName &&
+                                                        mUid == mUid;
+    };
+
+    bool isValid() const { return mType != Invalid; };
+
+    void setName(const std::string &name) { mName = name; };
+
+    std::string email() const { return mEmail; };
+    std::string uid() const { return mUid; };
+    std::string name() const { return mName; };
+
+    ReferenceType type() const { return mType; };
+
+private:
+    ReferenceType mType;
+    std::string mEmail;
+    std::string mUid;
+    std::string mName;
+};
+
+class Alarm {
+public:
+    enum Type {
+        InvalidAlarm,
+        EMailAlarm,
+        DisplayAlarm,
+        AudioAlarm
+    };
+    
+    Alarm();
+    Alarm(const Alarm &);
+    ~Alarm();
+
+    void operator=(const Alarm &);
+    bool operator==(const Alarm &other) const;
+
+    ///EMail Alarm, @param attendees accepts only email + name and no uid
+    Alarm(const std::string &summary, const std::string &description, const std::vector<ContactReference> attendees);
+    std::string summary() const;
+    std::string description() const;
+    std::vector<ContactReference> attendees() const;
+
+    ///Display Alarm
+    Alarm(const std::string &text);
+    std::string text() const;
+
+    ///Audio Alarm
+    Alarm(const Attachment &audio);
+    Attachment audioFile() const;
+    
+    void setRelativeStart(const Duration &, Relative);
+    Duration relativeStart() const;
+    Relative relativeTo() const;
+    
+    void setStart(const cDateTime &);
+    cDateTime start() const;
+
+    void setDuration(const Duration &, int numrepeat);
+    Duration duration() const;
+    int numrepeat() const;
+    
+    Type type() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+class RecurrenceRule {
+public:
+    
+    RecurrenceRule();
+    RecurrenceRule(const RecurrenceRule &);
+    ~RecurrenceRule();
+
+    void operator=(const RecurrenceRule &);
+    bool operator==(const RecurrenceRule &other) const;
+    
+    enum Frequency {
+        FreqNone,
+        Yearly,
+        Monthly,
+        Weekly,
+        Daily,
+        Hourly,
+        Minutely,
+        Secondly
+    };
+    
+    void setFrequency(Frequency);
+    Frequency frequency() const;
+    
+    void setWeekStart(Weekday);
+    Weekday weekStart() const;
+    
+    void setEnd(const cDateTime &);
+    cDateTime end() const;
+    
+    void setCount(int count);
+    int count() const;
+    
+    void setInterval(int);
+    int interval() const;
+    
+    void setBysecond(const std::vector<int> &);
+    std::vector<int> bysecond() const;
+    
+    void setByminute(const std::vector<int> &);
+    std::vector<int> byminute() const;
+    
+    void setByhour(const std::vector<int> &);
+    std::vector<int> byhour() const;
+    
+    void setByday(const std::vector<DayPos> &);
+    std::vector<DayPos> byday() const;
+    
+    void setBymonthday(const std::vector<int> &);
+    std::vector<int> bymonthday() const;
+    
+    void setByyearday(const std::vector<int> &);
+    std::vector<int> byyearday() const;
+    
+    void setByweekno(const std::vector<int> &);
+    std::vector<int> byweekno() const;
+    
+    void setBymonth(const std::vector<int> &);
+    std::vector<int> bymonth() const;
+    
+    bool isValid() const;
+    
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+enum PartStatus {
+    PartNeedsAction,
+    PartAccepted,
+    PartDeclined,
+    PartTentative,
+    PartDelegated
+};
+
+enum Role {
+    Required,
+    Chair,
+    Optional,
+    NonParticipant
+};
+
+class Attendee {
+public:
+    Attendee();
+    Attendee(const ContactReference &contact);
+    Attendee(const Attendee &);
+    ~Attendee();
+
+    void operator=(const Attendee &);
+    bool operator==(const Attendee &) const;
+
+    bool isValid() const;
+
+    void setContact(const ContactReference &);
+    ContactReference contact() const;
+
+    void setPartStat(PartStatus);
+    PartStatus partStat() const;
+
+    void setRole(Role);
+    Role role() const;
+
+    void setRSVP(bool);
+    bool rsvp() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+struct CustomProperty {
+    CustomProperty(){};
+    CustomProperty(const std::string &i, const std::string &v)
+    : identifier(i), value(v) {};
+
+    bool operator==(const CustomProperty &other) const{ return (identifier == other.identifier && value == other.value);};
+    std::string identifier;
+    std::string value;
+};
+
+template <typename T>
+std::vector<T> operator<< ( std::vector<T> v, const T &s)
+{
+    v.push_back(s);
+    return v;
+}
+
+
+//Prepared Kolab Objects
+
+
+class Configuration {
+    //TODO
+};
+
+
+    
+}
+
+#endif
diff --git a/libkolabxml/lib/kolabconversions.h b/libkolabxml/lib/kolabconversions.h
new file mode 100644
index 0000000..4871acd
--- /dev/null
+++ b/libkolabxml/lib/kolabconversions.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABOBJECTCONVERSION_H
+#define KOLABOBJECTCONVERSION_H
+
+#include <bindings/kolabformat.hxx>
+#include "kolabcontainers.h"
+#include <XMLParserWrapper.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+#include "global_definitions.h"
+#include "utils.h"
+#include "kolabnote.h"
+#include "shared_conversions.h"
+
+namespace Kolab {
+    namespace KolabObjects {
+        
+const char* const KOLAB_NAMESPACE = "http://kolab.org";
+    
+using namespace Kolab::Utils;
+using namespace Kolab::Shared;
+
+template <typename T>
+std::string serializeObject(const Kolab::Note &note, const std::string prod = std::string())
+{
+    clearErrors();
+    try {
+
+        const std::string &uid = getUID(note.uid());
+        setCreatedUid(uid);
+        
+        KolabXSD::Note::creation_date_type created = fromDateTime(note.created());
+        if (!note.created().isValid()) {
+            created = fromDateTime(getCurrentTime());
+        }
+
+        KolabXSD::Note n(getUID(note.uid()), prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION, created, fromDateTime(getCurrentTime()));
+
+        if (!note.categories().empty()) {
+            KolabXSD::Note::categories_sequence categories;
+            BOOST_FOREACH(const std::string &c, note.categories()) {
+                categories.push_back(c);
+            }
+            n.categories(categories);
+        }
+        switch (note.classification()) {
+            case Kolab::ClassPublic:
+                n.classification(KolabXSD::Note::classification_type::PUBLIC);
+                break;
+            case Kolab::ClassPrivate:
+                n.classification(KolabXSD::Note::classification_type::PRIVATE);
+                break;
+            case Kolab::ClassConfidential:
+                n.classification(KolabXSD::Note::classification_type::CONFIDENTIAL);
+                break;
+            default:
+                ERROR("unknown classification");
+        }
+        //TODO
+//         n.attachment();
+        n.summary(note.summary());
+        n.description(note.description());
+        n.color(note.color());
+
+        if (!note.customProperties().empty()) {
+            BOOST_FOREACH(const Kolab::CustomProperty &a, note.customProperties()) {
+                n.x_custom().push_back(KolabXSD::CustomType(a.identifier, a.value));
+            }
+        }
+
+        xml_schema::namespace_infomap map;
+        map[""].name = KOLAB_NAMESPACE;
+
+        std::ostringstream ostringstream;
+        KolabXSD::note(ostringstream, n, map);
+        return ostringstream.str();
+    } catch  (const xml_schema::exception& e) {
+        CRITICAL("Unknown Exception: failed to write Note");
+    }
+    return std::string();
+}
+
+template <typename T>
+boost::shared_ptr<Kolab::Note> deserializeObject(const std::string& s, bool isUrl)
+{
+    clearErrors();
+    try {
+        std::auto_ptr<KolabXSD::Note> note;
+        if (isUrl) {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            if (doc.get()) {
+                note = KolabXSD::note(doc);
+            }
+        } else {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            if (doc.get()) {
+                note = KolabXSD::note(doc);
+            }
+        }
+
+        if (!note.get()) {
+            CRITICAL("failed to parse note!");
+            return boost::shared_ptr<Kolab::Note>();
+        }
+
+        boost::shared_ptr<Kolab::Note> n = boost::shared_ptr<Kolab::Note>(new Kolab::Note);
+        n->setUid(note->uid());
+        n->setCreated(*toDate(note->creation_date()));
+        n->setLastModified(*toDate(note->last_modification_date()));
+        std::vector<std::string> categories;
+        std::copy(note->categories().begin(), note->categories().end(), std::back_inserter(categories));
+        n->setCategories(categories);
+        if (note->classification()) {
+            switch (*note->classification()) {
+                case KolabXSD::Note::classification_type::PUBLIC:
+                    n->setClassification(Kolab::ClassPublic);
+                    break;
+                case KolabXSD::Note::classification_type::PRIVATE:
+                    n->setClassification(Kolab::ClassPrivate);
+                    break;
+                case KolabXSD::Note::classification_type::CONFIDENTIAL:
+                    n->setClassification(Kolab::ClassConfidential);
+                    break;
+                default:
+                    ERROR("unknown classification");
+            }
+        }
+        //TODO
+//             n->setAttachments();
+        if (note->summary()) {
+            n->setSummary(*note->summary());
+        }
+        if (note->description()) {
+            n->setDescription(*note->description());
+        }
+        if (note->color()) {
+            n->setColor(*note->color());
+        }
+        
+        setProductId( note->prodid() );
+        //         setFormatVersion( vcards->vcard().version().text() );
+        //         global_xCardVersion = vcalendar.properties().version().text();
+        setKolabVersion( note->version() );
+        
+        if (!note->x_custom().empty()) {
+            std::vector<Kolab::CustomProperty> customProperties;
+            BOOST_FOREACH(const KolabXSD::CustomType &p, note->x_custom()) {
+                customProperties.push_back(CustomProperty(p.identifier(), p.value()));
+            }
+            n->setCustomProperties(customProperties);
+        }
+        return n;
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        CRITICAL("Failed to read note!");
+    }
+    
+    return boost::shared_ptr<T>();
+}
+    
+    }//Namespace
+} //Namespace
+
+#endif
diff --git a/libkolabxml/lib/kolabevent.cpp b/libkolabxml/lib/kolabevent.cpp
new file mode 100644
index 0000000..07b4bb0
--- /dev/null
+++ b/libkolabxml/lib/kolabevent.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabevent.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+struct Event::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence(), 
+    isTransparent(false){}
+
+    cDateTime end;
+    bool isTransparent;
+    Duration duration;
+    std::vector< Event > exceptions;
+};
+
+Event::Event()
+: d(new Event::Private())
+{
+//     std::cout << "ctor" << std::endl;
+}
+
+Event::Event(const Event &other)
+: d(new Event::Private())
+{
+    *d = *other.d;
+//     std::cout << "cctor" << std::endl;
+}
+
+Event::~Event()
+{
+//     std::cout << "dtor" << std::endl;
+}
+
+void Event::operator=(const Kolab::Event &other)
+{
+    *d = *other.d;
+}
+
+bool Event::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void Event::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Event::uid() const
+{
+    return d->uid;
+}
+
+void Event::setCreated(const Kolab::cDateTime &created)
+{
+    d->created = created;
+}
+
+cDateTime Event::created() const
+{
+    return d->created;
+}
+
+void Event::setLastModified(const Kolab::cDateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+cDateTime Event::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Event::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Event::sequence() const
+{
+    return d->sequence;
+}
+
+void Event::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Event::classification() const
+{
+    return d->classification;
+}
+
+void Event::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Event::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Event::categories() const
+{
+    return d->categories;
+}
+
+void Event::setStart(const Kolab::cDateTime &start)
+{
+    d->start = start;
+}
+
+cDateTime Event::start() const
+{
+    return d->start;
+}
+
+void Event::setEnd(const Kolab::cDateTime &end)
+{
+    d->end = end;
+}
+
+cDateTime Event::end() const
+{
+    return d->end;
+}
+
+void Event::setDuration(const Duration &duration)
+{
+    d->duration = duration;
+}
+
+Duration Event::duration() const
+{
+    return d->duration;
+}
+
+
+void Event::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture)
+{
+    d->recurrenceID = rID;
+    d->thisAndFuture = thisandfuture;
+}
+
+cDateTime Event::recurrenceID() const
+{
+    return d->recurrenceID;
+}
+
+bool Event::thisAndFuture() const
+{
+    return d->thisAndFuture;
+}
+
+void Event::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Event::summary() const
+{
+    return d->summary;
+}
+
+void Event::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Event::description() const
+{
+    return d->description;
+}
+
+void Event::setPriority(int priority)
+{
+    d->priority = priority;
+}
+
+int Event::priority() const
+{
+    return d->priority;
+}
+
+void Event::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Event::status() const
+{
+    return d->status;
+}
+
+void Event::setLocation(const std::string &location)
+{
+    d->location = location;
+}
+
+std::string Event::location() const
+{
+    return d->location;
+}
+
+void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+    d->rrule = rrule;
+}
+
+RecurrenceRule Event::recurrenceRule() const
+{
+    return d->rrule;
+}
+
+void Event::setRecurrenceDates(const std::vector< cDateTime > &dates)
+{
+    d->recurrenceDates = dates;
+}
+
+void Event::addRecurrenceDate(const Kolab::cDateTime &dt)
+{
+    d->recurrenceDates.push_back(dt);
+}
+
+std::vector< cDateTime > Event::recurrenceDates() const
+{
+    return d->recurrenceDates;
+}
+
+void Event::setExceptionDates(const std::vector< cDateTime > &dates)
+{
+    d->exceptionDates = dates;
+}
+
+void Event::addExceptionDate(const Kolab::cDateTime &dt)
+{
+    d->exceptionDates.push_back(dt);
+}
+
+std::vector< cDateTime > Event::exceptionDates() const
+{
+    return d->exceptionDates;
+}
+
+void Event::setTransparency(bool isTransparent)
+{
+    d->isTransparent = isTransparent;
+}
+
+bool Event::transparency() const
+{
+    return d->isTransparent;
+}
+
+void Event::setOrganizer(const ContactReference &organizer)
+{
+    d->organizer = organizer;
+}
+
+ContactReference Event::organizer() const
+{
+    return d->organizer;
+}
+
+void Event::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Event::attendees() const
+{
+    return d->attendees;
+}
+
+void Event::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Event::attachments() const
+{
+    return d->attachments;
+}
+
+void Event::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Event::customProperties() const
+{
+    return d->customProperties;
+}
+
+// void Event::setExceptions(const std::vector< Event > &exceptions)
+// {
+//     d->exceptions = exceptions;
+// }
+// 
+// std::vector< Event > Event::exceptions() const
+// {
+//     return d->exceptions;
+// }
+
+void Event::setAlarms(const std::vector< Alarm > &alarms)
+{
+    d->alarms = alarms;
+}
+
+std::vector< Alarm > Event::alarms() const
+{
+    return d->alarms;
+}
+
+
+
+
+}
\ No newline at end of file
diff --git a/libkolabxml/lib/kolabevent.h b/libkolabxml/lib/kolabevent.h
new file mode 100644
index 0000000..415a1e9
--- /dev/null
+++ b/libkolabxml/lib/kolabevent.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLAB_EVENT_H
+#define KOLAB_EVENT_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+
+class Event {
+public:
+    Event();
+    ~Event();
+    Event(const Event &);
+    void operator=(const Event &);
+    
+    bool isValid() const;
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const cDateTime &);
+    cDateTime created() const;
+    
+    void setLastModified(const cDateTime &);
+    cDateTime lastModified() const;
+    
+    void setSequence(int);
+    int sequence() const;
+    
+    void setClassification(Classification);
+    Classification classification() const;
+
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setStart(const cDateTime &);
+    cDateTime start() const;
+    
+    void setEnd(const cDateTime &);
+    cDateTime end() const;
+    
+    void setDuration(const Duration &);
+    Duration duration() const;
+    
+    void setTransparency(bool isTransparent);
+    bool transparency() const;
+    
+    void setRecurrenceRule(const RecurrenceRule &);
+    RecurrenceRule recurrenceRule() const;
+    
+    void setRecurrenceDates(const std::vector<cDateTime> &);
+    void addRecurrenceDate(const cDateTime &);
+    std::vector<cDateTime> recurrenceDates() const;
+    
+    void setExceptionDates(const std::vector<cDateTime> &);
+    void addExceptionDate(const cDateTime &);
+    std::vector<cDateTime> exceptionDates() const;
+    
+    void setRecurrenceID(const cDateTime &, bool thisandfuture);
+    cDateTime recurrenceID() const;
+    bool thisAndFuture() const;
+    
+    void setSummary(const std::string &);
+    std::string summary() const;
+    
+    void setDescription(const std::string &);
+    std::string description() const;
+    
+    void setPriority(int);
+    int priority() const;
+    
+    void setStatus(Status);
+    Status status() const;
+    
+    void setLocation(const std::string &);
+    std::string location() const;
+    
+    void setOrganizer(const ContactReference &);
+    ContactReference organizer() const;
+    
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
+    
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+/*    TODO what is this? Exceptions it is
+    void setExceptions(const std::vector<Event> &);
+    std::vector<Event> exceptions() const;*/
+    
+    void setAlarms(const std::vector<Alarm> &);
+    std::vector<Alarm> alarms() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+}
+
+#endif
+
diff --git a/libkolabxml/lib/kolabformat.cpp b/libkolabxml/lib/kolabformat.cpp
new file mode 100644
index 0000000..98a42a2
--- /dev/null
+++ b/libkolabxml/lib/kolabformat.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabformat.h"
+
+#include <iostream>
+#include "xcalconversions.h"
+
+#include "xcardconversions.h"
+#include "utils.h"
+#include "kolabconversions.h"
+
+namespace Kolab {
+    
+ErrorSeverity error()
+{
+    return Utils::getError();
+}
+
+std::string errorMessage()
+{
+    return Utils::getErrorMessage();
+}
+
+std::string productId()
+{
+    return Utils::productId();
+}
+
+std::string xCalVersion()
+{
+    return XCAL::global_xCalVersion;
+}
+
+std::string xKolabVersion()
+{
+    return Utils::kolabVersion();
+}
+
+std::string getSerializedUID()
+{
+    return Utils::createdUid();
+}
+
+Kolab::Event readEvent(const std::string& s, bool isUrl)
+{
+    Kolab::XCAL::IncidenceTrait <Kolab::Event >::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Event();
+    }
+    return *ptr;
+}
+
+std::string writeEvent(const Kolab::Event &event)
+{
+    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(event);
+}
+
+Kolab::Todo readTodo(const std::string& s, bool isUrl)
+{
+    XCAL::IncidenceTrait<Kolab::Todo>::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Todo();
+    }
+    return *ptr;
+}
+
+std::string writeTodo(const Kolab::Todo &event)
+{
+    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(event);
+}
+
+Journal readJournal(const std::string& s, bool isUrl)
+{
+    XCAL::IncidenceTrait<Kolab::Journal>::IncidencePtr ptr = XCAL::deserializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Journal();
+    }
+    return *ptr;
+}
+
+std::string writeJournal(const Kolab::Journal &j)
+{
+    return XCAL::serializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(j);
+}
+
+
+Kolab::Contact readContact(const std::string& s, bool isUrl)
+{
+    boost::shared_ptr <Kolab::Contact > ptr = XCARD::deserializeCard<Kolab::Contact>(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Contact();
+    }
+    return *ptr;
+}
+
+std::string writeContact(const Contact &contact)
+{
+    return XCARD::serializeCard(contact);
+}
+
+DistList readDistlist(const std::string& s, bool isUrl)
+{
+    boost::shared_ptr <Kolab::DistList> ptr = XCARD::deserializeCard<Kolab::DistList>(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::DistList();
+    }
+    return *ptr;
+}
+
+std::string writeDistlist(const DistList &list)
+{
+    return XCARD::serializeCard(list);
+}
+
+Note readNote(const std::string& s, bool isUrl)
+{
+    boost::shared_ptr <Kolab::Note> ptr = Kolab::KolabObjects::deserializeObject<Kolab::Note>(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Note();
+    }
+    return *ptr;
+    return Note();
+}
+
+std::string writeNote(const Note &note)
+{
+    return Kolab::KolabObjects::serializeObject<Kolab::Note>(note);
+}
+
+Configuration readConfiguration(const std::string& /*s*/, bool /*isUrl*/)
+{
+//     boost::shared_ptr <Kolab::Configuration> ptr = deserializeConfiguration(s, isUrl);
+//     if (!ptr.get()) {
+//         return Kolab::Configuration();
+//     }
+//     return *ptr;
+    return Configuration();
+}
+
+std::string writeConfiguration(const Configuration &/*config*/)
+{
+//     return serializeConfiguration(config);
+return std::string();
+}
+
+
+}
+
diff --git a/libkolabxml/lib/kolabformat.h b/libkolabxml/lib/kolabformat.h
new file mode 100644
index 0000000..090650c
--- /dev/null
+++ b/libkolabxml/lib/kolabformat.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABFORMAT_H
+#define KOLABFORMAT_H
+
+#include <string>
+#include "kolabcontainers.h"
+#include "kolabtodo.h"
+#include "kolabevent.h"
+#include "kolabjournal.h"
+#include "kolabcontact.h"
+#include "kolabnote.h"
+#include "global_definitions.h"
+
+namespace Kolab {
+
+/**
+ * Check to see if serialization/deserialization was successful.
+ */
+Kolab::ErrorSeverity error();
+std::string errorMessage();
+
+/**
+ * Returns productId string of the last deserialized object.
+ * Updated during deserialization of object.
+ */
+std::string productId();
+/**
+ * Returns KolabFormat version of the last deserialized object.
+ * Updated during deserialization of object.
+ */
+std::string xKolabVersion();
+/**
+ * Returns xCal version of the last deserialized xCal object.
+ * Updated during deserialization of object.
+ */
+std::string xCalVersion();
+
+/**
+ * Returns the UID of the last serialized  object.
+ * Updated during serialization of the object.
+ */
+std::string getSerializedUID();
+
+Kolab::Event readEvent(const std::string& s, bool isUrl);
+std::string writeEvent(const Kolab::Event &);
+
+Kolab::Todo readTodo(const std::string& s, bool isUrl);
+std::string writeTodo(const Kolab::Todo &);
+
+Kolab::Journal readJournal(const std::string& s, bool isUrl);
+std::string writeJournal(const Kolab::Journal &);
+
+Kolab::Contact readContact(const std::string& s, bool isUrl);
+std::string writeContact(const Kolab::Contact &);
+
+Kolab::DistList readDistlist(const std::string& s, bool isUrl);
+std::string writeDistlist(const Kolab::DistList &);
+
+Kolab::Note readNote(const std::string& s, bool isUrl);
+std::string writeNote(const Kolab::Note &);
+
+Kolab::Configuration readConfiguration(const std::string& s, bool isUrl);
+std::string writeConfiguration(const Kolab::Configuration &);
+
+}
+
+#endif // KOLABFORMAT_H
+
diff --git a/libkolabxml/lib/kolabformat.i b/libkolabxml/lib/kolabformat.i
new file mode 100644
index 0000000..30726f3
--- /dev/null
+++ b/libkolabxml/lib/kolabformat.i
@@ -0,0 +1,42 @@
+/* kolabformat.i */
+%module kolabformat
+%{
+
+    /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
+    #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
+
+    #include "global_definitions.h"
+    #include "kolabformat.h"
+    #include "kolabcontainers.h"
+    #include "kolabevent.h"
+    #include "kolabtodo.h"
+    #include "kolabjournal.h"
+    #include "kolabcontact.h"
+%}
+
+%include "std_string.i"
+%include "std_vector.i"
+
+namespace std {
+    %template(vectori) vector<int>;
+    %template(vectors) vector<string>;
+    %template(vectordaypos) vector<Kolab::DayPos>;
+    %template(vectorcs) vector<Kolab::CustomProperty>;
+    %template(vectoraddress) vector<Kolab::Address>;
+    %template(vectoraffiliation) vector<Kolab::Affiliation>;
+    %template(vectoralarm) vector<Kolab::Alarm>;
+    %template(vectorattachment) vector<Kolab::Attachment>;
+    %template(vectorattendee) vector<Kolab::Attendee>;
+    %template(vectorcontactref) vector<Kolab::ContactReference>;
+    %template(vectorrelated) vector<Kolab::Related>;
+    %template(vectortelephone) vector<Kolab::Telephone>;
+    %template(vectordatetime) vector<Kolab::cDateTime>;
+};
+
+%include "global_definitions.h"
+%include "kolabcontainers.h"
+%include "kolabevent.h"
+%include "kolabtodo.h"
+%include "kolabjournal.h"
+%include "kolabcontact.h"
+%include "kolabformat.h"
diff --git a/libkolabxml/lib/kolabjournal.cpp b/libkolabxml/lib/kolabjournal.cpp
new file mode 100644
index 0000000..f13633b
--- /dev/null
+++ b/libkolabxml/lib/kolabjournal.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabjournal.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+struct Journal::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence() {}
+};
+
+Journal::Journal()
+: d(new Journal::Private())
+{
+}
+
+Journal::Journal(const Journal &other)
+: d(new Journal::Private())
+{
+    *d = *other.d;
+}
+
+Journal::~Journal()
+{
+}
+
+void Journal::operator=(const Kolab::Journal &other)
+{
+    *d = *other.d;
+}
+
+bool Journal::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void Journal::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Journal::uid() const
+{
+    return d->uid;
+}
+
+void Journal::setCreated(const Kolab::cDateTime &created)
+{
+    d->created = created;
+}
+
+cDateTime Journal::created() const
+{
+    return d->created;
+}
+
+void Journal::setLastModified(const Kolab::cDateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+cDateTime Journal::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Journal::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Journal::sequence() const
+{
+    return d->sequence;
+}
+
+void Journal::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Journal::classification() const
+{
+    return d->classification;
+}
+
+void Journal::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Journal::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Journal::categories() const
+{
+    return d->categories;
+}
+
+void Journal::setStart(const Kolab::cDateTime &start)
+{
+    d->start = start;
+}
+
+cDateTime Journal::start() const
+{
+    return d->start;
+}
+
+void Journal::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Journal::summary() const
+{
+    return d->summary;
+}
+
+void Journal::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Journal::description() const
+{
+    return d->description;
+}
+
+
+void Journal::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Journal::status() const
+{
+    return d->status;
+}
+
+void Journal::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Journal::attendees() const
+{
+    return d->attendees;
+}
+
+void Journal::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Journal::attachments() const
+{
+    return d->attachments;
+}
+
+void Journal::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Journal::customProperties() const
+{
+    return d->customProperties;
+}
+
+
+}//Namespace
\ No newline at end of file
diff --git a/libkolabxml/lib/kolabjournal.h b/libkolabxml/lib/kolabjournal.h
new file mode 100644
index 0000000..9a904d3
--- /dev/null
+++ b/libkolabxml/lib/kolabjournal.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABJOURNAL_H
+#define KOLABJOURNAL_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+
+class Journal {
+public:
+    Journal();
+    ~Journal();
+    Journal(const Journal &);
+    void operator=(const Journal &);
+    
+    bool isValid() const;
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const cDateTime &);
+    cDateTime created() const;
+    
+    void setLastModified(const cDateTime &);
+    cDateTime lastModified() const;
+    
+    void setSequence(int);
+    int sequence() const;
+    
+    void setClassification(Classification);
+    Classification classification() const;
+
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setStart(const cDateTime &);
+    cDateTime start() const;
+    
+    void setSummary(const std::string &);
+    std::string summary() const;
+    
+    void setDescription(const std::string &);
+    std::string description() const;
+    
+    void setStatus(Status);
+    Status status() const;
+    
+    //TODO Contacts
+    
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
+    
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+
+}
+
+#endif
+
diff --git a/libkolabxml/lib/kolabnote.cpp b/libkolabxml/lib/kolabnote.cpp
new file mode 100644
index 0000000..c7931bb
--- /dev/null
+++ b/libkolabxml/lib/kolabnote.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "kolabnote.h"
+
+namespace Kolab {
+
+struct Note::Private
+{
+    Private()
+    : classification(ClassPublic){}
+    
+    std::string uid;
+    cDateTime created;
+    cDateTime lastModified;
+    std::vector< std::string > categories;
+    Classification classification;
+    
+    std::string summary;
+    std::string description;
+    std::string color;
+    
+    std::vector<Attachment> attachments;
+    std::vector<CustomProperty> customProperties;
+};
+
+Note::Note()
+: d(new Note::Private())
+{
+}
+
+Note::Note(const Note &other)
+: d(new Note::Private())
+{
+    *d = *other.d;
+}
+
+Note::~Note()
+{
+}
+
+void Note::operator=(const Kolab::Note &other)
+{
+    *d = *other.d;
+}
+
+bool Note::operator==(const Kolab::Note& other) const
+{
+    return ( d->uid == other.uid() &&
+    d->created == other.created() &&
+    d->lastModified == other.lastModified() &&
+    d->categories == other.categories() &&
+    d->classification == other.classification() &&
+    d->summary == other.summary() &&
+    d->description == other.description() &&
+    d->color == other.color() &&
+    d->attachments == other.attachments() &&
+    d->customProperties == other.customProperties());
+}
+
+bool Note::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void Note::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Note::uid() const
+{
+    return d->uid;
+}
+
+void Note::setCreated(const Kolab::cDateTime &created)
+{
+    d->created = created;
+}
+
+cDateTime Note::created() const
+{
+    return d->created;
+}
+
+void Note::setLastModified(const Kolab::cDateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+cDateTime Note::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Note::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Note::classification() const
+{
+    return d->classification;
+}
+
+void Note::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Note::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Note::categories() const
+{
+    return d->categories;
+}
+
+void Note::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Note::summary() const
+{
+    return d->summary;
+}
+
+void Note::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Note::description() const
+{
+    return d->description;
+}
+
+void Note::setColor(const std::string &color)
+{
+    d->color = color;
+}
+
+std::string Note::color() const
+{
+    return d->color;
+}
+
+void Note::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Note::attachments() const
+{
+    return d->attachments;
+}
+
+void Note::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Note::customProperties() const
+{
+    return d->customProperties;
+}
+
+} //Note
diff --git a/libkolabxml/lib/kolabnote.h b/libkolabxml/lib/kolabnote.h
new file mode 100644
index 0000000..6edffb6
--- /dev/null
+++ b/libkolabxml/lib/kolabnote.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABNOTE_H
+#define KOLABNOTE_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+    
+    class Note {
+    public:
+        Note();
+        ~Note();
+        Note(const Note &);
+        void operator=(const Note &);
+        bool operator==(const Note &) const;
+        
+        bool isValid() const;
+        
+        void setUid(const std::string &);
+        std::string uid() const;
+        
+        void setCreated(const cDateTime &);
+        cDateTime created() const;
+        
+        void setLastModified(const cDateTime &);
+        cDateTime lastModified() const;
+        
+        void setClassification(Classification);
+        Classification classification() const;
+        
+        void setCategories(const std::vector<std::string> &);
+        void addCategory(const std::string &);
+        std::vector<std::string> categories() const;
+        
+        void setSummary(const std::string &);
+        std::string summary() const;
+        
+        void setDescription(const std::string &);
+        std::string description() const;
+        
+        void setColor(const std::string &);
+        std::string color() const;
+        
+        void setAttachments(const std::vector<Attachment> &);
+        std::vector<Attachment> attachments() const;
+        
+        void setCustomProperties(const std::vector<CustomProperty> &);
+        std::vector<CustomProperty> customProperties() const;
+    private:
+        struct Private;
+        boost::scoped_ptr<Private> d;
+    };
+
+}
+
+#endif
+
diff --git a/libkolabxml/lib/kolabtodo.cpp b/libkolabxml/lib/kolabtodo.cpp
new file mode 100644
index 0000000..97d2e03
--- /dev/null
+++ b/libkolabxml/lib/kolabtodo.cpp
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabtodo.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+    
+    
+struct Todo::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence(),
+    percentComplete(0){}
+    
+    cDateTime due;
+    int percentComplete;
+};
+
+Todo::Todo()
+: d(new Todo::Private())
+{
+    
+}
+
+Todo::Todo(const Todo &other)
+: d(new Todo::Private())
+{
+    *d = *other.d;
+}
+
+Todo::~Todo()
+{
+    
+}
+
+void Todo::operator=(const Kolab::Todo &other)
+{
+    *d = *other.d;
+}
+
+bool Todo::isValid() const
+{
+    return !d->uid.empty();
+}
+
+void Todo::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Todo::uid() const
+{
+    return d->uid;
+}
+
+void Todo::setCreated(const Kolab::cDateTime &created)
+{
+    d->created = created;
+}
+
+cDateTime Todo::created() const
+{
+    return d->created;
+}
+
+void Todo::setLastModified(const Kolab::cDateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+cDateTime Todo::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Todo::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Todo::sequence() const
+{
+    return d->sequence;
+}
+
+void Todo::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Todo::classification() const
+{
+    return d->classification;
+}
+
+void Todo::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Todo::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Todo::categories() const
+{
+    return d->categories;
+}
+
+void Todo::setRelatedTo(const std::vector< std::string > &related)
+{
+    d->relatedTo = related;
+}
+
+void Todo::addRelatedTo(const std::string &related)
+{
+    d->relatedTo.push_back(related);
+}
+
+std::vector< std::string > Todo::relatedTo() const
+{
+    return d->relatedTo;
+}
+
+void Todo::setStart(const Kolab::cDateTime &start)
+{
+    d->start = start;
+}
+
+cDateTime Todo::start() const
+{
+    return d->start;
+}
+
+void Todo::setDue(const Kolab::cDateTime &due)
+{
+    d->due = due;
+}
+
+cDateTime Todo::due() const
+{
+    return d->due;
+}
+
+void Todo::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture)
+{
+    d->recurrenceID = rID;
+    d->thisAndFuture = thisandfuture;
+}
+
+cDateTime Todo::recurrenceID() const
+{
+    return d->recurrenceID;
+}
+
+bool Todo::thisAndFuture() const
+{
+    return d->thisAndFuture;
+}
+
+void Todo::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Todo::summary() const
+{
+    return d->summary;
+}
+
+void Todo::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Todo::description() const
+{
+    return d->description;
+}
+
+void Todo::setPriority(int priority)
+{
+    d->priority = priority;
+}
+
+int Todo::priority() const
+{
+    return d->priority;
+}
+
+void Todo::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Todo::status() const
+{
+    return d->status;
+}
+
+void Todo::setPercentComplete(int complete)
+{
+    d->percentComplete = complete;
+}
+    
+int Todo::percentComplete() const
+{
+    return d->percentComplete;
+}
+
+void Todo::setLocation(const std::string &location)
+{
+    d->location = location;
+}
+
+std::string Todo::location() const
+{
+    return d->location;
+}
+
+void Todo::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+    d->rrule = rrule;
+}
+
+RecurrenceRule Todo::recurrenceRule() const
+{
+    return d->rrule;
+}
+
+void Todo::setRecurrenceDates(const std::vector< cDateTime > &dates)
+{
+    d->recurrenceDates = dates;
+}
+
+void Todo::addRecurrenceDate(const Kolab::cDateTime &dt)
+{
+    d->recurrenceDates.push_back(dt);
+}
+
+std::vector< cDateTime > Todo::recurrenceDates() const
+{
+    return d->recurrenceDates;
+}
+
+void Todo::setExceptionDates(const std::vector< cDateTime > &dates)
+{
+    d->exceptionDates = dates;
+}
+
+void Todo::addExceptionDate(const Kolab::cDateTime &dt)
+{
+    d->exceptionDates.push_back(dt);
+}
+
+std::vector< cDateTime > Todo::exceptionDates() const
+{
+    return d->exceptionDates;
+}
+
+void Todo::setOrganizer(const ContactReference &organizer)
+{
+    d->organizer = organizer;
+}
+
+ContactReference Todo::organizer() const
+{
+    return d->organizer;
+}
+
+void Todo::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Todo::attendees() const
+{
+    return d->attendees;
+}
+
+void Todo::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Todo::attachments() const
+{
+    return d->attachments;
+}
+
+void Todo::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Todo::customProperties() const
+{
+    return d->customProperties;
+}
+
+void Todo::setAlarms(const std::vector< Alarm > &alarms)
+{
+    d->alarms = alarms;
+}
+
+std::vector< Alarm > Todo::alarms() const
+{
+    return d->alarms;
+}
+
+}
\ No newline at end of file
diff --git a/libkolabxml/lib/kolabtodo.h b/libkolabxml/lib/kolabtodo.h
new file mode 100644
index 0000000..ce547e3
--- /dev/null
+++ b/libkolabxml/lib/kolabtodo.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLAB_TODO_H
+#define KOLAB_TODO_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+    
+
+class Todo {
+public:
+    Todo();
+    ~Todo();
+    Todo(const Todo &);
+    void operator=(const Todo &);
+    
+    bool isValid() const;
+
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const cDateTime &);
+    cDateTime created() const;
+    
+    void setLastModified(const cDateTime &);
+    cDateTime lastModified() const;
+    
+    void setSequence(int);
+    int sequence() const;
+    
+    void setClassification(Classification);
+    Classification classification() const;
+
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setRelatedTo(const std::vector<std::string> &);
+    void addRelatedTo(const std::string &);
+    std::vector<std::string> relatedTo() const;
+    
+    void setStart(const cDateTime &);
+    cDateTime start() const;
+    
+    void setDue(const cDateTime &);
+    cDateTime due() const;
+
+    void setRecurrenceRule(const RecurrenceRule &);
+    RecurrenceRule recurrenceRule() const;
+    
+    void setRecurrenceDates(const std::vector<cDateTime> &);
+    void addRecurrenceDate(const cDateTime &);
+    std::vector<cDateTime> recurrenceDates() const;
+    
+    void setExceptionDates(const std::vector<cDateTime> &);
+    void addExceptionDate(const cDateTime &);
+    std::vector<cDateTime> exceptionDates() const;
+    
+    void setRecurrenceID(const cDateTime &, bool thisandfuture);
+    cDateTime recurrenceID() const;
+    bool thisAndFuture() const;
+    
+    void setSummary(const std::string &);
+    std::string summary() const;
+    
+    void setDescription(const std::string &);
+    std::string description() const;
+    
+    void setPriority(int);
+    int priority() const;
+    
+    void setStatus(Status);
+    Status status() const;
+    
+    void setPercentComplete(int);
+    int percentComplete() const;
+    
+    void setLocation(const std::string &);
+    std::string location() const;
+    
+    void setOrganizer(const ContactReference &);
+    ContactReference organizer() const;
+    
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
+    
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+    
+    void setAlarms(const std::vector<Alarm> &);
+    std::vector<Alarm> alarms() const;
+    
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+}
+
+#endif
+
diff --git a/libkolabxml/lib/php/CMakeLists.txt b/libkolabxml/lib/php/CMakeLists.txt
new file mode 100644
index 0000000..2d95c36
--- /dev/null
+++ b/libkolabxml/lib/php/CMakeLists.txt
@@ -0,0 +1,36 @@
+#Generate PHP wrapper
+include_directories(../)
+
+set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
+    COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  ../kolabformat.i
+    COMMENT "Generating php bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS ../kolabformat.i kolabxml
+    VERBATIM
+    )
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
+
+
+#Compile PHP Bindings
+# Since there is no php library we can't compile with -Wl,--no-undefined
+if (APPLE)
+    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flat_namespace -undefined suppress" )
+endif()
+
+find_package(PHP4)
+include_directories(${PHP4_INCLUDE_PATH})
+add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
+target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+
+configure_file(test.php ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
+
+install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
+
+install( FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php
+  test.php
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
\ No newline at end of file
diff --git a/libkolabxml/lib/php/test.php b/libkolabxml/lib/php/test.php
new file mode 100755
index 0000000..48c3304
--- /dev/null
+++ b/libkolabxml/lib/php/test.php
@@ -0,0 +1,162 @@
+<?php
+//run using "php -d enable_dl=On -d extension=./kolabformat.so  test.php"
+
+include("kolabformat.php");
+
+function assertequal($got, $expect, $name) {
+	if ($got == $expect) {
+		print "OK - $name\n";
+		return true;
+	}
+	else {
+		print "FAIL - $name\n";
+		print "-- Expected " . var_export($expect, true) . ", got " . var_export($got, true) . " --\n";
+		return false;
+	}
+}
+
+function assertcontains($haystack, $needle, $name) {
+	// remove whitespace
+	$haystack = preg_replace('/\n\s*/ims', '', $haystack);
+	$needle = preg_replace('/\n\s*/ims', '', $needle);
+
+	return assertequal(substr(strstr($haystack, $needle), 0, strlen($needle)), $needle, $name);
+}
+
+function asserttrue($arg, $name) {
+	return assertequal($arg, true, $name);
+}
+
+function assertfalse($arg, $name) {
+	return assertequal($arg, false, $name);
+}
+
+function array2vector($arr) {
+	$vec = new vectors;
+	foreach ((array)$arr as $val)
+		$vec->push($val);
+	return $vec;
+}
+
+
+/////// Test Event
+
+$e = new Event();
+$e->setCreated(new cDateTime(2012,3,14, 9,5,30));
+$e->setStart(new cDateTime(2012,7,31));
+$d = new cDateTime(2009,10,12);
+assertequal($e->exceptionDates()->size(), 0, "Event::exceptionDates()");
+$e->addExceptionDate($d);
+assertequal($e->exceptionDates()->size(), 1, "Event::addExceptionDate()");
+
+$r = new RecurrenceRule();
+$r->setFrequency(RecurrenceRule::Minutely);
+
+$bysec = new vectori();
+$bysec->push(1);
+$bysec->push(3);
+
+$r->setBySecond($bysec);
+$e->setRecurrenceRule($r);
+
+$xml = kolabformat::writeEvent($e);
+#print $xml;
+assertcontains($xml, '<dtstart><date>2012-07-31</date></dtstart>', "Event::setStart() with date only");
+assertcontains($xml, '<created><date-time>2012-03-14T09:05:30Z</date-time></created>', "Event::setCreated() with date-time");
+assertcontains($xml, '<rrule><recur><freq>MINUTELY</freq>', "RecurrenceRule::setFrequency()");
+assertcontains($xml, '<rrule><recur><freq>MINUTELY</freq><bysecond>1</bysecond><bysecond>3</bysecond></recur></rrule>', "RecurrenceRule::setBySecond()");
+assertcontains($xml, '<exdate><date>2009-10-12</date></exdate>', "Event Recurrence Exceptions");
+
+$e1 = kolabformat::readEvent($xml, false);
+assertequal($xml, kolabformat::writeEvent($e1), "kolabformat::readEvent() => kolabformat::writeEvent()");
+
+$s = $e1->start();
+assertequal(sprintf('%d-%d-%d', $s->year(), $s->month(), $s->day()), '2012-7-31', "Event::start()");
+
+$r = $e1->recurrenceRule();
+assertequal($r->frequency(), RecurrenceRule::Minutely, "RecurrenceRule::frequency()");
+assertequal($r->bysecond()->size(), 2, "RecurrenceRule::bysecond()");
+assertequal($e1->exceptionDates()->size(), 1, "Read Event::exceptionDates()");
+
+
+/////// Test Contact
+
+$c = new Contact;
+$c->setName("Contact-FN");
+
+$nc = new NameComponents;
+$nc->setSurnames(array2vector("Surname"));
+$nc->setGiven(array2vector("Given"));
+$nc->setAdditional(array2vector(array("Middle1", "Middle2")));
+$nc->setPrefixes(array2vector("Prefix"));
+#$nc->setSuffixes(new vectors);
+
+assertcontains($nc->surnames()->size(),    1, "NameComponents::setSurnames()");
+assertcontains($nc->given()->size(),       1, "NameComponents::setGiven()");
+assertcontains($nc->additional()->size(),  2, "NameComponents::setAdditional()");
+assertcontains($nc->prefixes()->size(),    1, "NameComponents::setPrefixes()");
+assertcontains($nc->suffixes()->size(),    0, "NameComponents::suffixes()");
+
+$c->setNameComponents($nc);
+$c->setTitles(array2vector("MyProfession"));
+
+$pic = "R0lGODlhEgASAIAAAMDAwAAAACH5BAEAAAAALAAAAAASABIAQAIPhI+py+0Po5y02ouz3pwXADs=";
+$c->setPhoto(base64_decode($pic), 'image/gif');
+$c->setGPSpos(array2vector("geo:46.952585,7.43766"));
+
+$bd = new cDateTime(1980,8,1);
+$c->setBDay($bd);
+
+$vcs = new vectorcs;
+$vcs->push(new CustomProperty("initials", "KF"));
+$c->setCustomProperties($vcs);
+
+$xml = kolabformat::writeContact($c);
+#print $xml;
+assertcontains($xml, "<uid><uri>urn:uuid:", "Generate Contact UID as urn::uuid");
+assertcontains($xml, "<n><surname>Surname</surname><given>Given</given><additional>Middle1</additional><additional>Middle2</additional><prefix>Prefix</prefix></n>", "Contact::setNameComponents()");
+assertcontains($xml, "<title><text>MyProfession</text></title>", "Contact::setTitles()");
+assertcontains($xml, "<photo><uri>data:image/gif;base64,$pic</uri></photo>", "Contact::setPhoto()");
+assertcontains($xml, "<bday><date>19800801</date></bday>", "Contact::setBDay()");
+assertcontains($xml, "<geo><uri>geo:46.952585,7.43766</uri></geo>", "Contact::setGPSpos()");
+
+$c1 = kolabformat::readContact($xml, false);
+assertequal($xml, kolabformat::writeContact($c1), "kolabformat::readContact() => kolabformat::writeContact()");
+assertequal($c1->photoMimetype(), "image/gif", "Contact::photoMimetype()");
+assertequal($c1->uid(), kolabformat::getSerializedUID(), "kolabformat::getSerializedUID()");
+
+$c1->setBDay(new cDateTime);
+$xml = kolabformat::writeContact($c);
+assertfalse(strpos($xml, '<bday><date>'), "Unset BDay with empty cDateTime");
+
+
+/////// Test DistList
+
+$dl = new DistList;
+$dl->setName("DalistÄÖŸ");
+
+$m = new vectorcontactref;
+$a = new ContactReference(ContactReference::EmailReference, "a at localhost", "Member-A");
+$m->push($a);
+
+$b = new ContactReference(ContactReference::UidReference, "x-member-b-fff");
+$b->setName("Member-B");
+$m->push($b);
+
+#$c = new ContactReference(ContactReference::EmailAndUidReference, "c at localhost", "dddaab06-0000-0000-eeb5-cc64ff7f0000");
+#$c->setName("Member-C");
+#$m->push($c);
+
+assertequal($m->size(), 2, "vectorcontactref::size()");
+$dl->setMembers($m);
+
+$xml = kolabformat::writeDistlist($dl);
+#print $xml;
+assertcontains($xml, '<fn><text>DalistÄÖŸ</text></fn>', "kolabformat::writeDistlist(): FN (UTF-8)");
+assertcontains($xml, '<uri>mailto:Member%2DA%3Ca%40localhost%3E</uri>', "kolabformat::writeDistlist(): mailto uri");
+assertcontains($xml, '<member><uri>urn:uuid:x-member-b-fff</uri>', "kolabformat::writeDistlist(): member urn::uuid");
+
+?>
+
+
+
diff --git a/libkolabxml/lib/python/CMakeLists.txt b/libkolabxml/lib/python/CMakeLists.txt
new file mode 100644
index 0000000..397405c
--- /dev/null
+++ b/libkolabxml/lib/python/CMakeLists.txt
@@ -0,0 +1,34 @@
+#Generate Python wrapper
+include_directories(../)
+
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
+    COMMAND ${SWIG} -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} ../kolabformat.i
+    COMMENT "Generating python bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS ../kolabformat.i kolabxml
+    VERBATIM
+    )
+
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
+#Compile Python Bindings
+find_package(PythonLibs)
+include_directories(${PYTHON_INCLUDE_DIRS})
+
+# python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
+add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
+
+configure_file(test.py ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
+
+install(TARGETS pythonbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
+
+install( FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.py
+  test.py
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
\ No newline at end of file
diff --git a/libkolabxml/lib/python/test.py b/libkolabxml/lib/python/test.py
new file mode 100644
index 0000000..f7a306e
--- /dev/null
+++ b/libkolabxml/lib/python/test.py
@@ -0,0 +1,16 @@
+import kolabformat
+e = kolabformat.Event()
+
+ex = e.exceptionDates()
+ex.size()
+ex.push_back(kolabformat.cDateTime(1,1,1))
+ex.size()
+e.exceptionDates().size()
+e.setExceptionDates(ex)
+e.exceptionDates().size()
+
+string = kolabformat.writeEvent(e);
+print string;
+e1 = kolabformat.readEvent(string, False);
+string = kolabformat.writeEvent(e1);
+print string;
\ No newline at end of file
diff --git a/libkolabxml/lib/shared_conversions.h b/libkolabxml/lib/shared_conversions.h
new file mode 100644
index 0000000..fd64ae5
--- /dev/null
+++ b/libkolabxml/lib/shared_conversions.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SHAREDCONVERSIONS_H
+#define SHAREDCONVERSIONS_H
+
+#include <xsd/cxx/tree/date-time.hxx>
+#include "kolabcontainers.h"
+#include <boost/shared_ptr.hpp>
+#include "utils.h"
+#include <bindings/iCalendar-params.hxx>
+
+namespace Kolab {
+    namespace Shared {
+typedef boost::shared_ptr<cDateTime> cDateTimePtr;
+
+typedef ::xsd::cxx::tree::type type;
+typedef ::xsd::cxx::tree::simple_type< type > simple_type;
+typedef ::xsd::cxx::tree::date< char, simple_type > date;
+typedef ::xsd::cxx::tree::date_time< char, simple_type > date_time;
+
+using namespace Utils;
+
+cDateTimePtr toDate(const date &dt)
+{
+    cDateTimePtr date(new cDateTime());
+    date->setDate(dt.year(), dt.month(), dt.day());
+    return date;
+}
+
+cDateTimePtr toDate(const date_time &dt)
+{
+    cDateTimePtr date(new cDateTime());
+    date->setDate(dt.year(), dt.month(), dt.day());
+    date->setTime(dt.hours(), dt.minutes(), dt.seconds());
+    if (dt.zone_present()) {
+        date->setUTC(true);
+    }
+    return date;
+}
+
+date_time fromDateTime(const cDateTime &d)
+{
+    date_time date(d.year(), d.month(), d.day(), d.hour(), d.minute(), d.second());
+    if (d.isUTC()) {
+        //Setting both zone hours/and zone minutes to zero results in a Z being appended to indicate UTC
+        date.zone_hours(0);
+        date.zone_minutes(0);
+    }
+    return date;
+}
+
+date fromDate(const cDateTime &d)
+{
+    date de(d.year(), d.month(), d.day());
+    return de;
+}
+
+std::string toURN(const std::string &uid)
+{
+    if (uid.substr(0, 9) == std::string("urn:uuid:")) {
+        return uid;
+    }
+    return std::string("urn:uuid:")+uid;
+}
+
+std::string fromURN(const std::string &uri)
+{
+    if (uri.substr(0, 9) != std::string("urn:uuid:")) {
+        WARNING("not a urn");
+        return uri;
+    }
+    return uri.substr(9);
+}
+
+Kolab::ContactReference toContactReference(const std::string &uri) {
+    std::string name;
+    if (uri.substr(0, 9) == std::string("urn:uuid:")) {
+        return Kolab::ContactReference(Kolab::ContactReference::UidReference, fromURN(uri));
+    }
+    const std::string &email = fromMailto(uri, name);
+    return Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name);
+}
+
+std::string fromContactReference(const Kolab::ContactReference &c, bool embeddName = true) {
+    switch (c.type()) {
+        case ContactReference::UidReference:
+            return toURN(c.uid());
+        case ContactReference::EmailReference:
+        case ContactReference::EmailAndUidReference:
+            if (embeddName) {
+                return toMailto(c.email(), c.name());
+            }
+            return toMailto(c.email());
+        case ContactReference::Invalid:
+        default:
+            WARNING("Tried serializing invalid ContactReference");
+    }
+    return std::string();
+}
+
+
+
+
+    } //Namespace
+} //Namespace
+
+#endif
\ No newline at end of file
diff --git a/libkolabxml/lib/uricode.h b/libkolabxml/lib/uricode.h
new file mode 100644
index 0000000..54bf542
--- /dev/null
+++ b/libkolabxml/lib/uricode.h
@@ -0,0 +1,122 @@
+// Uri encode and decode.
+// RFC1630, RFC1738, RFC2396
+
+#include <string>
+#include <assert.h>
+
+const char HEX2DEC[256] = 
+{
+    /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
+    /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
+    
+    /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    
+    /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    
+    /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
+};
+
+std::string UriDecode(const std::string & sSrc)
+{
+    // Note from RFC1630:  "Sequences which start with a percent sign
+    // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
+    // for future extension"
+    
+    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
+    const int SRC_LEN = sSrc.length();
+    const unsigned char * const SRC_END = pSrc + SRC_LEN;
+    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
+    
+    char * const pStart = new char[SRC_LEN];
+    char * pEnd = pStart;
+    
+    while (pSrc < SRC_LAST_DEC)
+    {
+        if (*pSrc == '%')
+        {
+            char dec1, dec2;
+            if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
+                && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))
+            {
+                *pEnd++ = (dec1 << 4) + dec2;
+                pSrc += 3;
+                continue;
+            }
+        }
+        
+        *pEnd++ = *pSrc++;
+    }
+    
+    // the last 2- chars
+    while (pSrc < SRC_END)
+        *pEnd++ = *pSrc++;
+    
+    std::string sResult(pStart, pEnd);
+    delete [] pStart;
+    return sResult;
+}
+
+// Only alphanum is safe.
+const char SAFE[256] =
+{
+    /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */
+    /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
+    
+    /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
+    /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
+    /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
+    /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
+    
+    /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    
+    /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+};
+
+std::string UriEncode(const std::string & sSrc)
+{
+    const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
+    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
+    const int SRC_LEN = sSrc.length();
+    unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
+    unsigned char * pEnd = pStart;
+    const unsigned char * const SRC_END = pSrc + SRC_LEN;
+    
+    for (; pSrc < SRC_END; ++pSrc)
+    {
+        if (SAFE[*pSrc]) 
+            *pEnd++ = *pSrc;
+        else
+        {
+            // escape this char
+            *pEnd++ = '%';
+            *pEnd++ = DEC2HEX[*pSrc >> 4];
+            *pEnd++ = DEC2HEX[*pSrc & 0x0F];
+        }
+    }
+    
+    std::string sResult((char *)pStart, (char *)pEnd);
+    delete [] pStart;
+    return sResult;
+}
+
diff --git a/libkolabxml/lib/utils.cpp b/libkolabxml/lib/utils.cpp
new file mode 100644
index 0000000..8096f54
--- /dev/null
+++ b/libkolabxml/lib/utils.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "utils.h"
+#include <string>
+
+#include <boost/version.hpp>
+
+#if BOOST_VERSION >= 104200
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#else
+#include <uuid/uuid.h>
+#endif
+
+#include <boost/lexical_cast.hpp>
+#include <boost/thread.hpp>
+#include <time.h>
+#include "base64.h"
+#include "uricode.h"
+
+namespace Kolab {
+    
+namespace Utils {
+
+/**
+ * We have to store our global variables thread-local to ensure thread-safety.
+ */
+struct Global {
+    std::string createdUID;
+    std::string productId;
+    std::string xKolabVersion;
+    
+    ErrorSeverity errorBit;
+    std::string errorMessage;
+};
+
+boost::thread_specific_ptr<Global> ptr;
+class ThreadLocal
+{
+public:
+    static Global &inst()
+    {
+        Global *t = ptr.get();
+//         std::cout << "inst " << boost::this_thread::get_id() << std::endl;
+        if (!t) {
+//             std::cout << "initialize Global" << std::endl;
+            t = new Global();
+            ptr.reset(t);
+        }
+        return *t;
+    }
+};
+
+void setKolabVersion(const std::string &s)
+{
+    ThreadLocal::inst().xKolabVersion = s;
+}
+
+std::string kolabVersion()
+{
+    return ThreadLocal::inst().xKolabVersion;
+}
+
+void setProductId(const std::string &s)
+{
+    ThreadLocal::inst().productId = s;
+}
+
+std::string productId()
+{
+    return ThreadLocal::inst().productId;
+}
+
+
+void setCreatedUid(const std::string &s)
+{
+    ThreadLocal::inst().createdUID = s;
+}
+
+std::string createdUid()
+{
+    return ThreadLocal::inst().createdUID;
+}
+
+
+std::string getUID(const std::string &s)
+{
+    if (s.empty()) {
+#if BOOST_VERSION >= 104200
+        boost::uuids::uuid u; // initialize uuid
+        return boost::uuids::to_string(u);
+#else
+        uuid_t u;
+        uuid_generate(u);
+        char out[37];
+        uuid_unparse(u,out);
+        return std::string(out, 36); //We don't need the terminating \0
+#endif
+    }
+    return s;
+}
+
+cDateTime getCurrentTime()
+{
+    time_t rawtime;
+    struct tm * ptm;
+    time(&rawtime);
+    ptm = gmtime(&rawtime);
+    return cDateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
+}
+
+
+void logMessage(const std::string &m, ErrorSeverity s)
+{
+    switch (s) {
+        case NoError:
+            std::cout << "Debug: " << m << std::endl;
+            break;
+        case Warning:
+            std::cerr << "Warning: " << m << std::endl;
+            break;
+        case Error:
+            std::cerr << "Error: " << m << std::endl;
+            if (ThreadLocal::inst().errorBit < Error) {
+                ThreadLocal::inst().errorBit = Error;
+                ThreadLocal::inst().errorMessage = m;
+            }
+            break;
+        case Critical:
+        default:
+            std::cerr << "Critical: " << m << std::endl;
+            if (ThreadLocal::inst().errorBit < Critical) {
+                ThreadLocal::inst().errorBit = Critical;
+                ThreadLocal::inst().errorMessage = m;
+            }
+    }
+}
+
+void logMessage(const std::string &message, const std::string &file, int line, ErrorSeverity s)
+{
+   logMessage(file+" "+boost::lexical_cast<std::string>(line)+": " + "  " + message, s);
+}
+
+void clearErrors()
+{
+    ThreadLocal::inst().errorBit = NoError;
+    ThreadLocal::inst().errorMessage.clear();
+}
+
+ErrorSeverity getError()
+{
+    return ThreadLocal::inst().errorBit;
+}
+
+std::string getErrorMessage()
+{
+    return ThreadLocal::inst().errorMessage;
+}
+
+
+std::string uriInlineEncoding(const std::string &s, const std::string &mimetype)
+{
+    return std::string("data:")+mimetype+std::string(";base64,")+base64_encode(reinterpret_cast<const unsigned char*>(s.c_str()), s.length());
+}
+
+std::string uriInlineDecoding(const std::string &s, std::string &mimetype)
+{
+    if (s.substr(0, 5) != std::string("data:")) {
+        ERROR("wrong picture encoding");
+        std::cout << s <<  "      " << s.substr(0, 5) << std::endl;
+        return std::string();
+    }
+    std::size_t pos = s.find(";",5);
+    if (pos == std::string::npos) {
+        ERROR("wrong picture encoding");
+        std::cout << s <<  "      " << s.substr(0, 5) << std::endl;
+        return std::string();
+    }
+    mimetype = s.substr(5, pos-5);
+    if (s.substr(pos+1, 6) != std::string("base64")) {
+        ERROR("wrong picture encoding");
+        std::cout << s <<  "      " << s.substr(pos+1, 6) << std::endl;
+        return std::string();
+    }
+    return base64_decode(s.substr(pos+8, s.size()-(pos+8)));
+}
+
+std::string toMailto(const std::string &email, const std::string &name)
+{
+    std::string mailto;
+    if (!name.empty()) {
+        mailto.append(name);
+    }
+    mailto.append("<");
+    mailto.append(email);
+    mailto.append(">");
+    return std::string("mailto:")+UriEncode(mailto);
+}
+
+std::string fromMailto(const std::string &mailtoUri, std::string &name)
+{
+    const std::string &decoded = UriDecode(mailtoUri);
+    if (decoded.substr(0, 7).compare("mailto:")) {
+        WARNING("no mailto address");
+        std::cout << decoded << std::endl;
+        return mailtoUri;
+    }
+    std::size_t begin = decoded.find('<',7);
+    if (begin == std::string::npos) {
+        WARNING("no mailto address");
+        std::cout << decoded << std::endl;
+        return mailtoUri;
+    }
+    std::size_t end = decoded.find('>', begin);
+    if (end == std::string::npos) {
+        WARNING("no mailto address");
+        std::cout << decoded << std::endl;
+        return mailtoUri;
+    }
+    name = decoded.substr(7, begin-7);
+    const std::string &email = decoded.substr(begin+1, end-begin-1);
+    return email;
+}
+
+std::string fromMailto(const std::string &mailtoUri)
+{
+    std::string n;
+    return fromMailto(mailtoUri, n);
+}
+
+} //Namespace
+
+} //Namespace
\ No newline at end of file
diff --git a/libkolabxml/lib/utils.h b/libkolabxml/lib/utils.h
new file mode 100644
index 0000000..15bf376
--- /dev/null
+++ b/libkolabxml/lib/utils.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <string>
+#include "kolabcontainers.h"
+#include "global_definitions.h"
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace Kolab {
+
+    namespace Utils {
+/**
+ * Returns a new globally unique UID if the parameter is empty
+ */
+std::string getUID(const std::string & = std::string());
+
+cDateTime getCurrentTime();
+
+void logMessage(const std::string &,const std::string &, int, ErrorSeverity s);
+     
+#define LOG(message) logMessage(message,__FILE__, __LINE__, NoError);
+#define WARNING(message) logMessage(message,__FILE__, __LINE__, Warning);
+#define ERROR(message) logMessage(message,__FILE__, __LINE__, Error);
+#define CRITICAL(message) logMessage(message,__FILE__, __LINE__, Critical);
+
+void logMessage(const std::string &, ErrorSeverity s = Warning);
+
+
+/**
+ * The following values must be updated by the serialization/deserialization functinos
+ */
+
+
+/**
+ * The error state after serialization/deserialization
+ */
+void clearErrors();
+ErrorSeverity getError();
+std::string getErrorMessage();
+
+/**
+ * The uid of the last serialized object
+ */
+void setCreatedUid(const std::string &);
+std::string createdUid();
+
+/**
+ * The productId of the last deserialized object
+ */
+void setProductId(const std::string &);
+std::string productId();
+
+/**
+ * The Kolab Format Version of the last deserialized object
+ */
+void setKolabVersion(const std::string &);
+std::string kolabVersion();
+
+/**
+ * Helper functions for save conversion of integer types (so we can catch overflows)
+ */
+
+template <typename T>
+int convertToInt(T integer)
+{
+    try {
+        return boost::numeric_cast<int>(integer);
+    } catch(boost::numeric::negative_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::positive_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        ERROR(e.what());
+    }
+    return 0;
+}
+
+template <typename T> 
+T fromInt(int integer)
+{
+    try {
+        return boost::numeric_cast<T>(integer);
+    } catch(boost::numeric::negative_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::positive_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        ERROR(e.what());
+    }
+    return 0;
+}
+
+std::string uriInlineEncoding(const std::string &, const std::string &mime);
+std::string uriInlineDecoding(const std::string &s, std::string &mimetype);
+
+std::string toMailto(const std::string &email, const std::string &name = std::string());
+std::string fromMailto(const std::string &mailtoUri, std::string &name);
+std::string fromMailto(const std::string &mailtoUri);
+
+    } //Namespace
+
+} //Namespace
+
+#endif
+
diff --git a/libkolabxml/lib/xcalconversions.h b/libkolabxml/lib/xcalconversions.h
new file mode 100644
index 0000000..601acea
--- /dev/null
+++ b/libkolabxml/lib/xcalconversions.h
@@ -0,0 +1,1701 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef XCALCONVERSIONS_H
+#define XCALCONVERSIONS_H
+
+#include "global_definitions.h"
+
+#include <bindings/kolabformat-xcal.hxx>
+#include <bindings/iCalendar-props.hxx>
+#include <compiled/XMLParserWrapper.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/numeric/conversion/converter_policies.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/foreach.hpp>
+
+#include <fstream>
+#include <iostream>
+
+#include <boost/lexical_cast.hpp>
+
+#include "kolabcontainers.h"
+#include "kolabtodo.h"
+#include "kolabevent.h"
+#include "kolabjournal.h"
+#include "utils.h"
+#include "base64.h"
+#include "shared_conversions.h"
+
+namespace Kolab {
+    namespace XCAL {
+        
+std::string global_xCalVersion;
+
+const char* const XCAL_VERSION = "2.0";
+const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
+
+const char* const TZ_PREFIX = "/kolab.org/";
+
+const char* const THISANDFUTURE = "THISANDFUTURE";
+
+const char* const BASE64 = "BASE64";
+
+const char* const NEEDSACTION = "NEEDS-ACTION";
+const char* const COMPLETED = "OPAQUE";
+const char* const INPROCESS = "IN-PROCESS";
+const char* const CANCELLED = "CANCELLED";
+const char* const TENTATIVE = "TENTATIVE";
+const char* const CONFIRMED = "CONFIRMED";
+const char* const DRAFT = "DRAFT";
+const char* const FINAL = "FINAL";
+
+const char* const CONFIDENTIAL = "CONFIDENTIAL";
+const char* const PRIVATE = "PRIVATE";
+const char* const PUBLIC = "PUBLIC";
+
+const char* const PARTACCEPTED = "ACCEPTED";
+const char* const PARTDECLINED = "DECLINED";
+const char* const PARTDELEGATED = "DELEGATED";
+const char* const PARTNEEDSACTION = "NEEDS-ACTION";
+const char* const PARTTENTATIVE = "TENTATIVE";
+
+const char* const CHAIR = "CHAIR";
+const char* const NONPARTICIPANT = "NON-PARTICIPANT";
+const char* const OPTIONAL = "OPT-PARTICIPANT";
+const char* const REQUIRED = "REQ-PARTICIPANT";
+
+const char* const DISPLAYALARM = "DISPLAY";
+const char* const EMAILALARM = "EMAIL";
+const char* const AUDIOALARM = "AUDIO";
+
+const char* const TRANSPARENT = "TRANSPARENT";
+const char* const OPAQUE = "OPAQUE";
+
+const char* const MO = "MO";
+const char* const TU = "TU";
+const char* const WE = "WE";
+const char* const TH = "TH";
+const char* const FR = "FR";
+const char* const SA = "SA";
+const char* const SU = "SU";
+
+//Alarms
+const char* const START = "START";
+const char* const END = "END";
+
+using namespace Kolab::Utils;
+using namespace Kolab::Shared;
+
+//=== Generic Conversions ===
+    
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
+}
+
+std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+    std::vector<std::string> d;
+    std::copy(s.text().begin(), s.text().end(), std::back_inserter(d));
+    return d;
+}
+
+template <typename T>
+std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
+{
+    std::auto_ptr<T> ptr(new T());
+    std::copy(list.begin(), list.end(), std::back_inserter(ptr->text()));
+    return ptr;
+}
+
+//TODO doesn't seem very useful after all, remove
+std::string toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return s.text();
+}
+
+
+
+
+std::string fromDayPos(const Kolab::DayPos &d)
+{   
+    std::string s;
+    if (d.occurence() != 0) {
+        s.append(boost::lexical_cast<std::string>(d.occurence()));
+    }
+    switch (d.weekday()) {
+        case Kolab::Monday:
+            s.append(MO);
+            break;
+        case Kolab::Tuesday:
+            s.append(TU);
+            break;
+        case Kolab::Wednesday:
+            s.append(WE);
+            break;
+        case Kolab::Thursday:
+            s.append(TH);
+            break;
+        case Kolab::Friday:
+            s.append(FR);
+            break;
+        case Kolab::Saturday:
+            s.append(SA);
+            break;
+        case Kolab::Sunday:
+            s.append(SU);
+            break;
+    }
+    return s;
+}
+
+Kolab::DayPos toDayPos(const std::string &s)
+{
+    std::string number;
+    bool gotOccurrence = false;
+    int occurrence = 0;
+    for (std::string::const_iterator it = s.begin(); it != s.end(); it++) {
+        switch(*it) {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case '+':
+            case '-':
+                number.push_back(*it);
+                break;
+            default:
+                if (!gotOccurrence && !number.empty()) {
+                    try {
+                        occurrence = boost::lexical_cast<int>(number);
+                    } catch(boost::bad_lexical_cast &) {
+                        ERROR("failed to convert: " + number);
+                        return DayPos();
+                    }
+                    number.clear();
+                }
+                gotOccurrence = true;
+                number.push_back(*it);
+                break;
+        }
+    }
+
+    if (number == MO) {
+        return DayPos(occurrence, Kolab::Monday);
+    } else if (number == TU) {
+        return DayPos(occurrence, Kolab::Tuesday);
+    } else if (number == WE) {
+        return DayPos(occurrence, Kolab::Wednesday);
+    } else if (number == TH) {
+        return DayPos(occurrence, Kolab::Thursday);
+    } else if (number == FR) {
+        return DayPos(occurrence, Kolab::Friday);
+    } else if (number == SA) {
+        return DayPos(occurrence, Kolab::Saturday);
+    } else if (number == SU) {
+        return DayPos(occurrence, Kolab::Sunday);
+    }
+    return DayPos();
+}
+
+std::string fromDuration(const Kolab::Duration &d)
+{
+    std::string s;
+    if (!d.isValid()) {
+        return s;
+    }
+    if (d.isNegative()) {
+        s.push_back('-');
+    }
+    s.push_back('P');
+    try {
+        if (d.weeks() > 0) {
+            s.append(boost::lexical_cast<std::string>(d.weeks()));
+            s.push_back('W');
+        }
+        if (d.days() > 0) {
+            s.append(boost::lexical_cast<std::string>(d.days()));
+            s.push_back('D');
+        }
+        if (d.hours() > 0 || d.minutes() > 0 || d.seconds() > 0) {
+            s.push_back('T');
+            if (d.hours() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.hours()));
+                s.push_back('H');
+            }
+            if (d.minutes() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.minutes()));
+                s.push_back('M');
+            }
+            if (d.seconds() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.seconds()));
+                s.push_back('S');
+            }
+        }
+        
+    } catch(boost::bad_lexical_cast &) { 
+        ERROR("failed to convert duration");
+        return std::string();
+    }
+    return s;
+}
+
+Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
+{
+    int weeks = 0;
+    int days = 0;
+    int hours = 0;
+    int minutes = 0;
+    int seconds = 0;
+    bool negative = false;
+
+    std::string number;
+
+    for (std::string::const_iterator it = d.begin(); it != d.end(); it++) {
+        switch(*it) {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                number.push_back(*it);
+                break;
+            case 'H':
+                try {
+                    hours = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) {
+                    ERROR("failed to convert: " +  number);
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'M':
+                try {
+                    minutes = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) {
+                    ERROR("failed to convert: " + number);
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'S':
+                try {
+                    seconds = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    ERROR("failed to convert: " + number);
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'T':
+                break;
+            case 'W':
+                try {
+                    weeks = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    ERROR("failed to convert: " + number);
+                    return Duration();
+                }
+                return Duration(weeks, negative);
+            case 'D':
+                try {
+                    days = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    ERROR("failed to convert: " + number);
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case '+':
+                break;
+            case '-':
+                negative = true;
+                break;
+            case 'P':
+                break;
+            default:
+                ERROR("failed to convert duration: " + *it);
+                return Duration();
+        }
+    }
+    return Duration(days, hours, minutes, seconds, negative);
+}
+
+template <typename T>
+T fromContactReference(const Kolab::ContactReference &c) {
+    T organizer(toMailto(c.email()));
+    
+    typename T::parameters_type p;
+    if (!c.name().empty()) {
+        icalendar_2_0::CnParamType name(c.name());
+        p.baseParameter().push_back(name);
+    }
+    if (!c.uid().empty()) {
+        icalendar_2_0::DirParamType dir(toURN(c.uid()));
+        p.baseParameter().push_back(dir);
+    }
+    organizer.parameters(p);
+    return organizer;
+}
+
+Kolab::ContactReference toContactReference(const icalendar_2_0::CalAddressPropertyType &cal)
+{
+    const std::string &email = fromMailto(cal.cal_address());;
+    std::string name;
+    std::string uid;
+    if (cal.parameters()) {
+        for (icalendar_2_0::ArrayOfParameters::baseParameter_const_iterator it((*cal.parameters()).baseParameter().begin()); it != (*cal.parameters()).baseParameter().end(); it++) {
+            if (const icalendar_2_0::CnParamType * tz = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
+                name = tz->text();
+                continue;
+            }
+            if (const icalendar_2_0::DirParamType * tz = dynamic_cast<const icalendar_2_0::DirParamType*> (&*it)) {
+                uid = tz->uri();
+                continue;
+            }
+        }
+    }
+    return Kolab::ContactReference(email, name, uid);
+}
+
+
+template <typename T>
+Kolab::Attachment toAttachment(T aProp)
+{
+    Kolab::Attachment a;
+    std::string mimetype;
+    if (aProp.parameters()) {
+        const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
+        for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+            if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
+                mimetype = p->text();
+            }
+            if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
+                if (p->text() != BASE64) {
+                    ERROR("wrong encoding");
+                    return Kolab::Attachment();
+                }
+            }
+            if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
+                a.setLabel(p->text());
+            }
+        }
+    }
+    if (mimetype.empty()) {
+        ERROR("no mimetype");
+    }
+
+    if (aProp.uri()) {
+        a.setUri(*aProp.uri(), mimetype);
+    } else if (aProp.binary()) {
+        a.setData(base64_decode(*aProp.binary()), mimetype);
+    } else {
+        ERROR("not uri and no data available");
+    }
+    return a;
+}
+
+icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
+{
+    icalendar_2_0::AttachPropType attachment;
+    icalendar_2_0::AttachPropType::parameters_type p;
+    p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
+    if (!a.label().empty()) {
+        p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
+    }
+    
+    if (!a.uri().empty()) {
+        attachment.uri(a.uri());
+    } else  if (!a.data().empty()) {
+        attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
+        p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
+    } else {
+        ERROR("no uri and no data");
+    }
+    
+    attachment.parameters(p);
+    return attachment;
+}
+
+//==== cDateTime ====
+
+
+std::string getTimezone(const icalendar_2_0::ArrayOfParameters &parameters) {
+    for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+        if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+            std::string tzid = tz->text();
+            if (tzid.find(TZ_PREFIX) != std::string::npos) {
+                tzid.erase(0, strlen(TZ_PREFIX));
+            } else {
+                WARNING("/kolab.org/ timezone prefix is missing");
+            }
+            return tzid;
+        }
+    }
+    return std::string();
+}
+
+cDateTimePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    cDateTimePtr date;
+    if (dtProperty.date_time()) {
+        date = Shared::toDate(*dtProperty.date_time());
+    } else if (dtProperty.date()) {
+        date = Shared::toDate(*dtProperty.date());
+    }
+
+    if (dtProperty.parameters()) {
+        const std::string &tzid = getTimezone(*dtProperty.parameters());
+        if (tzid.size()) {
+            date->setTimezone(tzid);
+        }
+    }
+    return date;
+}
+
+
+cDateTimePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    cDateTimePtr date;
+    if (dtProperty.date_time()) {
+        date = Shared::toDate(*dtProperty.date_time());
+    } else { //The utc-date-time element shouldn't even exist
+        date = cDateTimePtr(new cDateTime());
+        ERROR("This element shouldn't even be existing");
+        //TODO Implement anyways?
+        return date;
+    }
+    date->setUTC(true);
+    return date;
+}
+
+template <typename I>
+std::auto_ptr<I> fromDate(const cDateTime &dt)
+{
+    std::auto_ptr<I> ptr(new I);
+    if (dt.isDateOnly()) {
+        ptr->date(Shared::fromDate(dt));
+    } else {
+        ptr->date_time(Shared::fromDateTime(dt));
+
+        const std::string &timezone = dt.timezone();
+        if (timezone.size() != 0) {
+            std::string tz(TZ_PREFIX);
+            tz.append(timezone);
+            icalendar_2_0::TzidParamType tzidParam(tz);
+            icalendar_2_0::ArrayOfParameters parameters;
+            parameters.baseParameter().push_back(tzidParam);
+            ptr->parameters(parameters);
+        }
+    }
+    return ptr;
+}
+
+
+template <typename I>
+std::vector<cDateTime> toDateTimeList(I datelistProperty)
+{
+    std::vector<cDateTime>  list;
+    
+    std::string tzid;
+    if (datelistProperty.parameters()) {
+        tzid = getTimezone(*datelistProperty.parameters());
+    }
+    if (!datelistProperty.date().empty()) {
+        BOOST_FOREACH(const xml_schema::date &d, datelistProperty.date()) {
+            list.push_back(*Shared::toDate(d));
+        }
+    } else if (!datelistProperty.date_time().empty()) {
+        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
+            cDateTimePtr date = Shared::toDate(d);
+            if (tzid.size()) {
+                date->setTimezone(tzid);
+            }
+            list.push_back(*date);
+        }
+    }
+    return list;
+}
+
+template <typename I>
+std::auto_ptr<I> fromDateTimeList(const std::vector<cDateTime> &dtlist)
+{
+    
+    std::auto_ptr<I> ptr(new I);
+    BOOST_FOREACH(const cDateTime &dt, dtlist) {
+        if (dt.isDateOnly()) {
+            ptr->date().push_back(Shared::fromDate(dt));
+        } else {
+            ptr->date_time().push_back(Shared::fromDateTime(dt));
+        }
+        //TODO handle utc
+        //TODO check for equality of timezones?
+    }
+    
+    if (!dtlist.empty() && !dtlist.at(0).timezone().empty()) {
+        const std::string &timezone = dtlist.at(0).timezone();
+        if (timezone.size() != 0) {
+            std::string tz(TZ_PREFIX);
+            tz.append(timezone);
+            icalendar_2_0::TzidParamType tzidParam(tz);
+            icalendar_2_0::ArrayOfParameters parameters;
+            parameters.baseParameter().push_back(tzidParam);
+            ptr->parameters(parameters);
+        }
+    }
+    
+    return ptr;
+}
+
+
+//---- cDateTime ----
+
+
+
+//=== Attendee ===
+
+std::string mapPartStat(PartStatus status)
+{
+    switch (status) {
+        case PartAccepted:
+            return PARTACCEPTED;
+        case PartDeclined:
+            return PARTDECLINED;
+        case PartDelegated:
+            return PARTDELEGATED;
+        case PartNeedsAction:
+            return PARTNEEDSACTION;
+        case PartTentative:
+            return PARTTENTATIVE;
+    }
+    ERROR("PartStat not handled: " + status);
+    return std::string();
+}
+
+PartStatus mapPartStat(const std::string &status)
+{
+    if (status == PARTACCEPTED) {
+        return PartAccepted;
+    } else if (status == PARTDECLINED) {
+        return PartDeclined;
+    } else if (status == PARTDELEGATED) {
+        return PartDelegated;
+    } else if (status == PARTNEEDSACTION) {
+        return PartNeedsAction;
+    } else if (status == PARTTENTATIVE) {
+        return PartTentative;
+    }
+    ERROR("PartStat not handled: " + status);
+    return PartNeedsAction;
+}
+
+std::string mapRole(Role status)
+{
+    switch (status) {
+        case Chair:
+            return std::string(CHAIR);
+        case NonParticipant:
+            return NONPARTICIPANT;
+        case Optional:
+            return OPTIONAL;
+        case Required:
+            return REQUIRED;
+    }
+    ERROR("PartStat not handled: " + status);
+    return std::string();
+}
+
+Role mapRole(const std::string &status)
+{
+    if (status == CHAIR) {
+        return Chair;
+    } else if (status == NONPARTICIPANT) {
+        return NonParticipant;
+    } else if (status == OPTIONAL) {
+        return Optional;
+    } else if (status == REQUIRED) {
+        return Required;
+    }
+    ERROR("Unhandled Role " + status);
+    return Required;
+}
+
+
+
+
+
+//----------------
+
+//=== Recurrence Rule ===
+
+    typedef std::auto_ptr<RecurrenceRule> RecurrencePtr;
+
+
+    RecurrenceRule::Frequency mapRecurrenceFrequency(const icalendar_2_0::RecurType::freq_type &freq)
+    {
+        using namespace icalendar_2_0;
+        
+        switch (freq) {
+            case FreqRecurType::YEARLY:
+                return RecurrenceRule::Yearly;
+            case FreqRecurType::MONTHLY:
+                return RecurrenceRule::Monthly;
+            case FreqRecurType::WEEKLY:
+                return RecurrenceRule::Weekly;
+            case FreqRecurType::DAILY:
+                return RecurrenceRule::Daily;
+            case FreqRecurType::HOURLY:
+                return RecurrenceRule::Hourly;
+            case FreqRecurType::MINUTELY:
+                return RecurrenceRule::Minutely;
+            case FreqRecurType::SECONDLY:
+                return RecurrenceRule::Secondly;
+            default:
+                ERROR("invalid unhandled recurrenc type" + freq);
+        }
+        return RecurrenceRule::FreqNone;
+    }
+    
+    icalendar_2_0::RecurType::freq_type mapRecurrenceFrequency(RecurrenceRule::Frequency freq)
+    {
+        using namespace icalendar_2_0;
+
+        switch (freq) {
+            case RecurrenceRule::Yearly:
+                return FreqRecurType::YEARLY;
+            case RecurrenceRule::Monthly:
+                return FreqRecurType::MONTHLY;
+            case RecurrenceRule::Weekly:
+                return FreqRecurType::WEEKLY;
+            case RecurrenceRule::Daily:
+                return FreqRecurType::DAILY;
+            case RecurrenceRule::Hourly:
+                return FreqRecurType::HOURLY;
+            case RecurrenceRule::Minutely:
+                return FreqRecurType::MINUTELY;
+            case RecurrenceRule::Secondly:
+                return FreqRecurType::SECONDLY;
+            default:
+                ERROR("invalid unhandled recurrenc type");
+        }
+        return 0;
+    }
+    
+    static void setWeekStart(RecurrencePtr &r, const icalendar_2_0::RecurType::wkst_type &wkst)
+    {
+        using namespace icalendar_2_0;
+
+        switch (wkst) {
+            case WeekdayRecurType::MO:
+                r->setWeekStart(Kolab::Monday);
+                break;
+            case WeekdayRecurType::TU:
+                r->setWeekStart(Kolab::Tuesday);
+                break;
+            case WeekdayRecurType::WE:
+                r->setWeekStart(Kolab::Wednesday);
+                break;
+            case WeekdayRecurType::TH:
+                r->setWeekStart(Kolab::Thursday);
+                break;
+            case WeekdayRecurType::FR:
+                r->setWeekStart(Kolab::Friday);
+                break;
+            case WeekdayRecurType::SA:
+                r->setWeekStart(Kolab::Saturday);
+                break;
+            case WeekdayRecurType::SU:
+                r->setWeekStart(Kolab::Sunday);
+                break;
+            default:
+                ERROR("invalid unhandled weekday" + wkst);
+        }
+    }
+
+    
+    static void setByday(RecurrencePtr &r, const icalendar_2_0::RecurType::byday_sequence &list)
+    {
+        std::vector<DayPos> by;
+        for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(toDayPos(*it));
+        }
+        r->setByday(by);
+    }
+
+    template <typename T, typename I>
+    std::vector<int> bylist(const xsd::cxx::tree::sequence <T> &list)
+    { 
+        std::vector<int> by;
+        BOOST_FOREACH(const T i, list) {
+            by.push_back(convertToInt<I>(i));
+        }
+        return by;
+    }
+    
+RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+    using namespace icalendar_2_0;
+
+    RecurrencePtr r(new RecurrenceRule());
+    r->setFrequency(mapRecurrenceFrequency(rrule.freq()));
+    if (rrule.until()) {
+        cDateTimePtr date;
+        if ((*rrule.until()).date_time()) {
+            date = Shared::toDate(*(*rrule.until()).date_time());
+        } else if ((*rrule.until()).date()) {
+            date = Shared::toDate(*(*rrule.until()).date());
+        }
+        r->setEnd(*date);
+    } else if (rrule.count()) {
+        r->setCount(toInt(*rrule.count()));
+    }
+    if (rrule.interval()) {
+        r->setInterval(toInt(*rrule.interval()));
+    } else {
+        r->setInterval(1);
+    }
+    r->setBysecond(bylist<RecurType::bysecond_type, xml_schema::non_negative_integer>(rrule.bysecond()));
+    r->setByminute(bylist<RecurType::byminute_type, xml_schema::non_negative_integer>(rrule.byminute()));
+    r->setByhour(bylist<RecurType::byhour_type, xml_schema::non_negative_integer>(rrule.byhour()));
+    setByday(r, rrule.byday());
+    r->setBymonthday(bylist<RecurType::bymonthday_type, xml_schema::integer>(rrule.bymonthday()));
+    r->setByyearday(bylist<RecurType::byyearday_type, xml_schema::integer>(rrule.byyearday()));
+    r->setByweekno(bylist<RecurType::byweekno_type, xml_schema::integer>(rrule.byweekno()));
+    r->setBymonth(bylist<RecurType::bymonth_type, xml_schema::integer>(rrule.bymonth()));
+    if (rrule.wkst()) {
+        setWeekStart(r, *rrule.wkst());
+    }
+    return r;
+}
+    
+//--- Recurrence Rule ---
+
+template <typename I, typename T>
+void setIncidenceProperties(I &inc, const T &prop)
+{    
+    inc.setUid(toString(prop.uid()));
+    inc.setCreated(*toDate(prop.created()));
+    inc.setLastModified(*toDate(prop.dtstamp()));
+
+    if (prop.sequence()) {
+        inc.setSequence(toInt(*prop.sequence()));
+    }
+    
+    if (prop.class_()) {
+        std::string string(toString(*prop.class_()));
+        Kolab::Classification sec = ClassPublic;
+        if (string == PRIVATE) {
+            sec = ClassPrivate;
+        } else if (string == CONFIDENTIAL) {
+            sec = ClassConfidential;
+        }
+        inc.setClassification(sec);
+    }
+    
+    if (prop.categories()) {
+        inc.setCategories(toStringList(*prop.categories()));
+    }
+    
+    if (prop.dtstart()) {
+        const cDateTimePtr date = toDate(*prop.dtstart());
+        inc.setStart(*date);
+    }
+
+    if (prop.summary()) {
+        inc.setSummary(toString(*prop.summary()));
+    }
+
+    if (prop.description()) {
+        inc.setDescription(toString(*prop.description()));
+    }
+
+    if (prop.status()) {
+        const std::string &status =  toString(*prop.status());
+        if (status == NEEDSACTION) {
+            inc.setStatus(StatusNeedsAction);
+        } else if (status == COMPLETED) {
+            inc.setStatus(StatusCompleted);
+        } else if (status == INPROCESS) {
+            inc.setStatus(StatusInProcess);
+        } else if (status == CANCELLED) {
+            inc.setStatus(StatusCancelled);
+        } else if (status == TENTATIVE) {
+            inc.setStatus(StatusTentative);
+        } else if (status == CONFIRMED) {
+            inc.setStatus(StatusConfirmed);
+        } else if (status == DRAFT) {
+            inc.setStatus(StatusDraft);
+        } else if (status == FINAL) {
+            inc.setStatus(StatusFinal);
+        } else {
+            ERROR("Unhandled status");
+        }
+    }
+    
+    if (prop.attendee().size()) {
+        std::vector<Kolab::Attendee> attendees;
+        BOOST_FOREACH(typename T::attendee_type aProp, prop.attendee()) {
+            Kolab::Attendee a;
+            std::string name;
+            if (aProp.parameters()) {
+                const icalendar_2_0::AttendeePropType::parameters_type &parameters = *aProp.parameters();
+                for (icalendar_2_0::AttendeePropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                    if (const icalendar_2_0::CnParamType * p = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
+                        name = p->text();
+                    }
+                    if (const icalendar_2_0::PartstatParamType * p = dynamic_cast<const icalendar_2_0::PartstatParamType*> (&*it)) {
+                        PartStatus s = mapPartStat(p->text());
+                        if (s != PartNeedsAction) {
+                            a.setPartStat(s);
+                        }
+                    }
+                    if (const icalendar_2_0::RoleParamType * p = dynamic_cast<const icalendar_2_0::RoleParamType*> (&*it)) {
+                        Role s = mapRole(p->text());
+                        if (s != Required) {
+                            a.setRole(s);
+                        }
+                    }
+                    if (const icalendar_2_0::RsvpParamType * p = dynamic_cast<const icalendar_2_0::RsvpParamType*> (&*it)) {
+                        a.setRSVP(p->boolean());
+                    }
+                }
+            }
+            Kolab::ContactReference ref = toContactReference(aProp);
+            a.setContact(ref);
+            attendees.push_back(a);
+        }
+        inc.setAttendees(attendees);
+    }
+    
+    if (prop.attach().size()) {
+        std::vector<Kolab::Attachment> attachments;
+        BOOST_FOREACH(typename T::attach_type aProp, prop.attach()) {
+            const Kolab::Attachment &a = toAttachment<typename T::attach_type>(aProp);
+            if (!a.isValid()) {
+                ERROR("invalid attachment");
+                continue;
+            }
+            attachments.push_back(a);
+        }
+        inc.setAttachments(attachments);
+    }
+    
+    if (prop.x_custom().size()) {
+        std::vector<Kolab::CustomProperty> customProperties;
+        BOOST_FOREACH(typename T::x_custom_type p, prop.x_custom()) {
+            customProperties.push_back(CustomProperty(p.identifier(), p.value()));
+        }
+        inc.setCustomProperties(customProperties);
+    }
+
+}
+
+template <typename I, typename T>
+void setTodoEventProperties(I &inc, const T &prop)
+{
+
+    if (prop.rrule()) {
+       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
+       inc.setRecurrenceRule(*rrule);
+    }
+
+    if (prop.rdate()) {
+        inc.setRecurrenceDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
+        if (!prop.rdate()->period().empty()) {
+            ERROR("the period element must not be used, ignored.");
+        }
+    }
+
+    if (prop.exdate()) {
+       inc.setExceptionDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
+    }
+    
+    if (prop.recurrence_id()) {
+        bool thisandfuture = false;
+        if (prop.recurrence_id()->parameters()) {
+            const icalendar_2_0::RecurrenceIdPropType::parameters_type &parameters = *prop.recurrence_id()->parameters();
+            for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                if (dynamic_cast<const icalendar_2_0::RangeParamType*> (&*it)) {
+                    thisandfuture = true;
+                }
+            }
+        }
+        inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture);
+    }
+
+    if (prop.priority()) {
+        inc.setPriority(toInt(*prop.priority()));
+    }
+
+    if (prop.location()) {
+        inc.setLocation(toString(*prop.location()));
+    }
+    
+    if (prop.organizer()) {
+        inc.setOrganizer(toContactReference(*prop.organizer()));
+    }
+    
+}
+
+
+template <typename T, typename I>
+T fromList(const std::vector<int> &input) {
+    T list;
+    BOOST_FOREACH(int i, input) {
+        list.push_back(convertToInt<I>(i));
+    }
+    return list;
+}
+
+std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r)
+{
+    using namespace icalendar_2_0;
+        
+    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(mapRecurrenceFrequency(r.frequency())));
+    
+    RecurPropertyType::recur_type &recur = rruleProp->recur();
+    const cDateTime &endDate = r.end();
+    if (endDate.isValid()) {
+        RecurPropertyType::recur_type::until_type until;
+        if (endDate.isDateOnly()) {
+            until.date(Shared::fromDate(endDate));
+        } else {
+            until.date_time(Shared::fromDateTime(endDate));
+        }
+        recur.until(until);
+    } else if (r.count() > 0) {
+        recur.count(fromInt<RecurType::count_type>(r.count()));
+    }
+    
+    if (r.interval() > 1) {
+        recur.interval(fromInt<RecurType::interval_type>(r.interval()));
+    }
+    
+    if (!r.bysecond().empty()) {
+        recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
+    }
+    
+    if (!r.byminute().empty()) {
+        recur.byminute(fromList<RecurType::byminute_sequence, xml_schema::non_negative_integer>(r.byminute()));
+    }
+    
+    if (!r.byhour().empty()) {
+        recur.byhour(fromList<RecurType::byhour_sequence, xml_schema::non_negative_integer>(r.byhour()));
+    }
+    
+    if (!r.byday().empty()) {
+        RecurType::byday_sequence byday;
+        BOOST_FOREACH(const Kolab::DayPos &daypos, r.byday()) {
+            byday.push_back(fromDayPos(daypos));
+        }
+        recur.byday(byday);
+    }
+    
+    if (!r.bymonthday().empty()) {
+        recur.bymonthday(fromList<RecurType::bymonthday_sequence, xml_schema::integer>(r.bymonthday()));
+    }
+    
+    if (!r.byyearday().empty()) {
+        recur.byyearday(fromList<RecurType::byyearday_sequence, xml_schema::integer>(r.byyearday()));
+    }
+    
+    if (!r.byweekno().empty()) {
+        recur.byweekno(fromList<RecurType::byweekno_sequence, xml_schema::integer>(r.byweekno()));
+    }
+    
+    if (!r.bymonth().empty()) {
+        recur.bymonth(fromList<RecurType::bymonth_sequence, xml_schema::integer>(r.bymonth()));
+    }
+
+    return rruleProp;
+}
+
+
+
+
+template <typename T, typename I>
+void getIncidenceProperties(T &prop, const I &inc)
+{
+    using namespace icalendar_2_0;
+    
+    typedef T properties; 
+    
+    prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
+    
+    switch (inc.classification()) {
+        case Kolab::ClassConfidential:
+            prop.class_(typename properties::class_type(CONFIDENTIAL));
+            break;
+        case Kolab::ClassPrivate:
+            prop.class_(typename properties::class_type(PRIVATE));
+            break;
+        default:
+            prop.class_(typename properties::class_type(PUBLIC));
+            break;
+    }
+    
+    if (!inc.categories().empty()) {
+        prop.categories(*fromStringList<typename properties::categories_type>(inc.categories()));
+    }
+
+    if (inc.start().isValid()) {
+        prop.dtstart(fromDate<typename properties::dtstart_type>(inc.start()));
+    }
+
+    if (!inc.summary().empty()) {
+        prop.summary(typename properties::summary_type(inc.summary()));
+    }
+    
+    if (!inc.description().empty()) {
+        prop.description(typename properties::description_type(inc.description()));
+    }
+
+    if (inc.status() != StatusUndefined) {
+        switch (inc.status()) {
+            case StatusNeedsAction:
+                prop.status(typename properties::status_type(NEEDSACTION));
+                break;
+            case StatusCompleted:
+                prop.status(typename properties::status_type(COMPLETED));
+                break;
+            case StatusInProcess:
+                prop.status(typename properties::status_type(INPROCESS));
+                break;
+            case StatusCancelled:
+                prop.status(typename properties::status_type(CANCELLED));
+                break;
+            case StatusTentative:
+                prop.status(typename properties::status_type(TENTATIVE));
+                break;
+            case StatusConfirmed:
+                prop.status(typename properties::status_type(CONFIRMED));
+                break;
+            case StatusDraft:
+                prop.status(typename properties::status_type(DRAFT));
+                break;
+            case StatusFinal:
+                prop.status(typename properties::status_type(FINAL));
+                break;
+            default:
+                ERROR("unhandled status " + inc.status());
+        }
+
+    }
+
+    if (!inc.attendees().empty()) {        
+        
+        BOOST_FOREACH(const Kolab::Attendee &a, inc.attendees()) {
+            const Kolab::ContactReference &c = a.contact();
+            
+            typename properties::attendee_type attendee = fromContactReference<typename properties::attendee_type>(c);
+            
+            typename properties::attendee_type::parameters_type &p = *attendee.parameters();
+            
+            std::string stat = mapPartStat(a.partStat());
+            if (!stat.empty()) {
+                p.baseParameter().push_back(icalendar_2_0::PartstatParamType(stat));
+            }
+            
+            std::string r = mapRole(a.role());
+            if (!r.empty()) {
+                p.baseParameter().push_back(icalendar_2_0::RoleParamType(r));
+            }
+            
+            if (a.rsvp()) {
+                p.baseParameter().push_back(icalendar_2_0::RsvpParamType(true));
+            }
+
+            prop.attendee().push_back(attendee);
+
+        }
+    }
+    
+    if (!inc.attachments().empty()) {
+        BOOST_FOREACH(const Kolab::Attachment &a, inc.attachments()) {
+            prop.attach().push_back(fromAttachment(a));
+        }
+    }
+    
+    if (!inc.customProperties().empty()) {
+        BOOST_FOREACH(const Kolab::CustomProperty &a, inc.customProperties()) {
+            prop.x_custom().push_back(typename properties::x_custom_type(a.identifier, a.value));
+        }
+    }
+
+}
+
+template <typename T, typename I>
+void getTodoEventProperties(T &prop, const I &inc)
+{
+    using namespace icalendar_2_0;
+    typedef T properties; 
+    
+    if (inc.recurrenceRule().isValid()) {
+        const RecurrenceRule &r = inc.recurrenceRule();
+        prop.rrule(recurrenceProperty(r));
+        //TODO check if startdate is allDay if recurrence is allDay
+        //TODO check if startdate matches the one of the event (it MUST)
+    }
+    
+    if (!inc.recurrenceDates().empty()) {
+        prop.rdate(fromDateTimeList<typename properties::rdate_type>(inc.recurrenceDates()));
+    }
+    
+    if (!inc.exceptionDates().empty()) {
+        prop.exdate(fromDateTimeList<typename properties::exdate_type>(inc.exceptionDates()));
+    }
+    
+    if (inc.recurrenceID().isValid()) {
+        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<typename properties::recurrence_id_type>(inc.recurrenceID());
+        if (inc.thisAndFuture()) {
+            if (!recurrenceId->parameters()) {
+                recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
+            }
+            typename properties::recurrence_id_type::parameters_type &parameters = *recurrenceId->parameters(); //There is maybe already a timezone set
+            icalendar_2_0::RangeParamType range(THISANDFUTURE);
+            parameters.baseParameter().push_back(range);
+        }
+        
+        prop.recurrence_id(recurrenceId);
+    }
+    
+    if (inc.priority() != 0) {
+        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
+    }
+    
+    if (!inc.location().empty()) {
+        prop.location(typename properties::location_type(inc.location()));
+    }
+    
+    if (inc.organizer().isValid()) {
+        prop.organizer(fromContactReference<typename properties::organizer_type>(inc.organizer()));
+    }
+}
+
+//=== Alarms ===
+
+template <typename KolabType, typename IncidenceType>
+void setAlarms(typename KolabType::components_type& components, const IncidenceType &incidence)
+{
+    BOOST_FOREACH(const Kolab::Alarm &alarm, incidence.alarms()) {
+        typedef icalendar_2_0::ValarmType::properties_type PropType;
+        
+        PropType::trigger_type trigger;
+        if (alarm.start().isValid()) {
+            
+            trigger.date_time(fromDateTime(alarm.start()));
+        } else {
+            if (!alarm.relativeStart().isValid()) {
+                ERROR("no start and no relativeStart");
+                continue;
+            }
+            trigger.duration(PropType::trigger_type::duration_type(fromDuration(alarm.relativeStart())));
+            icalendar_2_0::ArrayOfParameters parameters;
+            if (alarm.relativeTo() == Kolab::End) {
+                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(END));
+            } else {
+                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(START));
+            }
+            trigger.parameters(parameters);
+        }
+
+        std::auto_ptr<PropType> p;
+        switch(alarm.type()) {
+            case Kolab::Alarm::DisplayAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(DISPLAYALARM), trigger));
+                p->description(PropType::description_type(alarm.description()));
+                break;
+            case Kolab::Alarm::EMailAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(EMAILALARM), trigger));
+                p->summary(PropType::summary_type(alarm.summary()));
+                p->description(PropType::description_type(alarm.description()));
+                BOOST_FOREACH(const Kolab::ContactReference &attendee, alarm.attendees()) {
+                    p->attendee().push_back(icalendar_2_0::ContactType(toMailto(attendee.email(), attendee.name())));
+                }
+                break;
+            case Kolab::Alarm::AudioAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(AUDIOALARM), trigger));
+                p->description(PropType::description_type(alarm.description()));
+                p->attach(fromAttachment(alarm.audioFile()));
+                break;
+            default:
+                ERROR("invalid alarm");
+                continue;
+        }
+        if (alarm.duration().isValid()) {
+            p->duration(PropType::duration_type(fromDuration(alarm.duration())));
+            p->repeat(PropType::repeat_type(fromInt<PropType::repeat_type::integer_type>(alarm.numrepeat())));
+        }
+
+        components.valarm().push_back(icalendar_2_0::ValarmType(p));
+    }
+}
+
+
+
+template <typename IncidenceType, typename KolabType>
+void getAlarms(IncidenceType &incidence, const typename KolabType::components_type &components)
+{
+    typedef icalendar_2_0::ValarmType::properties_type PropType;
+    std::vector<Kolab::Alarm> alarms;
+    BOOST_FOREACH(const typename KolabType::components_type::valarm_type &valarm, components.valarm()) {
+        const icalendar_2_0::ValarmType::properties_type &prop = valarm.properties();
+
+        Kolab::Alarm alarm;
+        if (prop.action().text() == DISPLAYALARM) {
+            if (!prop.description()) {
+                ERROR("description is missing");
+                continue;
+            }
+            alarm = Kolab::Alarm((*prop.description()).text());
+        } else if (prop.action().text() == EMAILALARM) {
+            std::vector<Kolab::ContactReference> attendees;
+            if (prop.attendee().empty()) {
+                WARNING("No receipents for email alarm");
+            }
+            for (typename PropType::attendee_const_iterator at(prop.attendee().begin()); at != prop.attendee().end(); at++) {
+                std::string name;
+                const std::string &email = fromMailto((*at).cal_address(), name);
+                attendees.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name));
+            }
+            if (!prop.description() || !prop.summary()) {
+                ERROR("description or summary is missing");
+                continue;
+            }
+            alarm = Kolab::Alarm((*prop.summary()).text(), (*prop.description()).text(), attendees);
+        } else if (prop.action().text() == AUDIOALARM) {
+            if (!prop.attach()) {
+                ERROR("audio file is missing");
+                continue;
+            }
+            const Kolab::Attachment &attach = toAttachment<icalendar_2_0::properties::attach_type>(*prop.attach());
+            if (!attach.isValid()) {
+                ERROR("audio file is invalid");
+                continue;
+            }
+            alarm = Kolab::Alarm(attach);
+        } else {
+            ERROR("unknown alarm type " + prop.action().text());
+            continue;
+        }
+        
+        if (prop.trigger().date_time()) {
+            alarm.setStart(*Shared::toDate(*prop.trigger().date_time()));
+            if (!alarm.start().isUTC()) {
+                ERROR("The start date time must be in UTC ");
+                continue;
+            }
+        } else if (prop.trigger().duration()) {
+            Kolab::Relative relativeTo = Kolab::Start;
+            if (prop.trigger().parameters()) {
+                BOOST_FOREACH(const icalendar_2_0::ArrayOfParameters::baseParameter_type &param, (*prop.trigger().parameters()).baseParameter()) {
+                    if (const icalendar_2_0::RelatedParamType *rel = dynamic_cast<const icalendar_2_0::RelatedParamType*> (&param)) {
+                        if (rel->text() == START) {
+                            relativeTo = Kolab::Start;
+                        } else if (rel->text() == END) {
+                            relativeTo = Kolab::End;
+                        } else {
+                            LOG("relativeTo not specified, default to start ");
+                        }
+                    }
+                }
+            }
+            
+            alarm.setRelativeStart(toDuration(*prop.trigger().duration()), relativeTo);
+        } else {
+            ERROR("no duration and not starttime ");
+            continue;
+        }
+        if (prop.duration()) {
+            int repeat = 0;
+            if (prop.repeat()) {
+                repeat = toInt(*prop.repeat());
+            }
+            alarm.setDuration(toDuration((*prop.duration()).duration()), repeat); //TODO check duration?
+        }
+        alarms.push_back(alarm);
+    }
+    incidence.setAlarms(alarms);
+}
+
+//--- Alarms ---
+
+class Incidence; //Just for Trait
+
+///Trait for Incidence object
+template <typename T, typename I> 
+struct IncidenceConverter;
+
+template <typename T> struct IncidenceConverter < Incidence, T >
+{
+    static std::string uid(const T &inc) {
+        if (inc.uid().empty()) { //generate new UID
+            return getUID();
+        }
+        return inc.uid();
+    }
+    
+    static xml_schema::date_time dtstamp() {
+        return fromDateTime(getCurrentTime());
+    }
+    
+    static xml_schema::date_time created(const T &inc) {
+        if (inc.created().isValid()) {
+            return fromDateTime(inc.created());
+        }
+        return fromDateTime(getCurrentTime());
+    }
+
+};
+
+
+///Trait for incidence properties specialized for Event/Todo/Journal
+template <typename T> struct IncidenceTrait;
+
+template < > struct IncidenceTrait <Kolab::Event>
+{
+    typedef icalendar_2_0::KolabEvent KolabType;
+    typedef Kolab::Event IncidenceType;
+    typedef boost::shared_ptr<Kolab::Event> IncidencePtr;
+
+    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
+    {
+        KolabType::components_type eventComponents;
+        setAlarms<icalendar_2_0::KolabEvent, IncidenceType>(eventComponents, event);
+        if (!eventComponents.valarm().empty()) {
+            vevent.components(eventComponents);
+        }
+        
+        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+        getTodoEventProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+        if (!event.start().isValid()) {
+            ERROR("Start date is missing, but is mandatory for events");
+        }
+
+        if (event.end().isValid()) {
+            prop.dtend(fromDate<icalendar_2_0::KolabEvent::properties_type::dtend_type>(event.end()));
+        } else if (event.duration().isValid()) {
+            prop.duration(icalendar_2_0::KolabEvent::properties_type::duration_type(fromDuration(event.duration())));
+        }
+        
+        if (event.transparency()) {
+            prop.transp( icalendar_2_0::KolabEvent::properties_type::transp_type(TRANSPARENT));
+        }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabEvent inc) //TODO to base trait
+    {
+        components.vevent().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
+    {
+        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        if (!prop.dtstart()) {
+            ERROR("Start date is missing, but is mandatory for events");
+        }
+
+        setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
+        setTodoEventProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+        if (prop.dtend()) {
+            event.setEnd(*toDate(*prop.dtend()));
+            if (event.end().isUTC() != event.end().isUTC() && 
+                event.end().timezone() != event.end().timezone() &&
+                event.end().isDateOnly() != event.end().isDateOnly()) {
+                ERROR("dtEnd has wrong timespec");
+            }
+        } else if (prop.duration()) {
+            event.setDuration(toDuration((*prop.duration()).duration()));
+        }
+
+        if (prop.transp()) {
+            if (toString(*prop.transp()) == TRANSPARENT) {
+                event.setTransparency(true);
+            } else {
+                event.setTransparency(false);
+                if (toString(*prop.transp()) != OPAQUE) {
+                    ERROR("wrong transparency value " + toString(*prop.transp()));
+                }
+            }
+        }
+        if (vevent.components()) {
+            getAlarms<Kolab::Event, icalendar_2_0::KolabEvent>(event, *vevent.components());
+        }
+    }
+
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vevent().begin();
+    }
+    
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vevent().end();
+    }
+    
+};
+
+template < > struct IncidenceTrait <Kolab::Todo>
+{
+    typedef icalendar_2_0::KolabTodo KolabType;
+    typedef Kolab::Todo IncidenceType;
+    typedef boost::shared_ptr<Kolab::Todo> IncidencePtr;
+
+    static void writeIncidence(icalendar_2_0::KolabTodo& vevent, const Kolab::Todo &todo)
+    {
+        KolabType::components_type eventComponents;
+        setAlarms<icalendar_2_0::KolabTodo, IncidenceType>(eventComponents, todo);
+        if (!eventComponents.valarm().empty()) {
+            vevent.components(eventComponents);
+        }
+
+        icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
+
+        getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+        getTodoEventProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+
+        if (!todo.relatedTo().empty()) {
+            icalendar_2_0::KolabTodo::properties_type::related_to_sequence list;
+            BOOST_FOREACH(std::string relatedTo, todo.relatedTo()) {
+                list.push_back(icalendar_2_0::KolabTodo::properties_type::related_to_type(relatedTo));
+            }
+            prop.related_to(list);
+        }
+        if (todo.due().isValid()) {
+            prop.due(fromDate<icalendar_2_0::KolabTodo::properties_type::due_type>(todo.due()));
+        }
+        if (todo.percentComplete() > 0) {
+            prop.percent_complete(icalendar_2_0::KolabTodo::properties_type::percent_complete_type(fromInt<icalendar_2_0::IntegerPropertyType::integer_type>(todo.percentComplete())));
+        }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabTodo inc) //TODO to base trait
+    {
+        components.vtodo().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
+    {
+        const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
+        setTodoEventProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
+
+        if (!prop.related_to().empty()) {
+            BOOST_FOREACH(icalendar_2_0::KolabTodo::properties_type::related_to_type p, prop.related_to()) {
+                todo.addRelatedTo(p.text());
+            }
+        }
+        if (prop.due()) {
+            todo.setDue(*toDate(*prop.due()));
+        }
+        if (prop.percent_complete()) {
+            todo.setPercentComplete(toInt(*prop.percent_complete()));
+        }
+        if (vevent.components()) {
+            getAlarms<Kolab::Todo, icalendar_2_0::KolabTodo>(todo, *vevent.components());
+        }
+    }
+
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vtodo().begin();
+    }
+    
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vtodo().end();
+    }
+    
+};
+
+template < > struct IncidenceTrait <Kolab::Journal>
+{
+    typedef icalendar_2_0::KolabJournal KolabType;
+    typedef Kolab::Journal IncidenceType;
+    typedef boost::shared_ptr<Kolab::Journal> IncidencePtr;
+
+    static void writeIncidence(icalendar_2_0::KolabJournal& vjournal, const Kolab::Journal &journal)
+    {
+        icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
+        getIncidenceProperties<icalendar_2_0::KolabJournal::properties_type>(prop, journal);
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabJournal inc)
+    {
+        components.vjournal().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Journal &journal, const icalendar_2_0::KolabJournal& vjournal)
+    {
+        const icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
+        setIncidenceProperties<Kolab::Journal, icalendar_2_0::KolabJournal::properties_type>(journal, prop);
+    }
+
+    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vjournal().begin();
+    }
+    
+    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vjournal().end();
+    }
+    
+};
+
+
+//////////////////////////////////=========================================
+
+
+template <typename T>
+std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
+    
+    using namespace icalendar_2_0;
+    typedef IncidenceConverter< Incidence, typename T::IncidenceType > IC;
+    typedef typename T::KolabType KolabType;
+    
+    clearErrors();
+
+    try {
+
+        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
+        setCreatedUid(uid.text());
+        typename KolabType::properties_type::dtstamp_type dtstamp;
+        dtstamp.date_time(IC::dtstamp());
+        typename KolabType::properties_type::created_type created;
+        created.date_time(IC::created(incidence));
+        typename KolabType::properties_type eventProps(uid, created, dtstamp);
+        
+        KolabType inc(eventProps);
+        
+        T::writeIncidence(inc, incidence);
+
+        VcalendarType::components_type components;
+        T::addIncidence(components, inc);
+        
+        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME+KOLAB_LIB_VERSION); //FIXME own version field for lib version
+        VcalendarType::properties_type::version_type version(XCAL_VERSION);
+        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION);
+        
+        VcalendarType::properties_type properties(prodid, version, x_kolab_version);
+        
+        VcalendarType vcalendar(properties, components);
+        
+        IcalendarType icalendar(vcalendar);
+
+        xml_schema::namespace_infomap map;
+        map[""].name = XCAL_NAMESPACE;
+        
+        std::ostringstream ostringstream;
+        icalendar_2_0::icalendar(ostringstream, icalendar, map);
+        return ostringstream.str();
+    } catch  (const xml_schema::exception& e) {
+        CRITICAL("failed to write Incidence");
+    } catch (...) {
+        CRITICAL("Unhandled exception");
+    }
+    return std::string();
+}
+
+
+template <typename T>
+typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
+{
+    using namespace icalendar_2_0;
+    typedef typename T::IncidencePtr IncidencePtr;
+    typedef typename T::IncidenceType IncidenceType;
+    typedef typename T::KolabType KolabType;
+    
+    clearErrors();
+    try {
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+        if (isUrl) {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+        } else {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+        }
+        
+        if (!icalendar.get()) {
+            CRITICAL("Failed to parse calendar!");
+            return IncidencePtr();
+        }
+
+        const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
+
+        std::vector < IncidencePtr > incidences;
+        for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
+            IncidencePtr e = IncidencePtr(new IncidenceType);
+            const KolabType &event = *it;
+            T::readIncidence(*e, event);
+            incidences.push_back(e);
+        }
+        
+        setProductId( vcalendar.properties().prodid().text() );
+        global_xCalVersion = vcalendar.properties().version().text();
+        setKolabVersion( vcalendar.properties().x_kolab_version().text() );
+
+
+        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+//         foreach (KCalCore::Event * event, events) {
+//             if (!event->hasRecurrenceId()) {
+//                 return event;
+//             }
+//         }
+        if (incidences.size() != 1) {
+            WARNING("wrong number of incidences: "+ incidences.size());
+        }
+        return *incidences.begin();
+    } catch  (const xml_schema::exception& e) {
+        std::cout <<  e << std::endl;
+        CRITICAL("Failed to read incidence!");
+    } catch (...) {
+        CRITICAL("Unhandled exception");
+    }
+    return IncidencePtr();
+}
+
+    }
+}//Namespace
+
+#endif
+
diff --git a/libkolabxml/lib/xcardconversions.h b/libkolabxml/lib/xcardconversions.h
new file mode 100644
index 0000000..0be6f0a
--- /dev/null
+++ b/libkolabxml/lib/xcardconversions.h
@@ -0,0 +1,1092 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABXCARDCONVERSION_H
+#define KOLABXCARDCONVERSION_H
+
+#include <bindings/kolabformat-xcard.hxx>
+#include "kolabcontainers.h"
+#include <XMLParserWrapper.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+#include <iomanip>
+#include "global_definitions.h"
+#include "utils.h"
+#include "kolabcontact.h"
+#include "shared_conversions.h"
+
+namespace Kolab {
+    namespace XCARD {
+        
+    const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+    const char* const INDIVIDUAL = "individual";
+    const char* const GROUP = "group";
+    const char* const MIME_PGP_KEYS = "application/pgp-keys";
+    const char* const MIME_PKCS7_MIME = "application/pkcs7-mime";
+
+using namespace Kolab::Utils;
+    
+template <typename T> 
+std::string getType();
+
+template <> 
+std::string getType<Kolab::Contact>()
+{
+    return INDIVIDUAL;
+}
+
+template <> 
+std::string getType<Kolab::DistList>()
+{
+    return GROUP;
+}
+
+template <typename T>
+xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input)
+{
+    xsd::cxx::tree::sequence<T> list;
+    BOOST_FOREACH(const std::string &s, input) {
+        list.push_back(T(s));
+    }
+    return list;
+}
+
+template <typename T>
+xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input, int preferredIndex)
+{
+    xsd::cxx::tree::sequence<T> list;
+    int index = 0;
+    BOOST_FOREACH(const std::string &s, input) {
+        T im(s);
+        if(preferredIndex == index) {
+            typename T::parameters_type parameters;
+            parameters.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+            im.parameters(parameters);
+        }
+        index++;
+        list.push_back(im);
+    }
+    return list;
+}
+
+template <typename T>
+std::vector<std::string> toUriList(const xsd::cxx::tree::sequence<T> &input)
+{
+    std::vector<std::string> list;
+    BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, input) {
+        list.push_back(s.uri());
+    }
+    return list;
+}
+
+template <typename T>
+std::vector<std::string> toTextList(const xsd::cxx::tree::sequence<T> &input)
+{
+    std::vector<std::string> list;
+    BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, input) {
+        list.push_back(s.text());
+    }
+    return list;
+}
+
+std::vector<std::string> toStringList(const ::xsd::cxx::tree::sequence< ::xml_schema::string > &s)
+{
+    std::vector<std::string> d;
+    std::copy(s.begin(), s.end(), std::back_inserter(d));
+    return d;
+}
+
+::xsd::cxx::tree::sequence< ::xml_schema::string > fromStringList(const std::vector<std::string> &s)
+{
+    ::xsd::cxx::tree::sequence< ::xml_schema::string > d;
+    std::copy(s.begin(), s.end(), std::back_inserter(d));
+    return d;
+}
+
+std::string fromDate(const cDateTime &dt)
+{
+    if (!dt.isDateOnly()) {
+        WARNING("fromDate called on date time value");
+    }
+    std::stringstream s;
+    s.fill('0');
+    s.width(4);
+    s << dt.year();
+    s.width(2);
+    s << dt.month();
+    s.width(2);
+    s << dt.day();
+    return s.str();
+}
+
+std::string fromDateTime(const cDateTime &dt)
+{
+    std::stringstream s;
+    s.fill('0');
+    s << std::right; 
+    s.width(4);
+    s << dt.year();
+    s.width(2);
+    s << dt.month();
+    s.width(2);
+    s << dt.day();
+    s.width(1);
+    if (dt.isDateOnly()) {
+        return s.str();
+    }
+    s << "T";
+    s.width(2);
+    s << dt.hour();
+    s.width(2);
+    s << dt.minute();
+    s.width(2);
+    s << dt.second();
+    if (dt.isUTC()) {
+        s << "Z";
+    }
+    return s.str();
+}
+
+cDateTime toDateTime(const std::string &input)
+{
+    int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
+    bool isUtc = false;
+    try {
+        year = boost::lexical_cast<int>(input.substr(0, 4));
+        month = boost::lexical_cast<int>(input.substr(4, 2));
+        day = boost::lexical_cast<int>(input.substr(6, 2));
+        if (input.size() >= 15) { //Minimum for time
+            if (input.at(8) != 'T') {
+                ERROR("Wrong demiliter");
+                return cDateTime();
+            }
+            hour = boost::lexical_cast<int>(input.substr(9, 2));
+            minute = boost::lexical_cast<int>(input.substr(11, 2));
+            second = boost::lexical_cast<int>(input.substr(13, 2));
+        } else {
+            if (input.size() >= 9) {
+                ERROR("Invalid dt " + input);
+                return cDateTime();
+            }
+            return cDateTime(year, month, day);
+        }
+        if (input.size() >= 16) {
+            if (input.at(15) == 'Z') {
+                isUtc = true;
+            } else {
+                ERROR("wrong utc char? " + input.at(15));
+                return cDateTime();
+            }
+        }
+    } catch (boost::bad_lexical_cast &c) {
+        ERROR("failed to convert: "+std::string(c.what()));
+        return cDateTime();
+    } catch (...) {
+        ERROR("failed to convert: unkown exception");
+        return cDateTime();
+    }
+    return cDateTime(year, month, day, hour, minute, second, isUtc);
+}
+
+cDateTime toDateTime(const vcard_4_0::DateDatetimePropertyType &prop)
+{
+    if (prop.date_time()) {
+        return toDateTime(*prop.date_time());
+    } else if (prop.date()) {
+        return toDateTime(*prop.date());
+    }
+    ERROR("no date and no datetime");
+    return cDateTime();
+}
+
+template <typename T>
+T fromDateTime(const Kolab::cDateTime &dt)
+{
+    T prop;
+
+    if (dt.isDateOnly()) {
+        prop.date(fromDate(dt));
+    } else {
+        prop.date_time(fromDateTime(dt));
+    }
+    return prop;
+}
+
+vcard_4_0::PrefTypeValueType fromCryptoPref(Kolab::Crypto::CryptoPref pref)
+{
+    switch (pref) {
+        case Kolab::Crypto::Always:
+            return vcard_4_0::CryptoType::encryptpref_type::text_type::Always;
+        case Kolab::Crypto::Ask:
+            return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
+        case Kolab::Crypto::IfPossible:
+            return vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible;
+        case Kolab::Crypto::Never:
+            return vcard_4_0::CryptoType::encryptpref_type::text_type::Never;
+        default:
+            WARNING("unknown encrypt pref");
+    }
+    return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask;
+}
+
+Kolab::Crypto::CryptoPref toCryptoPref(vcard_4_0::PrefTypeValueType pref)
+{
+    switch (pref) {
+        case vcard_4_0::CryptoType::encryptpref_type::text_type::Always:
+            return Kolab::Crypto::Always;
+        case vcard_4_0::CryptoType::encryptpref_type::text_type::Ask:
+            return Kolab::Crypto::Ask;
+        case vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible:
+            return Kolab::Crypto::IfPossible;
+        case vcard_4_0::CryptoType::encryptpref_type::text_type::Never:
+            return Kolab::Crypto::Never;
+        default:
+            WARNING("unknown encrypt pref");
+    }
+    return Kolab::Crypto::Ask;
+}
+
+vcard_4_0::relatedPropType fromRelated(const Kolab::Related &r)
+{
+    using namespace vcard_4_0;
+    vcard_4_0::relatedPropType related;
+    if (r.type() == Kolab::Related::Uid) {
+        related.uri(r.uri());
+    } else {
+        related.text(r.text());
+    }
+    if (r.relationTypes() != Kolab::Related::NoRelation) {
+        
+        vcard::adr_type::parameters_type::baseParameter_sequence base;
+        vcard::adr_type::parameters_type b;
+        
+        vcard_4_0::typeParamType::text_sequence seq;
+        if (r.relationTypes() & Kolab::Related::Child) {
+            seq.push_back(TypeValueType::child);
+        }
+        if (r.relationTypes() & Kolab::Related::Spouse) {
+            seq.push_back(TypeValueType::spouse);
+        }
+        if (r.relationTypes() & Kolab::Related::Assistant) {
+            seq.push_back(TypeValueType::x_assistant);
+        }
+        if (r.relationTypes() & Kolab::Related::Manager) {
+            seq.push_back(TypeValueType::x_manager);
+        }
+        if (!seq.empty()) {
+            vcard_4_0::typeParamType type;
+            type.text(seq);
+            b.baseParameter().push_back(type);
+        }
+        
+        related.parameters(b);
+    }
+    
+    return related;
+}
+
+Kolab::Related toRelated(const vcard_4_0::relatedPropType &r)
+{
+    Kolab::Related::DescriptionType type = Kolab::Related::Invalid;
+    std::string textOrUri;
+    if (r.uri()) {
+        type = Kolab::Related::Uid;
+        textOrUri = *r.uri();
+    } else if (r.text()) {
+        type = Kolab::Related::Text;
+        textOrUri = *r.text();
+    } else {
+        ERROR("no text and no uri");
+        return Kolab::Related();
+    }
+    Kolab::Related related(type, textOrUri);
+    if (r.parameters()) {
+        BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*r.parameters()).baseParameter()) {
+            if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                int types = 0;
+                BOOST_FOREACH(const std::string &s, rel->text()) {
+                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::child)) {
+                        types |= Kolab::Related::Child;
+                    }
+                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::spouse)) {
+                        types |= Kolab::Related::Spouse;
+                    }
+                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_assistant)) {
+                        types |= Kolab::Related::Assistant;
+                    }
+                    if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_manager)) {
+                        types |= Kolab::Related::Manager;
+                    }
+                }
+                related.setRelationTypes(types);
+            } 
+        }
+    }
+    return related;
+}
+
+vcard_4_0::vcard::adr_type fromAddress(const Kolab::Address &address)
+{
+    using namespace vcard_4_0;
+    vcard::adr_type a(vcard::adr_type::pobox_type(std::string()/*address.pobox()*/), 
+                      vcard::adr_type::ext_type(std::string()/*address.ext()*/),
+                                                vcard::adr_type::street_type(address.street()),
+                                                vcard::adr_type::locality_type(address.locality()),
+                                                vcard::adr_type::region_type(address.region()),
+                                                address.code(),
+                                                vcard::adr_type::country_type(address.country())
+                      );
+    vcard::adr_type::parameters_type b;
+    if (address.types()) {
+        vcard_4_0::typeParamType::text_sequence seq;
+        if (address.types() & Kolab::Address::Home) {
+            seq.push_back(TypeValueType::home);
+        }
+        if (address.types() & Kolab::Address::Work) {
+            seq.push_back(TypeValueType::work);
+        }
+        if (!seq.empty()) {
+            vcard_4_0::typeParamType type;
+            type.text(seq);
+            b.baseParameter().push_back(type);
+        }
+    }
+    if (!address.label().empty()) {
+        b.baseParameter().push_back(vcard_4_0::labelParamType(address.label()));
+    }
+    a.parameters(b);
+    return a;
+}
+
+Kolab::Address toAddress(const vcard_4_0::vcard::adr_type &adr, bool *isPreferred = 0)
+{
+    using namespace vcard_4_0;
+    Address address;
+    if (adr.parameters()) {
+        BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*adr.parameters()).baseParameter()) {
+            if (const vcard_4_0::labelParamType *rel = dynamic_cast<const vcard_4_0::labelParamType*> (&param)) {
+                address.setLabel(rel->text());
+            } else if (isPreferred && dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                *isPreferred = true;
+            } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                int types = 0;
+                BOOST_FOREACH(const std::string &s, rel->text()) {
+                    if (s == TypeValueType(TypeValueType::work)) {
+                        types |= Kolab::Telephone::Work;
+                    }
+                    if (s == TypeValueType(TypeValueType::home)) {
+                        types |= Kolab::Telephone::Home;
+                    }
+                }
+                address.setTypes(types);
+            } 
+        }
+    }
+    
+    address.setCode(adr.code());
+    address.setCountry(adr.country());
+    address.setLocality(adr.locality());
+    address.setRegion(adr.region());
+    address.setStreet(adr.street());
+    return address;
+}
+
+std::string toGeoUri(double lat, double lon)
+{
+    //lexical_cast doesn't work, so we're using stringstream
+    std::stringstream s;
+    s << "geo:";
+    s.precision(15); //can't use std::numeric_limits<double>::max_digits10 because that's c++ 0x, it should be 17, but that seems to cause rounding problems... no idea why.
+    s << lat << ",";
+    s.precision(15); //Needed to get the right precision somehow...
+    s << lon;
+    return s.str();
+}
+
+bool fromGeoUri(const std::string &uri, double &lat, double &lon)
+{
+    if (uri.substr(0,4) != std::string("geo:")) {
+        WARNING("not a geo uri");
+        return false;
+    }
+    std::size_t pos1 = uri.find(",");
+    if (pos1 == std::string::npos) {
+        WARNING("not a valid geo uri");
+        return false;
+    }
+    lat = boost::lexical_cast<double>(uri.substr(4, pos1-4));
+    lon = boost::lexical_cast<double>(uri.substr(pos1+1, uri.size()-pos1-1));
+    return true;
+}
+
+template <typename T> 
+void writeCard(vcard_4_0::vcard &vcard, const T &);
+
+template <> 
+void writeCard<Kolab::Contact>(vcard_4_0::vcard &vcard, const Kolab::Contact &contact)
+{
+    using namespace vcard_4_0;
+    
+    if (!contact.categories().empty()) {
+        vcard_4_0::vcard::categories_type cat;
+        vcard_4_0::vcard::categories_type::text_sequence seq;
+        BOOST_FOREACH(const std::string &s, contact.categories()) {
+            seq.push_back(s);
+        }
+        cat.text(seq);
+        vcard.categories(cat);
+    }
+    
+    if (contact.nameComponents().isValid()) {
+        const NameComponents &nc = contact.nameComponents();
+        vcard::n_type n;
+        n.surname(fromStringList(nc.surnames()));
+        n.given(fromStringList(nc.given()));
+        n.additional(fromStringList(nc.additional()));
+        n.prefix(fromStringList(nc.prefixes()));
+        n.suffix(fromStringList(nc.suffixes()));
+        vcard.n(n);
+    }
+    
+    if (!contact.note().empty()) {
+        vcard.note(vcard::note_type(contact.note()));
+    }
+    
+    if (!contact.freeBusyUrl().empty()) {
+        vcard.fburl(vcard::fburl_type(contact.freeBusyUrl()));
+    }
+    
+    if (!contact.titles().empty()) {
+        vcard.title(fromList<vcard::title_type>(contact.titles()));
+    }
+    
+    if (!contact.affiliations().empty()) {
+        vcard::group_sequence affiliations;
+        BOOST_FOREACH(const Affiliation &a, contact.affiliations()) {
+            affiliationPropType::org_type org;
+            org.text().push_back(a.organisation());
+            BOOST_FOREACH(const std::string &unit, a.organisationalUnits()) {
+                org.text().push_back(unit);
+            }
+            vcard::group_type group(org);
+            if (!a.logo().empty()) {
+                group.logo(affiliationPropType::logo_type(uriInlineEncoding(a.logo(), a.logoMimetype())));
+            }
+            group.role(fromList<affiliationPropType::role_type>(a.roles()));
+            BOOST_FOREACH(const Related &rel, a.relateds()) {
+                group.related().push_back(fromRelated(rel));
+            }
+            BOOST_FOREACH(const Address &adr, a.addresses()) {
+                group.adr().push_back(fromAddress(adr));
+            }
+
+            affiliations.push_back(group);
+        }
+        vcard.group(affiliations);
+    }
+    
+    if (!contact.urls().empty()) {
+        vcard.url(fromList<vcard::url_type>(contact.urls()));
+    }
+    
+    if (!contact.addresses().empty()) {
+        vcard::adr_sequence adrs;
+        int index = 0;
+        BOOST_FOREACH(const Kolab::Address &address, contact.addresses()) {
+            vcard::adr_type a = fromAddress(address);
+            if(contact.addressPreferredIndex() == index) {
+                if (a.parameters()) {
+                    (*a.parameters()).baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+                } else {
+                    vcard::adr_type::parameters_type b;
+                    b.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+                    a.parameters(b);
+                }
+            }
+            index++;
+            adrs.push_back(a);
+        }
+        vcard.adr(adrs);
+    }
+    
+    if (!contact.nickNames().empty()) {
+        vcard::nickname_type::text_sequence textsequence;
+        BOOST_FOREACH(const std::string &s, contact.nickNames()) {
+            textsequence.push_back(s);
+        }
+        vcard::nickname_type nickName;
+        nickName.text(textsequence);
+        vcard.nickname(nickName);
+    }
+    
+    if (!contact.relateds().empty()) {
+        vcard::related_sequence seq;
+        BOOST_FOREACH(const Kolab::Related &r, contact.relateds()) {
+            seq.push_back(fromRelated(r));
+        }
+        vcard.related(seq);
+    }
+    
+    if (contact.bDay().isValid()) {
+        Kolab::cDateTime dt = contact.bDay();
+        if (dt.isUTC() || !dt.timezone().empty()) {
+            WARNING("Must be local time, local time assumed");
+            dt.setUTC(false);
+        }
+        vcard.bday(fromDateTime<vcard::bday_type>(dt));
+    }
+    
+    if (contact.anniversary().isValid()) {
+        Kolab::cDateTime dt = contact.anniversary();
+        if (dt.isUTC() || !dt.timezone().empty()) {
+            WARNING("Must be local time, local time assumed");
+            dt.setUTC(false);
+        }
+        vcard.anniversary(fromDateTime<vcard::anniversary_type>(dt));
+    }
+    
+    if (!contact.photo().empty()) {
+        vcard::photo_type photo(vcard_4_0::UriPropertyType::uri_type(uriInlineEncoding(contact.photo(), contact.photoMimetype())));
+        vcard.photo(photo);
+    }
+    
+    if (contact.gender() != Contact::NotSet) {
+        switch (contact.gender()) {
+            case Contact::NotSpecified:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::empty));
+                break;
+            case Contact::Male:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::M));
+                break;
+            case Contact::Female:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::F));
+                break;
+            default:
+                ERROR("Unhandled gender");
+        }
+    }
+    
+    if (!contact.languages().empty()) {
+        vcard.lang(fromList<vcard::lang_type>(contact.languages()));
+    }
+    
+    if (!contact.telephones().empty()) {
+        vcard::tel_sequence seq;
+        int index = 0;
+        BOOST_FOREACH(const Kolab::Telephone &t, contact.telephones()) {
+            vcard::tel_type tel(t.number());
+            vcard_4_0::typeParamType telTypeParam;
+            if (t.types() & Kolab::Telephone::Car) {
+                telTypeParam.text().push_back(TypeValueType::x_car);
+            } 
+            if (t.types() & Kolab::Telephone::Cell) {
+                telTypeParam.text().push_back(TypeValueType::cell);
+            } 
+            if (t.types() & Kolab::Telephone::Fax) {
+                telTypeParam.text().push_back(TypeValueType::fax);
+            } 
+            if (t.types() & Kolab::Telephone::Home) {
+                telTypeParam.text().push_back(TypeValueType::home);
+            } 
+            if (t.types() & Kolab::Telephone::Work) {
+                telTypeParam.text().push_back(TypeValueType::work);
+            } 
+            if (t.types() & Kolab::Telephone::Text) {
+                telTypeParam.text().push_back(TypeValueType::text);
+            } 
+            if (t.types() & Kolab::Telephone::Voice) {
+                telTypeParam.text().push_back(TypeValueType::voice);
+            } 
+            if (t.types() & Kolab::Telephone::Video) {
+                telTypeParam.text().push_back(TypeValueType::video);
+            } 
+            if (t.types() & Kolab::Telephone::Textphone) {
+                telTypeParam.text().push_back(TypeValueType::textphone);
+            } 
+            if (t.types() & Kolab::Telephone::Pager) {
+                telTypeParam.text().push_back(TypeValueType::pager);
+            }
+            vcard::tel_type::parameters_type params;
+            if(contact.telephonesPreferredIndex() == index) {
+                params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+            }
+            index++;
+
+            if (!telTypeParam.text().empty()) {
+                params.baseParameter().push_back(telTypeParam);
+                tel.parameters(params);
+            }
+            seq.push_back(tel);
+        }
+        vcard.tel(seq);
+    }
+    
+    if (!contact.imAddresses().empty()) {
+        vcard.impp(fromList<vcard::impp_type>(contact.imAddresses(), contact.imAddressPreferredIndex()));
+    }
+    
+    if (!contact.emailAddresses().empty()) {
+        vcard.email(fromList<vcard::email_type>(contact.emailAddresses(), contact.emailAddressPreferredIndex()));
+    }
+    
+    if (!contact.gpsPos().empty()) {
+        vcard_4_0::vcard::geo_sequence list;
+        BOOST_FOREACH(const Kolab::Geo &g ,contact.gpsPos()) {
+            list.push_back(vcard_4_0::vcard::geo_type(toGeoUri(g.latitude, g.longitude)));
+        }
+        vcard.geo(list);
+    }
+    
+    if (contact.crypto().isValid()) {
+        vcard::x_crypto_type crypto;
+        const Kolab::Crypto &c = contact.crypto();
+        if (c.allowed()) {
+            vcard::x_crypto_type::allowed_type::text_sequence seq;
+            if (c.allowed() & Kolab::Crypto::PGPinline) {
+                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE);
+            }
+            if (c.allowed() & Kolab::Crypto::PGPmime) {
+                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_MIME);
+            }
+            if (c.allowed() & Kolab::Crypto::SMIME) {
+                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIME);
+            }
+            if (c.allowed() & Kolab::Crypto::SMIMEopaque) {
+                seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque);
+            }
+            vcard::x_crypto_type::allowed_type allowed;
+            allowed.text(seq);
+            crypto.allowed(allowed);
+        }
+        vcard_4_0::vcard::key_sequence keys;
+        if (!c.pgpKey().empty()) {
+            keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.pgpKey(), MIME_PGP_KEYS)));
+        }
+        if (!c.smimeKey().empty()) {
+            keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(c.smimeKey(), MIME_PKCS7_MIME)));
+        }
+        if (!keys.empty()) {
+            vcard.key(keys);
+        }
+        crypto.encryptpref(fromCryptoPref(c.encryptPref()));
+        crypto.signpref(fromCryptoPref(c.signPref()));
+
+        vcard.x_crypto(crypto);
+    }
+
+
+}
+
+template <> 
+void writeCard<Kolab::DistList>(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist)
+{
+    if (!distlist.members().empty()) {
+        vcard_4_0::vcard::member_sequence members;
+        BOOST_FOREACH (const Kolab::ContactReference &m, distlist.members()) {
+            members.push_back(vcard_4_0::vcard::member_type(Shared::fromContactReference(m)));
+        }
+        vcard.member(members);
+    } else {
+        WARNING("empty distlist");
+    }
+}
+
+
+
+template <typename T>
+std::string serializeCard(const T &card, const std::string prod = std::string()) {
+
+    using namespace vcard_4_0;
+    
+    clearErrors();
+
+    try {
+        vcard_4_0::vcard::uid_type uid(Shared::toURN(getUID(card.uid())));
+        setCreatedUid(Shared::fromURN(uid.uri()));
+        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
+        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
+        vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
+        vcard_4_0::vcard::kind_type kind(getType<T>());
+        vcard_4_0::vcard::fn_type fn(card.name());
+
+        vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+        
+        writeCard<T>(vcard, card);
+        
+        if (!card.customProperties().empty()) {
+            BOOST_FOREACH(const Kolab::CustomProperty &a, card.customProperties()) {
+                vcard.x_custom().push_back(vcard_4_0::CustomType(a.identifier, a.value));
+            }
+        }
+        
+        VcardsType vcards(vcard);
+
+        xml_schema::namespace_infomap map;
+        map[""].name = XCARD_NAMESPACE;
+        
+        std::ostringstream ostringstream;
+        vcard_4_0::vcards(ostringstream, vcards, map);
+        return ostringstream.str();
+    } catch  (const xml_schema::exception& e) {
+        CRITICAL("Unknown Exception: failed to write Contact");
+    }
+    return std::string();
+}
+
+template <typename T>
+boost::shared_ptr<T> readCard(const vcard_4_0::VcardsType::vcard_type &vcard);
+
+template <>
+boost::shared_ptr<Kolab::Contact> readCard <Kolab::Contact> (const vcard_4_0::VcardsType::vcard_type &vcard)
+{
+    using namespace vcard_4_0;
+    boost::shared_ptr<Kolab::Contact> contact(new Kolab::Contact);
+    
+    if (vcard.categories()) {
+        contact->setCategories(toStringList((*vcard.categories()).text()));
+    }
+    
+    if (vcard.n()) {
+        NameComponents nc;
+        nc.setSurnames(toStringList((*vcard.n()).surname()));
+        nc.setGiven(toStringList((*vcard.n()).given()));
+        nc.setPrefixes(toStringList((*vcard.n()).prefix()));
+        nc.setSuffixes(toStringList((*vcard.n()).suffix()));
+        nc.setAdditional(toStringList((*vcard.n()).additional()));
+        contact->setNameComponents(nc);
+    }
+    if (vcard.note()) {
+        contact->setNote((*vcard.note()).text());
+    }
+    if (vcard.fburl()) {
+        contact->setFreeBusyUrl((*vcard.fburl()).uri());
+    }
+    if (!vcard.title().empty()) {
+        contact->setTitles(toTextList<vcard::title_type >(vcard.title()));
+    }
+    if (!vcard.group().empty()) {
+        std::vector<Kolab::Affiliation> list;
+        BOOST_FOREACH (const vcard::group_type &group, vcard.group()) {
+            Kolab::Affiliation aff;
+            if (!group.org().text().empty()) {
+                aff.setOrganisation(*group.org().text().begin());
+                std::vector<std::string> units;
+                for ( vcard_4_0::NonEmptyTextListPropertyType::text_const_iterator it = ++group.org().text().begin(); it != group.org().text().end(); it++) {
+                    units.push_back(*it);
+                }
+                aff.setOrganisationalUnits(units);
+            } else {
+                WARNING("No org present");
+            }
+            std::string mimetype;
+            if (group.logo()) {
+                const std::string &logo = uriInlineDecoding((*group.logo()).uri(), mimetype);
+                aff.setLogo(logo, mimetype);
+            }
+            aff.setRoles(toTextList<vcard::group_type::role_type>(group.role()));
+            std::vector<Related> relateds;
+            BOOST_FOREACH(const vcard::group_type::related_type &rel, group.related()) {
+                relateds.push_back(toRelated(rel));
+            }
+            aff.setRelateds(relateds);
+            std::vector<Address> addresses;
+            BOOST_FOREACH(const vcard::group_type::adr_type &adr, group.adr()) {
+                addresses.push_back(toAddress(adr));
+            }
+            aff.setAddresses(addresses);
+            list.push_back(aff);
+        }
+        contact->setAffiliations(list);
+    }
+    if (!vcard.url().empty()) {
+        contact->setUrls(toUriList<vcard::url_type >(vcard.url()));
+    }
+    if (!vcard.adr().empty()) {
+        std::vector<Kolab::Address> list;
+        int preferredIndex = -1;
+        int index = 0;
+        BOOST_FOREACH(const vcard::adr_type &adr, vcard.adr()) {
+            bool isPreferred = false;
+            const Kolab::Address &address = toAddress(adr, &isPreferred);
+            if (isPreferred) {
+                preferredIndex = index;
+            }
+            index++;
+            list.push_back(address);
+        }
+        contact->setAddresses(list, preferredIndex);
+    }
+    if (vcard.nickname()) {
+        contact->setNickNames(toTextList<TextListPropertyType::text_type>((*vcard.nickname()).text()));
+    }
+    if (!vcard.related().empty()) {
+        std::vector<Related> list;
+        BOOST_FOREACH(const vcard_4_0::vcard::related_type &r, vcard.related()) {
+            list.push_back(toRelated(r));
+        }
+        contact->setRelateds(list);
+    }
+    if (vcard.bday()) {
+        contact->setBDay(toDateTime(*vcard.bday()));
+    }
+    if (vcard.anniversary()) {
+        contact->setAnniversary(toDateTime(*vcard.anniversary()));
+    }
+    if (vcard.photo()) {
+        std::string mimetype;
+        const std::string decodedPhoto =  uriInlineDecoding((*vcard.photo()).uri(), mimetype);
+        contact->setPhoto(decodedPhoto, mimetype);
+    }
+    if (vcard.gender()) {
+        if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::empty) {
+            contact->setGender(Kolab::Contact::NotSpecified);
+        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::M) {
+            contact->setGender(Kolab::Contact::Male);
+        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::F) {
+            contact->setGender(Kolab::Contact::Female);
+        }
+    }
+    if (!vcard.lang().empty()) {
+        std::vector<std::string> list;
+        BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) {
+            list.push_back(l.language_tag());
+        }
+        contact->setLanguages(list);
+    }
+    if (!vcard.tel().empty()) {
+        std::vector<Kolab::Telephone> list;
+        int preferredIndex = -1;
+        int index = 0;
+        BOOST_FOREACH(const vcard::tel_type &tel, vcard.tel()) {
+            Kolab::Telephone telephone;
+            if (tel.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*tel.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = index;
+                    } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                        int types = 0;
+                        BOOST_FOREACH(const std::string &s, rel->text()) {
+                            if (s == TypeValueType(TypeValueType::work)) {
+                                types |= Kolab::Telephone::Work;
+                            }
+                            if (s == TypeValueType(TypeValueType::home)) {
+                                types |= Kolab::Telephone::Home;
+                            }
+                            if (s == TypeValueType(TypeValueType::text)) {
+                                types |= Kolab::Telephone::Text;
+                            }
+                            if (s == TypeValueType(TypeValueType::voice)) {
+                                types |= Kolab::Telephone::Voice;
+                            }
+                            if (s == TypeValueType(TypeValueType::fax)) {
+                                types |= Kolab::Telephone::Fax;
+                            }
+                            if (s == TypeValueType(TypeValueType::cell)) {
+                                types |= Kolab::Telephone::Cell;
+                            }
+                            if (s == TypeValueType(TypeValueType::video)) {
+                                types |= Kolab::Telephone::Video;
+                            }
+                            if (s == TypeValueType(TypeValueType::pager)) {
+                                types |= Kolab::Telephone::Pager;
+                            }
+                            if (s == TypeValueType(TypeValueType::textphone)) {
+                                types |= Kolab::Telephone::Textphone;
+                            }
+                            if (s == TypeValueType(TypeValueType::x_car)) {
+                                types |= Kolab::Telephone::Car;
+                            }
+                        }
+                        telephone.setTypes(types);
+                    } 
+                }
+            }
+            index++;
+
+            telephone.setNumber(tel.text());
+            list.push_back(telephone);
+        }
+        contact->setTelephones(list, preferredIndex);
+    }
+    
+    if (!vcard.impp().empty()) {
+        int preferredIndex = -1;
+        
+        std::vector<std::string> list;
+        int i = 0;
+        BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, vcard.impp()) {
+            if (s.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = i;
+                    } 
+                }
+            }
+            i++;
+            list.push_back(s.uri());
+        }
+        
+        contact->setIMaddresses(list, preferredIndex);
+    }
+    if (!vcard.email().empty()) {
+        int preferredIndex = -1;
+        
+        std::vector<std::string> list;
+        int i = 0;
+        BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, vcard.email()) {
+            if (s.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = i;
+                    } 
+                }
+            }
+            i++;
+            list.push_back(s.text());
+        }
+        
+        contact->setEmailAddresses(list, preferredIndex);
+    }
+    if (!vcard.geo().empty()) {
+        std::vector<Geo> list;
+        BOOST_FOREACH(const vcard_4_0::geoPropType &s, vcard.geo()) {
+            double lon = 0.0;
+            double lat = 0.0;
+            if (fromGeoUri(s.uri(), lat, lon)) {
+                list.push_back(Kolab::Geo(lat, lon));
+            }
+        }
+        contact->setGPSpos(list);
+    }
+    if (vcard.x_crypto()) {
+        const vcard_4_0::vcard::x_crypto_type &crypto = *vcard.x_crypto();
+        Kolab::Crypto c;
+        if (crypto.allowed()) {
+            int allowed = 0;
+            BOOST_FOREACH(const vcard_4_0::vcard::x_crypto_type::allowed_type::text_type &m, crypto.allowed()->text()) {
+                if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE) {
+                    allowed |= Kolab::Crypto::PGPinline;
+                } else if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_MIME) {
+                    allowed |= Kolab::Crypto::PGPmime;
+                } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIME) {
+                    allowed |= Kolab::Crypto::SMIME;
+                } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque) {
+                    allowed |= Kolab::Crypto::SMIMEopaque;
+                } else {
+                    WARNING("unknown allowed property");
+                }
+            }
+            c.setAllowed(allowed);
+        }
+        if (!vcard.key().empty()) {
+            BOOST_FOREACH(const vcard_4_0::keyPropType &k, vcard.key()) {
+                std::string mimetype;
+                const std::string &key = uriInlineDecoding(k.uri(), mimetype);
+                if (mimetype == MIME_PGP_KEYS) {
+                    c.setPGPKey(key);
+                } else if (mimetype == MIME_PKCS7_MIME) {
+                    c.setSMIMEKey(key);
+                } else {
+                    WARNING("wrong mimetype on key");
+                }
+            }
+        }
+        if (crypto.encryptpref()) {
+            c.setEncryptPref(toCryptoPref(crypto.encryptpref()->text()));
+        }
+        if (crypto.signpref()) {
+            c.setSignPref(toCryptoPref(crypto.signpref()->text()));
+        }
+        contact->setCrypto(c);
+    }
+    return contact;
+}
+
+template <>
+boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
+{
+    using namespace vcard_4_0;
+    boost::shared_ptr<Kolab::DistList> distlist(new Kolab::DistList);
+
+    if (!vcard.member().empty()) {
+        std::vector<Kolab::ContactReference> members;
+
+        BOOST_FOREACH(const vcard_4_0::vcard::member_type & m, vcard.member()) {
+            members.push_back(Shared::toContactReference(m.uri()));
+        }
+        distlist->setMembers(members);
+    } else {
+        WARNING("empty distlist");
+    }
+    return distlist;
+}
+
+template <typename T>
+boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
+{
+    clearErrors();
+    try {
+        std::auto_ptr<vcard_4_0::VcardsType> vcards;
+        if (isUrl) {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            if (doc.get()) {
+                vcards = vcard_4_0::vcards(doc);
+            }
+        } else {
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            if (doc.get()) {
+                vcards = vcard_4_0::vcards(doc);
+            }
+        }
+
+        if (!vcards.get()) {
+            CRITICAL("failed to parse card!");
+            return boost::shared_ptr<T>();
+        }
+        
+        boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
+        card->setUid(Shared::fromURN(vcards->vcard().uid().uri()));
+        card->setName(vcards->vcard().fn().text());
+        
+        setProductId( vcards->vcard().prodid().text() );
+//         setFormatVersion( vcards->vcard().version().text() );
+//         global_xCardVersion = vcalendar.properties().version().text();
+        setKolabVersion( vcards->vcard().x_kolab_version().text() );
+        
+        if (!vcards->vcard().x_custom().empty()) {
+            std::vector<Kolab::CustomProperty> customProperties;
+            BOOST_FOREACH(const vcard_4_0::CustomType &p, vcards->vcard().x_custom()) {
+                customProperties.push_back(CustomProperty(p.identifier(), p.value()));
+            }
+            card->setCustomProperties(customProperties);
+        }
+        
+        return card;
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        CRITICAL("Failed to read card!");
+    }
+
+    return boost::shared_ptr<T>();
+}
+
+    }
+    
+} //Namespace
+
+#endif
\ No newline at end of file
diff --git a/libkolabxml/tests/CMakeLists.txt b/libkolabxml/tests/CMakeLists.txt
new file mode 100644
index 0000000..ecaa0ae
--- /dev/null
+++ b/libkolabxml/tests/CMakeLists.txt
@@ -0,0 +1,17 @@
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+if (QT4_FOUND)
+    message("Buildings tests")
+    QT4_AUTOMOC(bindingstest.cpp)
+    add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
+    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
+
+    QT4_AUTOMOC(conversiontest.cpp)
+    add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC})
+    target_link_libraries(conversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
+else()
+    message(WARNING "Could not build tests because qt is missing")
+endif()
diff --git a/libkolabxml/tests/bindingstest.cpp b/libkolabxml/tests/bindingstest.cpp
new file mode 100644
index 0000000..75eec5e
--- /dev/null
+++ b/libkolabxml/tests/bindingstest.cpp
@@ -0,0 +1,560 @@
+#include "bindingstest.h"
+
+#include <QObject>
+#include <QtTest/QtTest>
+
+#include "bindings/iCalendar-props.hxx"
+#include "bindings/iCalendar-valtypes.hxx"
+#include "bindings/kolabformat.hxx"
+
+#include <iostream>
+
+#include <xercesc/dom/DOMException.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <lib/kolabformat.h>
+#include <kdebug.h>
+// #include <kolab/kolabkcalconversion.h>
+#include <iostream>
+#include <fstream>
+#include "serializers.h"
+#include <lib/utils.h>
+#include <lib/kolabjournal.h>
+
+
+
+
+void BindingsTest::noteCompletness()
+{
+    Kolab::Note note;
+    note.setUid("UID");
+    note.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
+    note.setClassification(Kolab::ClassConfidential);
+    note.addCategory("Category");
+    note.setSummary("summary");
+    note.setDescription("description");
+    note.setColor("color");
+    const std::string &result = Kolab::writeNote(note);
+//     std::cout << result << std::endl;
+    
+    const Kolab::Note &re = Kolab::readNote(result, false);
+    QCOMPARE(re.uid(), note.uid());
+    QCOMPARE(re.created(), note.created());
+    QCOMPARE(re.classification(), note.classification());
+    QCOMPARE(re.categories(), note.categories());
+    QCOMPARE(re.summary(), note.summary());
+    QCOMPARE(re.description(), note.description());
+    QCOMPARE(re.color(), note.color());
+}
+
+
+// void BindingsTest::eventCompletness_data()
+template <typename T>
+void setIncidence(T &ev)
+{
+    ev.setUid("UID");
+    ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
+    ev.setSequence(1);
+    ev.setClassification(Kolab::ClassConfidential);
+    ev.addCategory("Category");
+    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
+    
+    Kolab::RecurrenceRule rule;
+    rule.setFrequency(Kolab::RecurrenceRule::Daily);
+    rule.setCount(5);
+    std::vector<int> list;
+    list.push_back(1);
+    list.push_back(3);
+    rule.setBysecond(list);
+    rule.setByminute(list);
+    rule.setByhour(list);
+    std::vector<Kolab::DayPos> byday;
+    byday.push_back(Kolab::DayPos(15, Kolab::Friday));
+    byday.push_back(Kolab::DayPos(0, Kolab::Monday));
+    byday.push_back(Kolab::DayPos(-3, Kolab::Monday));
+    rule.setByday(byday);
+    rule.setBymonthday(list);
+    rule.setByyearday(list);
+    rule.setByweekno(list);
+    rule.setBymonth(list);
+    
+    ev.setRecurrenceRule(rule);
+    ev.addRecurrenceDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
+    ev.addExceptionDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
+    ev.setRecurrenceID(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0), true);
+    ev.setSummary("summary");
+    ev.setDescription("description");
+    ev.setPriority(3);
+    ev.setStatus(Kolab::StatusConfirmed);
+    ev.setLocation("location");
+    ev.setOrganizer(Kolab::ContactReference("mail", "name", "uid"));
+    
+    Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid"));
+    attendee.setPartStat(Kolab::PartDelegated);
+    attendee.setRole(Kolab::Chair);
+    attendee.setRSVP(true);
+    
+    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
+    
+    std::vector<Kolab::Attachment> attachments;
+    
+    Kolab::Attachment attach;
+    attach.setData("data????*?*?*?*?*?", "mimetype");
+    attach.setLabel("label");
+    attachments.push_back(attach);
+    
+    Kolab::Attachment attach2;
+    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
+    attach2.setLabel("labe2l");
+    attachments.push_back(attach2);
+    
+    Kolab::Attachment attach3;
+    using namespace std;
+    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
+    if (file.is_open()) {
+        int size = file.tellg();
+        char *memblock = new char [size];
+        file.seekg (0, ios::beg);
+        file.read (memblock, size);
+        file.close();
+
+        attach3.setData(string(memblock, size), "mimetype");
+
+        delete[] memblock;
+    }
+    attach3.setLabel("labe3l");
+    attachments.push_back(attach3);
+    
+    ev.setAttachments(attachments);
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    ev.setCustomProperties(properties);
+    
+    std::vector<Kolab::Alarm> alarms;
+//     Kolab::Alarm dispAlarm("ident");
+//     dispAlarm.setRelativeStart(Kolab::Duration(3, true), Kolab::Start);
+//     alarms.push_back(dispAlarm);
+    std::vector<Kolab::ContactReference> att;
+    att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
+    att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
+    Kolab::Alarm emailAlarm("ident", "value", att);
+    emailAlarm.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true));
+    alarms.push_back(emailAlarm);
+//     Kolab::Attachment audiofile;
+//     audiofile.setUri("ksdjlksdflj", "sdkljdfl");
+//     Kolab::Alarm audio(audiofile);
+//     audio.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true));
+//     alarms.push_back(audio);
+    ev.setAlarms(alarms);
+}
+
+template <typename T>
+void checkIncidence(const T &ev, const T &re)
+{
+    //Common to all
+    
+    QCOMPARE(ev.uid(), re.uid());
+    QCOMPARE(ev.created(), re.created());
+    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
+    QCOMPARE(ev.sequence(), re.sequence());
+    QCOMPARE(ev.classification(), re.classification());
+    QCOMPARE(ev.categories(), re.categories());
+    QCOMPARE(ev.start(), re.start());
+    
+    //Recurrence
+    const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
+    const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
+    QCOMPARE(r1.isValid(), r2.isValid());
+    QCOMPARE(r1.frequency(), r2.frequency());
+    QCOMPARE(r1.interval(), r2.interval());
+    QCOMPARE(r1.weekStart(), r2.weekStart());
+    QCOMPARE(r1.count(), r2.count());
+    QCOMPARE(r1.end(), r2.end());
+    QCOMPARE(r1.bysecond(), r2.bysecond());
+    QCOMPARE(r1.byminute(), r2.byminute());
+    QCOMPARE(r1.byhour(), r2.byhour());
+    QCOMPARE(r1.byday(), r2.byday());
+    QCOMPARE(r1.bymonthday(), r2.bymonthday());
+    QCOMPARE(r1.byyearday(), r2.byyearday());
+    QCOMPARE(r1.byweekno(), r2.byweekno());
+    QCOMPARE(r1.bymonth(), r2.bymonth());
+        
+    //Rest
+    QCOMPARE(ev.recurrenceDates(), re.recurrenceDates());
+    QCOMPARE(ev.exceptionDates(), re.exceptionDates());
+    QCOMPARE(ev.recurrenceID(), re.recurrenceID());
+    QCOMPARE(ev.thisAndFuture(), re.thisAndFuture());
+    QCOMPARE(ev.summary(), re.summary());
+    QCOMPARE(ev.description(), re.description());
+    QCOMPARE(ev.priority(), re.priority());
+    QCOMPARE(ev.status(), re.status());
+    QCOMPARE(ev.location(), re.location());
+    QCOMPARE(ev.organizer(), re.organizer());
+    QCOMPARE(ev.attendees(), re.attendees());
+    QCOMPARE(ev.attachments(), re.attachments());
+    QCOMPARE(ev.customProperties(), re.customProperties());
+    QCOMPARE(ev.alarms(), re.alarms());
+}
+
+
+
+void BindingsTest::eventCompletness()
+{
+    Kolab::Event ev;
+    setIncidence(ev);
+    ev.setEnd(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
+    ev.setTransparency(true);
+    
+    std::string result = Kolab::writeEvent(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+//     std::cout << result << endl;
+    Kolab::Event e = Kolab::readEvent(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    checkIncidence(ev, e);
+    QCOMPARE(ev.end(), e.end());
+    QCOMPARE(ev.transparency(), e.transparency());
+    
+}
+
+void BindingsTest::eventDuration()
+{
+    Kolab::Event ev;
+    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
+    ev.setDuration(Kolab::Duration(11,22,33,44, true));
+
+    const std::string result = Kolab::writeEvent(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+//     std::cout << result << endl;
+    const Kolab::Event e = Kolab::readEvent(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    QVERIFY(ev.duration().isValid());
+    QCOMPARE(ev.duration(), e.duration());
+}
+
+void BindingsTest::todoCompletness()
+{
+    Kolab::Todo ev;
+    setIncidence(ev);
+    ev.setDue(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0));
+    ev.addRelatedTo("rel1");
+    ev.addRelatedTo("rel2");
+    ev.setPercentComplete(50);
+    
+    std::string result = Kolab::writeTodo(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+//     std::cout << result << endl;
+    Kolab::Todo e = Kolab::readTodo(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    checkIncidence(ev, e);
+    QCOMPARE(ev.due(), e.due());
+    QCOMPARE(ev.relatedTo(), e.relatedTo());
+    QCOMPARE(ev.percentComplete(), e.percentComplete());
+}
+
+void BindingsTest::journalCompletness()
+{
+    Kolab::Journal ev;
+    
+    
+    ev.setUid("UID");
+    ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0)); //UTC
+    ev.setSequence(1);
+    ev.setClassification(Kolab::ClassConfidential);
+    ev.addCategory("Category");
+    ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0));
+    Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid"));
+    attendee.setPartStat(Kolab::PartDelegated);
+    attendee.setRole(Kolab::Chair);
+    attendee.setRSVP(true);
+    
+    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
+    
+    std::vector<Kolab::Attachment> attachments;
+    
+    Kolab::Attachment attach;
+    attach.setData("data????*?*?*?*?*?", "mimetype");
+    attach.setLabel("label");
+    attachments.push_back(attach);
+    
+    Kolab::Attachment attach2;
+    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
+    attach2.setLabel("labe2l");
+    attachments.push_back(attach2);
+    
+    Kolab::Attachment attach3;
+    using namespace std;
+    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
+    if (file.is_open()) {
+        int size = file.tellg();
+        char *memblock = new char [size];
+        file.seekg (0, ios::beg);
+        file.read (memblock, size);
+        file.close();
+
+        attach3.setData(string(memblock, size), "mimetype");
+
+        delete[] memblock;
+    }
+    attach3.setLabel("labe3l");
+    attachments.push_back(attach3);
+    
+    ev.setAttachments(attachments);
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    ev.setCustomProperties(properties);
+    
+    
+    
+    std::string result = Kolab::writeJournal(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+//     std::cout << result << endl;
+    Kolab::Journal re = Kolab::readJournal(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    
+    
+    QCOMPARE(ev.uid(), re.uid());
+    QCOMPARE(ev.created(), re.created());
+    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
+    QCOMPARE(ev.sequence(), re.sequence());
+    QCOMPARE(ev.classification(), re.classification());
+    QCOMPARE(ev.categories(), re.categories());
+    QCOMPARE(ev.start(), re.start());
+    QCOMPARE(ev.summary(), re.summary());
+    QCOMPARE(ev.description(), re.description());
+    QCOMPARE(ev.status(), re.status());
+    QCOMPARE(ev.attendees(), re.attendees());
+    QCOMPARE(ev.attachments(), re.attachments());
+    QCOMPARE(ev.customProperties(), re.customProperties());
+    
+}
+
+void BindingsTest::contactCompletness()
+{
+    std::vector<std::string> stringlist;
+    stringlist.push_back("lbksdfbklsd");
+    stringlist.push_back("sdf");
+
+    Kolab::Contact c;
+    c.setUid("1045b57d-ff7f-0000-d814-867b4d7f0000");
+    c.setCategories(stringlist);
+    c.setName("name");
+    Kolab::NameComponents nc;
+    nc.setSurnames(stringlist);
+    nc.setGiven(stringlist);
+    nc.setAdditional(stringlist);
+    nc.setPrefixes(stringlist);
+    nc.setSuffixes(stringlist);
+    c.setNameComponents(nc);
+    c.setNote("note");
+    c.setFreeBusyUrl("freebusy");
+    c.setUrls(stringlist);
+    c.setNickNames(stringlist);
+    
+    std::vector <Kolab::Related> relateds;
+    Kolab::Related r1(Kolab::Related::Text, "text");
+    r1.setRelationTypes(Kolab::Related::Child);
+    relateds.push_back(r1);
+    Kolab::Related r2(Kolab::Related::Uid, "urn");
+    r2.setRelationTypes(Kolab::Related::Child|Kolab::Related::Spouse);
+    relateds.push_back(r2);
+    c.setRelateds(relateds);
+    
+    c.setBDay(Kolab::cDateTime(2001,12,10,12,12,12,false));
+    c.setAnniversary(Kolab::cDateTime(2001,3,2,1,1,1,false));
+    c.setPhoto("photo", "mimetype");
+    c.setGender(Kolab::Contact::Male);
+    c.setLanguages(stringlist);
+    c.setIMaddresses(stringlist,1);
+    c.setEmailAddresses(stringlist,1);
+    c.setTitles(stringlist);
+    
+    std::vector<Kolab::Affiliation> list;
+    Kolab::Affiliation aff;
+    aff.setOrganisation("org");
+    aff.setOrganisationalUnits(stringlist);
+    aff.setLogo("logo", "mime/miem");
+    aff.setRoles(stringlist);
+    std::vector<Kolab::Related> relateds2;
+    relateds2.push_back(Kolab::Related(Kolab::Related::Text, "textRelation", Kolab::Related::Assistant));
+    relateds2.push_back(Kolab::Related(Kolab::Related::Uid, "textRelation", Kolab::Related::Manager));
+    aff.setRelateds(relateds2);
+    std::vector<Kolab::Address> adrs;
+    Kolab::Address adr1;
+    adr1.setLabel("label");
+    adrs.push_back(adr1);
+    Kolab::Address adr2;
+    adr2.setStreet("street");
+    adr2.setTypes(Kolab::Address::Work);
+    adrs.push_back(adr2);
+    aff.setAddresses(adrs);
+    list.push_back(aff);
+    Kolab::Affiliation aff2;
+    list.push_back(aff2);
+    c.setAffiliations(list);
+    Kolab::Address address;
+    address.setCode("oiuoiu");
+    address.setCountry("werwer");
+    address.setLabel("lkjlkj");
+    address.setLocality("alla");
+    address.setRegion("skjdfkd");
+    address.setStreet("sldkflsdfj");
+    address.setTypes( Kolab::Address::Work | Kolab::Address::Home );
+    std::vector<Kolab::Address> addresses;
+    addresses.push_back(address);
+    addresses.push_back(address);
+    c.setAddresses(addresses);
+    Kolab::Telephone phone;
+    phone.setNumber("lkjsdflkjfds");
+    phone.setTypes(Kolab::Telephone::Work|
+                    Kolab::Telephone::Home|
+                    Kolab::Telephone::Text|
+                    Kolab::Telephone::Voice|
+                    Kolab::Telephone::Fax|
+                    Kolab::Telephone::Cell|
+                    Kolab::Telephone::Video|
+                    Kolab::Telephone::Pager|
+                    Kolab::Telephone::Textphone|
+                    Kolab::Telephone::Car
+    );
+
+    std::vector<Kolab::Telephone> telephones;
+    telephones.push_back(phone);
+    telephones.push_back(phone);
+    c.setTelephones(telephones, 1);
+    std::vector<Kolab::Geo> geo;
+    geo << Kolab::Geo(1.3, -40.3);
+    c.setGPSpos(geo);
+    Kolab::Crypto crypto;
+    crypto.setAllowed(Kolab::Crypto::PGPinline | Kolab::Crypto::SMIMEopaque);
+    crypto.setPGPKey("pgp");
+    crypto.setSignPref(Kolab::Crypto::IfPossible);
+    crypto.setEncryptPref(Kolab::Crypto::Never);
+    crypto.setSMIMEKey("smime");
+    c.setCrypto(crypto);
+    
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    c.setCustomProperties(properties);
+    
+    const std::string result = Kolab::writeContact(c);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    std::cout << result << endl;
+    Kolab::Contact e = Kolab::readContact(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    QCOMPARE(e.uid(), c.uid());
+    QCOMPARE(e.categories(), c.categories());
+    QCOMPARE(e.name(), c.name());
+    QCOMPARE(e.nameComponents(), c.nameComponents());
+    QCOMPARE(e.note(), c.note());
+    QCOMPARE(e.freeBusyUrl(), c.freeBusyUrl());
+    QCOMPARE(e.titles(), c.titles());
+    QCOMPARE(e.affiliations(), c.affiliations());
+    QCOMPARE(e.urls(), c.urls());
+    QCOMPARE(e.addresses(), c.addresses());
+    QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex());
+    QCOMPARE(e.nickNames(), c.nickNames());
+    QCOMPARE(e.relateds(), c.relateds());
+    QCOMPARE(e.bDay(), c.bDay());
+    QCOMPARE(e.anniversary(), c.anniversary());
+    QCOMPARE(e.photo(), c.photo());
+    QCOMPARE(e.photoMimetype(), c.photoMimetype());
+    QCOMPARE(e.gender(), c.gender());
+    QCOMPARE(e.languages(), c.languages());
+    QCOMPARE(e.telephones(), c.telephones());
+    QCOMPARE(e.telephonesPreferredIndex(), c.telephonesPreferredIndex());
+    QCOMPARE(e.imAddresses(), c.imAddresses());
+    QCOMPARE(e.imAddressPreferredIndex(), c.imAddressPreferredIndex());
+    QCOMPARE(e.emailAddresses(), c.emailAddresses());
+    QCOMPARE(e.emailAddressPreferredIndex(), c.emailAddressPreferredIndex());
+    QCOMPARE(e.gpsPos(), c.gpsPos());
+    QCOMPARE(e.crypto(), c.crypto());
+    QCOMPARE(e.customProperties(), c.customProperties());
+}
+
+void BindingsTest::distlistCompletness()
+{
+    std::vector<std::string> stringlist;
+    stringlist.push_back("lbksdfbklsd");
+    stringlist.push_back("sdf");
+
+    Kolab::DistList c;
+    c.setName("name");
+    c.setUid("uid");
+    std::vector<Kolab::ContactReference> members;
+    members.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name"));
+    members.push_back(Kolab::ContactReference(Kolab::ContactReference::UidReference, "urn"));
+    c.setMembers(members);
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    c.setCustomProperties(properties);
+    
+    const std::string result = Kolab::writeDistlist(c);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+//     std::cout << result << endl;
+    Kolab::DistList e = Kolab::readDistlist(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    QCOMPARE(e.uid(), c.uid());
+    QCOMPARE(e.name(), c.name());
+    QCOMPARE(e.members(), c.members());
+    QCOMPARE(e.customProperties(), c.customProperties());
+}
+
+
+void BindingsTest::versionTest()
+{
+    Kolab::Todo ev;
+    setIncidence(ev);
+    
+    std::string result = Kolab::writeTodo(ev);
+    Kolab::Todo e = Kolab::readTodo(result, false);
+    QCOMPARE(Kolab::productId(), std::string(Kolab::KOLAB_LIBNAME) + std::string(Kolab::KOLAB_LIB_VERSION));
+    QCOMPARE(Kolab::xKolabVersion(), std::string(Kolab::KOLAB_FORMAT_VERSION));
+    QCOMPARE(Kolab::xCalVersion(), std::string("2.0"));
+}
+
+void BindingsTest::errorTest()
+{
+    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
+    QCOMPARE(Kolab::error(), Kolab::Critical);
+    QVERIFY(!Kolab::errorMessage().empty());
+}
+
+//Don't break due to an error
+void BindingsTest::errorRecoveryTest()
+{
+    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
+    QCOMPARE(Kolab::error(), Kolab::Critical);
+
+    Kolab::Todo ev;
+    setIncidence(ev);
+    
+    const std::string result = Kolab::writeTodo(ev);
+    Kolab::readTodo(result, false);
+    QCOMPARE(Kolab::error(), Kolab::NoError);
+}
+
+void BindingsTest::BenchmarkRoundtripKolab()
+{
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result = Kolab::writeEvent(event);
+    QBENCHMARK {
+        Kolab::readEvent(result, false);
+    }
+}
+
+void BindingsTest::BenchmarkRoundtrip()
+{
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result;
+    QBENCHMARK {
+        result = Kolab::writeEvent(event);
+        Kolab::readEvent(result, false);
+    }
+}
+
+QTEST_MAIN( BindingsTest )
+
+#include "bindingstest.moc"
diff --git a/libkolabxml/tests/bindingstest.h b/libkolabxml/tests/bindingstest.h
new file mode 100644
index 0000000..16c933c
--- /dev/null
+++ b/libkolabxml/tests/bindingstest.h
@@ -0,0 +1,43 @@
+#ifndef BINDINGSTEST_H
+#define BINDINGSTEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+/*
+ * The test are roundtrip tests, which simply write an object out and read it again. The two objects are then compared for equality.
+ * This assumes that containers are working (comparison operators and adding/removing values).
+ * 
+ * Testing it properly would mean to add loads of testfiles in text so we could:
+ * serialize => compare to text representation
+ * deserialize => check values
+ * 
+ * If we would do this ideally for every property on every type that would result in a lot of work.
+ *
+ */ 
+
+class BindingsTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+
+    //Kolabformat
+    void noteCompletness();
+    void eventCompletness();
+    void eventDuration();
+    void todoCompletness();
+    void journalCompletness();
+    
+    void contactCompletness();
+    void distlistCompletness();
+
+    void versionTest();
+    void errorTest();
+    void errorRecoveryTest();
+
+    void BenchmarkRoundtripKolab();
+    void BenchmarkRoundtrip();
+
+};
+
+#endif
\ No newline at end of file
diff --git a/libkolabxml/tests/conversiontest.cpp b/libkolabxml/tests/conversiontest.cpp
new file mode 100644
index 0000000..0bed229
--- /dev/null
+++ b/libkolabxml/tests/conversiontest.cpp
@@ -0,0 +1,275 @@
+#include "conversiontest.h"
+
+#include <QtTest/QtTest>
+#include <lib/xcalconversions.h>
+#include <lib/xcardconversions.h>
+#include <lib/utils.h>
+
+#include "serializers.h"
+#include <boost/thread.hpp>
+
+Q_DECLARE_METATYPE(Kolab::Duration);
+Q_DECLARE_METATYPE(Kolab::DayPos);
+Q_DECLARE_METATYPE(Kolab::cDateTime);
+Q_DECLARE_METATYPE(Kolab::ErrorSeverity);
+Q_DECLARE_METATYPE(std::string);
+
+using namespace Kolab::XCAL;
+
+void ConversionTest::dateComparatorTest()
+{
+    QVERIFY( !(Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime()));
+    QVERIFY( Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false));
+}
+
+ 
+void ConversionTest::durationParserTest_data()
+{
+    QTest::addColumn<Kolab::Duration>("expected");
+    QTest::addColumn<QString>("string");
+
+    QTest::newRow("Time") << Kolab::Duration(0,2,3,4, false) << "+PT2H3M4S";
+    QTest::newRow("Day") << Kolab::Duration(1,2,3,4, false) << "+P1DT2H3M4S";
+    QTest::newRow("Week") << Kolab::Duration(1, false) << "+P1W";
+    QTest::newRow("Week Multidigit, negative") << Kolab::Duration(23, true) << "-P23W";
+    Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::durationParserTest()
+{
+    QFETCH(QString, string);
+    QFETCH(Kolab::Duration, expected);
+    const Kolab::Duration result = toDuration(string.toStdString());
+    QCOMPARE(result, expected);
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::durationSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::Duration>("duration");
+
+    QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false);
+    QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false);
+    QTest::newRow("Week positive") << "P1W" << Kolab::Duration(1, false);
+    QTest::newRow("Week negative") << "-P3W" << Kolab::Duration(3, true);
+    QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true);
+    Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::durationSerializerTest()
+{
+    QFETCH(Kolab::Duration, duration);
+    QFETCH(QString, expected);
+    const std::string result = fromDuration(duration);
+    QCOMPARE(QString::fromStdString(result), expected);
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+
+void ConversionTest::dayPosParserTest_data()
+{
+    QTest::addColumn<Kolab::DayPos>("expected");
+    QTest::addColumn<QString>("string");
+
+    QTest::newRow("positive") << Kolab::DayPos(15, Kolab::Wednesday) << "15WE";
+    QTest::newRow("positive with +") << Kolab::DayPos(15, Kolab::Wednesday) << "+15WE";
+    QTest::newRow("negative") << Kolab::DayPos(-15, Kolab::Wednesday) << "-15WE";
+    QTest::newRow("all occurrences") << Kolab::DayPos(0, Kolab::Wednesday) << "WE";
+    Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::dayPosParserTest()
+{
+    QFETCH(QString, string);
+    QFETCH(Kolab::DayPos, expected);
+    const Kolab::DayPos result = toDayPos(string.toStdString());
+    QCOMPARE(result, expected);
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::dayPosSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::DayPos>("daypos");
+
+    QTest::newRow("pos") << "15WE" << Kolab::DayPos(15, Kolab::Wednesday);
+    QTest::newRow("negative") << "-15WE" << Kolab::DayPos(-15, Kolab::Wednesday);
+    QTest::newRow("all occurrences") << "WE" << Kolab::DayPos(0, Kolab::Wednesday);
+    Kolab::Utils::clearErrors();
+
+}
+
+void ConversionTest::dayPosSerializerTest()
+{
+    QFETCH(Kolab::DayPos, daypos);
+    QFETCH(QString, expected);
+    const std::string result = fromDayPos(daypos);
+    QCOMPARE(QString::fromStdString(result), expected);
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::xcardDateParserTest_data()
+{
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<Kolab::cDateTime>("expected");
+    QTest::addColumn<Kolab::ErrorSeverity>("errorState");
+
+    QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) << Kolab::NoError;
+    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true) << Kolab::NoError;
+    QTest::newRow("date only") << "20010102" << Kolab::cDateTime(2001, 01, 02) << Kolab::NoError;
+    QTest::newRow("fail 1 short") << "20010102T03040" << Kolab::cDateTime() << Kolab::Error;
+    QTest::newRow("fail non utc") << "20010102T030401s" << Kolab::cDateTime() << Kolab::Error;
+    QTest::newRow("fail no time") << "20010102T" << Kolab::cDateTime() << Kolab::Error;
+    Kolab::Utils::clearErrors();
+}
+
+
+void ConversionTest::xcardDateParserTest()
+{
+    QFETCH(QString, input);
+    QFETCH(Kolab::cDateTime, expected);
+    QFETCH(Kolab::ErrorSeverity, errorState);
+    const Kolab::cDateTime &dt = Kolab::XCARD::toDateTime(input.toStdString());
+    QCOMPARE(dt, expected);
+    QCOMPARE(Kolab::Utils::getError(), errorState);
+}
+
+void ConversionTest::xCardSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::cDateTime>("dt");
+
+    QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false);
+    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true);
+    QTest::newRow("dateonly") << "20010102" << Kolab::cDateTime(2001, 01, 02);
+    Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::xCardSerializerTest()
+{
+    QFETCH(QString, expected);
+    QFETCH(Kolab::cDateTime, dt);
+    const std::string &s = Kolab::XCARD::fromDateTime(dt);
+    QCOMPARE(QString::fromStdString(s), expected);
+    if (dt.isDateOnly()) {
+        const std::string &s2 = Kolab::XCARD::fromDate(dt);
+        QCOMPARE(QString::fromStdString(s2), expected);
+    }
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::uriInlineEncodingTest()
+{
+    const std::string &s = Kolab::Utils::uriInlineEncoding("data", "mimetype/mime");
+    QCOMPARE(s, std::string("data:mimetype/mime;base64,ZGF0YQ=="));
+    std::string mimetype;
+    const std::string &d = Kolab::Utils::uriInlineDecoding(s, mimetype);
+    QCOMPARE(mimetype, std::string("mimetype/mime"));
+    QCOMPARE(d, std::string("data"));
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::mailtoUriEncodingTest_data()
+{
+    QTest::addColumn<QString>("email");
+    QTest::addColumn<QString>("name");
+    QTest::addColumn<QString>("result");
+    QTest::addColumn<QString>("resultEncoded");
+    
+    QTest::newRow("1") << "email_1 at email.com" << "John Doe" << "mailto:John Doe<email_1 at email.com>" << "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E";
+    
+    Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::mailtoUriEncodingTest()
+{
+    QFETCH(QString, email);
+    QFETCH(QString, name);
+    QFETCH(QString, result);
+    QFETCH(QString, resultEncoded);
+    const std::string &mailto = Kolab::XCARD::toMailto(email.toStdString(), name.toStdString());
+    std::cout << mailto << std::endl;
+    QCOMPARE(QString::fromStdString(mailto), resultEncoded);
+    std::string n;
+    const std::string &e = Kolab::XCARD::fromMailto(mailto, n);
+    QCOMPARE(QString::fromStdString(n), name);
+    QCOMPARE(QString::fromStdString(e), email);
+    
+}
+
+void ConversionTest::urnTest()
+{
+    QCOMPARE(Kolab::Shared::toURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"));
+    QCOMPARE(Kolab::Shared::toURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"));
+    QCOMPARE(Kolab::Shared::fromURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000"));
+    QCOMPARE(Kolab::Shared::fromURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000"));
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+void ConversionTest::geoUriTest()
+{
+    QCOMPARE(Kolab::XCARD::toGeoUri(-34.056, 179.3453), std::string("geo:-34.056,179.3453"));
+    QCOMPARE(Kolab::XCARD::toGeoUri(-34.1, 179.5), std::string("geo:-34.1,179.5"));
+    QCOMPARE(Kolab::XCARD::toGeoUri(-34.0, 179.0), std::string("geo:-34,179"));
+    QCOMPARE(Kolab::XCARD::toGeoUri(-34, 179), std::string("geo:-34,179"));
+    QCOMPARE(Kolab::XCARD::toGeoUri(-34.012342356, 179.3451234553), std::string("geo:-34.012342356,179.3451234553"));
+    
+    double lat, lon;
+    QVERIFY(Kolab::XCARD::fromGeoUri(std::string("geo:-34.056,179.3453"), lat, lon));
+    QCOMPARE(lat, -34.056);
+    QCOMPARE(lon, 179.3453);
+    QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
+}
+
+
+void ConversionTest::contactReferenceTest()
+{
+    Kolab::ContactReference email(Kolab::ContactReference::EmailReference, "mail", "name");
+    QCOMPARE(Kolab::Shared::fromContactReference(email), std::string("mailto:name%3Cmail%3E"));
+    Kolab::ContactReference urn(Kolab::ContactReference::UidReference, "urn");
+    QCOMPARE(Kolab::Shared::fromContactReference(urn), std::string("urn:uuid:urn"));
+    
+    QCOMPARE(Kolab::Shared::toContactReference("urn:uuid:urn"), urn);
+    QCOMPARE(Kolab::Shared::toContactReference("mailto:name%3Cmail%3E"), email);
+}
+
+
+void threadF() 
+{
+    for (int i = 0; i < 5; ++i)
+    {
+        std::stringstream s;
+//         s << boost::this_thread::get_id();
+        std::string uid = s.str();
+//         std::cout << uid << std::endl;
+        Kolab::Utils::setCreatedUid(uid);
+        boost::this_thread::sleep(boost::posix_time::seconds(1));
+        QCOMPARE(Kolab::Utils::createdUid(), uid);
+    }
+}
+
+void ConversionTest::threadLocalTest()
+{
+    //Ensure global variables are not mixed between threads and therefore threadsafe.
+    boost::thread t(threadF);
+    boost::thread t2(threadF);
+    t.join();
+    t2.join();
+}
+
+void ConversionTest::uuidGeneratorTest()
+{
+    const std::string &s = getUID();
+    std::cout << s << std::endl;
+    QVERIFY(!s.empty());
+    QCOMPARE(s.size(), (std::size_t)36ul);
+}
+
+
+
+QTEST_MAIN( ConversionTest )
+
+#include "conversiontest.moc"
+
+
diff --git a/libkolabxml/tests/conversiontest.h b/libkolabxml/tests/conversiontest.h
new file mode 100644
index 0000000..b586ed6
--- /dev/null
+++ b/libkolabxml/tests/conversiontest.h
@@ -0,0 +1,47 @@
+
+#ifndef CONVERSIONTEST_H
+#define CONVERSIONTEST_H
+
+#include <QObject>
+
+class ConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+    void dateComparatorTest();
+
+    void durationParserTest_data();
+    void durationParserTest();
+    
+    void durationSerializerTest_data();
+    void durationSerializerTest();
+    
+    void dayPosParserTest_data();
+    void dayPosParserTest();
+    
+    void dayPosSerializerTest_data();
+    void dayPosSerializerTest();
+    
+    void xcardDateParserTest_data();
+    void xcardDateParserTest();
+    
+    void xCardSerializerTest_data();
+    void xCardSerializerTest();
+    
+    void uriInlineEncodingTest();
+    
+    void mailtoUriEncodingTest_data();
+    void mailtoUriEncodingTest();
+    
+    void urnTest();
+    
+    void contactReferenceTest();
+    
+    void geoUriTest();
+    
+    void threadLocalTest();
+    
+    void uuidGeneratorTest();
+};
+
+#endif // CONVERSIONTEST_H
diff --git a/libkolabxml/tests/serializers.h b/libkolabxml/tests/serializers.h
new file mode 100644
index 0000000..39d904f
--- /dev/null
+++ b/libkolabxml/tests/serializers.h
@@ -0,0 +1,218 @@
+#ifndef SERIALIZERS_H
+#define SERIALIZERS_H
+
+#include <QByteArray>
+#include <QString>
+#include <lib/kolabformat.h>
+
+namespace QTest {
+    template<>
+    char *toString(const Kolab::cDateTime &dt)
+    {
+        QByteArray ba = "Kolab::cDateTime(";
+        ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", ";
+        ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", ";
+        ba += QString(dt.isUTC()?QString("UTC"):QString("TZ: "+QString::fromStdString(dt.timezone()))).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+    template<>
+    char *toString(const std::vector<Kolab::cDateTime> &v)
+    {
+        QByteArray ba = "vector<Kolab::cDateTime>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Attendee &a)
+    {
+        QByteArray ba = "Kolab::Attendee(";
+        ba += QString::fromStdString(a.contact().email()).toAscii() + ", " + QString::fromStdString(a.contact().name()).toAscii()+ ", " + 
+        QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role())  + ", " + QByteArray::number(a.rsvp())  + ", " + 
+        QString::fromStdString(a.contact().uid()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Attendee> &v)
+    {
+        QByteArray ba = "vector<Kolab::Attendee>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+     
+    template<>
+    char *toString(const std::string &s)
+    {
+        QByteArray ba = "string(";
+        ba += QString::fromStdString(s).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<std::string> &v)
+    {
+        QByteArray ba = "vector<std::string>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<int> &v)
+    {
+        QByteArray ba = "vector<int>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QString::number(v.at(i)).toAscii()+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Duration &dt)
+    {
+        QByteArray ba = "Kolab::Duration(";
+        ba += QByteArray::number(dt.weeks()) + ", " + QByteArray::number(dt.days())+ ", " + QByteArray::number(dt.hours()) + ", ";
+        ba += QByteArray::number(dt.minutes()) + ", " + QByteArray::number(dt.seconds()) + ", " + QByteArray::number(dt.isNegative());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::DayPos &dt)
+    {
+        QByteArray ba = "Kolab::DayPos(";
+        ba += QByteArray::number(dt.occurence()) + ", " + QByteArray::number(dt.weekday());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Attachment &a)
+    {
+        QByteArray ba = "Kolab::Attachment(";
+        ba += QString::fromStdString(a.uri()).toAscii() + ", " + QString::fromStdString(a.mimetype()).toAscii()+ ", " + 
+        QString::fromStdString(a.label()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Attachment> &v)
+    {
+        QByteArray ba = "vector<Kolab::Attachment>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::ContactReference &a)
+    {
+        QByteArray ba = "Kolab::ContactReference(";
+        ba += QString::fromStdString(a.email()).toAscii()+ ", ";
+        ba += QString::fromStdString(a.name()).toAscii()+ ", ";
+        ba += QString::fromStdString(a.uid()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::ContactReference> &v)
+    {
+        QByteArray ba = "vector<Kolab::ContactReference>(";
+        for (int i = 0; i < v.size(); i++) {
+                ba += QByteArray(toString(v.at(i)))+ "\n";
+            }
+            ba += ")";
+            return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Alarm &a)
+    {
+        QByteArray ba = "Kolab::Alarm(";
+        ba += QByteArray::number(a.type()) + "\n " + QString::fromStdString(a.summary()).toAscii()+ "\n " + 
+        QString::fromStdString(a.text()).toAscii()+"\n " +toString(a.duration()) + "\n " + QByteArray::number(a.numrepeat())+  "\n " + toString(a.start()) + "\n " +
+        toString(a.relativeStart())  + "\n " +  QByteArray::number(a.relativeTo()) + "\n " + toString(a.audioFile()) +  "\n " + toString(a.attendees()) + "\n ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Alarm> &v)
+    {
+        QByteArray ba = "vector<Kolab::Alarm>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Related &a)
+    {
+        QByteArray ba = "Kolab::Related(";
+        ba += QString::fromStdString(a.text()).toAscii()+ "\n " + 
+        QString::fromStdString(a.uri()).toAscii()+"\n " +
+        QByteArray::number(a.relationTypes()) + "\n " +
+        QByteArray::number(a.type()) + "\n ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Related> &v)
+    {
+        QByteArray ba = "vector<Kolab::Related>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Affiliation &a)
+    {
+        QByteArray ba = "Kolab::Affiliation(";
+        ba += QString::fromStdString(a.organisation()).toAscii()+ "\n " + 
+        QString::fromStdString(a.logo()).toAscii()+"\n " + "\n " + toString(a.roles())+  "\n " + toString(a.relateds()) + "\n " +
+        toString(a.addresses())  + "\n ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Affiliation> &v)
+    {
+        QByteArray ba = "vector<Kolab::Affiliation>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+
+
+ }
+ 
+#endif
+ 
\ No newline at end of file
diff --git a/libkolabxml/tests/testfiles/icalEvent.xml b/libkolabxml/tests/testfiles/icalEvent.xml
new file mode 100644
index 0000000..89f99a5
--- /dev/null
+++ b/libkolabxml/tests/testfiles/icalEvent.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--Copy of an example event from the xCal RFC-->
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0" >
+     <vcalendar>
+       <properties>
+         <prodid>
+           <text>-//Example Inc.//Example Client//EN</text>
+         </prodid>
+         <version>
+           <text>2.0</text>
+         </version>
+         <x-kolab-version > <!--xmlns="http://kolab.org"-->
+             <text>3.0dev1</text>
+         </x-kolab-version>
+       </properties>
+       <components>
+         <vevent>
+           <properties>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+             <created>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </created>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
+               </parameters>
+               <date-time>2006-01-02T12:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <rrule>
+               <recur>
+                 <freq>DAILY</freq>
+                 <count>5</count>
+               </recur>
+             </rrule>
+             <rdate>
+               <parameters>
+                 <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
+               </parameters>
+               <date-time>2007-02-06T00:11:21</date-time>
+       <!--        <period>
+                 <start>2006-01-02T15:00:00</start>
+                 <duration>PT2H</duration>
+               </period>-->
+             </rdate>
+             <summary>
+               <text>Event #2</text>
+             </summary>
+             <description>
+               <text>Test.&#x0a;Test.
+Test.</text>
+             </description>
+
+           </properties>
+         </vevent>
+<!--         <vevent>
+           <properties>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>Europe/Zurich</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T14:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <recurrence-id>
+               <parameters>
+                 <tzid><text>Europe/Zurich</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T12:00:00</date-time>
+             </recurrence-id>
+             <summary>
+               <text>Event #2 bis</text>
+             </summary>
+
+           </properties>
+           <components/>
+         </vevent>-->
+       </components>
+     </vcalendar>
+</icalendar>
diff --git a/libkolabxml/tests/testfiles/testevent.xml b/libkolabxml/tests/testfiles/testevent.xml
new file mode 100644
index 0000000..dd59990
--- /dev/null
+++ b/libkolabxml/tests/testfiles/testevent.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<vevent xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+
+  <properties>
+    <dtstart>
+      <date>2011-11-10+10:10</date>
+    </dtstart>
+    <rrule>
+      <recur>
+        <freq>DAILY</freq>
+        <count>2</count>
+        <byhour>3</byhour>
+      </recur>
+    </rrule>
+    <x-prop>
+        <parameters>
+        <pref><integer>1</integer></pref>
+        </parameters>                 <!-- Core vCard elements  -->
+        <text>value goes here</text>  <!-- are still accessible -->
+    </x-prop>
+
+  </properties>
+
+  <components/>
+
+</vevent>
diff --git a/libkolabxml/tests/testfiles/testkolabevent.xml b/libkolabxml/tests/testfiles/testkolabevent.xml
new file mode 100644
index 0000000..e991846
--- /dev/null
+++ b/libkolabxml/tests/testfiles/testkolabevent.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<kolab:event xmlns:kolab="http://kolab.org" xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+
+  <vevent>
+    <properties>
+      <dtstart>
+        <date>2011-11-10+10:10</date>
+      </dtstart>
+      <rrule>
+        <recur>
+           <count>2</count>
+          <byhour>3</byhour>
+          <freq>DAILY</freq>
+          
+        </recur>
+      </rrule>
+      <x-custom-property>
+         <unknown>blabla</unknown>
+      </x-custom-property>       
+      <x-unknown-property>
+         <unknown>blibla</unknown>
+      </x-unknown-property>       
+    </properties>
+    <components>
+      <valarm/>
+    </components>
+  </vevent>
+
+</kolab:event>


commit 79ede711aeab218c2fa63fc458c9c887c5e337d1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 14:55:34 2012 +0100

    Implemented v2 notes.

diff --git a/libkolab/kolabformat/kolabobject.cpp b/libkolab/kolabformat/kolabobject.cpp
index c3603a5..3e4bdb6 100644
--- a/libkolab/kolabformat/kolabobject.cpp
+++ b/libkolab/kolabformat/kolabobject.cpp
@@ -23,11 +23,13 @@
 #include <kolabformatV2/event.h>
 #include <kolabformatV2/contact.h>
 #include <kolabformatV2/distributionlist.h>
+#include <kolabformatV2/note.h>
 #include <mime/mimeutils.h>
 #include <conversion/kcalconversion.h>
 #include <qdom.h>
 #include <kdebug.h>
 #include <qbuffer.h>
+#include <akonadi/notes/noteutils.h>
 #include <kolab/kolabformat.h>
 
 
@@ -38,6 +40,8 @@ static QString todoKolabType() { return QString::fromLatin1("application/x-vnd.k
 static QString journalKolabType() { return QString::fromLatin1("application/x-vnd.kolab.journal"); };
 static QString contactKolabType() { return QString::fromLatin1("application/x-vnd.kolab.contact"); };
 static QString distlistKolabType() { return QString::fromLatin1("application/x-vnd.kolab.contact.distlist"); }
+static QString noteKolabType() { return QString::fromLatin1("application/x-vnd.kolab.note"); }
+
 static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
 
 /*
@@ -175,6 +179,39 @@ KMime::Message::Ptr contactToKolabFormat(const KolabV2::Contact& contact)
 }
 
 
+KMime::Message::Ptr noteFromKolab(const QByteArray &xmlData, const KMime::Message::Ptr &data)
+{
+    KolabV2::Note j;
+    if ( !j.load( xmlData ) ) {
+        kWarning() << "failed to read note";
+        return KMime::Message::Ptr();
+    }
+
+    Akonadi::NoteUtils::NoteMessageWrapper note;
+    note.setTitle(j.summary());
+    note.setText(j.body().toUtf8());
+    note.setFrom("kolab at kde4");
+    note.setCreationDate(data->date()->dateTime());
+    return note.message();
+}
+
+KMime::Message::Ptr noteToKolab(const KMime::Message::Ptr& msg)
+{
+    Akonadi::NoteUtils::NoteMessageWrapper note(msg);
+    KolabV2::Note j;
+    j.setSummary( note.title() );
+    j.setBody( note.text() );
+
+    KMime::Message::Ptr message = Mime::createMessage( noteKolabType() );
+    message->subject()->fromUnicodeString( j.summary(), "utf-8" );
+    KMime::Content* content = Mime::createMainPart( noteKolabType(), j.saveXML().toUtf8() );
+    message->addContent( content );
+
+    message->assemble();
+    return message;
+}
+
+
 //Normalize incidences before serializing them
 void normalizeIncidence(KCalCore::Incidence::Ptr i)
 {
@@ -206,6 +243,7 @@ public:
     KCalCore::Incidence::Ptr mIncidence;
     KABC::Addressee mAddressee;
     KABC::ContactGroup mContactGroup;
+    KMime::Message::Ptr mNote;
     ObjectType mObjectType;
     Version mVersion;
 };
@@ -268,6 +306,10 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
         kDebug() << "distlist";
         d->mContactGroup = contactGroupFromKolab(xmlData);
         d->mObjectType = DistlistObject;
+    }  else if (kolabType == noteKolabType()) { //Note
+        kDebug() << "notes";
+        d->mNote = noteFromKolab(xmlData, msg);
+        d->mObjectType = NoteObject;
     } else {
         kWarning() << "no kolab object found " << kolabType;
     }
@@ -317,6 +359,11 @@ KABC::ContactGroup KolabObjectReader::getDistlist() const
     return d->mContactGroup;
 }
 
+KMime::Message::Ptr KolabObjectReader::getNote() const
+{
+    return d->mNote;
+}
+
 
 
 KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v, const QString &tz)
@@ -386,6 +433,15 @@ KMime::Message::Ptr KolabObjectWriter::writeDistlist(const KABC::ContactGroup &d
     return distListToKolabFormat(d);
 }
 
+KMime::Message::Ptr KolabObjectWriter::writeNote(const KMime::Message::Ptr &note, Version v)
+{
+    if (v == KolabV3) {
+        //TODO
+    }
+    return noteToKolab(note);
+}
+
+
 
 }; //Namespace
 
diff --git a/libkolab/kolabformat/kolabobject.h b/libkolab/kolabformat/kolabobject.h
index a20ce99..3c00cbb 100644
--- a/libkolab/kolabformat/kolabobject.h
+++ b/libkolab/kolabformat/kolabobject.h
@@ -41,7 +41,8 @@ enum ObjectType {
     TodoObject,
     JournalObject,
     ContactObject,
-    DistlistObject
+    DistlistObject,
+    NoteObject
 };
 
 
@@ -70,6 +71,8 @@ public:
     KCalCore::Incidence::Ptr getIncidence() const;
     KABC::Addressee getContact() const;
     KABC::ContactGroup getDistlist() const;
+    KMime::Message::Ptr getNote() const;
+
 private:
     //@cond PRIVATE
     class Private;
@@ -84,6 +87,7 @@ public:
     static KMime::Message::Ptr writeJournal(const KCalCore::Journal::Ptr &, Version v = KolabV3, const QString &tz = QString());
     static KMime::Message::Ptr writeContact(const KABC::Addressee &, Version v = KolabV3);
     static KMime::Message::Ptr writeDistlist(const KABC::ContactGroup &, Version v = KolabV3);
+    static KMime::Message::Ptr writeNote(const KMime::Message::Ptr &, Version v = KolabV3);
 };
 
 }; //Namespace


commit 3dca5958002339e926490abda2d5736f33cd6500
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 14:54:41 2012 +0100

    FindKDELIbraries improved

diff --git a/cmake/modules/FindKDELibraries.cmake b/cmake/modules/FindKDELibraries.cmake
index 45e6c57..6d81cc6 100644
--- a/cmake/modules/FindKDELibraries.cmake
+++ b/cmake/modules/FindKDELibraries.cmake
@@ -2,17 +2,29 @@
 find_library(KCALCORE_LIBRARY NAMES kcalcore)
 if(KCALCORE_LIBRARY)
     set(KCALCORE_LIBRARY_FOUND ON)
-    message("KCalCore found")
+    message("KCalCore found: ${KCALCORE_LIBRARY}")
 endif(KCALCORE_LIBRARY)
 
 find_library(KMIME_LIBRARY NAMES kmime)
 if(KMIME_LIBRARY)
     set(KMIME_LIBRARY_FOUND ON)
-    message("KMime found")
+    message("KMime found: ${KMIME_LIBRARY}")
 endif(KMIME_LIBRARY)
 
 find_library(KABC_LIBRARY NAMES kabc)
 if(KABC_LIBRARY)
     set(KABC_LIBRARY_FOUND ON)
-    message("KABC found")
-endif(KABC_LIBRARY)
\ No newline at end of file
+    message("KABC found: ${KABC_LIBRARY}")
+endif(KABC_LIBRARY)
+
+find_library(AKONADI-KDE_LIBRARY NAMES akonadi-kde)
+if(AKONADI-KDE_LIBRARY)
+    set(AKONADI-KDE_LIBRARY_FOUND ON)
+    message("AKONADI-KDE found: ${AKONADI-KDE_LIBRARY}")
+endif(AKONADI-KDE_LIBRARY)
+
+find_library(AKONADI-NOTES_LIBRARY NAMES akonadi-notes)
+if(AKONADI-NOTES_LIBRARY)
+    set(AKONADI-NOTES_LIBRARY_FOUND ON)
+    message("AKONADI-NOTES found: ${AKONADI-NOTES_LIBRARY}")
+endif(AKONADI-NOTES_LIBRARY)
\ No newline at end of file
diff --git a/libkolab/CMakeLists.txt b/libkolab/CMakeLists.txt
index c00fdc7..4338a9d 100644
--- a/libkolab/CMakeLists.txt
+++ b/libkolab/CMakeLists.txt
@@ -30,7 +30,7 @@ set(LIBRARY_TYPE STATIC)
 add_subdirectory(kolabformatV2)
 
 add_library(kolab SHARED kolabformat/kolabobject.cpp mime/mimeutils.cpp conversion/kcalconversion.cpp)
-target_link_libraries(kolab kolabformatV2  ${KOLABXML} ${KCALCORE_LIBRARY} ${KMIME_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KABC_LIBRARY} akonadi-kde ${KDE4_KIO_LIBRARY})
+target_link_libraries(kolab kolabformatV2  ${KOLABXML} ${KCALCORE_LIBRARY} ${KMIME_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KABC_LIBRARY} ${AKONDI-KDE_LIBRARY} ${AKONADI-NOTES_LIBRARY} ${KDE4_KIO_LIBRARY})
 set_target_properties(kolab PROPERTIES VERSION 0.1 SOVERSION 0)
 
 install(TARGETS kolab EXPORT libkolabLibraryTargets ${KOLAB_INSTALL_DIRECTORIES})


commit 48d7b5e4a88482dfd87f1756dc005b782b10f284
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 14:54:15 2012 +0100

    fixed header install path

diff --git a/cmake/modules/FindKolabInternal.cmake b/cmake/modules/FindKolabInternal.cmake
index 9e817eb..fb9d6a5 100644
--- a/cmake/modules/FindKolabInternal.cmake
+++ b/cmake/modules/FindKolabInternal.cmake
@@ -46,6 +46,6 @@ set(KOLAB_INSTALL_DIRECTORIES  RUNTIME DESTINATION "${KOLAB_BIN_INSTALL_DIR}"
 if(KOLAB_HEADER_INSTALL_DIR)
     message("KOLAB_HEADER_INSTALL_DIR specified manually")
 else()
-    set(KOLAB_HEADER_INSTALL_DIR  "${CMAKE_INSTALL_PREFIX}/include")
+    set(KOLAB_HEADER_INSTALL_DIR  "${CMAKE_INSTALL_PREFIX}/include/kolab")
 endif()
 message("KOLAB_HEADER_INSTALL_DIR: ${KOLAB_HEADER_INSTALL_DIR}")


commit a5fbc9c6820d0fc6625cbf44896b50d34732793a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 12:57:17 2012 +0100

    Fix includes and library finding.

diff --git a/cmake/modules/FindKDELibraries.cmake b/cmake/modules/FindKDELibraries.cmake
new file mode 100644
index 0000000..45e6c57
--- /dev/null
+++ b/cmake/modules/FindKDELibraries.cmake
@@ -0,0 +1,18 @@
+#Find some libraries
+find_library(KCALCORE_LIBRARY NAMES kcalcore)
+if(KCALCORE_LIBRARY)
+    set(KCALCORE_LIBRARY_FOUND ON)
+    message("KCalCore found")
+endif(KCALCORE_LIBRARY)
+
+find_library(KMIME_LIBRARY NAMES kmime)
+if(KMIME_LIBRARY)
+    set(KMIME_LIBRARY_FOUND ON)
+    message("KMime found")
+endif(KMIME_LIBRARY)
+
+find_library(KABC_LIBRARY NAMES kabc)
+if(KABC_LIBRARY)
+    set(KABC_LIBRARY_FOUND ON)
+    message("KABC found")
+endif(KABC_LIBRARY)
\ No newline at end of file
diff --git a/libkolab/CMakeLists.txt b/libkolab/CMakeLists.txt
index 71d9e47..c00fdc7 100644
--- a/libkolab/CMakeLists.txt
+++ b/libkolab/CMakeLists.txt
@@ -3,12 +3,12 @@ project(libkolab)
 cmake_minimum_required(VERSION 2.6)
 
 include( ../cmake/modules/FindKolabInternal.cmake )
+include (../cmake/modules/FindKDELibraries.cmake)
 
 find_package(Qt4 REQUIRED)
 find_package(KDE4 REQUIRED)
 
 find_library(KOLABXML NAMES kolabxml)
-# find_library(KOLABKCAL NAMES kolabkcal)
 
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC" )
 
@@ -30,7 +30,7 @@ set(LIBRARY_TYPE STATIC)
 add_subdirectory(kolabformatV2)
 
 add_library(kolab SHARED kolabformat/kolabobject.cpp mime/mimeutils.cpp conversion/kcalconversion.cpp)
-target_link_libraries(kolab kolabformatV2  ${KOLABXML} kcalcore kmime ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} kabc akonadi-kde ${KDE4_KIO_LIBRARY})
+target_link_libraries(kolab kolabformatV2  ${KOLABXML} ${KCALCORE_LIBRARY} ${KMIME_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KABC_LIBRARY} akonadi-kde ${KDE4_KIO_LIBRARY})
 set_target_properties(kolab PROPERTIES VERSION 0.1 SOVERSION 0)
 
 install(TARGETS kolab EXPORT libkolabLibraryTargets ${KOLAB_INSTALL_DIRECTORIES})
diff --git a/libkolab/kolabformat/kolabobject.cpp b/libkolab/kolabformat/kolabobject.cpp
index 0a0cbc2..c3603a5 100644
--- a/libkolab/kolabformat/kolabobject.cpp
+++ b/libkolab/kolabformat/kolabobject.cpp
@@ -26,9 +26,7 @@
 #include <mime/mimeutils.h>
 #include <conversion/kcalconversion.h>
 #include <qdom.h>
-#include <kcalcore/journal.h>
 #include <kdebug.h>
-#include <kabc/addressee.h>
 #include <qbuffer.h>
 #include <kolab/kolabformat.h>
 
@@ -196,20 +194,43 @@ KCalCore::Event::Ptr readV2EventXML(const QByteArray& xmlData, QStringList& atta
 }
 
 
+//@cond PRIVATE
+class KolabObjectReader::Private
+{
+public:
+    Private()
+    : mObjectType( InvalidObject ),
+    mVersion( KolabV3 )
+    {}
+    
+    KCalCore::Incidence::Ptr mIncidence;
+    KABC::Addressee mAddressee;
+    KABC::ContactGroup mContactGroup;
+    ObjectType mObjectType;
+    Version mVersion;
+};
+//@endcond
+
 KolabObjectReader::KolabObjectReader()
+: d( new KolabObjectReader::Private )
 {
     
 }
 
 KolabObjectReader::KolabObjectReader(const KMime::Message::Ptr& msg)
+: d( new KolabObjectReader::Private )
 {
     parseMimeMessage(msg);
 }
 
+KolabObjectReader::~KolabObjectReader()
+{
+    delete d;
+}
 
 ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
 {
-    mObjectType = InvalidObject;
+    d->mObjectType = InvalidObject;
     KMime::Headers::Base *xKolabHeader = msg->getHeaderByType("X-Kolab-Type");
     if (!xKolabHeader) {
         kWarning() << "could not find xKolabHeader";
@@ -226,74 +247,74 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
     QStringList attachments;
     KCalCore::Incidence::Ptr i;
     kDebug() << kolabType;
-    mVersion = KolabV2;
+    d->mVersion = KolabV2;
     if (kolabType == eventKolabType()) { //Event
         kDebug() << "event";
-        mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
-        mObjectType = EventObject;
+        d->mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+        d->mObjectType = EventObject;
     } else if (kolabType == todoKolabType()) { //Todo 
         kDebug() << "todo";
-        mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
-        mObjectType = TodoObject;
+        d->mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
+        d->mObjectType = TodoObject;
     } else if (kolabType == journalKolabType()) { //Journal
         kDebug() << "journal";
-        mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
-        mObjectType = JournalObject;
+        d->mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
+        d->mObjectType = JournalObject;
     } else if (kolabType == contactKolabType()) { //Contact
         kDebug() << "contact";
-        mAddressee = addresseFromKolab(xmlData, msg);
-        mObjectType = ContactObject;
+        d->mAddressee = addresseFromKolab(xmlData, msg);
+        d->mObjectType = ContactObject;
     }  else if (kolabType == distlistKolabType()) { //Distlist
         kDebug() << "distlist";
-        mContactGroup = contactGroupFromKolab(xmlData);
-        mObjectType = DistlistObject;
+        d->mContactGroup = contactGroupFromKolab(xmlData);
+        d->mObjectType = DistlistObject;
     } else {
         kWarning() << "no kolab object found " << kolabType;
     }
-    if (mIncidence) {
-        Mime::getAttachments(mIncidence, attachments, msg);
+    if (d->mIncidence) {
+        Mime::getAttachments(d->mIncidence, attachments, msg);
     }
-    return mObjectType;
+    return d->mObjectType;
 }
 
 Version KolabObjectReader::getVersion() const
 {
-    return mVersion;
+    return d->mVersion;
 }
 
 ObjectType KolabObjectReader::getType() const
 {
-    return mObjectType;
+    return d->mObjectType;
 }
 
 KCalCore::Event::Ptr KolabObjectReader::getEvent() const
 {
-    return mIncidence.dynamicCast<KCalCore::Event>();
+    return d->mIncidence.dynamicCast<KCalCore::Event>();
 }
 
 KCalCore::Todo::Ptr KolabObjectReader::getTodo() const
 {
-    return mIncidence.dynamicCast<KCalCore::Todo>();
+    return d->mIncidence.dynamicCast<KCalCore::Todo>();
 }
 
 KCalCore::Journal::Ptr KolabObjectReader::getJournal() const
 {
-    return mIncidence.dynamicCast<KCalCore::Journal>();
+    return d->mIncidence.dynamicCast<KCalCore::Journal>();
 }
 
 KCalCore::Incidence::Ptr KolabObjectReader::getIncidence() const
 {
-    return mIncidence;
+    return d->mIncidence;
 }
 
 KABC::Addressee KolabObjectReader::getContact() const
 {
-    return mAddressee;
+    return d->mAddressee;
 }
 
 KABC::ContactGroup KolabObjectReader::getDistlist() const
 {
-    return mContactGroup;
+    return d->mContactGroup;
 }
 
 
diff --git a/libkolab/kolabformat/kolabobject.h b/libkolab/kolabformat/kolabobject.h
index 672c72c..a20ce99 100644
--- a/libkolab/kolabformat/kolabobject.h
+++ b/libkolab/kolabformat/kolabobject.h
@@ -20,17 +20,13 @@
 
 #include "kolab_export.h"
 
+#include <kabc/addressee.h>
+#include <kabc/contactgroup.h>
 #include <kcalcore/incidence.h>
 #include <kcalcore/event.h>
 #include <kcalcore/journal.h>
 #include <kcalcore/todo.h>
 #include <kmime/kmime_message.h>
-#include <kabc/addressee.h>
-#include <kabc/contactgroup.h>
-
-namespace KABC {
-class Addressee;
-}
 
 namespace Kolab {
 
@@ -60,7 +56,9 @@ KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStr
 class KOLAB_EXPORT KolabObjectReader {
 public:
     KolabObjectReader();
-    KolabObjectReader(const KMime::Message::Ptr &msg);
+    explicit KolabObjectReader(const KMime::Message::Ptr &msg);
+    ~KolabObjectReader();
+    
     ObjectType parseMimeMessage(const KMime::Message::Ptr &msg);
     
     ObjectType getType() const;
@@ -73,11 +71,10 @@ public:
     KABC::Addressee getContact() const;
     KABC::ContactGroup getDistlist() const;
 private:
-    KCalCore::Incidence::Ptr mIncidence;
-    KABC::Addressee mAddressee;
-    KABC::ContactGroup mContactGroup;
-    ObjectType mObjectType;
-    Version mVersion;
+    //@cond PRIVATE
+    class Private;
+    Private *const d;
+    //@endcond
 };
 
 class KOLAB_EXPORT KolabObjectWriter {
diff --git a/upgradetool/CMakeLists.txt b/upgradetool/CMakeLists.txt
index b0ab376..3ba6cb0 100644
--- a/upgradetool/CMakeLists.txt
+++ b/upgradetool/CMakeLists.txt
@@ -5,37 +5,15 @@ cmake_minimum_required(VERSION 2.6)
 find_package(Qt4 REQUIRED)
 find_package(KDE4 REQUIRED)
 
-find_library(KOLABXML NAMES kolabxml)
-# find_library(KOLABFORMATV2 NAMES kolabformatV2)
-# find_library(KOLABKCAL NAMES kolabkcal)
-find_library(KOLAB NAMES kolab)
-
-find_library(KCALCORE NAMES kcalcore)
-if(KCALCORE)
-    set(KCALCORE_FOUND ON)
-    message("KCalCore found")
-endif(KCALCORE)
-
-include_directories(/opt/devel/global/include ${QT_INCLUDES} /usr/local/include/kolab .)
-link_directories(/opt/devel/global/lib)
-
-find_library(KMIME_LIBS NAMES kmime)
-if(KMIME_LIBS)
-    set(KMIME_LIBS_FOUND ON)
-    message("KMime found")
-endif(KMIME_LIBS)
-
-# find_library(KOLABFORMATV2 NAMES kolabformat_v2 PATHS /opt/devel/global/lib)
-# if(KOLABFORMATV2)
-#     set(KOLABFORMATV2_FOUND ON)
-#     message("KOLABFORMATV2 found")
-# endif(KOLABFORMATV2)
-# set(KOLABFORMATV2 /opt/devel/global/lib/libkolabformat_v2.so)
-
-message(${KOLAB})
-
-set(COMMON_DEPENDENCIES  ${KOLAB} ${KOLABXML} ${KCALCORE} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY})
-message(${COMMON_DEPENDENCIES})
+find_library(KOLABXML_LIBRARY NAMES kolabxml)
+find_library(KOLAB_LIBRARY NAMES kolab)
+
+include (../cmake/modules/FindKolabInternal.cmake)
+include (../cmake/modules/FindKDELibraries.cmake)
+
+include_directories(${QT_INCLUDES} ./)
+
+set(COMMON_DEPENDENCIES  ${KOLAB_LIBRARY} ${KOLABXML_LIBRARY} ${KCALCORE_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBRARY} ${QT_GUI_LIBRARY} ${KABC_LIBRARY})
 add_executable(upgradetool upgradetool.cpp upgradeutilities.cpp)
 target_link_libraries(upgradetool ${COMMON_DEPENDENCIES})
 
diff --git a/upgradetool/upgradetooltests.cpp b/upgradetool/upgradetooltests.cpp
index 4782795..e1cba10 100644
--- a/upgradetool/upgradetooltests.cpp
+++ b/upgradetool/upgradetooltests.cpp
@@ -1,6 +1,6 @@
 #include "upgradetooltests.h"
 #include "upgradeutilities.h"
-#include <kolabformat.h>
+#include <kolab/kolabformat.h>
 #include <kdebug.h>
 
 void UpgradeToolTests::testConvertEvent()
diff --git a/upgradetool/upgradeutilities.cpp b/upgradetool/upgradeutilities.cpp
index e6e2ec3..8a22676 100644
--- a/upgradetool/upgradeutilities.cpp
+++ b/upgradetool/upgradeutilities.cpp
@@ -21,8 +21,8 @@
 #include <kolab/kcalconversion.h>
 #include <kdebug.h>
 
-#include <kolabevent.h>
-#include <kolabformat.h>
+#include <kolab/kolabevent.h>
+#include <kolab/kolabformat.h>
 
 namespace Kolab {
     namespace Upgrade {


commit f81bec24cf872f2435af79b83570367f2ade41c7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 12:41:26 2012 +0100

    Fix the header install directory

diff --git a/cmake/modules/FindKolabInternal.cmake b/cmake/modules/FindKolabInternal.cmake
index 1ccf0d5..9e817eb 100644
--- a/cmake/modules/FindKolabInternal.cmake
+++ b/cmake/modules/FindKolabInternal.cmake
@@ -6,6 +6,7 @@
 # The Result of this can be overridden by setting KOLAB_LIB_INSTALL_DIR "cmake -DKOLAB_LIB_INSTALL_DIR=/usr/lib64/ ."
 #
 # The runtime install is controlled by KOLAB_BIN_INSTALL_DIR
+# The header install is controlled by KOLAB_HEADER_INSTALL_DIR
 #
 # KOLAB_INSTALL_DIRECTORIES contains the determined install directories and should be used with install commands
 
@@ -41,4 +42,10 @@ set(KOLAB_INSTALL_DIRECTORIES  RUNTIME DESTINATION "${KOLAB_BIN_INSTALL_DIR}"
                                   LIBRARY DESTINATION "${KOLAB_LIB_INSTALL_DIR}"
                                   ARCHIVE DESTINATION "${KOLAB_LIB_INSTALL_DIR}" COMPONENT Devel )
 
-set(KOLAB_HEADER_INSTALL_DIR  "${INCLUDE_INSTALL_DIR}/kolab")
+
+if(KOLAB_HEADER_INSTALL_DIR)
+    message("KOLAB_HEADER_INSTALL_DIR specified manually")
+else()
+    set(KOLAB_HEADER_INSTALL_DIR  "${CMAKE_INSTALL_PREFIX}/include")
+endif()
+message("KOLAB_HEADER_INSTALL_DIR: ${KOLAB_HEADER_INSTALL_DIR}")


commit 6972232592b43631fa0c76d78dc5ac5af3641184
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 12:15:05 2012 +0100

    Install libraries to the correct (64bit) directory. Make it possible to override the determined path.

diff --git a/.gitignore b/.gitignore
index 99bb8e6..2325ff8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,6 @@ CMakeFiles
 CMakeCache.txt
 moc_*
 *.moc
-*.cmake
 *.pyc
 .*.swp
 configure
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 0fb586e..c76f992 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -13,6 +13,8 @@ if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND
     cmake_policy(SET CMP0017 NEW)
 endif()
 
+include( ../cmake/modules/FindKolabInternal.cmake )
+
 find_package(Boost COMPONENTS thread REQUIRED)
 
 if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 7b7e163..90f31f0 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -11,7 +11,8 @@ target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID})
 #For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
 set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wl,--no-undefined")
 set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
-install(TARGETS kolabxml LIBRARY DESTINATION lib)
+
+install(TARGETS kolabxml ${KOLAB_INSTALL_DIRECTORIES})
 
 install( FILES
     kolabformat.h
@@ -22,7 +23,7 @@ install( FILES
     kolabnote.h
     kolabcontainers.h
     global_definitions.h
-    DESTINATION include/kolab COMPONENT Devel)
+    DESTINATION ${KOLAB_HEADER_INSTALL_DIR} COMPONENT Devel)
 
 #----- The following makes sure libkolabxml is found in the install directory for installed files and not in the build directory (for libraries which link to libkolabxml)
 
@@ -30,14 +31,14 @@ install( FILES
 SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
 # when building, don't use the install RPATH already(but later on when installing)
 SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
-SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
 # add the automatically determined parts of the RPATH
 # which point to directories outside the build tree to the install RPATH
 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
 # the RPATH to be used when installing, but only if it's not a system directory
-LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
+LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${KOLAB_LIB_INSTALL_DIR}" isSystemDir)
 IF("${isSystemDir}" STREQUAL "-1")
-   SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+   SET(CMAKE_INSTALL_RPATH "${KOLAB_LIB_INSTALL_DIR}")
 ENDIF("${isSystemDir}" STREQUAL "-1")
 
 #-----------------------SWIG--------------------
diff --git a/cmake/modules/FindKolabInternal.cmake b/cmake/modules/FindKolabInternal.cmake
new file mode 100644
index 0000000..1ccf0d5
--- /dev/null
+++ b/cmake/modules/FindKolabInternal.cmake
@@ -0,0 +1,44 @@
+
+# The install directory is defined by the CMAKE_INSTALL_PREFIX which defaults to /usr/local if not specified.
+# To install i.e. to /usr use "cmake -DCMAKE_INSTALL_PREFIX=/usr ."
+#
+# The library directory suffix (64/32) is detected automatically based on the available directories in CMAKE_INSTALL_PREFIX
+# The Result of this can be overridden by setting KOLAB_LIB_INSTALL_DIR "cmake -DKOLAB_LIB_INSTALL_DIR=/usr/lib64/ ."
+#
+# The runtime install is controlled by KOLAB_BIN_INSTALL_DIR
+#
+# KOLAB_INSTALL_DIRECTORIES contains the determined install directories and should be used with install commands
+
+get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+
+if (${LIB64} STREQUAL "TRUE")
+    find_path(LIB32FOUND "${CMAKE_INSTALL_PREFIX}/lib32")
+    find_path(LIB64FOUND "${CMAKE_INSTALL_PREFIX}/lib64")
+    if (LIB64FOUND)
+        set(LIBSUFFIX 64)
+    else()
+        set(LIBSUFFIX "")
+    endif()
+else()
+    set(LIBSUFFIX "")
+endif()
+
+if(KOLAB_LIB_INSTALL_DIR)
+    message("KOLAB_LIB_INSTALL_DIR specified manually")
+else()
+    set(KOLAB_LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIBSUFFIX}")
+endif()
+message("KOLAB_LIB_INSTALL_DIR: ${KOLAB_LIB_INSTALL_DIR}")
+
+if(KOLAB_BIN_INSTALL_DIR)
+    message("KOLAB_BIN_INSTALL_DIR specified manually")
+else()
+    set(KOLAB_BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
+endif()
+message("KOLAB_BIN_INSTALL_DIR: ${KOLAB_BIN_INSTALL_DIR}")
+
+set(KOLAB_INSTALL_DIRECTORIES  RUNTIME DESTINATION "${KOLAB_BIN_INSTALL_DIR}"
+                                  LIBRARY DESTINATION "${KOLAB_LIB_INSTALL_DIR}"
+                                  ARCHIVE DESTINATION "${KOLAB_LIB_INSTALL_DIR}" COMPONENT Devel )
+
+set(KOLAB_HEADER_INSTALL_DIR  "${INCLUDE_INSTALL_DIR}/kolab")
diff --git a/libkolab/CMakeLists.txt b/libkolab/CMakeLists.txt
index 9ab3b44..71d9e47 100644
--- a/libkolab/CMakeLists.txt
+++ b/libkolab/CMakeLists.txt
@@ -2,6 +2,8 @@ project(libkolab)
 
 cmake_minimum_required(VERSION 2.6)
 
+include( ../cmake/modules/FindKolabInternal.cmake )
+
 find_package(Qt4 REQUIRED)
 find_package(KDE4 REQUIRED)
 
@@ -29,17 +31,17 @@ add_subdirectory(kolabformatV2)
 
 add_library(kolab SHARED kolabformat/kolabobject.cpp mime/mimeutils.cpp conversion/kcalconversion.cpp)
 target_link_libraries(kolab kolabformatV2  ${KOLABXML} kcalcore kmime ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} kabc akonadi-kde ${KDE4_KIO_LIBRARY})
-set_target_properties(kolab PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
+set_target_properties(kolab PROPERTIES VERSION 0.1 SOVERSION 0)
 
-install(TARGETS kolab EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
+install(TARGETS kolab EXPORT libkolabLibraryTargets ${KOLAB_INSTALL_DIRECTORIES})
 
 install( FILES
     kolab_export.h
-    DESTINATION ${INCLUDE_INSTALL_DIR}/kolab COMPONENT Devel)
+    DESTINATION ${KOLAB_HEADER_INSTALL_DIR} COMPONENT Devel)
 
 install( FILES
     kolabformat/kolabobject.h
     conversion/kcalconversion.h
-    DESTINATION ${INCLUDE_INSTALL_DIR}/kolab COMPONENT Devel)
+    DESTINATION ${KOLAB_HEADER_INSTALL_DIR} COMPONENT Devel)
 
 add_subdirectory(tests)
diff --git a/libkolab/akonadi-version.h.cmake b/libkolab/akonadi-version.h.cmake
new file mode 100644
index 0000000..58c028e
--- /dev/null
+++ b/libkolab/akonadi-version.h.cmake
@@ -0,0 +1,25 @@
+/*
+    This file is part of kdepim.
+    Copyright (C) 2009 Christophe Giboudeaux  <cgiboudeaux at gmail.com>
+
+    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef AKONADI_VERSION_H
+#define AKONADI_VERSION_H
+
+#define AKONADI_VERSION "@AKONADI_VERSION@"
+
+#endif // AKONADI_VERSION_H
\ No newline at end of file


commit 764463401c1d7628be7516bc2d36ee90d0545c8a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 11:09:36 2012 +0100

    Use libuuid as fallback for old boost versions.

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index f9daf30..0fb586e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -15,6 +15,15 @@ endif()
 
 find_package(Boost COMPONENTS thread REQUIRED)
 
+if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
+    find_library(UUID NAMES uuid)
+    if(UUID)
+        message("uuid found")
+    else (UUID)
+        message(FATAL_ERROR "uuid NOT found!")
+    endif(UUID)
+endif()
+
 find_package(Qt4)
 find_program( XSDCXX xsdcxx /usr/bin/)
 if(XSDCXX)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 5fa9455..7b7e163 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -6,7 +6,7 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wp,-D_FORTIFY_SOURCE=2 -O2" ) #a
 #Library with serialization/deserialization code and kolab-containers
 add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabnote.cpp kolabevent.cpp kolabtodo.cpp kolabjournal.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 
-target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES})
+target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID})
 
 #For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
 set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wl,--no-undefined")
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index f49b37b..8096f54 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -17,8 +17,16 @@
 
 #include "utils.h"
 #include <string>
+
+#include <boost/version.hpp>
+
+#if BOOST_VERSION >= 104200
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_io.hpp>
+#else
+#include <uuid/uuid.h>
+#endif
+
 #include <boost/lexical_cast.hpp>
 #include <boost/thread.hpp>
 #include <time.h>
@@ -93,8 +101,16 @@ std::string createdUid()
 std::string getUID(const std::string &s)
 {
     if (s.empty()) {
+#if BOOST_VERSION >= 104200
         boost::uuids::uuid u; // initialize uuid
         return boost::uuids::to_string(u);
+#else
+        uuid_t u;
+        uuid_generate(u);
+        char out[37];
+        uuid_unparse(u,out);
+        return std::string(out, 36); //We don't need the terminating \0
+#endif
     }
     return s;
 }
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
index 0ab7047..0bed229 100644
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@ -258,6 +258,13 @@ void ConversionTest::threadLocalTest()
     t2.join();
 }
 
+void ConversionTest::uuidGeneratorTest()
+{
+    const std::string &s = getUID();
+    std::cout << s << std::endl;
+    QVERIFY(!s.empty());
+    QCOMPARE(s.size(), (std::size_t)36ul);
+}
 
 
 
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
index 516470c..b586ed6 100644
--- a/c++/tests/conversiontest.h
+++ b/c++/tests/conversiontest.h
@@ -40,6 +40,8 @@ class ConversionTest : public QObject
     void geoUriTest();
     
     void threadLocalTest();
+    
+    void uuidGeneratorTest();
 };
 
 #endif // CONVERSIONTEST_H


commit 685a2b559f149db4aefe027f58c0124a7585f988
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Mar 23 10:26:40 2012 +0100

    Don't use the namespace of a specific xerces version.

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 169599a..dffff8d 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -226,7 +226,7 @@ void XMLParserWrapper::init()
     
 }
 
-xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
+xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
 {
     try {
         std::ifstream ifs;
@@ -237,10 +237,10 @@ xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parse
     {
         std::cerr << ": unable to open or read failure" << std::endl;
     }
-    return xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument >();
+    return xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument >();
 }
 
-xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
+xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
 {
     std::istringstream is(s);
     return parse(is, ""); //TODO set identifier?
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index c762044..4871acd 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -104,12 +104,12 @@ boost::shared_ptr<Kolab::Note> deserializeObject(const std::string& s, bool isUr
     try {
         std::auto_ptr<KolabXSD::Note> note;
         if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
             if (doc.get()) {
                 note = KolabXSD::note(doc);
             }
         } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
             if (doc.get()) {
                 note = KolabXSD::note(doc);
             }
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 526af01..601acea 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -1644,12 +1644,12 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
     try {
         std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
         if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
             if (doc.get()) {
                 icalendar = icalendar_2_0::icalendar(doc);
             }
         } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
             if (doc.get()) {
                 icalendar = icalendar_2_0::icalendar(doc);
             }
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index 310d444..0be6f0a 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -1043,12 +1043,12 @@ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
     try {
         std::auto_ptr<vcard_4_0::VcardsType> vcards;
         if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
             if (doc.get()) {
                 vcards = vcard_4_0::vcards(doc);
             }
         } else {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
             if (doc.get()) {
                 vcards = vcard_4_0::vcards(doc);
             }


commit aa9dcc565fe64f265a1017c3fc7d81fb35f31076
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Mar 21 23:31:48 2012 +0100

    V2 implementation for contacts and distlists.

diff --git a/libkolab/kolabformat/kolabobject.cpp b/libkolab/kolabformat/kolabobject.cpp
index 0a5059d..0a0cbc2 100644
--- a/libkolab/kolabformat/kolabobject.cpp
+++ b/libkolab/kolabformat/kolabobject.cpp
@@ -21,11 +21,15 @@
 #include <kolabformatV2/journal.h>
 #include <kolabformatV2/task.h>
 #include <kolabformatV2/event.h>
+#include <kolabformatV2/contact.h>
+#include <kolabformatV2/distributionlist.h>
 #include <mime/mimeutils.h>
 #include <conversion/kcalconversion.h>
 #include <qdom.h>
 #include <kcalcore/journal.h>
 #include <kdebug.h>
+#include <kabc/addressee.h>
+#include <qbuffer.h>
 #include <kolab/kolabformat.h>
 
 
@@ -34,6 +38,8 @@ namespace Kolab {
 static QString eventKolabType() { return QString::fromLatin1("application/x-vnd.kolab.event"); };
 static QString todoKolabType() { return QString::fromLatin1("application/x-vnd.kolab.task"); };
 static QString journalKolabType() { return QString::fromLatin1("application/x-vnd.kolab.journal"); };
+static QString contactKolabType() { return QString::fromLatin1("application/x-vnd.kolab.contact"); };
+static QString distlistKolabType() { return QString::fromLatin1("application/x-vnd.kolab.contact.distlist"); }
 static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
 
 /*
@@ -72,6 +78,105 @@ static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &da
     return ptr;
 }
 
+
+KABC::Addressee addresseFromKolab( const QByteArray &xmlData, const KMime::Message::Ptr &data)
+{
+    KABC::Addressee addressee;
+//     kDebug() << "xmlData " << xmlData;
+    KolabV2::Contact contact(QString::fromUtf8(xmlData));
+    const QString pictureAttachmentName = contact.pictureAttachmentName();
+    if (!pictureAttachmentName.isEmpty()) {
+      QByteArray type;
+      KMime::Content *imgContent = Mime::findContentByName(data, "kolab-picture.png", type);
+      if (imgContent) {
+        QByteArray imgData = imgContent->decodedContent();
+        QBuffer buffer(&imgData);
+        buffer.open(QIODevice::ReadOnly);
+        QImage image;
+        image.load(&buffer, "PNG");
+        contact.setPicture(image);
+      }
+    }
+
+    QString logoAttachmentName = contact.logoAttachmentName();
+    if (!logoAttachmentName.isEmpty()) {
+      QByteArray type;
+      KMime::Content *imgContent = Mime::findContentByName(data, "kolab-logo.png", type);
+      if (imgContent) {
+        QByteArray imgData = imgContent->decodedContent();
+        QBuffer buffer(&imgData);
+        buffer.open(QIODevice::ReadOnly);
+        QImage image;
+        image.load(&buffer, "PNG");
+        contact.setLogo(image);
+      }
+    }
+
+    QString soundAttachmentName = contact.soundAttachmentName();
+    if (!soundAttachmentName.isEmpty()) {
+      QByteArray type;
+      KMime::Content *content = Mime::findContentByName(data, "sound", type);
+      if (content) {
+        QByteArray sData = content->decodedContent();
+        contact.setSound(sData);
+      }
+    }
+    contact.saveTo(&addressee);
+    return addressee;
+}
+
+KABC::ContactGroup contactGroupFromKolab(const QByteArray &xmlData)
+{
+    KABC::ContactGroup contactGroup;
+    //     kDebug() << "xmlData " << xmlData;
+    KolabV2::DistributionList distList(QString::fromUtf8(xmlData));
+    distList.saveTo(&contactGroup);
+    return contactGroup;
+}
+
+
+KMime::Message::Ptr contactToKolabFormat(const KolabV2::Contact& contact)
+{
+    KMime::Message::Ptr message = Mime::createMessage( contactKolabType() ); //TODO v3 mimetype
+    message->subject()->fromUnicodeString( contact.uid(), "utf-8" );
+    message->from()->fromUnicodeString( contact.fullEmail(), "utf-8" );
+    
+    KMime::Content* content = Mime::createMainPart( contactKolabType(), contact.saveXML().toUtf8() ); //TODO v3 mimetype
+    message->addContent( content );
+    
+    if ( !contact.picture().isNull() ) {
+        QByteArray pic;
+        QBuffer buffer(&pic);
+        buffer.open(QIODevice::WriteOnly);
+        contact.picture().save(&buffer, "PNG");
+        buffer.close();
+        
+        content = Mime::createAttachmentPart(QByteArray(), "image/png", "kolab-picture.png", pic );
+        message->addContent(content);
+    }
+    
+    if ( !contact.logo().isNull() ) {
+        QByteArray pic;
+        QBuffer buffer(&pic);
+        buffer.open(QIODevice::WriteOnly);
+        contact.logo().save(&buffer, "PNG");
+        buffer.close();
+        
+        content = Mime::createAttachmentPart(QByteArray(), "image/png", "kolab-logo.png", pic );
+        message->addContent(content);
+    }
+    
+    
+    if ( !contact.sound().isEmpty() ) {
+        content = Mime::createAttachmentPart(QByteArray(), "audio/unknown", "sound", contact.sound() );
+        message->addContent(content);
+    }
+    
+    message->assemble();
+    return message;
+}
+
+
 //Normalize incidences before serializing them
 void normalizeIncidence(KCalCore::Incidence::Ptr i)
 {
@@ -117,7 +222,7 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
         qWarning() << "no part found";
         return InvalidObject;
     }
-    const QByteArray xmlData = xmlContent->decodedContent();
+    const QByteArray &xmlData = xmlContent->decodedContent();
     QStringList attachments;
     KCalCore::Incidence::Ptr i;
     kDebug() << kolabType;
@@ -125,18 +230,23 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
     if (kolabType == eventKolabType()) { //Event
         kDebug() << "event";
         mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
-        Q_ASSERT(mIncidence);
         mObjectType = EventObject;
     } else if (kolabType == todoKolabType()) { //Todo 
         kDebug() << "todo";
         mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
-        Q_ASSERT(mIncidence);
         mObjectType = TodoObject;
     } else if (kolabType == journalKolabType()) { //Journal
         kDebug() << "journal";
         mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
-        Q_ASSERT(mIncidence);
         mObjectType = JournalObject;
+    } else if (kolabType == contactKolabType()) { //Contact
+        kDebug() << "contact";
+        mAddressee = addresseFromKolab(xmlData, msg);
+        mObjectType = ContactObject;
+    }  else if (kolabType == distlistKolabType()) { //Distlist
+        kDebug() << "distlist";
+        mContactGroup = contactGroupFromKolab(xmlData);
+        mObjectType = DistlistObject;
     } else {
         kWarning() << "no kolab object found " << kolabType;
     }
@@ -176,6 +286,16 @@ KCalCore::Incidence::Ptr KolabObjectReader::getIncidence() const
     return mIncidence;
 }
 
+KABC::Addressee KolabObjectReader::getContact() const
+{
+    return mAddressee;
+}
+
+KABC::ContactGroup KolabObjectReader::getDistlist() const
+{
+    return mContactGroup;
+}
+
 
 
 KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v, const QString &tz)
@@ -214,6 +334,37 @@ KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr
     return Mime::createMessage(i, xCalMimeType(), journalKolabType(), xml.toLocal8Bit());
 }
 
+KMime::Message::Ptr KolabObjectWriter::writeContact(const KABC::Addressee &addressee, Version v)
+{
+    if (v == KolabV3) {
+        //TODO
+    }
+    KolabV2::Contact contact(&addressee);
+    return contactToKolabFormat(contact);
+}
+
+KMime::Message::Ptr distListToKolabFormat(const KolabV2::DistributionList& distList)
+{    
+    KMime::Message::Ptr message = Mime::createMessage( distlistKolabType() );
+    message->subject()->fromUnicodeString( distList.uid(), "utf-8" );
+    message->from()->fromUnicodeString( distList.uid(), "utf-8" );
+    
+    KMime::Content* content = Mime::createMainPart( distlistKolabType(), distList.saveXML().toUtf8() );
+    message->addContent( content );
+    
+    message->assemble();
+    return message;
+}
+
+KMime::Message::Ptr KolabObjectWriter::writeDistlist(const KABC::ContactGroup &distlist, Version v)
+{
+    if (v == KolabV3) {
+        //TODO
+    }
+    KolabV2::DistributionList d(&distlist);
+    return distListToKolabFormat(d);
+}
+
 
 }; //Namespace
 
diff --git a/libkolab/kolabformat/kolabobject.h b/libkolab/kolabformat/kolabobject.h
index a6f2dbd..672c72c 100644
--- a/libkolab/kolabformat/kolabobject.h
+++ b/libkolab/kolabformat/kolabobject.h
@@ -25,6 +25,12 @@
 #include <kcalcore/journal.h>
 #include <kcalcore/todo.h>
 #include <kmime/kmime_message.h>
+#include <kabc/addressee.h>
+#include <kabc/contactgroup.h>
+
+namespace KABC {
+class Addressee;
+}
 
 namespace Kolab {
 
@@ -38,6 +44,8 @@ enum ObjectType {
     EventObject,
     TodoObject,
     JournalObject,
+    ContactObject,
+    DistlistObject
 };
 
 
@@ -62,8 +70,12 @@ public:
     KCalCore::Todo::Ptr getTodo() const;
     KCalCore::Journal::Ptr getJournal() const;
     KCalCore::Incidence::Ptr getIncidence() const;
+    KABC::Addressee getContact() const;
+    KABC::ContactGroup getDistlist() const;
 private:
     KCalCore::Incidence::Ptr mIncidence;
+    KABC::Addressee mAddressee;
+    KABC::ContactGroup mContactGroup;
     ObjectType mObjectType;
     Version mVersion;
 };
@@ -73,6 +85,8 @@ public:
     static KMime::Message::Ptr writeEvent(const KCalCore::Event::Ptr &, Version v = KolabV3, const QString &tz = QString());
     static KMime::Message::Ptr writeTodo(const KCalCore::Todo::Ptr &, Version v = KolabV3, const QString &tz = QString());
     static KMime::Message::Ptr writeJournal(const KCalCore::Journal::Ptr &, Version v = KolabV3, const QString &tz = QString());
+    static KMime::Message::Ptr writeContact(const KABC::Addressee &, Version v = KolabV3);
+    static KMime::Message::Ptr writeDistlist(const KABC::ContactGroup &, Version v = KolabV3);
 };
 
 }; //Namespace


commit aa93ab267df1f414d834c189431efef6c6c8805f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Mar 21 19:24:54 2012 +0100

    Incidence code works for kolabresource v2 and for upgrade code.

diff --git a/libkolab/kolabformat/kolabobject.cpp b/libkolab/kolabformat/kolabobject.cpp
index 77c77fa..0a5059d 100644
--- a/libkolab/kolabformat/kolabobject.cpp
+++ b/libkolab/kolabformat/kolabobject.cpp
@@ -63,34 +63,22 @@ static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &da
         qWarning() << "couldn't find part";
         return IncidencePtr();
     }
-    const QByteArray xmlData = xmlContent->decodedContent();
+    const QByteArray &xmlData = xmlContent->decodedContent();
     
     QStringList attachments;
     IncidencePtr ptr = fromXML<IncidencePtr, Converter>(xmlData, attachments); //TODO do we care about timezone?
     Mime::getAttachments(ptr, attachments, data);
     
     return ptr;
-    //             KMime::Content *xmlContent = findContentByType( data, mimetype );
-    //             if ( xmlContent ) {
-        //                 const QByteArray xmlData = xmlContent->decodedContent();
-    // //                 qDebug() << xmlData;
-    //                 const QDomDocument xmlDoc = Converter::loadDocument( QString::fromUtf8(xmlData) );
-    //                 if ( !xmlDoc.isNull() ) {
-        //                     IncidencePtr i = Converter::fromXml( xmlDoc, timezoneId );
-    //                     attachmentsFromKolab( data, xmlDoc, i );
-    //                     return i;
-    //                 }
-    //             }
-    // //             qDebug() << "empty";
-    //             return IncidencePtr();
 }
 
+//Normalize incidences before serializing them
 void normalizeIncidence(KCalCore::Incidence::Ptr i)
 {
     Q_FOREACH (KCalCore::Attendee::Ptr a, i->attendees()) {
         a->setUid(QString()); //KCalCore sets the pointer as uid, we don't want that (if we wanted one, we'd want a real, globally unique one), so we clear the uid
     }
-    
+    //TODO Do we really not need the attachment uri for something else?
     Q_FOREACH (KCalCore::Attachment::Ptr attachment, i->attachments()) {
         attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
     }
@@ -108,6 +96,12 @@ KolabObjectReader::KolabObjectReader()
     
 }
 
+KolabObjectReader::KolabObjectReader(const KMime::Message::Ptr& msg)
+{
+    parseMimeMessage(msg);
+}
+
+
 ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
 {
     mObjectType = InvalidObject;
@@ -132,26 +126,23 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
         kDebug() << "event";
         mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
         Q_ASSERT(mIncidence);
-        Mime::getAttachments(mIncidence, attachments, msg);
-        normalizeIncidence(mIncidence);
         mObjectType = EventObject;
     } else if (kolabType == todoKolabType()) { //Todo 
         kDebug() << "todo";
         mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
         Q_ASSERT(mIncidence);
-        Mime::getAttachments(mIncidence, attachments, msg);
-        normalizeIncidence(mIncidence);
         mObjectType = TodoObject;
     } else if (kolabType == journalKolabType()) { //Journal
         kDebug() << "journal";
         mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
         Q_ASSERT(mIncidence);
-        Mime::getAttachments(mIncidence, attachments, msg);
-        normalizeIncidence(mIncidence);
         mObjectType = JournalObject;
     } else {
         kWarning() << "no kolab object found " << kolabType;
     }
+    if (mIncidence) {
+        Mime::getAttachments(mIncidence, attachments, msg);
+    }
     return mObjectType;
 }
 
@@ -167,43 +158,60 @@ ObjectType KolabObjectReader::getType() const
 
 KCalCore::Event::Ptr KolabObjectReader::getEvent() const
 {
-    return qSharedPointerDynamicCast<KCalCore::Event>(mIncidence);
+    return mIncidence.dynamicCast<KCalCore::Event>();
 }
 
 KCalCore::Todo::Ptr KolabObjectReader::getTodo() const
 {
-    return qSharedPointerDynamicCast<KCalCore::Todo>(mIncidence);
+    return mIncidence.dynamicCast<KCalCore::Todo>();
 }
 
 KCalCore::Journal::Ptr KolabObjectReader::getJournal() const
 {
-    return qSharedPointerDynamicCast<KCalCore::Journal>(mIncidence);
+    return mIncidence.dynamicCast<KCalCore::Journal>();
+}
+
+KCalCore::Incidence::Ptr KolabObjectReader::getIncidence() const
+{
+    return mIncidence;
 }
 
 
 
-KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v)
+KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v, const QString &tz)
 {
-    const Kolab::Event &incidence = Kolab::Conversion::fromKCalCore(*i);
-    const std::string &v3String = Kolab::writeEvent(incidence);
-    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), eventKolabType(), QString::fromStdString(v3String).toLocal8Bit());
-    return message;
+    if (v == KolabV3) {
+        normalizeIncidence(i);
+        const Kolab::Event &incidence = Kolab::Conversion::fromKCalCore(*i);
+        const std::string &v3String = Kolab::writeEvent(incidence);
+        return Mime::createMessage(i, xCalMimeType(), eventKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    }
+    const QString &xml = KolabV2::Event::eventToXML(i, tz);
+    return Mime::createMessage(i, xCalMimeType(), eventKolabType(), xml.toLocal8Bit());
 }
 
-KMime::Message::Ptr KolabObjectWriter::writeTodo(const KCalCore::Todo::Ptr &i, Version v)
+KMime::Message::Ptr KolabObjectWriter::writeTodo(const KCalCore::Todo::Ptr &i, Version v, const QString &tz)
 {
-    const Kolab::Todo &incidence = Kolab::Conversion::fromKCalCore(*i);
-    const std::string &v3String = Kolab::writeTodo(incidence);
-    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), todoKolabType(), QString::fromStdString(v3String).toLocal8Bit());
-    return message;
+    if (v == KolabV3) {
+        normalizeIncidence(i);
+        const Kolab::Todo &incidence = Kolab::Conversion::fromKCalCore(*i);
+        const std::string &v3String = Kolab::writeTodo(incidence);
+        return Mime::createMessage(i, xCalMimeType(), todoKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    }
+    const QString &xml = KolabV2::Task::taskToXML(i, tz);
+    return Mime::createMessage(i, xCalMimeType(), todoKolabType(), xml.toLocal8Bit());
 }
 
-KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr &i, Version v)
+KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr &i, Version v, const QString &tz)
 {
-    const Kolab::Journal &incidence = Kolab::Conversion::fromKCalCore(*i);
-    const std::string &v3String = Kolab::writeJournal(incidence);
-    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), journalKolabType(), QString::fromStdString(v3String).toLocal8Bit());
-    return message;
+    if (v == KolabV3) {
+        normalizeIncidence(i);
+        const Kolab::Journal &incidence = Kolab::Conversion::fromKCalCore(*i);
+        const std::string &v3String = Kolab::writeJournal(incidence);
+        return  Mime::createMessage(i, xCalMimeType(), journalKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    }
+    const QString &xml = KolabV2::Journal::journalToXML(i, tz);
+    return Mime::createMessage(i, xCalMimeType(), journalKolabType(), xml.toLocal8Bit());
 }
 
 
diff --git a/libkolab/kolabformat/kolabobject.h b/libkolab/kolabformat/kolabobject.h
index 7be2326..a6f2dbd 100644
--- a/libkolab/kolabformat/kolabobject.h
+++ b/libkolab/kolabformat/kolabobject.h
@@ -41,8 +41,6 @@ enum ObjectType {
 };
 
 
-
-
 KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStringList &attachments);
 
 /**
@@ -54,6 +52,7 @@ KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStr
 class KOLAB_EXPORT KolabObjectReader {
 public:
     KolabObjectReader();
+    KolabObjectReader(const KMime::Message::Ptr &msg);
     ObjectType parseMimeMessage(const KMime::Message::Ptr &msg);
     
     ObjectType getType() const;
@@ -62,6 +61,7 @@ public:
     KCalCore::Event::Ptr getEvent() const;
     KCalCore::Todo::Ptr getTodo() const;
     KCalCore::Journal::Ptr getJournal() const;
+    KCalCore::Incidence::Ptr getIncidence() const;
 private:
     KCalCore::Incidence::Ptr mIncidence;
     ObjectType mObjectType;
@@ -70,9 +70,9 @@ private:
 
 class KOLAB_EXPORT KolabObjectWriter {
 public:
-    static KMime::Message::Ptr writeEvent(const KCalCore::Event::Ptr &, Version v = KolabV3);
-    static KMime::Message::Ptr writeTodo(const KCalCore::Todo::Ptr &, Version v = KolabV3);
-    static KMime::Message::Ptr writeJournal(const KCalCore::Journal::Ptr &, Version v = KolabV3);
+    static KMime::Message::Ptr writeEvent(const KCalCore::Event::Ptr &, Version v = KolabV3, const QString &tz = QString());
+    static KMime::Message::Ptr writeTodo(const KCalCore::Todo::Ptr &, Version v = KolabV3, const QString &tz = QString());
+    static KMime::Message::Ptr writeJournal(const KCalCore::Journal::Ptr &, Version v = KolabV3, const QString &tz = QString());
 };
 
 }; //Namespace
diff --git a/libkolab/mime/mimeutils.cpp b/libkolab/mime/mimeutils.cpp
index e9587fd..1e58df6 100644
--- a/libkolab/mime/mimeutils.cpp
+++ b/libkolab/mime/mimeutils.cpp
@@ -63,13 +63,11 @@ KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString
         }
     }
     return 0;
-    
 }
 
 
-//TODO repalce
-void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
-                                            const KCalCore::Incidence::Ptr &incidence)
+//TODO replace with getAttachments
+void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc, const KCalCore::Incidence::Ptr &incidence)
 {
     QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
     for (int i = 0; i < nodes.size(); i++ ) {
@@ -77,12 +75,12 @@ void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &x
         QByteArray type;
         KMime::Content *content = findContentByName(data, name, type);
         if (!content) // guard against malformed events with non-existent attachments
-    continue;
-    const QByteArray c = content->decodedContent().toBase64();
-    KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
-    attachment->setLabel( name );
-    incidence->addAttachment(attachment);
-    kDebug() << "ATTACHEMENT NAME" << name << type;
+            continue;
+        const QByteArray c = content->decodedContent().toBase64();
+        KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
+        attachment->setLabel( name );
+        incidence->addAttachment(attachment);
+        kDebug() << "ATTACHEMENT NAME" << name << type;
     }
 }
 
@@ -97,8 +95,6 @@ QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mim
 }
 
 
-
-    
 QByteArray fromCid(const QString &cid)
 {
     if (cid.left(4) != QString::fromLatin1("cid:")) { //Don't set if not a cid, happens when serializing format v2
@@ -187,8 +183,8 @@ void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attac
         QByteArray type;
         KMime::Content *content = findContentByName(mimeData, name, type);
         if (!content) { // guard against malformed events with non-existent attachments
-                    qWarning() << "could not find attachment: "<< name;
-                    continue;
+            qWarning() << "could not find attachment: "<< name;
+            continue;
         }
         const QByteArray c = content->decodedContent().toBase64();
         KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
diff --git a/upgradetool/upgradetooltests.cpp b/upgradetool/upgradetooltests.cpp
index a470e76..4782795 100644
--- a/upgradetool/upgradetooltests.cpp
+++ b/upgradetool/upgradetooltests.cpp
@@ -5,10 +5,10 @@
 
 void UpgradeToolTests::testConvertEvent()
 {
-    QFile file( "complex.ics.mime" );
+    QFile file( "../../testfiles/v2/event/complex.ics.mime" );
     file.open( QFile::ReadOnly );
     const QByteArray data = file.readAll();
-    Q_ASSERT( !data.isEmpty() );
+    QVERIFY( !data.isEmpty() );
     kDebug() << Kolab::Upgrade::upgradeMime(data);
 }
 


commit 6fcb88426d7403b3407a562a903f7f6898c0a44a
Merge: 9f1f0a0 8a9fe78
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Mar 21 17:01:56 2012 +0100

    Merge branch 'master' into dev/libkolab



commit 9f1f0a0ad54ae230aac55f0721fd7c48dafadd53
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Mar 21 12:11:23 2012 +0100

    updated gitignore

diff --git a/.gitignore b/.gitignore
index d5c7800..99bb8e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,5 @@ aclocal.m4
 libkolabxml-*.tar.gz
 libkolabxml-*.*/
 libkolabxml.spec
+build
+*kdev4*


commit 8750a214e418dcf706f206f92125f4f21997cb7a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Mar 21 12:11:14 2012 +0100

    Large restructuring into libkolab/upgradetool + the library itself.

diff --git a/libkolab/CMakeLists.txt b/libkolab/CMakeLists.txt
new file mode 100644
index 0000000..9ab3b44
--- /dev/null
+++ b/libkolab/CMakeLists.txt
@@ -0,0 +1,45 @@
+project(libkolab)
+
+cmake_minimum_required(VERSION 2.6)
+
+find_package(Qt4 REQUIRED)
+find_package(KDE4 REQUIRED)
+
+find_library(KOLABXML NAMES kolabxml)
+# find_library(KOLABKCAL NAMES kolabkcal)
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC" )
+
+include_directories(    
+    ${QT_INCLUDES}
+    ${Boost_INCLUDE_DIR}
+    ${KDEPIMLIBS_INCLUDE_DIRS}
+    ${KDE4_INCLUDE_DIR}
+    ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}/kabc
+    ${CMAKE_SOURCE_DIR}/kabc
+    ${CMAKE_CURRENT_SOURCE_DIR}/kolabformatV2
+    ./
+)
+
+configure_file(akonadi-version.h.cmake "${CMAKE_BINARY_DIR}/akonadi-version.h" @ONLY)
+
+set(LIBRARY_TYPE STATIC)
+add_subdirectory(kolabformatV2)
+
+add_library(kolab SHARED kolabformat/kolabobject.cpp mime/mimeutils.cpp conversion/kcalconversion.cpp)
+target_link_libraries(kolab kolabformatV2  ${KOLABXML} kcalcore kmime ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} kabc akonadi-kde ${KDE4_KIO_LIBRARY})
+set_target_properties(kolab PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
+
+install(TARGETS kolab EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
+
+install( FILES
+    kolab_export.h
+    DESTINATION ${INCLUDE_INSTALL_DIR}/kolab COMPONENT Devel)
+
+install( FILES
+    kolabformat/kolabobject.h
+    conversion/kcalconversion.h
+    DESTINATION ${INCLUDE_INSTALL_DIR}/kolab COMPONENT Devel)
+
+add_subdirectory(tests)
diff --git a/libkolab/conversion/CMakeLists.txt b/libkolab/conversion/CMakeLists.txt
new file mode 100644
index 0000000..29e5262
--- /dev/null
+++ b/libkolab/conversion/CMakeLists.txt
@@ -0,0 +1,32 @@
+project(kolabkcal)
+
+cmake_minimum_required(VERSION 2.6)
+
+find_package(Qt4 REQUIRED)
+find_package(KDE4 REQUIRED)
+
+find_library(KOLABXML NAMES kolabxml)
+
+find_library(KCALCORE NAMES kcalcore)
+if(KCALCORE)
+    set(KCALCORE_FOUND ON)
+    message("KCalCore found")
+endif(KCALCORE)
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC" )
+
+# include_directories(KOLABXML_DIRS)
+
+#Library with converters to/from kcalcore
+add_library(kolabkcal SHARED kcalconversion.cpp)
+target_link_libraries(kolabkcal ${KOLABXML} ${KCALCORE} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY})
+
+set_target_properties(kolabkcal PROPERTIES VERSION 0.1.0 SOVERSION 0)
+install(TARGETS kolabkcal LIBRARY DESTINATION lib)
+
+install( FILES
+kcalconversion.h
+DESTINATION include/kolab COMPONENT Devel)
+
+add_subdirectory(tests)
+
diff --git a/libkolab/conversion/kcalconversion.cpp b/libkolab/conversion/kcalconversion.cpp
new file mode 100644
index 0000000..e8edc71
--- /dev/null
+++ b/libkolab/conversion/kcalconversion.cpp
@@ -0,0 +1,746 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kcalconversion.h"
+
+#include <kcalcore/recurrence.h>
+#include <QtCore/QBitArray>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+#include <vector>
+#include <KDE/KSystemTimeZones>
+
+namespace Kolab {
+    namespace Conversion {
+
+KDateTime toDate(const Kolab::cDateTime &dt)
+{
+    KDateTime date;
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return KDateTime();
+    }
+    if (dt.isDateOnly()) { //Date only
+        date.setDateOnly(true);
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
+    } else {
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
+        if (dt.isUTC()) { //UTC
+            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        } else if (!dt.timezone().empty()) { //Timezone
+            const KTimeZone &tz = KSystemTimeZones::zone(QString::fromStdString(dt.timezone())); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+            if (!tz.isValid()) {
+                qWarning() << "timezone not found" << QString::fromStdString(dt.timezone());
+                if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
+                    qWarning() << "ktimezoned is not available and required for timezone interpretation";
+                }
+            }
+            date.setTimeSpec(KDateTime::Spec(tz));
+        } else { //Floating
+            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
+        }
+    }
+    Q_ASSERT(date.timeSpec().isValid());
+    Q_ASSERT(date.isValid());
+    return date;
+}
+
+cDateTime fromDate(const KDateTime &dt)
+{
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return cDateTime();
+    }
+    cDateTime date;
+    if (dt.isDateOnly()) { //Date only
+        const QDate &d = dt.date();
+        date.setDate(d.year(), d.month(), d.day());
+    } else {
+        const QDate &d = dt.date();
+        date.setDate(d.year(), d.month(), d.day());
+        const QTime &t = dt.time();
+        date.setTime(t.hour(), t.minute(), t.second());
+        if (dt.timeType() == KDateTime::UTC) { //UTC
+            date.setUTC(true);
+        } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
+            //TODO handle local timezone?
+            date.setTimezone(dt.timeZone().name().toStdString()); //FIXME use system independent name according to spec
+        } else if (dt.timeType() != KDateTime::ClockTime) {
+            qWarning() << "invalid timespec, assuming floating time" << dt.timeType();
+            return cDateTime();
+        }
+    }
+    Q_ASSERT(date.isValid());
+    return date;
+}
+
+KCalCore::Duration toDuration(const Kolab::Duration &d)
+{
+    //TODO should we support negative durations?
+    if (d.hours() || d.minutes() || d.seconds()) {
+        return KCalCore::Duration(((((d.weeks() * 7 + d.days()) * 24 + d.hours()) * 60 + d.minutes()) * 60 + d.seconds()));
+    }
+    return KCalCore::Duration(d.weeks() * 7 + d.days(), KCalCore::Duration::Days);
+}
+
+Kolab::Duration fromDuration(const KCalCore::Duration &d)
+{
+    if (d.value() <= 0) {
+        return Kolab::Duration();
+    }
+    //We don't know how the seconds/days were distributed before, so no point in distributing them (probably)
+    //TODO should we support negative durations?
+    if (d.isDaily()) {
+        int days = d.value();
+        return Kolab::Duration(days, 0, 0, 0, false);
+    }
+    int seconds = d.value();
+//         int minutes = seconds / 60;
+//         seconds = seconds % 60;
+//         int hours = minutes / 60;
+//         minutes = minutes % 60;
+    return Kolab::Duration(0, 0, 0, seconds, false);
+
+}
+
+KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
+{
+    switch(c) {
+        case Kolab::ClassPublic:
+            return KCalCore::Incidence::SecrecyPublic;
+        case Kolab::ClassPrivate:
+            return KCalCore::Incidence::SecrecyPrivate;
+        case Kolab::ClassConfidential:
+            return KCalCore::Incidence::SecrecyConfidential;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Incidence::SecrecyPublic;
+}
+
+Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
+{
+    switch(c) {
+        case KCalCore::Incidence::SecrecyPublic:
+            return Kolab::ClassPublic;
+        case KCalCore::Incidence::SecrecyPrivate:
+            return Kolab::ClassPrivate;
+        case KCalCore::Incidence::SecrecyConfidential:
+            return Kolab::ClassConfidential;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::ClassPublic;
+}
+
+int toPriority(int priority)
+{
+    //Same mapping
+    return priority;
+}
+
+int fromPriority(int priority)
+{
+    //Same mapping
+    return priority;
+}
+
+KCalCore::Incidence::Status toStatus(Kolab::Status s)
+{
+    switch (s) {
+        case StatusUndefined:
+            return  KCalCore::Incidence::StatusNone;
+        case StatusNeedsAction:
+            return  KCalCore::Incidence::StatusNeedsAction;
+        case StatusCompleted:
+            return  KCalCore::Incidence::StatusCompleted;
+        case StatusInProcess:
+            return  KCalCore::Incidence::StatusInProcess;
+        case StatusCancelled:
+            return  KCalCore::Incidence::StatusCanceled;
+        case StatusTentative:
+            return  KCalCore::Incidence::StatusTentative;
+        case StatusConfirmed:
+            return  KCalCore::Incidence::StatusConfirmed;
+        case StatusDraft:
+            return  KCalCore::Incidence::StatusDraft;
+        case StatusFinal:
+            return  KCalCore::Incidence::StatusFinal;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Incidence::StatusNone;
+}
+
+Kolab::Status fromStatus(KCalCore::Incidence::Status s)
+{
+    switch (s) {
+        case KCalCore::Incidence::StatusNone:
+            return StatusUndefined;
+        case KCalCore::Incidence::StatusNeedsAction:
+            return StatusNeedsAction;
+        case KCalCore::Incidence::StatusCompleted:
+            return StatusCompleted;
+        case KCalCore::Incidence::StatusInProcess:
+            return StatusInProcess;
+        case KCalCore::Incidence::StatusCanceled:
+            return StatusCancelled;
+        case KCalCore::Incidence::StatusTentative:
+            return StatusTentative;
+        case KCalCore::Incidence::StatusConfirmed:
+            return StatusConfirmed;
+        case KCalCore::Incidence::StatusDraft:
+            return StatusDraft;
+        case KCalCore::Incidence::StatusFinal:
+            return StatusFinal;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return StatusUndefined;
+}
+
+QStringList toStringList(const std::vector<std::string> &l)
+{
+    QStringList list;
+    foreach(const std::string &s, l) {
+        list.append(QString::fromStdString(s));
+    }
+    return list;
+}
+
+std::vector<std::string> fromStringList(const QStringList &l)
+{
+    std::vector<std::string> list;
+    foreach(const QString &s, l) {
+        list.push_back(s.toStdString());
+    }
+    return list;
+}
+
+KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
+{
+    switch (p) {
+        case PartNeedsAction:
+            return KCalCore::Attendee::NeedsAction;
+        case PartAccepted:
+            return KCalCore::Attendee::Accepted;
+        case PartDeclined:
+            return KCalCore::Attendee::Declined;
+        case PartTentative:
+            return KCalCore::Attendee::Tentative;
+        case PartDelegated:
+            return KCalCore::Attendee::Delegated;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Attendee::NeedsAction;
+}
+
+Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
+{
+    switch (p) {
+        case KCalCore::Attendee::NeedsAction:
+            return PartNeedsAction;
+        case KCalCore::Attendee::Accepted:
+            return PartAccepted;
+        case KCalCore::Attendee::Declined:
+            return PartDeclined;
+        case KCalCore::Attendee::Tentative:
+            return PartTentative;
+        case KCalCore::Attendee::Delegated:
+            return PartDelegated;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return PartNeedsAction;
+}
+
+KCalCore::Attendee::Role toRole(Kolab::Role r)
+{
+    switch (r) {
+        case Required:
+            return KCalCore::Attendee::ReqParticipant;
+        case Chair:
+            return KCalCore::Attendee::Chair;
+        case Optional:
+            return KCalCore::Attendee::OptParticipant;
+        case NonParticipant:
+            return KCalCore::Attendee::NonParticipant;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Attendee::ReqParticipant;
+}
+
+Kolab::Role fromRole(KCalCore::Attendee::Role r)
+{
+    switch (r) {
+        case KCalCore::Attendee::ReqParticipant:
+            return Required;
+        case KCalCore::Attendee::Chair:
+            return Chair;
+        case KCalCore::Attendee::OptParticipant:
+            return Optional;
+        case KCalCore::Attendee::NonParticipant:
+            return NonParticipant;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Required;
+}
+
+template <typename T>
+void setIncidence(KCalCore::Incidence &i, const T &e)
+{
+    if (!e.uid().empty()) {
+        i.setUid(QString::fromStdString(e.uid()));
+    }
+    
+    i.setCreated(toDate(e.created()));
+    i.setLastModified(toDate(e.lastModified()));
+    i.setRevision(e.sequence());
+    i.setSecrecy(toSecrecy(e.classification()));
+    i.setCategories(toStringList(e.categories()));
+    
+    if (e.start().isValid()) {
+        i.setDtStart(toDate(e.start()));
+    }
+
+    i.setSummary(QString::fromStdString(e.summary())); //TODO detect richtext
+    i.setDescription(QString::fromStdString(e.description())); //TODO detect richtext
+    i.setStatus(toStatus(e.status()));
+    foreach (const Kolab::Attendee a, e.attendees()) {
+        //We shouldn't rely on a uid if we're going with mail+name and not on mail+name if we're going with UID (of ical btw. and not kaddresee)
+        i.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(QString::fromStdString(a.contact().name()), 
+                                                                     QString::fromStdString(a.contact().email()),  //TODO handle uid
+                                                                     a.rsvp(),
+                                                                     toPartStat(a.partStat()),
+                                                                     toRole(a.role()) ))); //FIXME doesn't make sense to set both, either email or uid
+    }
+    foreach (const Kolab::Attachment a, e.attachments()) {
+        KCalCore::Attachment::Ptr ptr;
+        if (!a.uri().empty()) {
+            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString::fromStdString(a.uri()), QString::fromStdString(a.mimetype())));
+        } else {
+            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), QString::fromStdString(a.mimetype())));
+        }
+        if (!a.label().empty()) {
+            ptr->setLabel(QString::fromStdString(a.label()));
+        }
+        i.addAttachment(ptr);
+    }
+//     i.addAlarm(); //TODO
+//     i.setCustomProperties(); //TODO
+}
+
+template <typename T, typename I>
+void getIncidence(T &i, const I &e)
+{
+    i.setUid(e.uid().toStdString());
+    i.setCreated(fromDate(e.created()));
+    i.setLastModified(fromDate(e.lastModified()));
+    i.setSequence(e.revision());
+    i.setClassification(fromSecrecy(e.secrecy()));
+    i.setCategories(fromStringList(e.categories()));
+    
+    i.setStart(fromDate(e.dtStart()));
+    i.setSummary(e.summary().toStdString());
+    i.setDescription(e.description().toStdString());
+    i.setStatus(fromStatus(e.status()));
+    std::vector<Kolab::Attendee> attendees;
+    foreach (const KCalCore::Attendee::Ptr ptr, e.attendees()) {
+        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference, ptr->email().toStdString(), ptr->name().toStdString())); //TODO handle uid
+        a.setRSVP(ptr->RSVP());
+        a.setPartStat(fromPartStat(ptr->status()));
+        a.setRole(fromRole(ptr->role()));
+//         a.setUid(ptr->uid().toStdString()); //TODO
+        attendees.push_back(a);
+    }
+    i.setAttendees(attendees);
+    std::vector<Kolab::Attachment> attachments;
+    foreach (const KCalCore::Attachment::Ptr ptr, e.attachments()) {
+        Kolab::Attachment a;
+        if (ptr->isUri()) {
+            a.setUri(ptr->uri().toStdString(), ptr->mimeType().toStdString());
+        } else {
+            a.setData(std::string(ptr->decodedData().data(), ptr->decodedData().size()), ptr->mimeType().toStdString());
+        }
+        a.setLabel(ptr->label().toStdString());
+        attachments.push_back(a);
+    }
+    i.setAttachments(attachments);
+    //TODO alarms
+    //TODO custom properties
+}
+
+int toWeekDay(Kolab::Weekday wday)
+{
+    switch (wday) {
+        case Kolab::Monday:
+            return  1;
+        case Kolab::Tuesday:
+            return 2;
+        case Kolab::Wednesday:
+            return 3;
+        case Kolab::Thursday:
+            return 4;
+        case Kolab::Friday:
+            return 5;
+        case Kolab::Saturday:
+            return 6;
+        case Kolab::Sunday:
+            return 7;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return 1;
+}
+
+Kolab::Weekday fromWeekDay(int wday)
+{
+    switch (wday) {
+        case 1:
+            return Kolab::Monday;
+        case 2:
+            return Kolab::Tuesday;
+        case 3:
+            return Kolab::Wednesday;
+        case 4:
+            return Kolab::Thursday;
+        case 5:
+            return Kolab::Friday;
+        case 6:
+            return Kolab::Saturday;
+        case 7:
+            return Kolab::Sunday;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::Monday;
+}
+
+KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
+{
+    switch(freq) {
+        case Kolab::RecurrenceRule::FreqNone:
+            qWarning() << "no recurrence?";
+            break;
+        case Kolab::RecurrenceRule::Yearly:
+            return KCalCore::RecurrenceRule::rYearly;
+        case Kolab::RecurrenceRule::Monthly:
+            return KCalCore::RecurrenceRule::rMonthly;
+        case Kolab::RecurrenceRule::Weekly:
+            return KCalCore::RecurrenceRule::rWeekly;
+        case Kolab::RecurrenceRule::Daily:
+            return KCalCore::RecurrenceRule::rDaily;
+        case Kolab::RecurrenceRule::Hourly:
+            return KCalCore::RecurrenceRule::rHourly;
+        case Kolab::RecurrenceRule::Minutely:
+            return KCalCore::RecurrenceRule::rMinutely;
+        case Kolab::RecurrenceRule::Secondly:
+            return KCalCore::RecurrenceRule::rSecondly;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::RecurrenceRule::rNone;
+}
+
+Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
+{
+    switch(freq) {
+        case KCalCore::RecurrenceRule::rNone:
+            qWarning() << "no recurrence?";
+            break;
+        case KCalCore::RecurrenceRule::rYearly:
+            return Kolab::RecurrenceRule::Yearly;
+        case KCalCore::RecurrenceRule::rMonthly:
+            return Kolab::RecurrenceRule::Monthly;
+        case KCalCore::RecurrenceRule::rWeekly:
+            return Kolab::RecurrenceRule::Weekly;
+        case KCalCore::RecurrenceRule::rDaily:
+            return Kolab::RecurrenceRule::Daily;
+        case KCalCore::RecurrenceRule::rHourly:
+            return Kolab::RecurrenceRule::Hourly;
+        case KCalCore::RecurrenceRule::rMinutely:
+            return Kolab::RecurrenceRule::Minutely;
+        case KCalCore::RecurrenceRule::rSecondly:
+            return Kolab::RecurrenceRule::Secondly;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::RecurrenceRule::FreqNone;
+}
+
+KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
+{
+    return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday()));
+}
+
+Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
+{
+    return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()));
+}
+
+template <typename T>
+void setRecurrence(KCalCore::Incidence &e, const T &event)
+{
+    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
+    if (rrule.isValid()) {
+        KCalCore::Recurrence *rec = e.recurrence();
+        
+        KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
+        Q_ASSERT(defaultRR);
+        
+        defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
+        defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
+        defaultRR->setFrequency(rrule.interval());
+        
+        if (rrule.end().isValid()) {
+            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
+        } else {
+            rec->setDuration(rrule.count());
+        }
+        
+        if (!rrule.bysecond().empty()) {
+            defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
+        }
+        if (!rrule.byminute().empty()) {
+            defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
+        }
+        if (!rrule.byhour().empty()) {
+            defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
+        }
+        if (!rrule.byday().empty()) {
+            QList<KCalCore::RecurrenceRule::WDayPos> daypos;
+            foreach(const Kolab::DayPos &dp, rrule.byday()) {
+                daypos.append(toWeekDayPos(dp));
+            }
+            defaultRR->setByDays(daypos);
+        }
+        if (!rrule.bymonthday().empty()) {
+            defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
+        }
+        if (!rrule.byyearday().empty()) {
+            defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
+        }
+        if (!rrule.byweekno().empty()) {
+            defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
+        }
+        if (!rrule.bymonth().empty()) {
+            defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
+        }
+    }
+    foreach (const Kolab::cDateTime &dt, event.recurrenceDates()) {
+        const KDateTime &date = toDate(dt);
+        if (date.isDateOnly()) {
+            e.recurrence()->addRDate(date.date());
+        } else {
+            e.recurrence()->addRDateTime(date);
+        }
+    }
+    foreach (const Kolab::cDateTime &dt, event.exceptionDates()) {
+        const KDateTime &date = toDate(dt);
+        if (date.isDateOnly()) {
+            e.recurrence()->addExDate(date.date());
+        } else {
+            e.recurrence()->addExDateTime(date);
+        }
+    }
+
+}
+
+template <typename T, typename I>
+void getRecurrence(T &i, const I &e)
+{
+    if (!e.recurs()) {
+        return;
+    }
+    KCalCore::Recurrence *rec = e.recurrence();
+    KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
+    if (!defaultRR) {
+        qWarning() << "no recurrence";
+        return;
+    }
+    Q_ASSERT(defaultRR);
+
+    Kolab::RecurrenceRule rrule;
+    rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
+    rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
+    rrule.setInterval(defaultRR->frequency());
+  
+    if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
+        if (defaultRR->duration() > 0) {
+            rrule.setCount(defaultRR->duration());
+        }
+    } else {
+        rrule.setEnd(fromDate(defaultRR->endDt()));
+    }
+    
+    rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
+    rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
+    rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
+    
+    std::vector<Kolab::DayPos> daypos;
+    foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
+        daypos.push_back(fromWeekDayPos(dp));
+    }
+    rrule.setByday(daypos);
+    
+    rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
+    rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
+    rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
+    rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
+    i.setRecurrenceRule(rrule);
+    
+    std::vector<Kolab::cDateTime> rdates;
+    foreach (const KDateTime &dt, rec->rDateTimes()) {
+        rdates.push_back(fromDate(dt));
+    }
+    foreach (const QDate &dt, rec->rDates()) {
+        rdates.push_back(fromDate(KDateTime(dt)));
+    }
+    i.setRecurrenceDates(rdates);
+    
+    std::vector<Kolab::cDateTime> exdates;
+    foreach (const KDateTime &dt, rec->exDateTimes()) {
+        exdates.push_back(fromDate(dt));
+    }
+    foreach (const QDate &dt, rec->exDates()) {
+        exdates.push_back(fromDate(KDateTime(dt)));
+    }
+    i.setExceptionDates(exdates);
+    
+    if (!rec->exRules().empty()) {
+        qWarning() << "exrules are not supported";
+    }
+}
+
+template <typename T>
+void setTodoEvent(KCalCore::Incidence &i, const T &e)
+{
+    i.setPriority(toPriority(e.priority()));
+    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
+    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizer().name()), QString::fromStdString(e.organizer().email())))); //TODO handle uid too
+    if (e.recurrenceID().isValid()) {
+        i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
+    }
+    setRecurrence(i, e);
+}
+
+template <typename T, typename I>
+void getTodoEvent(T &i, const I &e)
+{
+    i.setPriority(fromPriority(e.priority()));
+    i.setLocation(e.location().toStdString());
+    i.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, e.organizer()->email().toStdString(), e.organizer()->name().toStdString())); //TODO handle uid too
+    i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
+    getRecurrence(i, e);
+}
+
+KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
+{
+    KCalCore::Event::Ptr e(new KCalCore::Event);
+    setIncidence(*e, event);
+    setTodoEvent(*e, event);
+    if (event.end().isValid()) {
+        e->setDtEnd(toDate(event.end()));
+    }
+    if (event.duration().isValid()) {
+        e->setDuration(toDuration(event.duration()));
+    }
+    if (event.transparency()) {
+        e->setTransparency(KCalCore::Event::Transparent);
+    } else {
+        e->setTransparency(KCalCore::Event::Opaque);
+    }
+    return e;
+}
+
+Event fromKCalCore(const KCalCore::Event &event)
+{
+    Event e;
+    getIncidence(e, event);
+    getTodoEvent(e, event);
+    if (event.hasEndDate()) {
+        e.setEnd(fromDate(event.dtEnd()));
+    } else if (event.hasDuration()) {
+        e.setDuration(fromDuration(event.duration()));
+    }
+    if (event.transparency() == KCalCore::Event::Transparent) {
+        e.setTransparency(true);
+    } else {
+        e.setTransparency(false);
+    }
+    return e;
+}
+
+
+
+KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
+{
+    KCalCore::Todo::Ptr e(new KCalCore::Todo);
+    setIncidence(*e, todo);
+    setTodoEvent(*e, todo);
+    if (todo.due().isValid()) {
+        e->setDtDue(toDate(todo.due()));
+    }
+    return e;
+}
+
+Todo fromKCalCore ( const KCalCore::Todo &todo )
+{
+    Todo t;
+    getIncidence(t, todo);
+    getTodoEvent(t, todo);
+    t.setDue(fromDate(todo.dtDue(true)));
+    return t;
+}
+
+KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
+{
+    KCalCore::Journal::Ptr e(new KCalCore::Journal);
+    setIncidence(*e, journal);
+    //TODO contacts
+    return e;
+}
+
+Journal fromKCalCore ( const KCalCore::Journal &journal )
+{
+    Journal j;
+    getIncidence(j, journal);
+    //TODO contacts
+    return j;
+}
+
+
+
+}
+}
\ No newline at end of file
diff --git a/libkolab/conversion/kcalconversion.h b/libkolab/conversion/kcalconversion.h
new file mode 100644
index 0000000..236064a
--- /dev/null
+++ b/libkolab/conversion/kcalconversion.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABKCALCONVERSION_H
+#define KOLABKCALCONVERSION_H
+
+#include "kolab_export.h"
+
+#include <kolab/kolabevent.h>
+#include <kolab/kolabtodo.h>
+#include <kolab/kolabjournal.h>
+#include <kcalcore/event.h>
+#include <kcalcore/todo.h>
+#include <kcalcore/journal.h>
+
+namespace Kolab {
+    /**
+     * Conversion of Kolab-Containers to/from KCalCore Containers.
+     *
+     * TODO: There is no error handling other than qWarning used so far.
+     */
+    namespace Conversion {
+
+        KOLAB_EXPORT KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
+        KOLAB_EXPORT Kolab::Event fromKCalCore(const KCalCore::Event &);
+
+        KOLAB_EXPORT KCalCore::Todo::Ptr toKCalCore(const Kolab::Todo &);
+        KOLAB_EXPORT Kolab::Todo fromKCalCore(const KCalCore::Todo &);
+
+        KOLAB_EXPORT KCalCore::Journal::Ptr toKCalCore(const Kolab::Journal &);
+        KOLAB_EXPORT Kolab::Journal fromKCalCore(const KCalCore::Journal &);
+
+        KOLAB_EXPORT KDateTime toDate(const Kolab::cDateTime &dt);
+        KOLAB_EXPORT cDateTime fromDate(const KDateTime &dt);
+
+    };
+};
+
+#endif
\ No newline at end of file
diff --git a/libkolab/conversion/tests/CMakeLists.txt b/libkolab/conversion/tests/CMakeLists.txt
new file mode 100644
index 0000000..9340bad
--- /dev/null
+++ b/libkolab/conversion/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+
+QT4_AUTOMOC(kcalconversiontest.cpp)
+add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabkcal ${XERCES_C})
+
diff --git a/libkolab/conversion/tests/kcalconversiontest.cpp b/libkolab/conversion/tests/kcalconversiontest.cpp
new file mode 100644
index 0000000..b6549c8
--- /dev/null
+++ b/libkolab/conversion/tests/kcalconversiontest.cpp
@@ -0,0 +1,714 @@
+#include "kcalconversiontest.h"
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+#include <KDE/KSystemTimeZones>
+#include <kcalcore/recurrence.h>
+
+#include "kolabkcalconversion.h"
+#include "kolabkcalconversion.cpp"
+// #include <lib/calendaring.h>
+
+// #include "serializers.h"
+
+using namespace Kolab::KCalConversion;
+
+Q_DECLARE_METATYPE(Kolab::Duration);
+Q_DECLARE_METATYPE(Kolab::cDateTime);
+Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(Kolab::Todo);
+Q_DECLARE_METATYPE(Kolab::Journal);
+Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
+Q_DECLARE_METATYPE(KCalCore::Event);
+Q_DECLARE_METATYPE(KCalCore::Todo);
+Q_DECLARE_METATYPE(KCalCore::Journal);
+Q_DECLARE_METATYPE(KCalCore::Duration);
+
+namespace QTest {
+    
+    template<>
+    char *toString(const KDateTime &dt)
+    {
+        QByteArray ba = "KDateTime(";
+        ba += dt.toString().toAscii();
+        ba += dt.timeZone().name();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Attendee &at)
+    {
+        QByteArray ba = "Attendee(";
+        ba += at.name().toAscii() + ", ";
+        ba += at.email().toAscii() + ", ";
+        ba += QString::number(at.role()) + ", ";
+        ba += QString::number(at.status()) + ", ";
+        ba += QString::number(at.RSVP()) + ", ";
+        ba += at.delegate().toAscii() + ", ";
+        ba += at.delegator().toAscii() + ", ";
+        ba += at.uid().toAscii() + ", ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    
+    template<>
+    char *toString(const QList<int> &l)
+    {
+        QByteArray ba = "QList<int>(";
+        foreach(int i, l) {
+            ba += QString::number(i) + ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const QList<KCalCore::RecurrenceRule::WDayPos> &l)
+    {
+        QByteArray ba = "QList<int>(";
+        foreach(const KCalCore::RecurrenceRule::WDayPos &i, l) {
+            ba += QString::number(i.pos()) + " ";
+            ba += QString::number(i.day()) + ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::DateList &l)
+    {
+        QByteArray ba = "KCalCore::DateList(";
+        foreach(const QDate &i, l) {
+            ba += i.toString();
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::DateTimeList &l)
+    {
+        QByteArray ba = "KCalCore::DateTimeList(";
+        foreach(const KDateTime &i, l) {
+            ba += toString(i);
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Recurrence &at)
+    {
+        at.dump();
+        KCalCore::RecurrenceRule *r = at.defaultRRule();
+        QByteArray ba;
+        if (!r) {
+            ba += "Recurrence( )";
+        } else {
+            Q_ASSERT(r);
+            Q_ASSERT(at.rRules().size() == 1);
+            
+            ba += "Recurrence(";
+            ba += QString::number(r->recurrenceType()) + "\n";
+            ba += QString::number(r->frequency()) + "\n";
+            ba += QString::number(r->duration()) + "\n";
+            ba += QByteArray(toString(r->startDt())) + "\n";
+            ba += QByteArray(toString(r->endDt())) + "\n";
+            ba += QByteArray(toString(r->bySeconds())) + "\n";
+            ba += QByteArray(toString(r->byMinutes())) + "\n";
+            ba += QByteArray(toString(r->byHours())) + "\n";
+            ba += QByteArray(toString(r->byDays())) + "\n";
+            ba += QByteArray(toString(r->byMonthDays())) + "\n";
+            ba += QByteArray(toString(r->byYearDays())) + "\n";
+            ba += QByteArray(toString(r->byMonths())) + "\n";
+            ba += ")\n";
+            ba += QByteArray(toString(at.exDates())) + "\n";
+            ba += QByteArray(toString(at.exDateTimes())) + "\n";
+            ba += QByteArray(toString(at.rDates())) + "\n";
+            ba += QByteArray(toString(at.rDateTimes())) + "\n";
+            
+        }
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::RecurrenceRule &at)
+    {
+        QByteArray ba;
+        ba += "KolabRecurrenceRule(";
+        ba += QString::number(at.weekStart()) + "\n";
+        ba += QString::number(at.frequency()) + "\n";
+        ba += QString::number(at.interval()) + "\n";
+        ba += QString::number(at.count()) + "\n";
+        ba += QByteArray(toString(at.end())) + "\n";
+        ba += QByteArray(toString(at.bysecond())) + "\n";
+        ba += QByteArray(toString(at.byminute())) + "\n";
+        ba += QByteArray(toString(at.byhour())) + "\n";
+        ba += QByteArray(toString(at.byday())) + "\n";
+        ba += QByteArray(toString(at.bymonthday())) + "\n";
+        ba += QByteArray(toString(at.byyearday())) + "\n";
+        ba += QByteArray(toString(at.byweekno())) + "\n";
+        ba += QByteArray(toString(at.bymonth())) + "\n";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Duration &d)
+    {
+        QByteArray ba;
+        ba += "KCalCore::Duration(";
+        ba += QString::number(d.isDaily()) + ", ";
+        ba += QString::number(d.value()) + " ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+}
+
+template <typename T>
+void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
+{
+    QCOMPARE(list.size(), other.size());
+    for (int i = 0 ; i < list.size(); i++) {
+        QCOMPARE(*list.at(i), *other.at(i));
+    }
+}
+
+
+void KCalConversionTest::testDate_data()
+{
+    QTest::addColumn<Kolab::cDateTime>( "input" );
+    QTest::addColumn<KDateTime>( "result" );
+
+    QTest::newRow( "datetime with tz" ) << Kolab::cDateTime("Europe/Zurich",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Zurich"));
+    QTest::newRow( "floating datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, false) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::Spec(KDateTime::ClockTime));
+    QTest::newRow( "utc datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, true) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
+    QTest::newRow( "date only" ) << Kolab::cDateTime(2006,1,8) << KDateTime(QDate(2006, 1, 8));
+}
+
+
+void KCalConversionTest::testDate()
+{
+    QFETCH(Kolab::cDateTime, input);
+    QFETCH(KDateTime, result);
+    
+    const KDateTime &r = Kolab::KCalConversion::toDate(input);
+    QCOMPARE(r, result);
+    
+    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
+    QCOMPARE(r2, input);
+}
+
+void KCalConversionTest::testDuration_data()
+{
+    QTest::addColumn<Kolab::Duration>( "input" );
+    QTest::addColumn<KCalCore::Duration>( "result" );
+    QTest::addColumn<Kolab::Duration>( "fromResult" );
+    
+    QTest::newRow( "seconds" ) << Kolab::Duration(0,0,0,30,false) << KCalCore::Duration(30, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,30,false);
+    QTest::newRow( "minutes" ) << Kolab::Duration(0,0,1,30,false) << KCalCore::Duration(90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,90,false);
+    QTest::newRow( "hours" ) << Kolab::Duration(0,1,1,30,false) << KCalCore::Duration(60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,60*60+90,false);
+    QTest::newRow( "days" ) << Kolab::Duration(1,1,1,30,false) << KCalCore::Duration(24*60*60+60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,24*60*60+60*60+90,false);
+    QTest::newRow( "daysonly" ) << Kolab::Duration(30,0,0,0, false) << KCalCore::Duration(30, KCalCore::Duration::Days) << Kolab::Duration(30,0,0,0,false);
+    QTest::newRow( "weeks" ) << Kolab::Duration(30,false) << KCalCore::Duration(30*7, KCalCore::Duration::Days) << Kolab::Duration(30*7,0,0,0,false);
+}
+
+
+void KCalConversionTest::testDuration()
+{
+    QFETCH(Kolab::Duration, input);
+    QFETCH(KCalCore::Duration, result);
+    QFETCH(Kolab::Duration, fromResult);
+    
+    const KCalCore::Duration &r = Kolab::KCalConversion::toDuration(input);
+    QCOMPARE(r, result);
+    
+    const Kolab::Duration &r2 = Kolab::KCalConversion::fromDuration(result);
+    QCOMPARE(r2, fromResult);
+}
+
+
+void KCalConversionTest::testDateTZ_data()
+{
+    QTest::addColumn<Kolab::cDateTime>( "input" );
+    QTest::addColumn<KDateTime>( "result" );
+    QTest::addColumn<int>( "offset" );
+       
+    QTest::newRow( "berlin" ) << Kolab::cDateTime("Europe/Berlin",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Berlin")) << 3600;
+}
+
+void KCalConversionTest::testDateTZ()
+{
+    QFETCH(Kolab::cDateTime, input);
+    QFETCH(KDateTime, result);
+    QFETCH(int, offset);
+    
+    const KDateTime &r = Kolab::KCalConversion::toDate(input);
+    QCOMPARE(result.timeZone().name(), QString::fromStdString(input.timezone()));
+    QCOMPARE(r.timeZone().currentOffset(), offset);
+    
+    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
+    QCOMPARE(QString::fromStdString(r2.timezone()), result.timeZone().name());
+}
+
+
+void KCalConversionTest::testConversion_data()
+{
+    QTest::addColumn<KCalCore::Event>( "kcal" );
+    QTest::addColumn<Kolab::Event>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    Kolab::cDateTime date3(2012,2,2,12,12,10);
+    std::vector<int> intVector;
+    intVector.push_back(1);
+    intVector.push_back(-3);
+    intVector.push_back(2);
+    std::vector<std::string> stringVector;
+    stringVector.push_back("cat1");
+    stringVector.push_back("cat2");
+    stringVector.push_back("parent/child");
+    
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
+        kcal.setCategories(toStringList(stringVector));
+        kcal.setDtStart(toDate(date));
+        kcal.setDtEnd(toDate(date2));
+        kcal.setTransparency(KCalCore::Event::Transparent);
+        
+        kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setDuration(5);
+        kcal.recurrence()->addRDateTime(toDate(date2));
+        kcal.recurrence()->addRDate(toDate(date2).date());
+        kcal.recurrence()->addExDateTime(toDate(date3));
+        kcal.recurrence()->addExDate(toDate(date3).date());
+        
+        KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
+        QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
+        rr->setBySeconds(intList);
+        rr->setByMinutes(intList);
+        rr->setByHours(intList);
+        rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,1) << KCalCore::RecurrenceRule::WDayPos(5,4));
+        rr->setByMonthDays(intList);
+        rr->setByYearDays(intList);
+        rr->setByMonths(intList);
+        rr->setByWeekNumbers(intList);
+        
+        kcal.setSummary("summary");
+        kcal.setDescription("description");
+        kcal.setPriority(3);
+        kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
+        kcal.setLocation("location");
+        kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
+        kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant)));
+        //TODO KCalCore Delegate/Delegator
+        kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
+        KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
+        KCalCore::Person::List addressees;
+        addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
+        alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
+        kcal.addAlarm(alarm);
+        //TODO alarms
+        //TODO custom properties
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setClassification(Kolab::ClassConfidential);
+        kolab.setCategories(stringVector);
+        kolab.setStart(date);
+        kolab.setEnd(date2);
+        kolab.setTransparency(true);
+        
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setCount(5);
+        rrule.setBysecond(intVector);
+        rrule.setByminute(intVector);
+        rrule.setByhour(intVector);
+        rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
+        rrule.setBymonthday(intVector);
+        rrule.setByyearday(intVector);
+        rrule.setByweekno(intVector);
+        rrule.setBymonth(intVector);
+        
+        kolab.setRecurrenceRule(rrule);
+        kolab.setRecurrenceID(date2, true);
+        kolab.setRecurrenceDates(std::vector<Kolab::cDateTime>() << date2 << Kolab::cDateTime(date2.year(), date2.month(), date2.day()));
+        kolab.setExceptionDates(std::vector<Kolab::cDateTime>() << date3 << Kolab::cDateTime(date3.year(), date3.month(), date3.day()));
+        
+        kolab.setSummary("summary");
+        kolab.setDescription("description");
+        kolab.setPriority(3);
+        kolab.setStatus(Kolab::StatusConfirmed);
+        kolab.setLocation("location");
+        kolab.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"organizer at email", "organizer")); //TODO uid
+        
+        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"attendee at email", "attendee"));//TODO uid
+        kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
+        
+        Kolab::Attachment attach;
+        attach.setUri("uri", "mimetype/mime");
+        kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
+        
+    //     std::vector<std::string> receipents;
+    //     receipents.push_back("email at email");
+    //     Kolab::Alarm alarm2("summary", "description", receipents);
+    //     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
+
+        QTest::newRow( "with endDate and recurrence duration" ) << kcal << kolab;
+    }
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setDtStart(toDate(date));
+        kcal.setDuration(KCalCore::Duration(toDate(date), toDate(date2)));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(date3));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setStart(date);
+        kolab.setDuration(Kolab::Duration(0, 0, 1, 0));
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(date3);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("with duration and recurrence endDate") << kcal << kolab;
+    }
+    {
+        Kolab::cDateTime start(2011,1,1);
+        Kolab::cDateTime end(2011,1,3);
+        
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setDtStart(toDate(start));
+        kcal.setDtEnd(toDate(end));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(end));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setStart(start);
+        kolab.setEnd(end);
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(end);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("date only dates") << kcal << kolab;
+    }
+}
+
+void KCalConversionTest::testConversion()
+{
+    QFETCH(KCalCore::Event, kcal);
+    QFETCH(Kolab::Event, kolab);
+    
+    const KCalCore::Event::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->created(), kcal.created());
+    QCOMPARE(e->lastModified(), kcal.lastModified());
+    QCOMPARE(e->revision(), kcal.revision());
+    QCOMPARE(e->secrecy(), kcal.secrecy());
+    QCOMPARE(e->categories(), kcal.categories());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->dtEnd(), kcal.dtEnd());
+    QCOMPARE(e->duration(), kcal.duration());
+    QCOMPARE(e->transparency(), kcal.transparency());
+    QCOMPARE(*e->recurrence(), *kcal.recurrence());
+    QCOMPARE(e->recurrenceId(), kcal.recurrenceId());
+    QCOMPARE(e->recurrenceType(), kcal.recurrenceType());
+    QCOMPARE(e->summary(), kcal.summary());
+    QCOMPARE(e->description(), kcal.description());
+    QCOMPARE(e->priority(), kcal.priority());
+    QCOMPARE(e->status(), kcal.status());
+    QCOMPARE(e->location(), kcal.location());
+    QCOMPARE(e->organizer()->name(), kcal.organizer()->name());
+    QCOMPARE(e->organizer()->email(), kcal.organizer()->email());
+    comparePointerVectors(e->attendees(), kcal.attendees());
+    comparePointerVectors(e->attachments(), kcal.attachments());
+    
+//     QCOMPARE(e->alarms(), kcal.alarms()); //TODO
+//TODO custom properties
+
+    QBENCHMARK {
+        toKCalCore(kolab);
+    }
+    
+    const Kolab::Event &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.created(), kolab.created());
+    QCOMPARE(b.lastModified(), kolab.lastModified());
+    QCOMPARE(b.sequence(), kolab.sequence());
+    QCOMPARE(b.classification(), kolab.classification());
+    QCOMPARE(b.categories(), kolab.categories());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.end(), kolab.end());
+    QCOMPARE(b.duration(), kolab.duration());
+    QCOMPARE(b.transparency(), kolab.transparency());
+    
+    QCOMPARE(b.recurrenceRule(), kolab.recurrenceRule());
+    QCOMPARE(b.recurrenceID(), kolab.recurrenceID());
+    QCOMPARE(b.recurrenceDates(), kolab.recurrenceDates());
+    QCOMPARE(b.exceptionDates(), kolab.exceptionDates());
+    
+    QCOMPARE(b.summary(), kolab.summary());
+    QCOMPARE(b.description(), kolab.description());
+    QCOMPARE(b.status(), kolab.status());
+}
+
+
+void KCalConversionTest::testTodoConversion_data()
+{
+    QTest::addColumn<KCalCore::Todo>( "kcal" );
+    QTest::addColumn<Kolab::Todo>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Todo kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setDtDue(toDate(date2));
+        
+        Kolab::Todo kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setDue(date2);
+
+        QTest::newRow( "todo" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testTodoConversion()
+{
+    QFETCH(KCalCore::Todo, kcal);
+    QFETCH(Kolab::Todo, kolab);
+    
+    const KCalCore::Todo::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->dtDue(), kcal.dtDue());
+   
+    const Kolab::Todo &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.due(), kolab.due());
+}
+
+void KCalConversionTest::testJournalConversion_data()
+{
+    QTest::addColumn<KCalCore::Journal>( "kcal" );
+    QTest::addColumn<Kolab::Journal>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Journal kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setSummary("summary");
+        
+        Kolab::Journal kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setSummary("summary");
+        
+        QTest::newRow( "journal" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testJournalConversion()
+{
+    QFETCH(KCalCore::Journal, kcal);
+    QFETCH(Kolab::Journal, kolab);
+    
+    const KCalCore::Journal::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->summary(), kcal.summary());
+    
+    const Kolab::Journal &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.summary(), kolab.summary());
+}
+
+
+void KCalConversionTest::testEventConflict_data()
+{
+    QTest::addColumn<Kolab::Event>( "e1" );
+    QTest::addColumn<Kolab::Event>( "e2" );
+    QTest::addColumn<bool>( "result" );
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1));
+        
+        QTest::newRow( "after" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1));
+        
+        QTest::newRow( "before" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        QTest::newRow( "conflict" ) << e1 << e2 << true;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
+        
+        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
+        
+        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
+    }
+}
+
+void KCalConversionTest::testEventConflict()
+{
+//     QFETCH(Kolab::Event, e1);
+//     QFETCH(Kolab::Event, e2);
+//     QFETCH(bool, result);
+//     QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
+}
+
+
+
+void KCalConversionTest::testTimesInInterval_data()
+{
+    QTest::addColumn<Kolab::Event>( "event" );
+    QTest::addColumn<Kolab::cDateTime>( "start" );
+    QTest::addColumn<Kolab::cDateTime>( "end" );
+    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
+    {
+        {
+            Kolab::Event event;
+            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
+            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
+            Kolab::RecurrenceRule rrule;
+            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+            rrule.setInterval(1);
+            rrule.setCount(5);
+            event.setRecurrenceRule(rrule);
+
+            std::vector<Kolab::cDateTime> result;
+            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1)); 
+            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1));
+            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1)); 
+            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1));
+            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1)); 
+            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1) << Kolab::cDateTime(2011,1,5,1,1,1) << result;
+        }
+    }
+}
+
+void KCalConversionTest::testTimesInInterval()
+{
+//     QFETCH(Kolab::Event, event);
+//     QFETCH(Kolab::cDateTime, start);
+//     QFETCH(Kolab::cDateTime, end);
+//     QFETCH(std::vector<Kolab::cDateTime>, result);
+//     QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
+}
+
+void KCalConversionTest::testTimesInIntervalBenchmark()
+{
+//     Kolab::Event event;
+//     event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
+//     event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
+//     Kolab::RecurrenceRule rrule;
+//     rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+//     rrule.setInterval(1);
+//     rrule.setCount(500);
+//     event.setRecurrenceRule(rrule);
+//     
+//     QBENCHMARK {
+//         Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+//     }
+//     const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+//     QVERIFY(result.size() == 500);
+//     qDebug() << QTest::toString(result);    
+}
+
+// void KCalConversionTest::BenchmarkRoundtripKCAL()
+// {
+//     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+//     std::string result = Kolab::writeEvent(event);
+//     QBENCHMARK {
+//         Kolab::KCalConversion::toKCalCore(Kolab::readEvent(result, false));
+//     }
+// }
+
+QTEST_MAIN( KCalConversionTest )
+
+#include "kcalconversiontest.moc"
diff --git a/libkolab/conversion/tests/kcalconversiontest.h b/libkolab/conversion/tests/kcalconversiontest.h
new file mode 100644
index 0000000..fa926a5
--- /dev/null
+++ b/libkolab/conversion/tests/kcalconversiontest.h
@@ -0,0 +1,38 @@
+#ifndef KCALCONVERSIONTEST_H
+#define KCALCONVERSIONTEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+class KCalConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+
+    void testDate_data();
+    void testDate();
+    
+    void testDuration_data();
+    void testDuration();
+    
+    void testConversion_data();
+    void testConversion();
+
+    void testTodoConversion_data();
+    void testTodoConversion();
+    
+    void testJournalConversion_data();
+    void testJournalConversion();
+    
+    void testDateTZ_data();
+    void testDateTZ();
+
+    void testEventConflict_data();
+    void testEventConflict();
+    
+    void testTimesInInterval_data();
+    void testTimesInInterval();
+    void testTimesInIntervalBenchmark();
+};
+
+#endif
\ No newline at end of file
diff --git a/libkolab/kolab_export.h b/libkolab/kolab_export.h
new file mode 100644
index 0000000..61d9b47
--- /dev/null
+++ b/libkolab/kolab_export.h
@@ -0,0 +1,50 @@
+/*
+ *  This file is part of kdepimlibs.
+ *  Copyright (c) 2012 Christian Mollekopf <mollekopf at kolabsys.com>
+ * 
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ * 
+ *  This library 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
+ *  Library General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KOLAB_EXPORT_H
+#define KOLAB_EXPORT_H
+
+#include <kdemacros.h>
+
+#ifndef KOLAB_EXPORT
+# if defined(KOLAB_STATIC_LIBS)
+/* No export/import for static libraries */
+#  define KOLAB_EXPORT
+# elif defined(MAKE_KOLAB_LIB)
+/* We are building this library */
+#  define KOLAB_EXPORT KDE_EXPORT
+# else
+/* We are using this library */
+#  define KOLAB_EXPORT KDE_IMPORT
+# endif
+#endif
+
+# ifndef KOLAB_EXPORT_DEPRECATED
+#  define KOLAB_EXPORT_DEPRECATED KDE_DEPRECATED KOLAB_EXPORT
+# endif
+
+/**
+ *  @namespace Kolab
+ * 
+ *  @brief
+ *  Contains all the KOLAB library global classes, objects, and functions.
+ */
+
+#endif
diff --git a/libkolab/kolabformat/CMakeLists.txt b/libkolab/kolabformat/CMakeLists.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/libkolab/kolabformat/CMakeLists.txt
@@ -0,0 +1 @@
+
diff --git a/libkolab/kolabformat/kolabobject.cpp b/libkolab/kolabformat/kolabobject.cpp
new file mode 100644
index 0000000..77c77fa
--- /dev/null
+++ b/libkolab/kolabformat/kolabobject.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "kolabobject.h"
+#include <kolabbase.h>
+#include <kolabformatV2/journal.h>
+#include <kolabformatV2/task.h>
+#include <kolabformatV2/event.h>
+#include <mime/mimeutils.h>
+#include <conversion/kcalconversion.h>
+#include <qdom.h>
+#include <kcalcore/journal.h>
+#include <kdebug.h>
+#include <kolab/kolabformat.h>
+
+
+namespace Kolab {
+
+static QString eventKolabType() { return QString::fromLatin1("application/x-vnd.kolab.event"); };
+static QString todoKolabType() { return QString::fromLatin1("application/x-vnd.kolab.task"); };
+static QString journalKolabType() { return QString::fromLatin1("application/x-vnd.kolab.journal"); };
+static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
+
+/*
+ * Parse XML, create KCalCore container and extract attachments
+ */
+//TODO V2 specific
+template <typename KCalPtr, typename Container>
+static KCalPtr fromXML(const QByteArray &xmlData, QStringList &attachments)
+{
+    const QDomDocument xmlDoc = KolabV2::KolabBase::loadDocument( QString::fromUtf8(xmlData) ); //TODO extract function from V2 format
+    Q_ASSERT ( !xmlDoc.isNull() );
+    const KCalPtr i = Container::fromXml( xmlDoc, QString() ); //For parsing we don't need the timezone, so we don't set one
+    Q_ASSERT ( i );
+    QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
+    for (int i = 0; i < nodes.size(); i++ ) {
+        attachments.append(nodes.at(i).toElement().text());
+    }
+    return i;
+}
+
+//TODO V2 specific
+template <typename IncidencePtr, typename Converter>
+static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &data, const QByteArray &mimetype, const QString &timezoneId )
+{
+    KMime::Content *xmlContent = Mime::findContentByType( data, mimetype );
+    if ( !xmlContent ) {
+        qWarning() << "couldn't find part";
+        return IncidencePtr();
+    }
+    const QByteArray xmlData = xmlContent->decodedContent();
+    
+    QStringList attachments;
+    IncidencePtr ptr = fromXML<IncidencePtr, Converter>(xmlData, attachments); //TODO do we care about timezone?
+    Mime::getAttachments(ptr, attachments, data);
+    
+    return ptr;
+    //             KMime::Content *xmlContent = findContentByType( data, mimetype );
+    //             if ( xmlContent ) {
+        //                 const QByteArray xmlData = xmlContent->decodedContent();
+    // //                 qDebug() << xmlData;
+    //                 const QDomDocument xmlDoc = Converter::loadDocument( QString::fromUtf8(xmlData) );
+    //                 if ( !xmlDoc.isNull() ) {
+        //                     IncidencePtr i = Converter::fromXml( xmlDoc, timezoneId );
+    //                     attachmentsFromKolab( data, xmlDoc, i );
+    //                     return i;
+    //                 }
+    //             }
+    // //             qDebug() << "empty";
+    //             return IncidencePtr();
+}
+
+void normalizeIncidence(KCalCore::Incidence::Ptr i)
+{
+    Q_FOREACH (KCalCore::Attendee::Ptr a, i->attendees()) {
+        a->setUid(QString()); //KCalCore sets the pointer as uid, we don't want that (if we wanted one, we'd want a real, globally unique one), so we clear the uid
+    }
+    
+    Q_FOREACH (KCalCore::Attachment::Ptr attachment, i->attachments()) {
+        attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
+    }
+}
+
+
+KCalCore::Event::Ptr readV2EventXML(const QByteArray& xmlData, QStringList& attachments)
+{
+    return fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+}
+
+
+KolabObjectReader::KolabObjectReader()
+{
+    
+}
+
+ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
+{
+    mObjectType = InvalidObject;
+    KMime::Headers::Base *xKolabHeader = msg->getHeaderByType("X-Kolab-Type");
+    if (!xKolabHeader) {
+        kWarning() << "could not find xKolabHeader";
+        return InvalidObject;
+    }
+    const QString &kolabType = xKolabHeader->asUnicodeString(); //TODO we probably shouldn't use unicodeString
+    
+    KMime::Content *xmlContent = Mime::findContentByType( msg, kolabType.toLocal8Bit() );
+    if ( !xmlContent ) {
+        qWarning() << "no part found";
+        return InvalidObject;
+    }
+    const QByteArray xmlData = xmlContent->decodedContent();
+    QStringList attachments;
+    KCalCore::Incidence::Ptr i;
+    kDebug() << kolabType;
+    mVersion = KolabV2;
+    if (kolabType == eventKolabType()) { //Event
+        kDebug() << "event";
+        mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+        Q_ASSERT(mIncidence);
+        Mime::getAttachments(mIncidence, attachments, msg);
+        normalizeIncidence(mIncidence);
+        mObjectType = EventObject;
+    } else if (kolabType == todoKolabType()) { //Todo 
+        kDebug() << "todo";
+        mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
+        Q_ASSERT(mIncidence);
+        Mime::getAttachments(mIncidence, attachments, msg);
+        normalizeIncidence(mIncidence);
+        mObjectType = TodoObject;
+    } else if (kolabType == journalKolabType()) { //Journal
+        kDebug() << "journal";
+        mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
+        Q_ASSERT(mIncidence);
+        Mime::getAttachments(mIncidence, attachments, msg);
+        normalizeIncidence(mIncidence);
+        mObjectType = JournalObject;
+    } else {
+        kWarning() << "no kolab object found " << kolabType;
+    }
+    return mObjectType;
+}
+
+Version KolabObjectReader::getVersion() const
+{
+    return mVersion;
+}
+
+ObjectType KolabObjectReader::getType() const
+{
+    return mObjectType;
+}
+
+KCalCore::Event::Ptr KolabObjectReader::getEvent() const
+{
+    return qSharedPointerDynamicCast<KCalCore::Event>(mIncidence);
+}
+
+KCalCore::Todo::Ptr KolabObjectReader::getTodo() const
+{
+    return qSharedPointerDynamicCast<KCalCore::Todo>(mIncidence);
+}
+
+KCalCore::Journal::Ptr KolabObjectReader::getJournal() const
+{
+    return qSharedPointerDynamicCast<KCalCore::Journal>(mIncidence);
+}
+
+
+
+KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v)
+{
+    const Kolab::Event &incidence = Kolab::Conversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeEvent(incidence);
+    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), eventKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    return message;
+}
+
+KMime::Message::Ptr KolabObjectWriter::writeTodo(const KCalCore::Todo::Ptr &i, Version v)
+{
+    const Kolab::Todo &incidence = Kolab::Conversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeTodo(incidence);
+    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), todoKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    return message;
+}
+
+KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr &i, Version v)
+{
+    const Kolab::Journal &incidence = Kolab::Conversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeJournal(incidence);
+    KMime::Message::Ptr message = Mime::createMessage(i, xCalMimeType(), journalKolabType(), QString::fromStdString(v3String).toLocal8Bit());
+    return message;
+}
+
+
+}; //Namespace
+
diff --git a/libkolab/kolabformat/kolabobject.h b/libkolab/kolabformat/kolabobject.h
new file mode 100644
index 0000000..7be2326
--- /dev/null
+++ b/libkolab/kolabformat/kolabobject.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABOBJECT_H
+#define KOLABOBJECT_H
+
+#include "kolab_export.h"
+
+#include <kcalcore/incidence.h>
+#include <kcalcore/event.h>
+#include <kcalcore/journal.h>
+#include <kcalcore/todo.h>
+#include <kmime/kmime_message.h>
+
+namespace Kolab {
+
+enum Version {
+    KolabV2,
+    KolabV3
+};
+
+enum ObjectType {
+    InvalidObject,
+    EventObject,
+    TodoObject,
+    JournalObject,
+};
+
+
+
+
+KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStringList &attachments);
+
+/**
+ * Class to read Kolab Mime files
+ * 
+ * It implements the Kolab specifics of Mime message handling
+ * 
+ */
+class KOLAB_EXPORT KolabObjectReader {
+public:
+    KolabObjectReader();
+    ObjectType parseMimeMessage(const KMime::Message::Ptr &msg);
+    
+    ObjectType getType() const;
+    
+    Version getVersion() const;
+    KCalCore::Event::Ptr getEvent() const;
+    KCalCore::Todo::Ptr getTodo() const;
+    KCalCore::Journal::Ptr getJournal() const;
+private:
+    KCalCore::Incidence::Ptr mIncidence;
+    ObjectType mObjectType;
+    Version mVersion;
+};
+
+class KOLAB_EXPORT KolabObjectWriter {
+public:
+    static KMime::Message::Ptr writeEvent(const KCalCore::Event::Ptr &, Version v = KolabV3);
+    static KMime::Message::Ptr writeTodo(const KCalCore::Todo::Ptr &, Version v = KolabV3);
+    static KMime::Message::Ptr writeJournal(const KCalCore::Journal::Ptr &, Version v = KolabV3);
+};
+
+}; //Namespace
+
+#endif // KOLABOBJECT_H
diff --git a/libkolab/kolabformatV2/CMakeLists.txt b/libkolab/kolabformatV2/CMakeLists.txt
new file mode 100644
index 0000000..588ee2a
--- /dev/null
+++ b/libkolab/kolabformatV2/CMakeLists.txt
@@ -0,0 +1,37 @@
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC" )
+
+########### next target ###############
+
+set( kolabformatv2_SRCS
+    kolabbase.cpp
+    contact.cpp
+    distributionlist.cpp
+    event.cpp
+    task.cpp
+    journal.cpp
+    incidence.cpp
+    note.cpp
+#     kolabformatv2.cpp
+)
+
+
+add_library(kolabformatV2 ${LIBRARY_TYPE} ${kolabformatv2_SRCS})
+# ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTXML_LIBRARY} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDEPIMLIBS_KMIME_LIBS} kdepim-copy ${KDEPIMLIBS_KCALCORE_LIBS}
+target_link_libraries(kolabformatV2  kcalcore kmime ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} kabc akonadi-kde ${KDE4_KIO_LIBRARY})
+set_target_properties(kolabformatV2 PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
+
+# # install(TARGETS kolabformatV2 EXPORT kolabformatLibraryTargets LIBRARY DESTINATION lib)
+# install(TARGETS kolabformatV2 EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
+# 
+# install( FILES
+#     kolabv2_export.h
+# #     kolabformatv2.h
+#     kolabbase.h
+#     contact.h
+#     distributionlist.h
+#     event.h
+#     task.h
+#     journal.h
+#     incidence.h
+#     note.h
+#     DESTINATION ${INCLUDE_INSTALL_DIR}/kolabformatV2 COMPONENT Devel)
\ No newline at end of file
diff --git a/libkolab/kolabformatV2/journal.h b/libkolab/kolabformatV2/journal.h
index bcd3e30..670c67a 100644
--- a/libkolab/kolabformatV2/journal.h
+++ b/libkolab/kolabformatV2/journal.h
@@ -36,7 +36,7 @@
 
 #include <kcalcore/journal.h>
 
-#include <kolabbase.h>
+#include "kolabbase.h"
 
 class QDomElement;
 
diff --git a/libkolab/kolabformatV2/kolabformatv2.cpp b/libkolab/kolabformatV2/kolabformatv2.cpp
deleted file mode 100644
index 8d1054f..0000000
--- a/libkolab/kolabformatV2/kolabformatv2.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "kolabformatv2.h"
-#include <quuid.h>
-
-namespace KolabV2 {
-    
-
-
-    
-KMime::Message::Ptr ConversionUtils::readMimeFile( const QString &fileName )
-{
-//     qDebug() << fileName;
-    QFile file( fileName );
-    file.open( QFile::ReadOnly );
-    const QByteArray data = file.readAll();
-    Q_ASSERT( !data.isEmpty() );
-    
-    KMime::Message *msg = new KMime::Message;
-    msg->setContent( data );
-    msg->parse();
-    return KMime::Message::Ptr(msg);
-}
-
-KMime::Content* ConversionUtils::findContentByType(const KMime::Message::Ptr &data, const QByteArray &type)
-{
-    const KMime::Content::List list = data->contents();
-//     qDebug() << list.size();
-    Q_FOREACH(KMime::Content *c, list)
-    {
-//         qDebug() << c->contentType()->mimeType() << type;
-        if (c->contentType()->mimeType() ==  type)
-            return c;
-    }
-    return 0;
-    
-}
-
-KMime::Content* ConversionUtils::findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type)
-{
-    const KMime::Content::List list = data->contents();
-    Q_FOREACH(KMime::Content *c, list)
-    {
-        if ( c->contentType()->name() == name ) {
-            type = c->contentType()->mimeType();
-            return c;
-        }
-    }
-    return 0;
-    
-}
-
-
-//TODO repalce
-void ConversionUtils::attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
-                          const KCalCore::Incidence::Ptr &incidence)
-{
-    QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
-    for (int i = 0; i < nodes.size(); i++ ) {
-        const QString name = nodes.at(i).toElement().text();
-        QByteArray type;
-        KMime::Content *content = findContentByName(data, name, type);
-        if (!content) // guard against malformed events with non-existent attachments
-        continue;
-        const QByteArray c = content->decodedContent().toBase64();
-        KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
-        attachment->setLabel( name );
-        incidence->addAttachment(attachment);
-        kDebug() << "ATTACHEMENT NAME" << name << type;
-    }
-}
-
-QByteArray ConversionUtils::getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype)
-{
-    KMime::Content *xmlContent = findContentByType( data, mimetype );
-    if ( xmlContent ) {
-        return xmlContent->decodedContent();
-    }
-    kDebug() << "document not found";
-    return QByteArray();
-}
-
-
-
-KCalCore::Incidence::Ptr ConversionUtils::eventFromMimeFile(const QString &mimeFileName)
-{
-    const KMime::Message::Ptr kolabItem = readMimeFile( mimeFileName );
-    KCalCore::Incidence::Ptr convertedIncidence = incidenceFromKolabImpl<KCalCore::Event::Ptr, KolabV2::Event>( kolabItem, QByteArray("application/x-vnd.kolab.event"), QString::fromLatin1("Europe/Berlin") );
-    return convertedIncidence;
-}
-
-QByteArray fromCid(const QString &cid)
-{
-    if (cid.left(4) != QString::fromLatin1("cid:")) { //Don't set if not a cid, happens when serializing format v2
-        return QByteArray();
-    }
-    return cid.right(cid.size()-4).toLatin1();
-}
-
-KMime::Message::Ptr ConversionUtils::createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml)
-{
-    KMime::Message::Ptr message = createMessage( xKolabType );
-    message->from()->addAddress( incidencePtr->organizer()->email().toUtf8(), incidencePtr->organizer()->name() );
-    message->subject()->fromUnicodeString( incidencePtr->uid(), "utf-8" );
-    
-    KMime::Content *content = createMainPart( mimetype, xml );
-    message->addContent( content );
-    
-    Q_FOREACH (KCalCore::Attachment::Ptr attachment, incidencePtr->attachments()) {
-        content = createAttachmentPart(fromCid(attachment->uri()), attachment->mimeType(), attachment->label(), attachment->decodedData() );
-        message->addContent( content );
-    }
-    
-    message->assemble();
-    return message;
-}
-
-KMime::Content* ConversionUtils::createExplanationPart()
-{
-    KMime::Content *content = new KMime::Content();
-    content->contentType()->setMimeType( "text/plain" );
-    content->contentType()->setCharset( "us-ascii" );
-    content->contentTransferEncoding()->setEncoding( KMime::Headers::CE7Bit );
-    content->setBody( "This is a Kolab Groupware object.\n"
-    "To view this object you will need an email client that can understand the Kolab Groupware format.\n"
-    "For a list of such email clients please visit\n"
-    "http://www.kolab.org/kolab2-clients.html\n" );
-    return content;
-}
-
-
-KMime::Message::Ptr ConversionUtils::createMessage(const QString& xKolabType)
-{
-    KMime::Message::Ptr message( new KMime::Message );
-    message->date()->setDateTime( KDateTime::currentLocalDateTime() );
-    KMime::Headers::Generic *h = new KMime::Headers::Generic( "X-Kolab-Type", message.get(), xKolabType, "utf-8" );
-    message->appendHeader( h );
-    message->userAgent()->from7BitString( "Akonadi Kolab Proxy Resource" );
-    message->contentType()->setMimeType( "multipart/mixed" );
-    message->contentType()->setBoundary( KMime::multiPartBoundary() );
-    
-    message->addContent( createExplanationPart() );
-    return message;
-}
-
-
-KMime::Content* ConversionUtils::createMainPart(const QString& mimeType, const QByteArray& decodedContent)
-{
-    KMime::Content* content = new KMime::Content();
-    content->contentType()->setMimeType( mimeType.toLatin1() );
-    content->contentType()->setName( "kolab.xml", "us-ascii" );
-    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr );
-    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
-    content->contentDisposition()->setFilename( "kolab.xml" );
-    content->setBody( decodedContent );
-    return content;
-}
-
-KMime::Content* ConversionUtils::createAttachmentPart(const QByteArray& cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent)
-{
-    KMime::Content* content = new KMime::Content();
-    if (!cid.isEmpty()) {
-        content->contentID()->setIdentifier( cid );
-    }
-    content->contentType()->setMimeType( mimeType.toLatin1() );
-    content->contentType()->setName( fileName, "us-ascii" );
-    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 );
-    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
-    content->contentDisposition()->setFilename( fileName );
-    content->setBody( decodedContent );
-    return content;
-}
-
-
-}
diff --git a/libkolab/kolabformatV2/kolabformatv2.h b/libkolab/kolabformatV2/kolabformatv2.h
deleted file mode 100644
index d6ec87f..0000000
--- a/libkolab/kolabformatV2/kolabformatv2.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KOLABFORMATv2_H
-#define KOLABFORMATv2_H
-
-#include "kolabv2_export.h"
-
-#include <kcalcore/incidence.h>
-#include <kcalcore/event.h>
-#include <akonadi/item.h>
-#include <kmime/kmime_message.h>
-#include <QtCore/qfile.h>
-#include "event.h"
-// #include <kolabhandler.h>
-
-namespace KolabV2 {
-    
-  class KOLABV2_EXPORT ConversionUtils {
-    public:
-        
-        static QString eventKolabType() { return QString::fromLatin1("application/x-vnd.kolab.event"); };
-        static QString todoKolabType() { return QString::fromLatin1("application/x-vnd.kolab.task"); };
-        static QString journalKolabType() { return QString::fromLatin1("application/x-vnd.kolab.journal"); };
-        static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
-    
-        //TODO Generic
-        static KMime::Message::Ptr readMimeFile( const QString &fileName );
-        //TODO Generic
-        static KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type);
-        //TODO Generic
-        static KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteArray &type);
-        
-        //TODO replace
-        static void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
-                                const KCalCore::Incidence::Ptr &incidence);
-        
-        //TODO Generic
-        static QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype);
-        
-        /**
-         * Get Attachments from a Mime message
-         * 
-         * Set the attachments listed in @param attachments on @param incidence from @param mimeData
-         */
-        //TODO Generic
-        static void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attachments, const KMime::Message::Ptr &mimeData)
-        {
-            foreach (const QString &name, attachments) {
-                QByteArray type;
-                KMime::Content *content = KolabV2::ConversionUtils::findContentByName(mimeData, name, type);
-                if (!content) { // guard against malformed events with non-existent attachments
-                    qWarning() << "could not find attachment: "<< name;
-                    continue;
-                }
-                const QByteArray c = content->decodedContent().toBase64();
-                KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
-                attachment->setLabel( name );
-                incidence->addAttachment(attachment);
-                kDebug() << "ATTACHEMENT NAME" << name << type;
-            }
-        }
-    
-        //TODO Generic
-        void setAttachments(KMime::Message::Ptr &mimeData, const KCalCore::Incidence::Ptr incidence)
-        {
-            
-        }
-        
-        
-        /**
-         * Parse XML, create KCalCore container and extract attachments
-         */
-        //TODO V2 specific
-        template <typename KCalPtr, typename Container>
-        static KCalPtr fromXML(const QByteArray &xmlData, QStringList &attachments)
-        {
-            const QDomDocument xmlDoc = KolabV2::KolabBase::loadDocument( QString::fromUtf8(xmlData) ); //TODO extract function from V2 format
-            Q_ASSERT ( !xmlDoc.isNull() );
-            const KCalPtr i = Container::fromXml( xmlDoc, QString() ); //For parsing we don't need the timezone, so we don't set one
-            Q_ASSERT ( i );
-            QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
-            for (int i = 0; i < nodes.size(); i++ ) {
-                attachments.append(nodes.at(i).toElement().text());
-            }
-            return i;
-        }
-        
-        //TODO V2 specific
-        template <typename IncidencePtr, typename Converter>
-        static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &data, const QByteArray &mimetype, const QString &timezoneId )
-        {
-            KMime::Content *xmlContent = findContentByType( data, mimetype );
-            if ( !xmlContent ) {
-                qWarning() << "couldn't find part";
-                return IncidencePtr();
-            }
-            const QByteArray xmlData = xmlContent->decodedContent();
-            
-            QStringList attachments;
-            IncidencePtr ptr = fromXML<IncidencePtr, Converter>(xmlData, attachments); //TODO do we care about timezone?
-            getAttachments(ptr, attachments, data);
-            
-            return ptr;
-//             KMime::Content *xmlContent = findContentByType( data, mimetype );
-//             if ( xmlContent ) {
-//                 const QByteArray xmlData = xmlContent->decodedContent();
-// //                 qDebug() << xmlData;
-//                 const QDomDocument xmlDoc = Converter::loadDocument( QString::fromUtf8(xmlData) );
-//                 if ( !xmlDoc.isNull() ) {
-//                     IncidencePtr i = Converter::fromXml( xmlDoc, timezoneId );
-//                     attachmentsFromKolab( data, xmlDoc, i );
-//                     return i;
-//                 }
-//             }
-// //             qDebug() << "empty";
-//             return IncidencePtr();
-        }
-        
-        
-        static KCalCore::Incidence::Ptr eventFromMimeFile(const QString &mimeFileName);
-        
-        
-        ///Generic serializing functions
-        static KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml);
-        
-        static KMime::Content* createExplanationPart();
-        static KMime::Message::Ptr createMessage(const QString& mimeType);
-        static KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent);
-        static KMime::Content* createAttachmentPart(const QByteArray &cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent);
-
-    };
-    
-}
-#endif
diff --git a/libkolab/kolabformatV2/note.h b/libkolab/kolabformatV2/note.h
index c88c659..3406ecc 100644
--- a/libkolab/kolabformatV2/note.h
+++ b/libkolab/kolabformatV2/note.h
@@ -36,7 +36,7 @@
 
 #include <kcalcore/journal.h>
 
-#include <kolabbase.h>
+#include "kolabbase.h"
 
 class QDomElement;
 
diff --git a/libkolab/kolabformatV2/task.h b/libkolab/kolabformatV2/task.h
index 148d164..487b98a 100644
--- a/libkolab/kolabformatV2/task.h
+++ b/libkolab/kolabformatV2/task.h
@@ -34,7 +34,7 @@
 #ifndef KOLABV2_TASK_H
 #define KOLABV2_TASK_H
 
-#include <incidence.h>
+#include "incidence.h"
 
 #include <kcalcore/todo.h>
 #include <kcalcore/incidence.h>
diff --git a/libkolab/mime/mimeutils.cpp b/libkolab/mime/mimeutils.cpp
new file mode 100644
index 0000000..e9587fd
--- /dev/null
+++ b/libkolab/mime/mimeutils.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mimeutils.h"
+#include <quuid.h>
+#include <QtCore/qfile.h>
+#include <qdom.h>
+#include <kdebug.h>
+
+namespace Kolab {
+    namespace Mime {
+
+KMime::Message::Ptr readMimeFile( const QString &fileName )
+{
+    //     qDebug() << fileName;
+    QFile file( fileName );
+    file.open( QFile::ReadOnly );
+    const QByteArray data = file.readAll();
+    Q_ASSERT( !data.isEmpty() );
+    
+    KMime::Message *msg = new KMime::Message;
+    msg->setContent( data );
+    msg->parse();
+    return KMime::Message::Ptr(msg);
+}
+
+KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteArray &type)
+{
+    const KMime::Content::List list = data->contents();
+    //     qDebug() << list.size();
+    Q_FOREACH(KMime::Content *c, list)
+    {
+        //         qDebug() << c->contentType()->mimeType() << type;
+        if (c->contentType()->mimeType() ==  type)
+            return c;
+    }
+    return 0;
+    
+}
+
+KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type)
+{
+    const KMime::Content::List list = data->contents();
+    Q_FOREACH(KMime::Content *c, list)
+    {
+        if ( c->contentType()->name() == name ) {
+            type = c->contentType()->mimeType();
+            return c;
+        }
+    }
+    return 0;
+    
+}
+
+
+//TODO repalce
+void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
+                                            const KCalCore::Incidence::Ptr &incidence)
+{
+    QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
+    for (int i = 0; i < nodes.size(); i++ ) {
+        const QString name = nodes.at(i).toElement().text();
+        QByteArray type;
+        KMime::Content *content = findContentByName(data, name, type);
+        if (!content) // guard against malformed events with non-existent attachments
+    continue;
+    const QByteArray c = content->decodedContent().toBase64();
+    KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
+    attachment->setLabel( name );
+    incidence->addAttachment(attachment);
+    kDebug() << "ATTACHEMENT NAME" << name << type;
+    }
+}
+
+QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype)
+{
+    KMime::Content *xmlContent = findContentByType( data, mimetype );
+    if ( xmlContent ) {
+        return xmlContent->decodedContent();
+    }
+    kDebug() << "document not found";
+    return QByteArray();
+}
+
+
+
+    
+QByteArray fromCid(const QString &cid)
+{
+    if (cid.left(4) != QString::fromLatin1("cid:")) { //Don't set if not a cid, happens when serializing format v2
+        return QByteArray();
+    }
+    return cid.right(cid.size()-4).toLatin1();
+}
+
+KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml)
+{
+    KMime::Message::Ptr message = createMessage( xKolabType );
+    message->from()->addAddress( incidencePtr->organizer()->email().toUtf8(), incidencePtr->organizer()->name() );
+    message->subject()->fromUnicodeString( incidencePtr->uid(), "utf-8" );
+    
+    KMime::Content *content = createMainPart( mimetype, xml );
+    message->addContent( content );
+    
+    Q_FOREACH (KCalCore::Attachment::Ptr attachment, incidencePtr->attachments()) {
+        content = createAttachmentPart(fromCid(attachment->uri()), attachment->mimeType(), attachment->label(), attachment->decodedData() );
+        message->addContent( content );
+    }
+    
+    message->assemble();
+    return message;
+}
+
+KMime::Content* createExplanationPart()
+{
+    KMime::Content *content = new KMime::Content();
+    content->contentType()->setMimeType( "text/plain" );
+    content->contentType()->setCharset( "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CE7Bit );
+    content->setBody( "This is a Kolab Groupware object.\n"
+    "To view this object you will need an email client that can understand the Kolab Groupware format.\n"
+    "For a list of such email clients please visit\n"
+    "http://www.kolab.org/kolab2-clients.html\n" );
+    return content;
+}
+
+
+KMime::Message::Ptr createMessage(const QString& xKolabType)
+{
+    KMime::Message::Ptr message( new KMime::Message );
+    message->date()->setDateTime( KDateTime::currentLocalDateTime() );
+    KMime::Headers::Generic *h = new KMime::Headers::Generic( "X-Kolab-Type", message.get(), xKolabType, "utf-8" );
+    message->appendHeader( h );
+    message->userAgent()->from7BitString( "Akonadi Kolab Proxy Resource" );
+    message->contentType()->setMimeType( "multipart/mixed" );
+    message->contentType()->setBoundary( KMime::multiPartBoundary() );
+    
+    message->addContent( createExplanationPart() );
+    return message;
+}
+
+
+KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent)
+{
+    KMime::Content* content = new KMime::Content();
+    content->contentType()->setMimeType( mimeType.toLatin1() );
+    content->contentType()->setName( "kolab.xml", "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr );
+    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
+    content->contentDisposition()->setFilename( "kolab.xml" );
+    content->setBody( decodedContent );
+    return content;
+}
+
+KMime::Content* createAttachmentPart(const QByteArray& cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent)
+{
+    KMime::Content* content = new KMime::Content();
+    if (!cid.isEmpty()) {
+        content->contentID()->setIdentifier( cid );
+    }
+    content->contentType()->setMimeType( mimeType.toLatin1() );
+    content->contentType()->setName( fileName, "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 );
+    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
+    content->contentDisposition()->setFilename( fileName );
+    content->setBody( decodedContent );
+    return content;
+}
+
+void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attachments, const KMime::Message::Ptr &mimeData)
+{
+    foreach (const QString &name, attachments) {
+        QByteArray type;
+        KMime::Content *content = findContentByName(mimeData, name, type);
+        if (!content) { // guard against malformed events with non-existent attachments
+                    qWarning() << "could not find attachment: "<< name;
+                    continue;
+        }
+        const QByteArray c = content->decodedContent().toBase64();
+        KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
+        attachment->setLabel( name );
+        incidence->addAttachment(attachment);
+        kDebug() << "ATTACHEMENT NAME" << name << type;
+    }
+}
+
+
+
+}; //Namespace
+}; //Namespace
diff --git a/libkolab/mime/mimeutils.h b/libkolab/mime/mimeutils.h
new file mode 100644
index 0000000..5a166ec
--- /dev/null
+++ b/libkolab/mime/mimeutils.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABMIMEUTILS_H
+#define KOLABMIMEUTILS_H
+
+#include "kolab_export.h"
+
+#include <kcalcore/incidence.h>
+#include <kcalcore/event.h>
+#include <kmime/kmime_message.h>
+class QDomDocument;
+
+namespace Kolab {
+    namespace Mime {
+
+//TODO Generic
+KMime::Message::Ptr readMimeFile( const QString &fileName );
+//TODO Generic
+KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type);
+//TODO Generic
+KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteArray &type);
+
+//TODO replace
+void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc, const KCalCore::Incidence::Ptr &incidence);
+
+//TODO Generic
+QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype);
+
+/**
+    * Get Attachments from a Mime message
+    * 
+    * Set the attachments listed in @param attachments on @param incidence from @param mimeData
+    */
+//TODO Generic
+void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attachments, const KMime::Message::Ptr &mimeData);
+
+
+///Generic serializing functions
+KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml);
+
+KMime::Content* createExplanationPart();
+KMime::Message::Ptr createMessage(const QString& mimeType);
+KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent);
+KMime::Content* createAttachmentPart(const QByteArray &cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent);
+
+    };
+}; //Namespace
+
+#endif
diff --git a/libkolab/tests/CMakeLists.txt b/libkolab/tests/CMakeLists.txt
new file mode 100644
index 0000000..fc724f6
--- /dev/null
+++ b/libkolab/tests/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+QT4_AUTOMOC(benchmark.cpp)
+add_executable(benchmarktest benchmark.cpp  ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
+target_link_libraries(benchmarktest ${QT_QTTEST_LIBRARY} kolab)
+
+# kolabformatV2 ${KOLABKCAL} ${KOLABXML} kcalcore kmime ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} kabc akonadi-kde ${KDE4_KIO_LIBRARY}
+# ../mime/mimeutils_p.h ../mime/mimeutils.cpp
\ No newline at end of file
diff --git a/libkolab/tests/benchmark.cpp b/libkolab/tests/benchmark.cpp
new file mode 100644
index 0000000..09d2bbf
--- /dev/null
+++ b/libkolab/tests/benchmark.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "benchmark.h"
+#include "kolabformatV2/event.h"
+#include "conversion/kcalconversion.h"
+#include <kmime/kmime_message.h>
+#include <kolab/kolabformat.h>
+#include <kdebug.h>
+
+KMime::Message::Ptr readMimeFile( const QString &fileName )
+{
+    QFile file( fileName );
+    file.open( QFile::ReadOnly );
+    const QByteArray data = file.readAll();
+    Q_ASSERT( !data.isEmpty() );
+    
+    KMime::Message *msg = new KMime::Message;
+    msg->setContent( data );
+    msg->parse();
+    return KMime::Message::Ptr(msg);
+}
+
+KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteArray &type)
+{
+    const KMime::Content::List list = data->contents();
+    Q_FOREACH(KMime::Content *c, list) {
+        if (c->contentType()->mimeType() ==  type)
+            return c;
+    }
+    return 0;
+    
+}
+
+void BenchmarkTests::parsingBenchmarkComparison_data()
+{
+    QTest::addColumn<bool>("v2Parser");
+    QTest::newRow("v2") << true;
+    QTest::newRow("v3") << false;
+}
+
+void BenchmarkTests::parsingBenchmarkComparison()
+{
+    const KMime::Message::Ptr kolabItem = readMimeFile( "../../../testfiles/v2/event/complex.ics.mime" );
+    KMime::Content *xmlContent = findContentByType( kolabItem, "application/x-vnd.kolab.event" );
+    QVERIFY ( xmlContent );
+    const QByteArray xmlData = xmlContent->decodedContent();
+    //     qDebug() << xmlData;
+    const QDomDocument xmlDoc = KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) );
+    QVERIFY ( !xmlDoc.isNull() );
+    const KCalCore::Event::Ptr i = KolabV2::Event::fromXml( xmlDoc, QString::fromLatin1("Europe/Berlin") );
+    QVERIFY ( i );
+    const Kolab::Event &event = Kolab::Conversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeEvent(event);
+    
+    QFETCH(bool, v2Parser);
+    
+    //     Kolab::readEvent(v3String, false); //init parser (doesn't really change the results it seems)
+    //     qDebug() << QString::fromUtf8(xmlData);
+    //     qDebug() << "------------------------------------------------------------------------------------";
+    //     qDebug() << QString::fromStdString(v3String);
+    if (v2Parser) {
+        QBENCHMARK {
+            KolabV2::Event::fromXml( KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) ), QString::fromLatin1("Europe/Berlin") );
+        }
+    } else {
+        QBENCHMARK {
+            Kolab::readEvent(v3String, false);
+        }
+    }
+}
+
+
+QTEST_MAIN( BenchmarkTests )
+
+#include "benchmark.moc"
diff --git a/libkolab/tests/benchmark.h b/libkolab/tests/benchmark.h
new file mode 100644
index 0000000..09184d7
--- /dev/null
+++ b/libkolab/tests/benchmark.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BENCHMARK_TEST_H
+#define BENCHMARK_TEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+class BenchmarkTests : public QObject
+{
+    Q_OBJECT
+private slots:
+    
+    
+    void parsingBenchmarkComparison_data();
+    void parsingBenchmarkComparison();
+    
+};
+
+#endif
diff --git a/libkolabkcal/kolabkcalconversion.cpp b/libkolabkcal/kolabkcalconversion.cpp
deleted file mode 100644
index bb1e0c3..0000000
--- a/libkolabkcal/kolabkcalconversion.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabkcalconversion.h"
-
-#include <kcalcore/recurrence.h>
-#include <QtCore/QBitArray>
-#include <QtCore/QVector>
-#include <QtCore/QDebug>
-#include <vector>
-#include <KDE/KSystemTimeZones>
-
-namespace Kolab {
-namespace KCalConversion {
-
-KDateTime toDate(const Kolab::cDateTime &dt)
-{
-    KDateTime date;
-    if (!dt.isValid()) {
-//         qDebug() << "invalid datetime converted";
-        return KDateTime();
-    }
-    if (dt.isDateOnly()) { //Date only
-        date.setDateOnly(true);
-        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
-    } else {
-        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
-        if (dt.isUTC()) { //UTC
-            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        } else if (!dt.timezone().empty()) { //Timezone
-            const KTimeZone &tz = KSystemTimeZones::zone(QString::fromStdString(dt.timezone())); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
-            if (!tz.isValid()) {
-                qWarning() << "timezone not found" << QString::fromStdString(dt.timezone());
-                if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
-                    qWarning() << "ktimezoned is not available and required for timezone interpretation";
-                }
-            }
-            date.setTimeSpec(KDateTime::Spec(tz));
-        } else { //Floating
-            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
-        }
-    }
-    Q_ASSERT(date.timeSpec().isValid());
-    Q_ASSERT(date.isValid());
-    return date;
-}
-
-cDateTime fromDate(const KDateTime &dt)
-{
-    if (!dt.isValid()) {
-//         qDebug() << "invalid datetime converted";
-        return cDateTime();
-    }
-    cDateTime date;
-    if (dt.isDateOnly()) { //Date only
-        const QDate &d = dt.date();
-        date.setDate(d.year(), d.month(), d.day());
-    } else {
-        const QDate &d = dt.date();
-        date.setDate(d.year(), d.month(), d.day());
-        const QTime &t = dt.time();
-        date.setTime(t.hour(), t.minute(), t.second());
-        if (dt.timeType() == KDateTime::UTC) { //UTC
-            date.setUTC(true);
-        } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
-            //TODO handle local timezone?
-            date.setTimezone(dt.timeZone().name().toStdString()); //FIXME use system independent name according to spec
-        } else if (dt.timeType() != KDateTime::ClockTime) {
-            qWarning() << "invalid timespec, assuming floating time" << dt.timeType();
-            return cDateTime();
-        }
-    }
-    Q_ASSERT(date.isValid());
-    return date;
-}
-
-KCalCore::Duration toDuration(const Kolab::Duration &d)
-{
-    //TODO should we support negative durations?
-    if (d.hours() || d.minutes() || d.seconds()) {
-        return KCalCore::Duration(((((d.weeks() * 7 + d.days()) * 24 + d.hours()) * 60 + d.minutes()) * 60 + d.seconds()));
-    }
-    return KCalCore::Duration(d.weeks() * 7 + d.days(), KCalCore::Duration::Days);
-}
-
-Kolab::Duration fromDuration(const KCalCore::Duration &d)
-{
-    if (d.value() <= 0) {
-        return Kolab::Duration();
-    }
-    //We don't know how the seconds/days were distributed before, so no point in distributing them (probably)
-    //TODO should we support negative durations?
-    if (d.isDaily()) {
-        int days = d.value();
-        return Kolab::Duration(days, 0, 0, 0, false);
-    }
-    int seconds = d.value();
-//         int minutes = seconds / 60;
-//         seconds = seconds % 60;
-//         int hours = minutes / 60;
-//         minutes = minutes % 60;
-    return Kolab::Duration(0, 0, 0, seconds, false);
-
-}
-
-KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
-{
-    switch(c) {
-        case Kolab::ClassPublic:
-            return KCalCore::Incidence::SecrecyPublic;
-        case Kolab::ClassPrivate:
-            return KCalCore::Incidence::SecrecyPrivate;
-        case Kolab::ClassConfidential:
-            return KCalCore::Incidence::SecrecyConfidential;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Incidence::SecrecyPublic;
-}
-
-Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
-{
-    switch(c) {
-        case KCalCore::Incidence::SecrecyPublic:
-            return Kolab::ClassPublic;
-        case KCalCore::Incidence::SecrecyPrivate:
-            return Kolab::ClassPrivate;
-        case KCalCore::Incidence::SecrecyConfidential:
-            return Kolab::ClassConfidential;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::ClassPublic;
-}
-
-int toPriority(int priority)
-{
-    //Same mapping
-    return priority;
-}
-
-int fromPriority(int priority)
-{
-    //Same mapping
-    return priority;
-}
-
-KCalCore::Incidence::Status toStatus(Kolab::Status s)
-{
-    switch (s) {
-        case StatusUndefined:
-            return  KCalCore::Incidence::StatusNone;
-        case StatusNeedsAction:
-            return  KCalCore::Incidence::StatusNeedsAction;
-        case StatusCompleted:
-            return  KCalCore::Incidence::StatusCompleted;
-        case StatusInProcess:
-            return  KCalCore::Incidence::StatusInProcess;
-        case StatusCancelled:
-            return  KCalCore::Incidence::StatusCanceled;
-        case StatusTentative:
-            return  KCalCore::Incidence::StatusTentative;
-        case StatusConfirmed:
-            return  KCalCore::Incidence::StatusConfirmed;
-        case StatusDraft:
-            return  KCalCore::Incidence::StatusDraft;
-        case StatusFinal:
-            return  KCalCore::Incidence::StatusFinal;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Incidence::StatusNone;
-}
-
-Kolab::Status fromStatus(KCalCore::Incidence::Status s)
-{
-    switch (s) {
-        case KCalCore::Incidence::StatusNone:
-            return StatusUndefined;
-        case KCalCore::Incidence::StatusNeedsAction:
-            return StatusNeedsAction;
-        case KCalCore::Incidence::StatusCompleted:
-            return StatusCompleted;
-        case KCalCore::Incidence::StatusInProcess:
-            return StatusInProcess;
-        case KCalCore::Incidence::StatusCanceled:
-            return StatusCancelled;
-        case KCalCore::Incidence::StatusTentative:
-            return StatusTentative;
-        case KCalCore::Incidence::StatusConfirmed:
-            return StatusConfirmed;
-        case KCalCore::Incidence::StatusDraft:
-            return StatusDraft;
-        case KCalCore::Incidence::StatusFinal:
-            return StatusFinal;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return StatusUndefined;
-}
-
-QStringList toStringList(const std::vector<std::string> &l)
-{
-    QStringList list;
-    foreach(const std::string &s, l) {
-        list.append(QString::fromStdString(s));
-    }
-    return list;
-}
-
-std::vector<std::string> fromStringList(const QStringList &l)
-{
-    std::vector<std::string> list;
-    foreach(const QString &s, l) {
-        list.push_back(s.toStdString());
-    }
-    return list;
-}
-
-KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
-{
-    switch (p) {
-        case PartNeedsAction:
-            return KCalCore::Attendee::NeedsAction;
-        case PartAccepted:
-            return KCalCore::Attendee::Accepted;
-        case PartDeclined:
-            return KCalCore::Attendee::Declined;
-        case PartTentative:
-            return KCalCore::Attendee::Tentative;
-        case PartDelegated:
-            return KCalCore::Attendee::Delegated;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Attendee::NeedsAction;
-}
-
-Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
-{
-    switch (p) {
-        case KCalCore::Attendee::NeedsAction:
-            return PartNeedsAction;
-        case KCalCore::Attendee::Accepted:
-            return PartAccepted;
-        case KCalCore::Attendee::Declined:
-            return PartDeclined;
-        case KCalCore::Attendee::Tentative:
-            return PartTentative;
-        case KCalCore::Attendee::Delegated:
-            return PartDelegated;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return PartNeedsAction;
-}
-
-KCalCore::Attendee::Role toRole(Kolab::Role r)
-{
-    switch (r) {
-        case Required:
-            return KCalCore::Attendee::ReqParticipant;
-        case Chair:
-            return KCalCore::Attendee::Chair;
-        case Optional:
-            return KCalCore::Attendee::OptParticipant;
-        case NonParticipant:
-            return KCalCore::Attendee::NonParticipant;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Attendee::ReqParticipant;
-}
-
-Kolab::Role fromRole(KCalCore::Attendee::Role r)
-{
-    switch (r) {
-        case KCalCore::Attendee::ReqParticipant:
-            return Required;
-        case KCalCore::Attendee::Chair:
-            return Chair;
-        case KCalCore::Attendee::OptParticipant:
-            return Optional;
-        case KCalCore::Attendee::NonParticipant:
-            return NonParticipant;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Required;
-}
-
-template <typename T>
-void setIncidence(KCalCore::Incidence &i, const T &e)
-{
-    if (!e.uid().empty()) {
-        i.setUid(QString::fromStdString(e.uid()));
-    }
-    
-    i.setCreated(toDate(e.created()));
-    i.setLastModified(toDate(e.lastModified()));
-    i.setRevision(e.sequence());
-    i.setSecrecy(toSecrecy(e.classification()));
-    i.setCategories(toStringList(e.categories()));
-    
-    if (e.start().isValid()) {
-        i.setDtStart(toDate(e.start()));
-    }
-
-    i.setSummary(QString::fromStdString(e.summary())); //TODO detect richtext
-    i.setDescription(QString::fromStdString(e.description())); //TODO detect richtext
-    i.setStatus(toStatus(e.status()));
-    foreach (const Kolab::Attendee a, e.attendees()) {
-        //We shouldn't rely on a uid if we're going with mail+name and not on mail+name if we're going with UID (of ical btw. and not kaddresee)
-        i.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(QString::fromStdString(a.contact().name()), 
-                                                                     QString::fromStdString(a.contact().email()),  //TODO handle uid
-                                                                     a.rsvp(),
-                                                                     toPartStat(a.partStat()),
-                                                                     toRole(a.role()) ))); //FIXME doesn't make sense to set both, either email or uid
-    }
-    foreach (const Kolab::Attachment a, e.attachments()) {
-        KCalCore::Attachment::Ptr ptr;
-        if (!a.uri().empty()) {
-            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString::fromStdString(a.uri()), QString::fromStdString(a.mimetype())));
-        } else {
-            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), QString::fromStdString(a.mimetype())));
-        }
-        if (!a.label().empty()) {
-            ptr->setLabel(QString::fromStdString(a.label()));
-        }
-        i.addAttachment(ptr);
-    }
-//     i.addAlarm(); //TODO
-//     i.setCustomProperties(); //TODO
-}
-
-template <typename T, typename I>
-void getIncidence(T &i, const I &e)
-{
-    i.setUid(e.uid().toStdString());
-    i.setCreated(fromDate(e.created()));
-    i.setLastModified(fromDate(e.lastModified()));
-    i.setSequence(e.revision());
-    i.setClassification(fromSecrecy(e.secrecy()));
-    i.setCategories(fromStringList(e.categories()));
-    
-    i.setStart(fromDate(e.dtStart()));
-    i.setSummary(e.summary().toStdString());
-    i.setDescription(e.description().toStdString());
-    i.setStatus(fromStatus(e.status()));
-    std::vector<Kolab::Attendee> attendees;
-    foreach (const KCalCore::Attendee::Ptr ptr, e.attendees()) {
-        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference, ptr->email().toStdString(), ptr->name().toStdString())); //TODO handle uid
-        a.setRSVP(ptr->RSVP());
-        a.setPartStat(fromPartStat(ptr->status()));
-        a.setRole(fromRole(ptr->role()));
-//         a.setUid(ptr->uid().toStdString()); //TODO
-        attendees.push_back(a);
-    }
-    i.setAttendees(attendees);
-    std::vector<Kolab::Attachment> attachments;
-    foreach (const KCalCore::Attachment::Ptr ptr, e.attachments()) {
-        Kolab::Attachment a;
-        if (ptr->isUri()) {
-            a.setUri(ptr->uri().toStdString(), ptr->mimeType().toStdString());
-        } else {
-            a.setData(std::string(ptr->decodedData().data(), ptr->decodedData().size()), ptr->mimeType().toStdString());
-        }
-        a.setLabel(ptr->label().toStdString());
-        attachments.push_back(a);
-    }
-    i.setAttachments(attachments);
-    //TODO alarms
-    //TODO custom properties
-}
-
-int toWeekDay(Kolab::Weekday wday)
-{
-    switch (wday) {
-        case Kolab::Monday:
-            return  1;
-        case Kolab::Tuesday:
-            return 2;
-        case Kolab::Wednesday:
-            return 3;
-        case Kolab::Thursday:
-            return 4;
-        case Kolab::Friday:
-            return 5;
-        case Kolab::Saturday:
-            return 6;
-        case Kolab::Sunday:
-            return 7;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return 1;
-}
-
-Kolab::Weekday fromWeekDay(int wday)
-{
-    switch (wday) {
-        case 1:
-            return Kolab::Monday;
-        case 2:
-            return Kolab::Tuesday;
-        case 3:
-            return Kolab::Wednesday;
-        case 4:
-            return Kolab::Thursday;
-        case 5:
-            return Kolab::Friday;
-        case 6:
-            return Kolab::Saturday;
-        case 7:
-            return Kolab::Sunday;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::Monday;
-}
-
-KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
-{
-    switch(freq) {
-        case Kolab::RecurrenceRule::FreqNone:
-            qWarning() << "no recurrence?";
-            break;
-        case Kolab::RecurrenceRule::Yearly:
-            return KCalCore::RecurrenceRule::rYearly;
-        case Kolab::RecurrenceRule::Monthly:
-            return KCalCore::RecurrenceRule::rMonthly;
-        case Kolab::RecurrenceRule::Weekly:
-            return KCalCore::RecurrenceRule::rWeekly;
-        case Kolab::RecurrenceRule::Daily:
-            return KCalCore::RecurrenceRule::rDaily;
-        case Kolab::RecurrenceRule::Hourly:
-            return KCalCore::RecurrenceRule::rHourly;
-        case Kolab::RecurrenceRule::Minutely:
-            return KCalCore::RecurrenceRule::rMinutely;
-        case Kolab::RecurrenceRule::Secondly:
-            return KCalCore::RecurrenceRule::rSecondly;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::RecurrenceRule::rNone;
-}
-
-Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
-{
-    switch(freq) {
-        case KCalCore::RecurrenceRule::rNone:
-            qWarning() << "no recurrence?";
-            break;
-        case KCalCore::RecurrenceRule::rYearly:
-            return Kolab::RecurrenceRule::Yearly;
-        case KCalCore::RecurrenceRule::rMonthly:
-            return Kolab::RecurrenceRule::Monthly;
-        case KCalCore::RecurrenceRule::rWeekly:
-            return Kolab::RecurrenceRule::Weekly;
-        case KCalCore::RecurrenceRule::rDaily:
-            return Kolab::RecurrenceRule::Daily;
-        case KCalCore::RecurrenceRule::rHourly:
-            return Kolab::RecurrenceRule::Hourly;
-        case KCalCore::RecurrenceRule::rMinutely:
-            return Kolab::RecurrenceRule::Minutely;
-        case KCalCore::RecurrenceRule::rSecondly:
-            return Kolab::RecurrenceRule::Secondly;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::RecurrenceRule::FreqNone;
-}
-
-KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
-{
-    return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday()));
-}
-
-Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
-{
-    return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()));
-}
-
-template <typename T>
-void setRecurrence(KCalCore::Incidence &e, const T &event)
-{
-    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
-    if (rrule.isValid()) {
-        KCalCore::Recurrence *rec = e.recurrence();
-        
-        KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
-        Q_ASSERT(defaultRR);
-        
-        defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
-        defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
-        defaultRR->setFrequency(rrule.interval());
-        
-        if (rrule.end().isValid()) {
-            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
-        } else {
-            rec->setDuration(rrule.count());
-        }
-        
-        if (!rrule.bysecond().empty()) {
-            defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
-        }
-        if (!rrule.byminute().empty()) {
-            defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
-        }
-        if (!rrule.byhour().empty()) {
-            defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
-        }
-        if (!rrule.byday().empty()) {
-            QList<KCalCore::RecurrenceRule::WDayPos> daypos;
-            foreach(const Kolab::DayPos &dp, rrule.byday()) {
-                daypos.append(toWeekDayPos(dp));
-            }
-            defaultRR->setByDays(daypos);
-        }
-        if (!rrule.bymonthday().empty()) {
-            defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
-        }
-        if (!rrule.byyearday().empty()) {
-            defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
-        }
-        if (!rrule.byweekno().empty()) {
-            defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
-        }
-        if (!rrule.bymonth().empty()) {
-            defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
-        }
-    }
-    foreach (const Kolab::cDateTime &dt, event.recurrenceDates()) {
-        const KDateTime &date = toDate(dt);
-        if (date.isDateOnly()) {
-            e.recurrence()->addRDate(date.date());
-        } else {
-            e.recurrence()->addRDateTime(date);
-        }
-    }
-    foreach (const Kolab::cDateTime &dt, event.exceptionDates()) {
-        const KDateTime &date = toDate(dt);
-        if (date.isDateOnly()) {
-            e.recurrence()->addExDate(date.date());
-        } else {
-            e.recurrence()->addExDateTime(date);
-        }
-    }
-
-}
-
-template <typename T, typename I>
-void getRecurrence(T &i, const I &e)
-{
-    if (!e.recurs()) {
-        return;
-    }
-    KCalCore::Recurrence *rec = e.recurrence();
-    KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
-    if (!defaultRR) {
-        qWarning() << "no recurrence";
-        return;
-    }
-    Q_ASSERT(defaultRR);
-
-    Kolab::RecurrenceRule rrule;
-    rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
-    rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
-    rrule.setInterval(defaultRR->frequency());
-  
-    if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
-        if (defaultRR->duration() > 0) {
-            rrule.setCount(defaultRR->duration());
-        }
-    } else {
-        rrule.setEnd(fromDate(defaultRR->endDt()));
-    }
-    
-    rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
-    rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
-    rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
-    
-    std::vector<Kolab::DayPos> daypos;
-    foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
-        daypos.push_back(fromWeekDayPos(dp));
-    }
-    rrule.setByday(daypos);
-    
-    rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
-    rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
-    rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
-    rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
-    i.setRecurrenceRule(rrule);
-    
-    std::vector<Kolab::cDateTime> rdates;
-    foreach (const KDateTime &dt, rec->rDateTimes()) {
-        rdates.push_back(fromDate(dt));
-    }
-    foreach (const QDate &dt, rec->rDates()) {
-        rdates.push_back(fromDate(KDateTime(dt)));
-    }
-    i.setRecurrenceDates(rdates);
-    
-    std::vector<Kolab::cDateTime> exdates;
-    foreach (const KDateTime &dt, rec->exDateTimes()) {
-        exdates.push_back(fromDate(dt));
-    }
-    foreach (const QDate &dt, rec->exDates()) {
-        exdates.push_back(fromDate(KDateTime(dt)));
-    }
-    i.setExceptionDates(exdates);
-    
-    if (!rec->exRules().empty()) {
-        qWarning() << "exrules are not supported";
-    }
-}
-
-template <typename T>
-void setTodoEvent(KCalCore::Incidence &i, const T &e)
-{
-    i.setPriority(toPriority(e.priority()));
-    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
-    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizer().name()), QString::fromStdString(e.organizer().email())))); //TODO handle uid too
-    if (e.recurrenceID().isValid()) {
-        i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
-    }
-    setRecurrence(i, e);
-}
-
-template <typename T, typename I>
-void getTodoEvent(T &i, const I &e)
-{
-    i.setPriority(fromPriority(e.priority()));
-    i.setLocation(e.location().toStdString());
-    i.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, e.organizer()->email().toStdString(), e.organizer()->name().toStdString())); //TODO handle uid too
-    i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
-    getRecurrence(i, e);
-}
-
-KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
-{
-    KCalCore::Event::Ptr e(new KCalCore::Event);
-    setIncidence(*e, event);
-    setTodoEvent(*e, event);
-    if (event.end().isValid()) {
-        e->setDtEnd(toDate(event.end()));
-    }
-    if (event.duration().isValid()) {
-        e->setDuration(toDuration(event.duration()));
-    }
-    if (event.transparency()) {
-        e->setTransparency(KCalCore::Event::Transparent);
-    } else {
-        e->setTransparency(KCalCore::Event::Opaque);
-    }
-    return e;
-}
-
-Event fromKCalCore(const KCalCore::Event &event)
-{
-    Event e;
-    getIncidence(e, event);
-    getTodoEvent(e, event);
-    if (event.hasEndDate()) {
-        e.setEnd(fromDate(event.dtEnd()));
-    } else if (event.hasDuration()) {
-        e.setDuration(fromDuration(event.duration()));
-    }
-    if (event.transparency() == KCalCore::Event::Transparent) {
-        e.setTransparency(true);
-    } else {
-        e.setTransparency(false);
-    }
-    return e;
-}
-
-
-
-KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
-{
-    KCalCore::Todo::Ptr e(new KCalCore::Todo);
-    setIncidence(*e, todo);
-    setTodoEvent(*e, todo);
-    if (todo.due().isValid()) {
-        e->setDtDue(toDate(todo.due()));
-    }
-    return e;
-}
-
-Todo fromKCalCore ( const KCalCore::Todo &todo )
-{
-    Todo t;
-    getIncidence(t, todo);
-    getTodoEvent(t, todo);
-    t.setDue(fromDate(todo.dtDue(true)));
-    return t;
-}
-
-KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
-{
-    KCalCore::Journal::Ptr e(new KCalCore::Journal);
-    setIncidence(*e, journal);
-    //TODO contacts
-    return e;
-}
-
-Journal fromKCalCore ( const KCalCore::Journal &journal )
-{
-    Journal j;
-    getIncidence(j, journal);
-    //TODO contacts
-    return j;
-}
-
-
-
-}
-}
\ No newline at end of file
diff --git a/libkolabkcal/kolabkcalconversion.h b/libkolabkcal/kolabkcalconversion.h
deleted file mode 100644
index fe1ae04..0000000
--- a/libkolabkcal/kolabkcalconversion.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABKCALCONVERSION_H
-#define KOLABKCALCONVERSION_H
-
-#include <kolab/kolabevent.h>
-#include <kolab/kolabtodo.h>
-#include <kolab/kolabjournal.h>
-#include <kcalcore/event.h>
-#include <kcalcore/todo.h>
-#include <kcalcore/journal.h>
-
-namespace Kolab {
-    /**
-     * Conversion of Kolab-Containers to/from KCalCore Containers.
-     *
-     * TODO: There is no error handling other than qWarning used so far.
-     */
-    namespace KCalConversion {
-
-        KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
-        Kolab::Event fromKCalCore(const KCalCore::Event &);
-
-        KCalCore::Todo::Ptr toKCalCore(const Kolab::Todo &);
-        Kolab::Todo fromKCalCore(const KCalCore::Todo &);
-
-        KCalCore::Journal::Ptr toKCalCore(const Kolab::Journal &);
-        Kolab::Journal fromKCalCore(const KCalCore::Journal &);
-
-        KDateTime toDate(const Kolab::cDateTime &dt);
-        cDateTime fromDate(const KDateTime &dt);
-
-    };
-};
-
-#endif
\ No newline at end of file
diff --git a/libkolabkcal/tests/CMakeLists.txt b/libkolabkcal/tests/CMakeLists.txt
deleted file mode 100644
index 9340bad..0000000
--- a/libkolabkcal/tests/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
-
-QT4_AUTOMOC(kcalconversiontest.cpp)
-add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabkcal ${XERCES_C})
-
diff --git a/libkolabkcal/tests/kcalconversiontest.cpp b/libkolabkcal/tests/kcalconversiontest.cpp
deleted file mode 100644
index b6549c8..0000000
--- a/libkolabkcal/tests/kcalconversiontest.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-#include "kcalconversiontest.h"
-
-#include <QtCore/QObject>
-#include <QtTest/QtTest>
-#include <KDE/KSystemTimeZones>
-#include <kcalcore/recurrence.h>
-
-#include "kolabkcalconversion.h"
-#include "kolabkcalconversion.cpp"
-// #include <lib/calendaring.h>
-
-// #include "serializers.h"
-
-using namespace Kolab::KCalConversion;
-
-Q_DECLARE_METATYPE(Kolab::Duration);
-Q_DECLARE_METATYPE(Kolab::cDateTime);
-Q_DECLARE_METATYPE(Kolab::Event);
-Q_DECLARE_METATYPE(Kolab::Todo);
-Q_DECLARE_METATYPE(Kolab::Journal);
-Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
-Q_DECLARE_METATYPE(KCalCore::Event);
-Q_DECLARE_METATYPE(KCalCore::Todo);
-Q_DECLARE_METATYPE(KCalCore::Journal);
-Q_DECLARE_METATYPE(KCalCore::Duration);
-
-namespace QTest {
-    
-    template<>
-    char *toString(const KDateTime &dt)
-    {
-        QByteArray ba = "KDateTime(";
-        ba += dt.toString().toAscii();
-        ba += dt.timeZone().name();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Attendee &at)
-    {
-        QByteArray ba = "Attendee(";
-        ba += at.name().toAscii() + ", ";
-        ba += at.email().toAscii() + ", ";
-        ba += QString::number(at.role()) + ", ";
-        ba += QString::number(at.status()) + ", ";
-        ba += QString::number(at.RSVP()) + ", ";
-        ba += at.delegate().toAscii() + ", ";
-        ba += at.delegator().toAscii() + ", ";
-        ba += at.uid().toAscii() + ", ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    
-    template<>
-    char *toString(const QList<int> &l)
-    {
-        QByteArray ba = "QList<int>(";
-        foreach(int i, l) {
-            ba += QString::number(i) + ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const QList<KCalCore::RecurrenceRule::WDayPos> &l)
-    {
-        QByteArray ba = "QList<int>(";
-        foreach(const KCalCore::RecurrenceRule::WDayPos &i, l) {
-            ba += QString::number(i.pos()) + " ";
-            ba += QString::number(i.day()) + ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::DateList &l)
-    {
-        QByteArray ba = "KCalCore::DateList(";
-        foreach(const QDate &i, l) {
-            ba += i.toString();
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::DateTimeList &l)
-    {
-        QByteArray ba = "KCalCore::DateTimeList(";
-        foreach(const KDateTime &i, l) {
-            ba += toString(i);
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Recurrence &at)
-    {
-        at.dump();
-        KCalCore::RecurrenceRule *r = at.defaultRRule();
-        QByteArray ba;
-        if (!r) {
-            ba += "Recurrence( )";
-        } else {
-            Q_ASSERT(r);
-            Q_ASSERT(at.rRules().size() == 1);
-            
-            ba += "Recurrence(";
-            ba += QString::number(r->recurrenceType()) + "\n";
-            ba += QString::number(r->frequency()) + "\n";
-            ba += QString::number(r->duration()) + "\n";
-            ba += QByteArray(toString(r->startDt())) + "\n";
-            ba += QByteArray(toString(r->endDt())) + "\n";
-            ba += QByteArray(toString(r->bySeconds())) + "\n";
-            ba += QByteArray(toString(r->byMinutes())) + "\n";
-            ba += QByteArray(toString(r->byHours())) + "\n";
-            ba += QByteArray(toString(r->byDays())) + "\n";
-            ba += QByteArray(toString(r->byMonthDays())) + "\n";
-            ba += QByteArray(toString(r->byYearDays())) + "\n";
-            ba += QByteArray(toString(r->byMonths())) + "\n";
-            ba += ")\n";
-            ba += QByteArray(toString(at.exDates())) + "\n";
-            ba += QByteArray(toString(at.exDateTimes())) + "\n";
-            ba += QByteArray(toString(at.rDates())) + "\n";
-            ba += QByteArray(toString(at.rDateTimes())) + "\n";
-            
-        }
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::RecurrenceRule &at)
-    {
-        QByteArray ba;
-        ba += "KolabRecurrenceRule(";
-        ba += QString::number(at.weekStart()) + "\n";
-        ba += QString::number(at.frequency()) + "\n";
-        ba += QString::number(at.interval()) + "\n";
-        ba += QString::number(at.count()) + "\n";
-        ba += QByteArray(toString(at.end())) + "\n";
-        ba += QByteArray(toString(at.bysecond())) + "\n";
-        ba += QByteArray(toString(at.byminute())) + "\n";
-        ba += QByteArray(toString(at.byhour())) + "\n";
-        ba += QByteArray(toString(at.byday())) + "\n";
-        ba += QByteArray(toString(at.bymonthday())) + "\n";
-        ba += QByteArray(toString(at.byyearday())) + "\n";
-        ba += QByteArray(toString(at.byweekno())) + "\n";
-        ba += QByteArray(toString(at.bymonth())) + "\n";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Duration &d)
-    {
-        QByteArray ba;
-        ba += "KCalCore::Duration(";
-        ba += QString::number(d.isDaily()) + ", ";
-        ba += QString::number(d.value()) + " ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-
-}
-
-template <typename T>
-void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
-{
-    QCOMPARE(list.size(), other.size());
-    for (int i = 0 ; i < list.size(); i++) {
-        QCOMPARE(*list.at(i), *other.at(i));
-    }
-}
-
-
-void KCalConversionTest::testDate_data()
-{
-    QTest::addColumn<Kolab::cDateTime>( "input" );
-    QTest::addColumn<KDateTime>( "result" );
-
-    QTest::newRow( "datetime with tz" ) << Kolab::cDateTime("Europe/Zurich",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Zurich"));
-    QTest::newRow( "floating datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, false) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::Spec(KDateTime::ClockTime));
-    QTest::newRow( "utc datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, true) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
-    QTest::newRow( "date only" ) << Kolab::cDateTime(2006,1,8) << KDateTime(QDate(2006, 1, 8));
-}
-
-
-void KCalConversionTest::testDate()
-{
-    QFETCH(Kolab::cDateTime, input);
-    QFETCH(KDateTime, result);
-    
-    const KDateTime &r = Kolab::KCalConversion::toDate(input);
-    QCOMPARE(r, result);
-    
-    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
-    QCOMPARE(r2, input);
-}
-
-void KCalConversionTest::testDuration_data()
-{
-    QTest::addColumn<Kolab::Duration>( "input" );
-    QTest::addColumn<KCalCore::Duration>( "result" );
-    QTest::addColumn<Kolab::Duration>( "fromResult" );
-    
-    QTest::newRow( "seconds" ) << Kolab::Duration(0,0,0,30,false) << KCalCore::Duration(30, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,30,false);
-    QTest::newRow( "minutes" ) << Kolab::Duration(0,0,1,30,false) << KCalCore::Duration(90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,90,false);
-    QTest::newRow( "hours" ) << Kolab::Duration(0,1,1,30,false) << KCalCore::Duration(60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,60*60+90,false);
-    QTest::newRow( "days" ) << Kolab::Duration(1,1,1,30,false) << KCalCore::Duration(24*60*60+60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,24*60*60+60*60+90,false);
-    QTest::newRow( "daysonly" ) << Kolab::Duration(30,0,0,0, false) << KCalCore::Duration(30, KCalCore::Duration::Days) << Kolab::Duration(30,0,0,0,false);
-    QTest::newRow( "weeks" ) << Kolab::Duration(30,false) << KCalCore::Duration(30*7, KCalCore::Duration::Days) << Kolab::Duration(30*7,0,0,0,false);
-}
-
-
-void KCalConversionTest::testDuration()
-{
-    QFETCH(Kolab::Duration, input);
-    QFETCH(KCalCore::Duration, result);
-    QFETCH(Kolab::Duration, fromResult);
-    
-    const KCalCore::Duration &r = Kolab::KCalConversion::toDuration(input);
-    QCOMPARE(r, result);
-    
-    const Kolab::Duration &r2 = Kolab::KCalConversion::fromDuration(result);
-    QCOMPARE(r2, fromResult);
-}
-
-
-void KCalConversionTest::testDateTZ_data()
-{
-    QTest::addColumn<Kolab::cDateTime>( "input" );
-    QTest::addColumn<KDateTime>( "result" );
-    QTest::addColumn<int>( "offset" );
-       
-    QTest::newRow( "berlin" ) << Kolab::cDateTime("Europe/Berlin",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Berlin")) << 3600;
-}
-
-void KCalConversionTest::testDateTZ()
-{
-    QFETCH(Kolab::cDateTime, input);
-    QFETCH(KDateTime, result);
-    QFETCH(int, offset);
-    
-    const KDateTime &r = Kolab::KCalConversion::toDate(input);
-    QCOMPARE(result.timeZone().name(), QString::fromStdString(input.timezone()));
-    QCOMPARE(r.timeZone().currentOffset(), offset);
-    
-    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
-    QCOMPARE(QString::fromStdString(r2.timezone()), result.timeZone().name());
-}
-
-
-void KCalConversionTest::testConversion_data()
-{
-    QTest::addColumn<KCalCore::Event>( "kcal" );
-    QTest::addColumn<Kolab::Event>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    Kolab::cDateTime date3(2012,2,2,12,12,10);
-    std::vector<int> intVector;
-    intVector.push_back(1);
-    intVector.push_back(-3);
-    intVector.push_back(2);
-    std::vector<std::string> stringVector;
-    stringVector.push_back("cat1");
-    stringVector.push_back("cat2");
-    stringVector.push_back("parent/child");
-    
-    {
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setRevision(3);
-        kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
-        kcal.setCategories(toStringList(stringVector));
-        kcal.setDtStart(toDate(date));
-        kcal.setDtEnd(toDate(date2));
-        kcal.setTransparency(KCalCore::Event::Transparent);
-        
-        kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setDuration(5);
-        kcal.recurrence()->addRDateTime(toDate(date2));
-        kcal.recurrence()->addRDate(toDate(date2).date());
-        kcal.recurrence()->addExDateTime(toDate(date3));
-        kcal.recurrence()->addExDate(toDate(date3).date());
-        
-        KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
-        QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
-        rr->setBySeconds(intList);
-        rr->setByMinutes(intList);
-        rr->setByHours(intList);
-        rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,1) << KCalCore::RecurrenceRule::WDayPos(5,4));
-        rr->setByMonthDays(intList);
-        rr->setByYearDays(intList);
-        rr->setByMonths(intList);
-        rr->setByWeekNumbers(intList);
-        
-        kcal.setSummary("summary");
-        kcal.setDescription("description");
-        kcal.setPriority(3);
-        kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
-        kcal.setLocation("location");
-        kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
-        kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant)));
-        //TODO KCalCore Delegate/Delegator
-        kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
-        KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
-        KCalCore::Person::List addressees;
-        addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
-        alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
-        kcal.addAlarm(alarm);
-        //TODO alarms
-        //TODO custom properties
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setSequence(3);
-        kolab.setClassification(Kolab::ClassConfidential);
-        kolab.setCategories(stringVector);
-        kolab.setStart(date);
-        kolab.setEnd(date2);
-        kolab.setTransparency(true);
-        
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setCount(5);
-        rrule.setBysecond(intVector);
-        rrule.setByminute(intVector);
-        rrule.setByhour(intVector);
-        rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
-        rrule.setBymonthday(intVector);
-        rrule.setByyearday(intVector);
-        rrule.setByweekno(intVector);
-        rrule.setBymonth(intVector);
-        
-        kolab.setRecurrenceRule(rrule);
-        kolab.setRecurrenceID(date2, true);
-        kolab.setRecurrenceDates(std::vector<Kolab::cDateTime>() << date2 << Kolab::cDateTime(date2.year(), date2.month(), date2.day()));
-        kolab.setExceptionDates(std::vector<Kolab::cDateTime>() << date3 << Kolab::cDateTime(date3.year(), date3.month(), date3.day()));
-        
-        kolab.setSummary("summary");
-        kolab.setDescription("description");
-        kolab.setPriority(3);
-        kolab.setStatus(Kolab::StatusConfirmed);
-        kolab.setLocation("location");
-        kolab.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"organizer at email", "organizer")); //TODO uid
-        
-        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"attendee at email", "attendee"));//TODO uid
-        kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
-        
-        Kolab::Attachment attach;
-        attach.setUri("uri", "mimetype/mime");
-        kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
-        
-    //     std::vector<std::string> receipents;
-    //     receipents.push_back("email at email");
-    //     Kolab::Alarm alarm2("summary", "description", receipents);
-    //     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
-
-        QTest::newRow( "with endDate and recurrence duration" ) << kcal << kolab;
-    }
-    {
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setRevision(3);
-        kcal.setDtStart(toDate(date));
-        kcal.setDuration(KCalCore::Duration(toDate(date), toDate(date2)));
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setEndDateTime(toDate(date3));
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setSequence(3);
-        kolab.setStart(date);
-        kolab.setDuration(Kolab::Duration(0, 0, 1, 0));
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setEnd(date3);
-        kolab.setRecurrenceRule(rrule);
-        
-        QTest::newRow("with duration and recurrence endDate") << kcal << kolab;
-    }
-    {
-        Kolab::cDateTime start(2011,1,1);
-        Kolab::cDateTime end(2011,1,3);
-        
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setDtStart(toDate(start));
-        kcal.setDtEnd(toDate(end));
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setEndDateTime(toDate(end));
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setStart(start);
-        kolab.setEnd(end);
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setEnd(end);
-        kolab.setRecurrenceRule(rrule);
-        
-        QTest::newRow("date only dates") << kcal << kolab;
-    }
-}
-
-void KCalConversionTest::testConversion()
-{
-    QFETCH(KCalCore::Event, kcal);
-    QFETCH(Kolab::Event, kolab);
-    
-    const KCalCore::Event::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->created(), kcal.created());
-    QCOMPARE(e->lastModified(), kcal.lastModified());
-    QCOMPARE(e->revision(), kcal.revision());
-    QCOMPARE(e->secrecy(), kcal.secrecy());
-    QCOMPARE(e->categories(), kcal.categories());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->dtEnd(), kcal.dtEnd());
-    QCOMPARE(e->duration(), kcal.duration());
-    QCOMPARE(e->transparency(), kcal.transparency());
-    QCOMPARE(*e->recurrence(), *kcal.recurrence());
-    QCOMPARE(e->recurrenceId(), kcal.recurrenceId());
-    QCOMPARE(e->recurrenceType(), kcal.recurrenceType());
-    QCOMPARE(e->summary(), kcal.summary());
-    QCOMPARE(e->description(), kcal.description());
-    QCOMPARE(e->priority(), kcal.priority());
-    QCOMPARE(e->status(), kcal.status());
-    QCOMPARE(e->location(), kcal.location());
-    QCOMPARE(e->organizer()->name(), kcal.organizer()->name());
-    QCOMPARE(e->organizer()->email(), kcal.organizer()->email());
-    comparePointerVectors(e->attendees(), kcal.attendees());
-    comparePointerVectors(e->attachments(), kcal.attachments());
-    
-//     QCOMPARE(e->alarms(), kcal.alarms()); //TODO
-//TODO custom properties
-
-    QBENCHMARK {
-        toKCalCore(kolab);
-    }
-    
-    const Kolab::Event &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.created(), kolab.created());
-    QCOMPARE(b.lastModified(), kolab.lastModified());
-    QCOMPARE(b.sequence(), kolab.sequence());
-    QCOMPARE(b.classification(), kolab.classification());
-    QCOMPARE(b.categories(), kolab.categories());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.end(), kolab.end());
-    QCOMPARE(b.duration(), kolab.duration());
-    QCOMPARE(b.transparency(), kolab.transparency());
-    
-    QCOMPARE(b.recurrenceRule(), kolab.recurrenceRule());
-    QCOMPARE(b.recurrenceID(), kolab.recurrenceID());
-    QCOMPARE(b.recurrenceDates(), kolab.recurrenceDates());
-    QCOMPARE(b.exceptionDates(), kolab.exceptionDates());
-    
-    QCOMPARE(b.summary(), kolab.summary());
-    QCOMPARE(b.description(), kolab.description());
-    QCOMPARE(b.status(), kolab.status());
-}
-
-
-void KCalConversionTest::testTodoConversion_data()
-{
-    QTest::addColumn<KCalCore::Todo>( "kcal" );
-    QTest::addColumn<Kolab::Todo>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    
-    {
-        KCalCore::Todo kcal;
-        kcal.setUid("uid");
-        kcal.setDtStart(toDate(date));
-        kcal.setDtDue(toDate(date2));
-        
-        Kolab::Todo kolab;
-        kolab.setUid("uid");
-        kolab.setStart(date);
-        kolab.setDue(date2);
-
-        QTest::newRow( "todo" ) << kcal << kolab;
-    }
-}
-
-
-void KCalConversionTest::testTodoConversion()
-{
-    QFETCH(KCalCore::Todo, kcal);
-    QFETCH(Kolab::Todo, kolab);
-    
-    const KCalCore::Todo::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->dtDue(), kcal.dtDue());
-   
-    const Kolab::Todo &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.due(), kolab.due());
-}
-
-void KCalConversionTest::testJournalConversion_data()
-{
-    QTest::addColumn<KCalCore::Journal>( "kcal" );
-    QTest::addColumn<Kolab::Journal>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    
-    {
-        KCalCore::Journal kcal;
-        kcal.setUid("uid");
-        kcal.setDtStart(toDate(date));
-        kcal.setSummary("summary");
-        
-        Kolab::Journal kolab;
-        kolab.setUid("uid");
-        kolab.setStart(date);
-        kolab.setSummary("summary");
-        
-        QTest::newRow( "journal" ) << kcal << kolab;
-    }
-}
-
-
-void KCalConversionTest::testJournalConversion()
-{
-    QFETCH(KCalCore::Journal, kcal);
-    QFETCH(Kolab::Journal, kolab);
-    
-    const KCalCore::Journal::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->summary(), kcal.summary());
-    
-    const Kolab::Journal &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.summary(), kolab.summary());
-}
-
-
-void KCalConversionTest::testEventConflict_data()
-{
-    QTest::addColumn<Kolab::Event>( "e1" );
-    QTest::addColumn<Kolab::Event>( "e2" );
-    QTest::addColumn<bool>( "result" );
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1));
-        
-        QTest::newRow( "after" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1));
-        
-        QTest::newRow( "before" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        QTest::newRow( "conflict" ) << e1 << e2 << true;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
-    }
-}
-
-void KCalConversionTest::testEventConflict()
-{
-//     QFETCH(Kolab::Event, e1);
-//     QFETCH(Kolab::Event, e2);
-//     QFETCH(bool, result);
-//     QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
-}
-
-
-
-void KCalConversionTest::testTimesInInterval_data()
-{
-    QTest::addColumn<Kolab::Event>( "event" );
-    QTest::addColumn<Kolab::cDateTime>( "start" );
-    QTest::addColumn<Kolab::cDateTime>( "end" );
-    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
-    {
-        {
-            Kolab::Event event;
-            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
-            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
-            Kolab::RecurrenceRule rrule;
-            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-            rrule.setInterval(1);
-            rrule.setCount(5);
-            event.setRecurrenceRule(rrule);
-
-            std::vector<Kolab::cDateTime> result;
-            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1)); 
-            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1));
-            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1)); 
-            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1));
-            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1)); 
-            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1) << Kolab::cDateTime(2011,1,5,1,1,1) << result;
-        }
-    }
-}
-
-void KCalConversionTest::testTimesInInterval()
-{
-//     QFETCH(Kolab::Event, event);
-//     QFETCH(Kolab::cDateTime, start);
-//     QFETCH(Kolab::cDateTime, end);
-//     QFETCH(std::vector<Kolab::cDateTime>, result);
-//     QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
-}
-
-void KCalConversionTest::testTimesInIntervalBenchmark()
-{
-//     Kolab::Event event;
-//     event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
-//     event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
-//     Kolab::RecurrenceRule rrule;
-//     rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-//     rrule.setInterval(1);
-//     rrule.setCount(500);
-//     event.setRecurrenceRule(rrule);
-//     
-//     QBENCHMARK {
-//         Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-//     }
-//     const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-//     QVERIFY(result.size() == 500);
-//     qDebug() << QTest::toString(result);    
-}
-
-// void KCalConversionTest::BenchmarkRoundtripKCAL()
-// {
-//     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-//     std::string result = Kolab::writeEvent(event);
-//     QBENCHMARK {
-//         Kolab::KCalConversion::toKCalCore(Kolab::readEvent(result, false));
-//     }
-// }
-
-QTEST_MAIN( KCalConversionTest )
-
-#include "kcalconversiontest.moc"
diff --git a/libkolabkcal/tests/kcalconversiontest.h b/libkolabkcal/tests/kcalconversiontest.h
deleted file mode 100644
index fa926a5..0000000
--- a/libkolabkcal/tests/kcalconversiontest.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef KCALCONVERSIONTEST_H
-#define KCALCONVERSIONTEST_H
-
-#include <QtCore/QObject>
-#include <QtTest/QtTest>
-
-class KCalConversionTest : public QObject
-{
-  Q_OBJECT
-  private slots:
-
-    void testDate_data();
-    void testDate();
-    
-    void testDuration_data();
-    void testDuration();
-    
-    void testConversion_data();
-    void testConversion();
-
-    void testTodoConversion_data();
-    void testTodoConversion();
-    
-    void testJournalConversion_data();
-    void testJournalConversion();
-    
-    void testDateTZ_data();
-    void testDateTZ();
-
-    void testEventConflict_data();
-    void testEventConflict();
-    
-    void testTimesInInterval_data();
-    void testTimesInInterval();
-    void testTimesInIntervalBenchmark();
-};
-
-#endif
\ No newline at end of file
diff --git a/upgradetool/CMakeLists.txt b/upgradetool/CMakeLists.txt
index b6d4090..b0ab376 100644
--- a/upgradetool/CMakeLists.txt
+++ b/upgradetool/CMakeLists.txt
@@ -6,6 +6,9 @@ find_package(Qt4 REQUIRED)
 find_package(KDE4 REQUIRED)
 
 find_library(KOLABXML NAMES kolabxml)
+# find_library(KOLABFORMATV2 NAMES kolabformatV2)
+# find_library(KOLABKCAL NAMES kolabkcal)
+find_library(KOLAB NAMES kolab)
 
 find_library(KCALCORE NAMES kcalcore)
 if(KCALCORE)
@@ -16,11 +19,11 @@ endif(KCALCORE)
 include_directories(/opt/devel/global/include ${QT_INCLUDES} /usr/local/include/kolab .)
 link_directories(/opt/devel/global/lib)
 
-# find_library(KMIME_LIBS NAMES kmime)
-# if(KMIME_LIBS)
-#     set(KMIME_LIBS_FOUND ON)
-#     message("KMime found")
-# endif(KMIME_LIBS)
+find_library(KMIME_LIBS NAMES kmime)
+if(KMIME_LIBS)
+    set(KMIME_LIBS_FOUND ON)
+    message("KMime found")
+endif(KMIME_LIBS)
 
 # find_library(KOLABFORMATV2 NAMES kolabformat_v2 PATHS /opt/devel/global/lib)
 # if(KOLABFORMATV2)
@@ -29,12 +32,12 @@ link_directories(/opt/devel/global/lib)
 # endif(KOLABFORMATV2)
 # set(KOLABFORMATV2 /opt/devel/global/lib/libkolabformat_v2.so)
 
-set(COMMON_DEPENDENCIES kolabxml kolabkcal ${KCALCORE} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY} ${KOLABFORMATV2} kolabformatV2)
+message(${KOLAB})
 
+set(COMMON_DEPENDENCIES  ${KOLAB} ${KOLABXML} ${KCALCORE} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY})
+message(${COMMON_DEPENDENCIES})
 add_executable(upgradetool upgradetool.cpp upgradeutilities.cpp)
-target_link_libraries(upgradetool  ${COMMON_DEPENDENCIES})
-
-
+target_link_libraries(upgradetool ${COMMON_DEPENDENCIES})
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
@@ -44,5 +47,5 @@ message("Buildings tests")
 
 QT4_AUTOMOC(upgradetooltests.cpp)
 add_executable(upgradetooltests upgradetooltests.cpp upgradeutilities.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-target_link_libraries(upgradetooltests ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY}  ${COMMON_DEPENDENCIES})
+target_link_libraries(upgradetooltests ${QT_QTTEST_LIBRARY} ${COMMON_DEPENDENCIES})
 
diff --git a/upgradetool/upgradetool.cpp b/upgradetool/upgradetool.cpp
index 8b67917..5d1e41e 100644
--- a/upgradetool/upgradetool.cpp
+++ b/upgradetool/upgradetool.cpp
@@ -18,18 +18,10 @@
 #include <QtCore/qcoreapplication.h>
 #include <QtCore/QStringList>
 #include <QtCore/qfile.h>
-#include <kmime/kmime_message.h>
-#include <kcalcore/icalformat.h>
+#include <kdebug.h>
 
-#include <kolabformatV2/event.h>
-#include <kolabformatV2/kolabformatv2.h>
 #include "upgradeutilities.h"
 
-#include <kolab/kolabkcalconversion.h>
-#include <kolab/kolabformat.h>
-#include <kolab/kolabevent.h>
-
-
 /**
  * Usage:
  * 
diff --git a/upgradetool/upgradetooltests.cpp b/upgradetool/upgradetooltests.cpp
index 384a025..a470e76 100644
--- a/upgradetool/upgradetooltests.cpp
+++ b/upgradetool/upgradetooltests.cpp
@@ -1,23 +1,10 @@
 #include "upgradetooltests.h"
-#include <kolabformatv2.h>
 #include "upgradeutilities.h"
-#include <kolabkcalconversion.h>
 #include <kolabformat.h>
-
+#include <kdebug.h>
 
 void UpgradeToolTests::testConvertEvent()
 {
-//     const KMime::Message::Ptr kolabItem = KolabV2::ConversionUtils::readMimeFile( "complex.ics.mime" );
-//     QVERIFY(kolabItem);
-//     //     std::cout << kolabItem->textContent();
-//     KCalCore::Event::Ptr convertedIncidence = KolabV2::ConversionUtils::incidenceFromKolabImpl<KCalCore::Event::Ptr, KolabV2::Event>( kolabItem, "application/x-vnd.kolab.event", QString::fromLatin1("Europe/Berlin") );
-//     QVERIFY(convertedIncidence);
-//     const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*convertedIncidence);
-//     QVERIFY(event.isValid());
-//     std::cout << Kolab::writeEvent(event);
-
-//     Kolab::Upgrade::upgradeEventXML()
-    
     QFile file( "complex.ics.mime" );
     file.open( QFile::ReadOnly );
     const QByteArray data = file.readAll();
@@ -25,44 +12,6 @@ void UpgradeToolTests::testConvertEvent()
     kDebug() << Kolab::Upgrade::upgradeMime(data);
 }
 
-void UpgradeToolTests::parsingBenchmarkComparison_data()
-{
-    QTest::addColumn<bool>("v2Parser");
-    QTest::newRow("v2") << true;
-    QTest::newRow("v3") << false;
-}
-
-void UpgradeToolTests::parsingBenchmarkComparison()
-{
-    const KMime::Message::Ptr kolabItem = KolabV2::ConversionUtils::readMimeFile( "complex.ics.mime" );
-    KMime::Content *xmlContent = KolabV2::ConversionUtils::findContentByType( kolabItem, "application/x-vnd.kolab.event" );
-    QVERIFY ( xmlContent );
-    const QByteArray xmlData = xmlContent->decodedContent();
-//     qDebug() << xmlData;
-    const QDomDocument xmlDoc = KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) );
-    QVERIFY ( !xmlDoc.isNull() );
-    const KCalCore::Event::Ptr i = KolabV2::Event::fromXml( xmlDoc, QString::fromLatin1("Europe/Berlin") );
-    QVERIFY ( i );
-    const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*i);
-    const std::string &v3String = Kolab::writeEvent(event);
-    
-    QFETCH(bool, v2Parser);
-    
-//     Kolab::readEvent(v3String, false); //init parser (doesn't really change the results it seems)
-//     qDebug() << QString::fromUtf8(xmlData);
-//     qDebug() << "------------------------------------------------------------------------------------";
-//     qDebug() << QString::fromStdString(v3String);
-    if (v2Parser) {
-        QBENCHMARK {
-            KolabV2::Event::fromXml( KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) ), QString::fromLatin1("Europe/Berlin") );
-        }
-    } else {
-        QBENCHMARK {
-            Kolab::readEvent(v3String, false);
-        }
-    }
-}
-
 
 QTEST_MAIN( UpgradeToolTests )
 
diff --git a/upgradetool/upgradetooltests.h b/upgradetool/upgradetooltests.h
index 5392b47..4769660 100644
--- a/upgradetool/upgradetooltests.h
+++ b/upgradetool/upgradetooltests.h
@@ -12,10 +12,7 @@ class UpgradeToolTests : public QObject
 private slots:
     
     void testConvertEvent();
-    
-    void parsingBenchmarkComparison_data();
-    void parsingBenchmarkComparison();
-    
+
 };
 
 #endif
diff --git a/upgradetool/upgradeutilities.cpp b/upgradetool/upgradeutilities.cpp
index f81d74e..e6e2ec3 100644
--- a/upgradetool/upgradeutilities.cpp
+++ b/upgradetool/upgradeutilities.cpp
@@ -17,31 +17,16 @@
 
 
 #include "upgradeutilities.h"
-
-#include <kolabformatV2/event.h>
-#include <kolabformatV2/task.h>
-#include <kolabformatV2/journal.h>
-#include <kolabformatV2/kolabformatv2.h>
-
-#include <Qt/qdom.h>
+#include <kolab/kolabobject.h>
+#include <kolab/kcalconversion.h>
+#include <kdebug.h>
 
 #include <kolabevent.h>
-#include <kolabkcalconversion.h>
 #include <kolabformat.h>
 
 namespace Kolab {
     namespace Upgrade {
 
-void normalizeIncidence(KCalCore::Incidence::Ptr i)
-{
-    Q_FOREACH (KCalCore::Attendee::Ptr a, i->attendees()) {
-        a->setUid(QString()); //KCalCore sets the pointer as uid, we don't want that (if we wanted one, we'd want a real, globally unique one), so we clear the uid
-    }
-    
-    Q_FOREACH (KCalCore::Attachment::Ptr attachment, i->attachments()) {
-        attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
-    }
-}
         
 /**
  * Upgrades the format of a complete mime message containing a kolab object
@@ -53,70 +38,36 @@ QString upgradeMime(const QByteArray &input)
     msg->parse();
     msg->content(KMime::ContentIndex());
     
-    KMime::Headers::Base *xKolabHeader = msg->getHeaderByType("X-Kolab-Type");
-    if (!xKolabHeader) {
-        kWarning() << "could not find xKolabHeader";
-        return QString();
-    }
-    const QString &kolabType = xKolabHeader->asUnicodeString(); //TODO we probably shouldn't use unicodeString
-    KMime::Content *xmlContent = KolabV2::ConversionUtils::findContentByType( msg, kolabType.toLocal8Bit() );
-    if ( !xmlContent ) {
-        qWarning() << "no part found";
-        return QString();
-    }
-    const QByteArray xmlData = xmlContent->decodedContent();
-    QStringList attachments;
-    KCalCore::Incidence::Ptr i;
-    std::string v3String;
-    QString mimetype;
-    kDebug() << kolabType;
-    if (kolabType == KolabV2::ConversionUtils::eventKolabType()) { //Event
-        kDebug() << "event";
-        i = KolabV2::ConversionUtils::fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
-        Q_ASSERT(i);
-        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
-        normalizeIncidence(i);
-        const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Event*>(i.data()));
-        v3String = Kolab::writeEvent(event);
-        mimetype = KolabV2::ConversionUtils::xCalMimeType();
-    } else if (kolabType == KolabV2::ConversionUtils::todoKolabType()) { //Todo 
-        kDebug() << "todo";
-        i = KolabV2::ConversionUtils::fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
-        Q_ASSERT(i);
-        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
-        normalizeIncidence(i);
-        const Kolab::Todo &todo = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Todo*>(i.data()));
-        v3String = Kolab::writeTodo(todo);
-        mimetype = KolabV2::ConversionUtils::xCalMimeType();
-    } else if (kolabType == KolabV2::ConversionUtils::journalKolabType()) { //Journal
-        kDebug() << "journal";
-        i = KolabV2::ConversionUtils::fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
-        Q_ASSERT(i);
-        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
-        normalizeIncidence(i);
-        const Kolab::Journal &journal = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Journal*>(i.data()));
-        v3String = Kolab::writeJournal(journal);
-        mimetype = KolabV2::ConversionUtils::xCalMimeType();
-    } else {
-        kWarning() << "no kolab object found " << kolabType;
-        return QString();
+    Kolab::KolabObjectReader reader;
+    
+    KMime::Message::Ptr message;
+    switch (reader.parseMimeMessage(msg)) {
+        case Kolab::EventObject:
+            message = Kolab::KolabObjectWriter::writeEvent(reader.getEvent());
+            break;
+        case Kolab::TodoObject:
+            message = Kolab::KolabObjectWriter::writeTodo(reader.getTodo());
+            break;
+        case Kolab::JournalObject:
+            message = Kolab::KolabObjectWriter::writeJournal(reader.getJournal());
+            break;
+        case Kolab::InvalidObject:
+            kWarning() << "failed to read mime file";
+            return QString();
     }
 
-    KMime::Message::Ptr message = KolabV2::ConversionUtils::createMessage(i, mimetype, kolabType, QString::fromStdString(v3String).toLocal8Bit());
-
     QString result;
     QTextStream s(&result);
     message->toStream(s);
     return result;
-
 }
 
 
 
 QString upgradeEventXML(const QByteArray &xmlData, QStringList &attachments)
 {
-    const KCalCore::Event::Ptr i = KolabV2::ConversionUtils::fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
-    const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*i);
+    const KCalCore::Event::Ptr i = Kolab::readV2EventXML(xmlData, attachments);
+    const Kolab::Event &event = Kolab::Conversion::fromKCalCore(*i);
     const std::string &v3String = Kolab::writeEvent(event);
     return QString::fromStdString(v3String);
 }


commit 2ca5638553a7d4c6b20b76a42ab21037e2ad05f0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 11:35:42 2012 +0100

    fix includes

diff --git a/libkolab/kolabformatV2/kolabbase.h b/libkolab/kolabformatV2/kolabbase.h
index a1c3db9..5bdfdec 100644
--- a/libkolab/kolabformatV2/kolabbase.h
+++ b/libkolab/kolabformatV2/kolabbase.h
@@ -37,8 +37,8 @@
 
 #include <kcalcore/incidence.h>
 
-#include <KDateTime>
-#include <KTimeZone>
+#include <kdatetime.h>
+#include <ktimezone.h>
 
 #include <QColor>
 #include <qdom.h>


commit 80cdfb352753ac5727739d0df1efe7b07e321db1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 11:24:46 2012 +0100

    remove kde traces from core library, move calendaring to libkolab

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index f7f3026..f9daf30 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -38,24 +38,6 @@ if(SWIG)
     message("SWIG found")
 endif(SWIG)
 
-#We search for the needed libraries manually because FindKDE.cmake sets a miriad of linker options which we don't want.
-find_library(KDECORE NAMES kdecore PATH_SUFFIXES kde4/devel)
-if(KDECORE)
-    set(KDECORE_FOUND ON)
-    message("KDElibs found")
-endif(KDECORE)
-
-find_library(KCALCORE NAMES kcalcore)
-if(KCALCORE)
-    set(KCALCORE_FOUND ON)
-    message("KCalCore found")
-endif(KCALCORE)
-
-find_path(KCALCORE_INCLUDE_DIR kcalcore/event.h
-          PATHS /usr/include /usr/include/kde4/ )
-
-include_directories(${KCALCORE_INCLUDE_DIR})
-
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
 
 # set( CMAKE_VERBOSE_MAKEFILE on )
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index ac961a8..f7b570e 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -40,27 +40,6 @@ IF("${isSystemDir}" STREQUAL "-1")
    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
 ENDIF("${isSystemDir}" STREQUAL "-1")
 
-#----- KCalCore libs
-if(KDECORE_FOUND AND KCALCORE_FOUND)
-    message("Building KCalCore dependend libraries.")
-
-    #Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
-    add_library(kolabkcal SHARED kolabkcalconversion.cpp calendaring.cpp)
-    target_link_libraries(kolabkcal kolabxml ${KCALCORE} ${KDECORE})
-
-    set_target_properties(kolabkcal PROPERTIES VERSION 0.1.0 SOVERSION 0)
-    install(TARGETS kolabkcal LIBRARY DESTINATION lib)
-
-    install( FILES
-    kolabkcalconversion.h
-    calendaring.h
-    DESTINATION include/kolab COMPONENT Devel)
-
-else()
-    message(WARNING "Could not build KCalCore/KDElibs dependend libraries, because kdepimlibs/kdelibs is missing.")
-endif()
-
-
 #-----------------------SWIG--------------------
 
 if (SWIG_FOUND)
diff --git a/c++/lib/calendaring.cpp b/c++/lib/calendaring.cpp
deleted file mode 100644
index e35af0e..0000000
--- a/c++/lib/calendaring.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "calendaring.h"
-
-#include <kcalcore/event.h>
-#include <KDE/KCalCore/Todo>
-#include <Qt/qdebug.h>
-
-#include "kolabkcalconversion.h"
-
-namespace Kolab {
-
-    namespace Calendaring {
-
-        bool conflicts(const Kolab::Event &e1, const Kolab::Event &e2)
-        {
-            KCalCore::Event::Ptr k1 = KCalConversion::toKCalCore(e1);
-            KCalCore::Event::Ptr k2 = KCalConversion::toKCalCore(e2);
-            if (k2->dtEnd().compare(k1->dtStart()) == KDateTime::Before) {
-                return false;
-            } else if (k1->dtEnd().compare(k2->dtStart()) == KDateTime::Before) {
-                return false;
-            }
-            return true;
-        }
-
-        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &e, const Kolab::cDateTime &start, const Kolab::cDateTime &end)
-        {
-            KCalCore::Event::Ptr k = KCalConversion::toKCalCore(e);
-            KCalCore::DateTimeList list = k->recurrence()->timesInInterval(KCalConversion::toDate(start), KCalConversion::toDate(end));
-            std::vector<Kolab::cDateTime> dtList;
-            foreach(const KDateTime &dt, list) {
-                dtList.push_back(KCalConversion::fromDate(dt));
-            }
-            return dtList;
-        }
-
-    } //Namespace
-} //Namespace
\ No newline at end of file
diff --git a/c++/lib/calendaring.h b/c++/lib/calendaring.h
deleted file mode 100644
index 12d7c53..0000000
--- a/c++/lib/calendaring.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KOLABCALENDARING_H
-#define KOLABCALENDARING_H
-
-#include "kolabevent.h"
-#include <kcalcore/event.h>
-
-namespace Kolab {
-    namespace Calendaring {
-        /**
-         * Returns true if the events conflict (overlap)
-         */
-        bool conflicts(const Kolab::Event &, const Kolab::Event &);
-
-        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &, const Kolab::cDateTime &start, const Kolab::cDateTime &end);
-    };
-};
-
-#endif
\ No newline at end of file
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 04b2b3a..ecaa0ae 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -3,19 +3,15 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
-if (QT4_FOUND AND KDECORE_FOUND AND KCALCORE_FOUND)
+if (QT4_FOUND)
     message("Buildings tests")
     QT4_AUTOMOC(bindingstest.cpp)
     add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml kolabkcal ${XERCES_C})
-
-    QT4_AUTOMOC(kcalconversiontest.cpp)
-    add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabkcal ${XERCES_C})
+    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
 
     QT4_AUTOMOC(conversiontest.cpp)
     add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC})
     target_link_libraries(conversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
 else()
-    message(WARNING "Could not build tests because kdepimlibs, kdelibs or qt is missing")
+    message(WARNING "Could not build tests because qt is missing")
 endif()
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 5bd327a..aca55ce 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -13,7 +13,7 @@
 #include <xercesc/dom/DOMImplementation.hpp>
 #include <lib/kolabformat.h>
 #include <kdebug.h>
-#include <lib/kolabkcalconversion.h>
+// #include <kolab/kolabkcalconversion.h>
 #include <iostream>
 #include <fstream>
 #include "serializers.h"
@@ -543,14 +543,6 @@ void BindingsTest::BenchmarkRoundtripKolab()
         Kolab::readEvent(result, false);
     }
 }
-void BindingsTest::BenchmarkRoundtripKCAL()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeEvent(event);
-    QBENCHMARK {
-        Kolab::KCalConversion::toKCalCore(Kolab::readEvent(result, false));
-    }
-}
 
 void BindingsTest::BenchmarkRoundtrip()
 {
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index f62c0b8..16c933c 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -36,7 +36,6 @@ class BindingsTest : public QObject
     void errorRecoveryTest();
 
     void BenchmarkRoundtripKolab();
-    void BenchmarkRoundtripKCAL();
     void BenchmarkRoundtrip();
 
 };
diff --git a/libkolab/calendaring/calendaring.cpp b/libkolab/calendaring/calendaring.cpp
new file mode 100644
index 0000000..e35af0e
--- /dev/null
+++ b/libkolab/calendaring/calendaring.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "calendaring.h"
+
+#include <kcalcore/event.h>
+#include <KDE/KCalCore/Todo>
+#include <Qt/qdebug.h>
+
+#include "kolabkcalconversion.h"
+
+namespace Kolab {
+
+    namespace Calendaring {
+
+        bool conflicts(const Kolab::Event &e1, const Kolab::Event &e2)
+        {
+            KCalCore::Event::Ptr k1 = KCalConversion::toKCalCore(e1);
+            KCalCore::Event::Ptr k2 = KCalConversion::toKCalCore(e2);
+            if (k2->dtEnd().compare(k1->dtStart()) == KDateTime::Before) {
+                return false;
+            } else if (k1->dtEnd().compare(k2->dtStart()) == KDateTime::Before) {
+                return false;
+            }
+            return true;
+        }
+
+        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &e, const Kolab::cDateTime &start, const Kolab::cDateTime &end)
+        {
+            KCalCore::Event::Ptr k = KCalConversion::toKCalCore(e);
+            KCalCore::DateTimeList list = k->recurrence()->timesInInterval(KCalConversion::toDate(start), KCalConversion::toDate(end));
+            std::vector<Kolab::cDateTime> dtList;
+            foreach(const KDateTime &dt, list) {
+                dtList.push_back(KCalConversion::fromDate(dt));
+            }
+            return dtList;
+        }
+
+    } //Namespace
+} //Namespace
\ No newline at end of file
diff --git a/libkolab/calendaring/calendaring.h b/libkolab/calendaring/calendaring.h
new file mode 100644
index 0000000..12d7c53
--- /dev/null
+++ b/libkolab/calendaring/calendaring.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABCALENDARING_H
+#define KOLABCALENDARING_H
+
+#include "kolabevent.h"
+#include <kcalcore/event.h>
+
+namespace Kolab {
+    namespace Calendaring {
+        /**
+         * Returns true if the events conflict (overlap)
+         */
+        bool conflicts(const Kolab::Event &, const Kolab::Event &);
+
+        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &, const Kolab::cDateTime &start, const Kolab::cDateTime &end);
+    };
+};
+
+#endif
\ No newline at end of file
diff --git a/libkolab/calendaring/calendaring.i b/libkolab/calendaring/calendaring.i
new file mode 100644
index 0000000..45410e4
--- /dev/null
+++ b/libkolab/calendaring/calendaring.i
@@ -0,0 +1,24 @@
+/* calendaring.i */
+%module kolabcalendaring
+%{
+
+    /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
+    #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
+
+    #include "calendaring.h"
+%}
+
+/*
+%include "std_string.i"
+%include "std_vector.i"
+
+namespace std {
+    %template(vectori) vector<int>;
+    %template(vectors) vector<string>;
+    %template(vectordate) vector<Kolab::DateTime>;
+    %template(vectordaypos) vector<Kolab::DayPos>;
+};*/
+
+/*%apply const std::string& {std::string* foo};*/
+
+%include "calendaring.h"


commit b7f4b4c1c47cc372ee7ff8615343bd93d936e795
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 11:22:56 2012 +0100

    fixed upgradetool cmake file

diff --git a/upgradetool/CMakeLists.txt b/upgradetool/CMakeLists.txt
index ffc557c..b6d4090 100644
--- a/upgradetool/CMakeLists.txt
+++ b/upgradetool/CMakeLists.txt
@@ -5,6 +5,14 @@ cmake_minimum_required(VERSION 2.6)
 find_package(Qt4 REQUIRED)
 find_package(KDE4 REQUIRED)
 
+find_library(KOLABXML NAMES kolabxml)
+
+find_library(KCALCORE NAMES kcalcore)
+if(KCALCORE)
+    set(KCALCORE_FOUND ON)
+    message("KCalCore found")
+endif(KCALCORE)
+
 include_directories(/opt/devel/global/include ${QT_INCLUDES} /usr/local/include/kolab .)
 link_directories(/opt/devel/global/lib)
 
@@ -21,7 +29,7 @@ link_directories(/opt/devel/global/lib)
 # endif(KOLABFORMATV2)
 # set(KOLABFORMATV2 /opt/devel/global/lib/libkolabformat_v2.so)
 
-set(COMMON_DEPENDENCIES kolabxml kolabkcal ${KCALCORE} ${KDECORE} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY} ${KOLABFORMATV2} kolabformatV2)
+set(COMMON_DEPENDENCIES kolabxml kolabkcal ${KCALCORE} ${KDE4_KDECORE_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY} ${KOLABFORMATV2} kolabformatV2)
 
 add_executable(upgradetool upgradetool.cpp upgradeutilities.cpp)
 target_link_libraries(upgradetool  ${COMMON_DEPENDENCIES})


commit 9a6f7ce9822b02fa6f3617847fc9f0e4cbf70782
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 11:22:21 2012 +0100

    moved kcalcoreconversion

diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
deleted file mode 100644
index bb1e0c3..0000000
--- a/c++/lib/kolabkcalconversion.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "kolabkcalconversion.h"
-
-#include <kcalcore/recurrence.h>
-#include <QtCore/QBitArray>
-#include <QtCore/QVector>
-#include <QtCore/QDebug>
-#include <vector>
-#include <KDE/KSystemTimeZones>
-
-namespace Kolab {
-namespace KCalConversion {
-
-KDateTime toDate(const Kolab::cDateTime &dt)
-{
-    KDateTime date;
-    if (!dt.isValid()) {
-//         qDebug() << "invalid datetime converted";
-        return KDateTime();
-    }
-    if (dt.isDateOnly()) { //Date only
-        date.setDateOnly(true);
-        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
-    } else {
-        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
-        if (dt.isUTC()) { //UTC
-            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        } else if (!dt.timezone().empty()) { //Timezone
-            const KTimeZone &tz = KSystemTimeZones::zone(QString::fromStdString(dt.timezone())); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
-            if (!tz.isValid()) {
-                qWarning() << "timezone not found" << QString::fromStdString(dt.timezone());
-                if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
-                    qWarning() << "ktimezoned is not available and required for timezone interpretation";
-                }
-            }
-            date.setTimeSpec(KDateTime::Spec(tz));
-        } else { //Floating
-            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
-        }
-    }
-    Q_ASSERT(date.timeSpec().isValid());
-    Q_ASSERT(date.isValid());
-    return date;
-}
-
-cDateTime fromDate(const KDateTime &dt)
-{
-    if (!dt.isValid()) {
-//         qDebug() << "invalid datetime converted";
-        return cDateTime();
-    }
-    cDateTime date;
-    if (dt.isDateOnly()) { //Date only
-        const QDate &d = dt.date();
-        date.setDate(d.year(), d.month(), d.day());
-    } else {
-        const QDate &d = dt.date();
-        date.setDate(d.year(), d.month(), d.day());
-        const QTime &t = dt.time();
-        date.setTime(t.hour(), t.minute(), t.second());
-        if (dt.timeType() == KDateTime::UTC) { //UTC
-            date.setUTC(true);
-        } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
-            //TODO handle local timezone?
-            date.setTimezone(dt.timeZone().name().toStdString()); //FIXME use system independent name according to spec
-        } else if (dt.timeType() != KDateTime::ClockTime) {
-            qWarning() << "invalid timespec, assuming floating time" << dt.timeType();
-            return cDateTime();
-        }
-    }
-    Q_ASSERT(date.isValid());
-    return date;
-}
-
-KCalCore::Duration toDuration(const Kolab::Duration &d)
-{
-    //TODO should we support negative durations?
-    if (d.hours() || d.minutes() || d.seconds()) {
-        return KCalCore::Duration(((((d.weeks() * 7 + d.days()) * 24 + d.hours()) * 60 + d.minutes()) * 60 + d.seconds()));
-    }
-    return KCalCore::Duration(d.weeks() * 7 + d.days(), KCalCore::Duration::Days);
-}
-
-Kolab::Duration fromDuration(const KCalCore::Duration &d)
-{
-    if (d.value() <= 0) {
-        return Kolab::Duration();
-    }
-    //We don't know how the seconds/days were distributed before, so no point in distributing them (probably)
-    //TODO should we support negative durations?
-    if (d.isDaily()) {
-        int days = d.value();
-        return Kolab::Duration(days, 0, 0, 0, false);
-    }
-    int seconds = d.value();
-//         int minutes = seconds / 60;
-//         seconds = seconds % 60;
-//         int hours = minutes / 60;
-//         minutes = minutes % 60;
-    return Kolab::Duration(0, 0, 0, seconds, false);
-
-}
-
-KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
-{
-    switch(c) {
-        case Kolab::ClassPublic:
-            return KCalCore::Incidence::SecrecyPublic;
-        case Kolab::ClassPrivate:
-            return KCalCore::Incidence::SecrecyPrivate;
-        case Kolab::ClassConfidential:
-            return KCalCore::Incidence::SecrecyConfidential;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Incidence::SecrecyPublic;
-}
-
-Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
-{
-    switch(c) {
-        case KCalCore::Incidence::SecrecyPublic:
-            return Kolab::ClassPublic;
-        case KCalCore::Incidence::SecrecyPrivate:
-            return Kolab::ClassPrivate;
-        case KCalCore::Incidence::SecrecyConfidential:
-            return Kolab::ClassConfidential;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::ClassPublic;
-}
-
-int toPriority(int priority)
-{
-    //Same mapping
-    return priority;
-}
-
-int fromPriority(int priority)
-{
-    //Same mapping
-    return priority;
-}
-
-KCalCore::Incidence::Status toStatus(Kolab::Status s)
-{
-    switch (s) {
-        case StatusUndefined:
-            return  KCalCore::Incidence::StatusNone;
-        case StatusNeedsAction:
-            return  KCalCore::Incidence::StatusNeedsAction;
-        case StatusCompleted:
-            return  KCalCore::Incidence::StatusCompleted;
-        case StatusInProcess:
-            return  KCalCore::Incidence::StatusInProcess;
-        case StatusCancelled:
-            return  KCalCore::Incidence::StatusCanceled;
-        case StatusTentative:
-            return  KCalCore::Incidence::StatusTentative;
-        case StatusConfirmed:
-            return  KCalCore::Incidence::StatusConfirmed;
-        case StatusDraft:
-            return  KCalCore::Incidence::StatusDraft;
-        case StatusFinal:
-            return  KCalCore::Incidence::StatusFinal;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Incidence::StatusNone;
-}
-
-Kolab::Status fromStatus(KCalCore::Incidence::Status s)
-{
-    switch (s) {
-        case KCalCore::Incidence::StatusNone:
-            return StatusUndefined;
-        case KCalCore::Incidence::StatusNeedsAction:
-            return StatusNeedsAction;
-        case KCalCore::Incidence::StatusCompleted:
-            return StatusCompleted;
-        case KCalCore::Incidence::StatusInProcess:
-            return StatusInProcess;
-        case KCalCore::Incidence::StatusCanceled:
-            return StatusCancelled;
-        case KCalCore::Incidence::StatusTentative:
-            return StatusTentative;
-        case KCalCore::Incidence::StatusConfirmed:
-            return StatusConfirmed;
-        case KCalCore::Incidence::StatusDraft:
-            return StatusDraft;
-        case KCalCore::Incidence::StatusFinal:
-            return StatusFinal;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return StatusUndefined;
-}
-
-QStringList toStringList(const std::vector<std::string> &l)
-{
-    QStringList list;
-    foreach(const std::string &s, l) {
-        list.append(QString::fromStdString(s));
-    }
-    return list;
-}
-
-std::vector<std::string> fromStringList(const QStringList &l)
-{
-    std::vector<std::string> list;
-    foreach(const QString &s, l) {
-        list.push_back(s.toStdString());
-    }
-    return list;
-}
-
-KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
-{
-    switch (p) {
-        case PartNeedsAction:
-            return KCalCore::Attendee::NeedsAction;
-        case PartAccepted:
-            return KCalCore::Attendee::Accepted;
-        case PartDeclined:
-            return KCalCore::Attendee::Declined;
-        case PartTentative:
-            return KCalCore::Attendee::Tentative;
-        case PartDelegated:
-            return KCalCore::Attendee::Delegated;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Attendee::NeedsAction;
-}
-
-Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
-{
-    switch (p) {
-        case KCalCore::Attendee::NeedsAction:
-            return PartNeedsAction;
-        case KCalCore::Attendee::Accepted:
-            return PartAccepted;
-        case KCalCore::Attendee::Declined:
-            return PartDeclined;
-        case KCalCore::Attendee::Tentative:
-            return PartTentative;
-        case KCalCore::Attendee::Delegated:
-            return PartDelegated;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return PartNeedsAction;
-}
-
-KCalCore::Attendee::Role toRole(Kolab::Role r)
-{
-    switch (r) {
-        case Required:
-            return KCalCore::Attendee::ReqParticipant;
-        case Chair:
-            return KCalCore::Attendee::Chair;
-        case Optional:
-            return KCalCore::Attendee::OptParticipant;
-        case NonParticipant:
-            return KCalCore::Attendee::NonParticipant;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::Attendee::ReqParticipant;
-}
-
-Kolab::Role fromRole(KCalCore::Attendee::Role r)
-{
-    switch (r) {
-        case KCalCore::Attendee::ReqParticipant:
-            return Required;
-        case KCalCore::Attendee::Chair:
-            return Chair;
-        case KCalCore::Attendee::OptParticipant:
-            return Optional;
-        case KCalCore::Attendee::NonParticipant:
-            return NonParticipant;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Required;
-}
-
-template <typename T>
-void setIncidence(KCalCore::Incidence &i, const T &e)
-{
-    if (!e.uid().empty()) {
-        i.setUid(QString::fromStdString(e.uid()));
-    }
-    
-    i.setCreated(toDate(e.created()));
-    i.setLastModified(toDate(e.lastModified()));
-    i.setRevision(e.sequence());
-    i.setSecrecy(toSecrecy(e.classification()));
-    i.setCategories(toStringList(e.categories()));
-    
-    if (e.start().isValid()) {
-        i.setDtStart(toDate(e.start()));
-    }
-
-    i.setSummary(QString::fromStdString(e.summary())); //TODO detect richtext
-    i.setDescription(QString::fromStdString(e.description())); //TODO detect richtext
-    i.setStatus(toStatus(e.status()));
-    foreach (const Kolab::Attendee a, e.attendees()) {
-        //We shouldn't rely on a uid if we're going with mail+name and not on mail+name if we're going with UID (of ical btw. and not kaddresee)
-        i.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(QString::fromStdString(a.contact().name()), 
-                                                                     QString::fromStdString(a.contact().email()),  //TODO handle uid
-                                                                     a.rsvp(),
-                                                                     toPartStat(a.partStat()),
-                                                                     toRole(a.role()) ))); //FIXME doesn't make sense to set both, either email or uid
-    }
-    foreach (const Kolab::Attachment a, e.attachments()) {
-        KCalCore::Attachment::Ptr ptr;
-        if (!a.uri().empty()) {
-            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString::fromStdString(a.uri()), QString::fromStdString(a.mimetype())));
-        } else {
-            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), QString::fromStdString(a.mimetype())));
-        }
-        if (!a.label().empty()) {
-            ptr->setLabel(QString::fromStdString(a.label()));
-        }
-        i.addAttachment(ptr);
-    }
-//     i.addAlarm(); //TODO
-//     i.setCustomProperties(); //TODO
-}
-
-template <typename T, typename I>
-void getIncidence(T &i, const I &e)
-{
-    i.setUid(e.uid().toStdString());
-    i.setCreated(fromDate(e.created()));
-    i.setLastModified(fromDate(e.lastModified()));
-    i.setSequence(e.revision());
-    i.setClassification(fromSecrecy(e.secrecy()));
-    i.setCategories(fromStringList(e.categories()));
-    
-    i.setStart(fromDate(e.dtStart()));
-    i.setSummary(e.summary().toStdString());
-    i.setDescription(e.description().toStdString());
-    i.setStatus(fromStatus(e.status()));
-    std::vector<Kolab::Attendee> attendees;
-    foreach (const KCalCore::Attendee::Ptr ptr, e.attendees()) {
-        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference, ptr->email().toStdString(), ptr->name().toStdString())); //TODO handle uid
-        a.setRSVP(ptr->RSVP());
-        a.setPartStat(fromPartStat(ptr->status()));
-        a.setRole(fromRole(ptr->role()));
-//         a.setUid(ptr->uid().toStdString()); //TODO
-        attendees.push_back(a);
-    }
-    i.setAttendees(attendees);
-    std::vector<Kolab::Attachment> attachments;
-    foreach (const KCalCore::Attachment::Ptr ptr, e.attachments()) {
-        Kolab::Attachment a;
-        if (ptr->isUri()) {
-            a.setUri(ptr->uri().toStdString(), ptr->mimeType().toStdString());
-        } else {
-            a.setData(std::string(ptr->decodedData().data(), ptr->decodedData().size()), ptr->mimeType().toStdString());
-        }
-        a.setLabel(ptr->label().toStdString());
-        attachments.push_back(a);
-    }
-    i.setAttachments(attachments);
-    //TODO alarms
-    //TODO custom properties
-}
-
-int toWeekDay(Kolab::Weekday wday)
-{
-    switch (wday) {
-        case Kolab::Monday:
-            return  1;
-        case Kolab::Tuesday:
-            return 2;
-        case Kolab::Wednesday:
-            return 3;
-        case Kolab::Thursday:
-            return 4;
-        case Kolab::Friday:
-            return 5;
-        case Kolab::Saturday:
-            return 6;
-        case Kolab::Sunday:
-            return 7;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return 1;
-}
-
-Kolab::Weekday fromWeekDay(int wday)
-{
-    switch (wday) {
-        case 1:
-            return Kolab::Monday;
-        case 2:
-            return Kolab::Tuesday;
-        case 3:
-            return Kolab::Wednesday;
-        case 4:
-            return Kolab::Thursday;
-        case 5:
-            return Kolab::Friday;
-        case 6:
-            return Kolab::Saturday;
-        case 7:
-            return Kolab::Sunday;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::Monday;
-}
-
-KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
-{
-    switch(freq) {
-        case Kolab::RecurrenceRule::FreqNone:
-            qWarning() << "no recurrence?";
-            break;
-        case Kolab::RecurrenceRule::Yearly:
-            return KCalCore::RecurrenceRule::rYearly;
-        case Kolab::RecurrenceRule::Monthly:
-            return KCalCore::RecurrenceRule::rMonthly;
-        case Kolab::RecurrenceRule::Weekly:
-            return KCalCore::RecurrenceRule::rWeekly;
-        case Kolab::RecurrenceRule::Daily:
-            return KCalCore::RecurrenceRule::rDaily;
-        case Kolab::RecurrenceRule::Hourly:
-            return KCalCore::RecurrenceRule::rHourly;
-        case Kolab::RecurrenceRule::Minutely:
-            return KCalCore::RecurrenceRule::rMinutely;
-        case Kolab::RecurrenceRule::Secondly:
-            return KCalCore::RecurrenceRule::rSecondly;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return KCalCore::RecurrenceRule::rNone;
-}
-
-Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
-{
-    switch(freq) {
-        case KCalCore::RecurrenceRule::rNone:
-            qWarning() << "no recurrence?";
-            break;
-        case KCalCore::RecurrenceRule::rYearly:
-            return Kolab::RecurrenceRule::Yearly;
-        case KCalCore::RecurrenceRule::rMonthly:
-            return Kolab::RecurrenceRule::Monthly;
-        case KCalCore::RecurrenceRule::rWeekly:
-            return Kolab::RecurrenceRule::Weekly;
-        case KCalCore::RecurrenceRule::rDaily:
-            return Kolab::RecurrenceRule::Daily;
-        case KCalCore::RecurrenceRule::rHourly:
-            return Kolab::RecurrenceRule::Hourly;
-        case KCalCore::RecurrenceRule::rMinutely:
-            return Kolab::RecurrenceRule::Minutely;
-        case KCalCore::RecurrenceRule::rSecondly:
-            return Kolab::RecurrenceRule::Secondly;
-        default:
-            qWarning() << "unhandled";
-            Q_ASSERT(0);
-    }
-    return Kolab::RecurrenceRule::FreqNone;
-}
-
-KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
-{
-    return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday()));
-}
-
-Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
-{
-    return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()));
-}
-
-template <typename T>
-void setRecurrence(KCalCore::Incidence &e, const T &event)
-{
-    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
-    if (rrule.isValid()) {
-        KCalCore::Recurrence *rec = e.recurrence();
-        
-        KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
-        Q_ASSERT(defaultRR);
-        
-        defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
-        defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
-        defaultRR->setFrequency(rrule.interval());
-        
-        if (rrule.end().isValid()) {
-            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
-        } else {
-            rec->setDuration(rrule.count());
-        }
-        
-        if (!rrule.bysecond().empty()) {
-            defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
-        }
-        if (!rrule.byminute().empty()) {
-            defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
-        }
-        if (!rrule.byhour().empty()) {
-            defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
-        }
-        if (!rrule.byday().empty()) {
-            QList<KCalCore::RecurrenceRule::WDayPos> daypos;
-            foreach(const Kolab::DayPos &dp, rrule.byday()) {
-                daypos.append(toWeekDayPos(dp));
-            }
-            defaultRR->setByDays(daypos);
-        }
-        if (!rrule.bymonthday().empty()) {
-            defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
-        }
-        if (!rrule.byyearday().empty()) {
-            defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
-        }
-        if (!rrule.byweekno().empty()) {
-            defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
-        }
-        if (!rrule.bymonth().empty()) {
-            defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
-        }
-    }
-    foreach (const Kolab::cDateTime &dt, event.recurrenceDates()) {
-        const KDateTime &date = toDate(dt);
-        if (date.isDateOnly()) {
-            e.recurrence()->addRDate(date.date());
-        } else {
-            e.recurrence()->addRDateTime(date);
-        }
-    }
-    foreach (const Kolab::cDateTime &dt, event.exceptionDates()) {
-        const KDateTime &date = toDate(dt);
-        if (date.isDateOnly()) {
-            e.recurrence()->addExDate(date.date());
-        } else {
-            e.recurrence()->addExDateTime(date);
-        }
-    }
-
-}
-
-template <typename T, typename I>
-void getRecurrence(T &i, const I &e)
-{
-    if (!e.recurs()) {
-        return;
-    }
-    KCalCore::Recurrence *rec = e.recurrence();
-    KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
-    if (!defaultRR) {
-        qWarning() << "no recurrence";
-        return;
-    }
-    Q_ASSERT(defaultRR);
-
-    Kolab::RecurrenceRule rrule;
-    rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
-    rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
-    rrule.setInterval(defaultRR->frequency());
-  
-    if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
-        if (defaultRR->duration() > 0) {
-            rrule.setCount(defaultRR->duration());
-        }
-    } else {
-        rrule.setEnd(fromDate(defaultRR->endDt()));
-    }
-    
-    rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
-    rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
-    rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
-    
-    std::vector<Kolab::DayPos> daypos;
-    foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
-        daypos.push_back(fromWeekDayPos(dp));
-    }
-    rrule.setByday(daypos);
-    
-    rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
-    rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
-    rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
-    rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
-    i.setRecurrenceRule(rrule);
-    
-    std::vector<Kolab::cDateTime> rdates;
-    foreach (const KDateTime &dt, rec->rDateTimes()) {
-        rdates.push_back(fromDate(dt));
-    }
-    foreach (const QDate &dt, rec->rDates()) {
-        rdates.push_back(fromDate(KDateTime(dt)));
-    }
-    i.setRecurrenceDates(rdates);
-    
-    std::vector<Kolab::cDateTime> exdates;
-    foreach (const KDateTime &dt, rec->exDateTimes()) {
-        exdates.push_back(fromDate(dt));
-    }
-    foreach (const QDate &dt, rec->exDates()) {
-        exdates.push_back(fromDate(KDateTime(dt)));
-    }
-    i.setExceptionDates(exdates);
-    
-    if (!rec->exRules().empty()) {
-        qWarning() << "exrules are not supported";
-    }
-}
-
-template <typename T>
-void setTodoEvent(KCalCore::Incidence &i, const T &e)
-{
-    i.setPriority(toPriority(e.priority()));
-    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
-    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizer().name()), QString::fromStdString(e.organizer().email())))); //TODO handle uid too
-    if (e.recurrenceID().isValid()) {
-        i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
-    }
-    setRecurrence(i, e);
-}
-
-template <typename T, typename I>
-void getTodoEvent(T &i, const I &e)
-{
-    i.setPriority(fromPriority(e.priority()));
-    i.setLocation(e.location().toStdString());
-    i.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, e.organizer()->email().toStdString(), e.organizer()->name().toStdString())); //TODO handle uid too
-    i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
-    getRecurrence(i, e);
-}
-
-KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
-{
-    KCalCore::Event::Ptr e(new KCalCore::Event);
-    setIncidence(*e, event);
-    setTodoEvent(*e, event);
-    if (event.end().isValid()) {
-        e->setDtEnd(toDate(event.end()));
-    }
-    if (event.duration().isValid()) {
-        e->setDuration(toDuration(event.duration()));
-    }
-    if (event.transparency()) {
-        e->setTransparency(KCalCore::Event::Transparent);
-    } else {
-        e->setTransparency(KCalCore::Event::Opaque);
-    }
-    return e;
-}
-
-Event fromKCalCore(const KCalCore::Event &event)
-{
-    Event e;
-    getIncidence(e, event);
-    getTodoEvent(e, event);
-    if (event.hasEndDate()) {
-        e.setEnd(fromDate(event.dtEnd()));
-    } else if (event.hasDuration()) {
-        e.setDuration(fromDuration(event.duration()));
-    }
-    if (event.transparency() == KCalCore::Event::Transparent) {
-        e.setTransparency(true);
-    } else {
-        e.setTransparency(false);
-    }
-    return e;
-}
-
-
-
-KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
-{
-    KCalCore::Todo::Ptr e(new KCalCore::Todo);
-    setIncidence(*e, todo);
-    setTodoEvent(*e, todo);
-    if (todo.due().isValid()) {
-        e->setDtDue(toDate(todo.due()));
-    }
-    return e;
-}
-
-Todo fromKCalCore ( const KCalCore::Todo &todo )
-{
-    Todo t;
-    getIncidence(t, todo);
-    getTodoEvent(t, todo);
-    t.setDue(fromDate(todo.dtDue(true)));
-    return t;
-}
-
-KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
-{
-    KCalCore::Journal::Ptr e(new KCalCore::Journal);
-    setIncidence(*e, journal);
-    //TODO contacts
-    return e;
-}
-
-Journal fromKCalCore ( const KCalCore::Journal &journal )
-{
-    Journal j;
-    getIncidence(j, journal);
-    //TODO contacts
-    return j;
-}
-
-
-
-}
-}
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
deleted file mode 100644
index 0568d63..0000000
--- a/c++/lib/kolabkcalconversion.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLABKCALCONVERSION_H
-#define KOLABKCALCONVERSION_H
-
-#include "kolabevent.h"
-#include "kolabtodo.h"
-#include "kolabjournal.h"
-#include <kcalcore/event.h>
-#include <kcalcore/todo.h>
-#include <kcalcore/journal.h>
-
-namespace Kolab {
-    /**
-     * Conversion of Kolab-Containers to/from KCalCore Containers.
-     *
-     * TODO: There is no error handling other than qWarning used so far.
-     */
-    namespace KCalConversion {
-
-        KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
-        Kolab::Event fromKCalCore(const KCalCore::Event &);
-
-        KCalCore::Todo::Ptr toKCalCore(const Kolab::Todo &);
-        Kolab::Todo fromKCalCore(const KCalCore::Todo &);
-
-        KCalCore::Journal::Ptr toKCalCore(const Kolab::Journal &);
-        Kolab::Journal fromKCalCore(const KCalCore::Journal &);
-
-        KDateTime toDate(const Kolab::cDateTime &dt);
-        cDateTime fromDate(const KDateTime &dt);
-
-    };
-};
-
-#endif
\ No newline at end of file
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
deleted file mode 100644
index ab4171d..0000000
--- a/c++/tests/kcalconversiontest.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-#include "kcalconversiontest.h"
-
-#include <QtCore/QObject>
-#include <QtTest/QtTest>
-#include <KDE/KSystemTimeZones>
-#include <kcalcore/recurrence.h>
-
-#include <lib/kolabkcalconversion.h>
-#include <lib/kolabkcalconversion.cpp>
-#include <lib/calendaring.h>
-
-#include "serializers.h"
-
-using namespace Kolab::KCalConversion;
-
-Q_DECLARE_METATYPE(Kolab::Duration);
-Q_DECLARE_METATYPE(Kolab::cDateTime);
-Q_DECLARE_METATYPE(Kolab::Event);
-Q_DECLARE_METATYPE(Kolab::Todo);
-Q_DECLARE_METATYPE(Kolab::Journal);
-Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
-Q_DECLARE_METATYPE(KCalCore::Event);
-Q_DECLARE_METATYPE(KCalCore::Todo);
-Q_DECLARE_METATYPE(KCalCore::Journal);
-Q_DECLARE_METATYPE(KCalCore::Duration);
-
-namespace QTest {
-    
-    template<>
-    char *toString(const KDateTime &dt)
-    {
-        QByteArray ba = "KDateTime(";
-        ba += dt.toString().toAscii();
-        ba += dt.timeZone().name();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Attendee &at)
-    {
-        QByteArray ba = "Attendee(";
-        ba += at.name().toAscii() + ", ";
-        ba += at.email().toAscii() + ", ";
-        ba += QString::number(at.role()) + ", ";
-        ba += QString::number(at.status()) + ", ";
-        ba += QString::number(at.RSVP()) + ", ";
-        ba += at.delegate().toAscii() + ", ";
-        ba += at.delegator().toAscii() + ", ";
-        ba += at.uid().toAscii() + ", ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    
-    template<>
-    char *toString(const QList<int> &l)
-    {
-        QByteArray ba = "QList<int>(";
-        foreach(int i, l) {
-            ba += QString::number(i) + ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const QList<KCalCore::RecurrenceRule::WDayPos> &l)
-    {
-        QByteArray ba = "QList<int>(";
-        foreach(const KCalCore::RecurrenceRule::WDayPos &i, l) {
-            ba += QString::number(i.pos()) + " ";
-            ba += QString::number(i.day()) + ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::DateList &l)
-    {
-        QByteArray ba = "KCalCore::DateList(";
-        foreach(const QDate &i, l) {
-            ba += i.toString();
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::DateTimeList &l)
-    {
-        QByteArray ba = "KCalCore::DateTimeList(";
-        foreach(const KDateTime &i, l) {
-            ba += toString(i);
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Recurrence &at)
-    {
-        at.dump();
-        KCalCore::RecurrenceRule *r = at.defaultRRule();
-        QByteArray ba;
-        if (!r) {
-            ba += "Recurrence( )";
-        } else {
-            Q_ASSERT(r);
-            Q_ASSERT(at.rRules().size() == 1);
-            
-            ba += "Recurrence(";
-            ba += QString::number(r->recurrenceType()) + "\n";
-            ba += QString::number(r->frequency()) + "\n";
-            ba += QString::number(r->duration()) + "\n";
-            ba += QByteArray(toString(r->startDt())) + "\n";
-            ba += QByteArray(toString(r->endDt())) + "\n";
-            ba += QByteArray(toString(r->bySeconds())) + "\n";
-            ba += QByteArray(toString(r->byMinutes())) + "\n";
-            ba += QByteArray(toString(r->byHours())) + "\n";
-            ba += QByteArray(toString(r->byDays())) + "\n";
-            ba += QByteArray(toString(r->byMonthDays())) + "\n";
-            ba += QByteArray(toString(r->byYearDays())) + "\n";
-            ba += QByteArray(toString(r->byMonths())) + "\n";
-            ba += ")\n";
-            ba += QByteArray(toString(at.exDates())) + "\n";
-            ba += QByteArray(toString(at.exDateTimes())) + "\n";
-            ba += QByteArray(toString(at.rDates())) + "\n";
-            ba += QByteArray(toString(at.rDateTimes())) + "\n";
-            
-        }
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::RecurrenceRule &at)
-    {
-        QByteArray ba;
-        ba += "KolabRecurrenceRule(";
-        ba += QString::number(at.weekStart()) + "\n";
-        ba += QString::number(at.frequency()) + "\n";
-        ba += QString::number(at.interval()) + "\n";
-        ba += QString::number(at.count()) + "\n";
-        ba += QByteArray(toString(at.end())) + "\n";
-        ba += QByteArray(toString(at.bysecond())) + "\n";
-        ba += QByteArray(toString(at.byminute())) + "\n";
-        ba += QByteArray(toString(at.byhour())) + "\n";
-        ba += QByteArray(toString(at.byday())) + "\n";
-        ba += QByteArray(toString(at.bymonthday())) + "\n";
-        ba += QByteArray(toString(at.byyearday())) + "\n";
-        ba += QByteArray(toString(at.byweekno())) + "\n";
-        ba += QByteArray(toString(at.bymonth())) + "\n";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::Duration &d)
-    {
-        QByteArray ba;
-        ba += "KCalCore::Duration(";
-        ba += QString::number(d.isDaily()) + ", ";
-        ba += QString::number(d.value()) + " ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-
-}
-
-template <typename T>
-void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
-{
-    QCOMPARE(list.size(), other.size());
-    for (int i = 0 ; i < list.size(); i++) {
-        QCOMPARE(*list.at(i), *other.at(i));
-    }
-}
-
-
-void KCalConversionTest::testDate_data()
-{
-    QTest::addColumn<Kolab::cDateTime>( "input" );
-    QTest::addColumn<KDateTime>( "result" );
-
-    QTest::newRow( "datetime with tz" ) << Kolab::cDateTime("Europe/Zurich",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Zurich"));
-    QTest::newRow( "floating datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, false) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::Spec(KDateTime::ClockTime));
-    QTest::newRow( "utc datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, true) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
-    QTest::newRow( "date only" ) << Kolab::cDateTime(2006,1,8) << KDateTime(QDate(2006, 1, 8));
-}
-
-
-void KCalConversionTest::testDate()
-{
-    QFETCH(Kolab::cDateTime, input);
-    QFETCH(KDateTime, result);
-    
-    const KDateTime &r = Kolab::KCalConversion::toDate(input);
-    QCOMPARE(r, result);
-    
-    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
-    QCOMPARE(r2, input);
-}
-
-void KCalConversionTest::testDuration_data()
-{
-    QTest::addColumn<Kolab::Duration>( "input" );
-    QTest::addColumn<KCalCore::Duration>( "result" );
-    QTest::addColumn<Kolab::Duration>( "fromResult" );
-    
-    QTest::newRow( "seconds" ) << Kolab::Duration(0,0,0,30,false) << KCalCore::Duration(30, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,30,false);
-    QTest::newRow( "minutes" ) << Kolab::Duration(0,0,1,30,false) << KCalCore::Duration(90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,90,false);
-    QTest::newRow( "hours" ) << Kolab::Duration(0,1,1,30,false) << KCalCore::Duration(60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,60*60+90,false);
-    QTest::newRow( "days" ) << Kolab::Duration(1,1,1,30,false) << KCalCore::Duration(24*60*60+60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,24*60*60+60*60+90,false);
-    QTest::newRow( "daysonly" ) << Kolab::Duration(30,0,0,0, false) << KCalCore::Duration(30, KCalCore::Duration::Days) << Kolab::Duration(30,0,0,0,false);
-    QTest::newRow( "weeks" ) << Kolab::Duration(30,false) << KCalCore::Duration(30*7, KCalCore::Duration::Days) << Kolab::Duration(30*7,0,0,0,false);
-}
-
-
-void KCalConversionTest::testDuration()
-{
-    QFETCH(Kolab::Duration, input);
-    QFETCH(KCalCore::Duration, result);
-    QFETCH(Kolab::Duration, fromResult);
-    
-    const KCalCore::Duration &r = Kolab::KCalConversion::toDuration(input);
-    QCOMPARE(r, result);
-    
-    const Kolab::Duration &r2 = Kolab::KCalConversion::fromDuration(result);
-    QCOMPARE(r2, fromResult);
-}
-
-
-void KCalConversionTest::testDateTZ_data()
-{
-    QTest::addColumn<Kolab::cDateTime>( "input" );
-    QTest::addColumn<KDateTime>( "result" );
-    QTest::addColumn<int>( "offset" );
-       
-    QTest::newRow( "berlin" ) << Kolab::cDateTime("Europe/Berlin",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Berlin")) << 3600;
-}
-
-void KCalConversionTest::testDateTZ()
-{
-    QFETCH(Kolab::cDateTime, input);
-    QFETCH(KDateTime, result);
-    QFETCH(int, offset);
-    
-    const KDateTime &r = Kolab::KCalConversion::toDate(input);
-    QCOMPARE(result.timeZone().name(), QString::fromStdString(input.timezone()));
-    QCOMPARE(r.timeZone().currentOffset(), offset);
-    
-    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
-    QCOMPARE(QString::fromStdString(r2.timezone()), result.timeZone().name());
-}
-
-
-void KCalConversionTest::testConversion_data()
-{
-    QTest::addColumn<KCalCore::Event>( "kcal" );
-    QTest::addColumn<Kolab::Event>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    Kolab::cDateTime date3(2012,2,2,12,12,10);
-    std::vector<int> intVector;
-    intVector.push_back(1);
-    intVector.push_back(-3);
-    intVector.push_back(2);
-    std::vector<std::string> stringVector;
-    stringVector.push_back("cat1");
-    stringVector.push_back("cat2");
-    stringVector.push_back("parent/child");
-    
-    {
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setRevision(3);
-        kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
-        kcal.setCategories(toStringList(stringVector));
-        kcal.setDtStart(toDate(date));
-        kcal.setDtEnd(toDate(date2));
-        kcal.setTransparency(KCalCore::Event::Transparent);
-        
-        kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setDuration(5);
-        kcal.recurrence()->addRDateTime(toDate(date2));
-        kcal.recurrence()->addRDate(toDate(date2).date());
-        kcal.recurrence()->addExDateTime(toDate(date3));
-        kcal.recurrence()->addExDate(toDate(date3).date());
-        
-        KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
-        QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
-        rr->setBySeconds(intList);
-        rr->setByMinutes(intList);
-        rr->setByHours(intList);
-        rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,1) << KCalCore::RecurrenceRule::WDayPos(5,4));
-        rr->setByMonthDays(intList);
-        rr->setByYearDays(intList);
-        rr->setByMonths(intList);
-        rr->setByWeekNumbers(intList);
-        
-        kcal.setSummary("summary");
-        kcal.setDescription("description");
-        kcal.setPriority(3);
-        kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
-        kcal.setLocation("location");
-        kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
-        kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant)));
-        //TODO KCalCore Delegate/Delegator
-        kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
-        KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
-        KCalCore::Person::List addressees;
-        addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
-        alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
-        kcal.addAlarm(alarm);
-        //TODO alarms
-        //TODO custom properties
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setSequence(3);
-        kolab.setClassification(Kolab::ClassConfidential);
-        kolab.setCategories(stringVector);
-        kolab.setStart(date);
-        kolab.setEnd(date2);
-        kolab.setTransparency(true);
-        
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setCount(5);
-        rrule.setBysecond(intVector);
-        rrule.setByminute(intVector);
-        rrule.setByhour(intVector);
-        rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
-        rrule.setBymonthday(intVector);
-        rrule.setByyearday(intVector);
-        rrule.setByweekno(intVector);
-        rrule.setBymonth(intVector);
-        
-        kolab.setRecurrenceRule(rrule);
-        kolab.setRecurrenceID(date2, true);
-        kolab.setRecurrenceDates(std::vector<Kolab::cDateTime>() << date2 << Kolab::cDateTime(date2.year(), date2.month(), date2.day()));
-        kolab.setExceptionDates(std::vector<Kolab::cDateTime>() << date3 << Kolab::cDateTime(date3.year(), date3.month(), date3.day()));
-        
-        kolab.setSummary("summary");
-        kolab.setDescription("description");
-        kolab.setPriority(3);
-        kolab.setStatus(Kolab::StatusConfirmed);
-        kolab.setLocation("location");
-        kolab.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"organizer at email", "organizer")); //TODO uid
-        
-        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"attendee at email", "attendee"));//TODO uid
-        kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
-        
-        Kolab::Attachment attach;
-        attach.setUri("uri", "mimetype/mime");
-        kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
-        
-    //     std::vector<std::string> receipents;
-    //     receipents.push_back("email at email");
-    //     Kolab::Alarm alarm2("summary", "description", receipents);
-    //     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
-
-        QTest::newRow( "with endDate and recurrence duration" ) << kcal << kolab;
-    }
-    {
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setRevision(3);
-        kcal.setDtStart(toDate(date));
-        kcal.setDuration(KCalCore::Duration(toDate(date), toDate(date2)));
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setEndDateTime(toDate(date3));
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setSequence(3);
-        kolab.setStart(date);
-        kolab.setDuration(Kolab::Duration(0, 0, 1, 0));
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setEnd(date3);
-        kolab.setRecurrenceRule(rrule);
-        
-        QTest::newRow("with duration and recurrence endDate") << kcal << kolab;
-    }
-    {
-        Kolab::cDateTime start(2011,1,1);
-        Kolab::cDateTime end(2011,1,3);
-        
-        KCalCore::Event kcal;
-        kcal.setUid("uid");
-        kcal.setCreated(toDate(date));
-        kcal.setLastModified(toDate(date));
-        kcal.setDtStart(toDate(start));
-        kcal.setDtEnd(toDate(end));
-        kcal.recurrence()->setDaily(3);
-        kcal.recurrence()->setEndDateTime(toDate(end));
-        
-        Kolab::Event kolab;
-        kolab.setUid("uid");
-        kolab.setCreated(date);
-        kolab.setLastModified(date);
-        kolab.setStart(start);
-        kolab.setEnd(end);
-        Kolab::RecurrenceRule rrule;
-        rrule.setInterval(3);
-        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-        rrule.setEnd(end);
-        kolab.setRecurrenceRule(rrule);
-        
-        QTest::newRow("date only dates") << kcal << kolab;
-    }
-}
-
-void KCalConversionTest::testConversion()
-{
-    QFETCH(KCalCore::Event, kcal);
-    QFETCH(Kolab::Event, kolab);
-    
-    const KCalCore::Event::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->created(), kcal.created());
-    QCOMPARE(e->lastModified(), kcal.lastModified());
-    QCOMPARE(e->revision(), kcal.revision());
-    QCOMPARE(e->secrecy(), kcal.secrecy());
-    QCOMPARE(e->categories(), kcal.categories());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->dtEnd(), kcal.dtEnd());
-    QCOMPARE(e->duration(), kcal.duration());
-    QCOMPARE(e->transparency(), kcal.transparency());
-    QCOMPARE(*e->recurrence(), *kcal.recurrence());
-    QCOMPARE(e->recurrenceId(), kcal.recurrenceId());
-    QCOMPARE(e->recurrenceType(), kcal.recurrenceType());
-    QCOMPARE(e->summary(), kcal.summary());
-    QCOMPARE(e->description(), kcal.description());
-    QCOMPARE(e->priority(), kcal.priority());
-    QCOMPARE(e->status(), kcal.status());
-    QCOMPARE(e->location(), kcal.location());
-    QCOMPARE(e->organizer()->name(), kcal.organizer()->name());
-    QCOMPARE(e->organizer()->email(), kcal.organizer()->email());
-    comparePointerVectors(e->attendees(), kcal.attendees());
-    comparePointerVectors(e->attachments(), kcal.attachments());
-    
-//     QCOMPARE(e->alarms(), kcal.alarms()); //TODO
-//TODO custom properties
-
-    QBENCHMARK {
-        toKCalCore(kolab);
-    }
-    
-    const Kolab::Event &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.created(), kolab.created());
-    QCOMPARE(b.lastModified(), kolab.lastModified());
-    QCOMPARE(b.sequence(), kolab.sequence());
-    QCOMPARE(b.classification(), kolab.classification());
-    QCOMPARE(b.categories(), kolab.categories());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.end(), kolab.end());
-    QCOMPARE(b.duration(), kolab.duration());
-    QCOMPARE(b.transparency(), kolab.transparency());
-    
-    QCOMPARE(b.recurrenceRule(), kolab.recurrenceRule());
-    QCOMPARE(b.recurrenceID(), kolab.recurrenceID());
-    QCOMPARE(b.recurrenceDates(), kolab.recurrenceDates());
-    QCOMPARE(b.exceptionDates(), kolab.exceptionDates());
-    
-    QCOMPARE(b.summary(), kolab.summary());
-    QCOMPARE(b.description(), kolab.description());
-    QCOMPARE(b.status(), kolab.status());
-}
-
-
-void KCalConversionTest::testTodoConversion_data()
-{
-    QTest::addColumn<KCalCore::Todo>( "kcal" );
-    QTest::addColumn<Kolab::Todo>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    
-    {
-        KCalCore::Todo kcal;
-        kcal.setUid("uid");
-        kcal.setDtStart(toDate(date));
-        kcal.setDtDue(toDate(date2));
-        
-        Kolab::Todo kolab;
-        kolab.setUid("uid");
-        kolab.setStart(date);
-        kolab.setDue(date2);
-
-        QTest::newRow( "todo" ) << kcal << kolab;
-    }
-}
-
-
-void KCalConversionTest::testTodoConversion()
-{
-    QFETCH(KCalCore::Todo, kcal);
-    QFETCH(Kolab::Todo, kolab);
-    
-    const KCalCore::Todo::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->dtDue(), kcal.dtDue());
-   
-    const Kolab::Todo &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.due(), kolab.due());
-}
-
-void KCalConversionTest::testJournalConversion_data()
-{
-    QTest::addColumn<KCalCore::Journal>( "kcal" );
-    QTest::addColumn<Kolab::Journal>( "kolab" );
-    
-    Kolab::cDateTime date(2011,2,2,12,11,10);
-    Kolab::cDateTime date2(2011,2,2,12,12,10);
-    
-    {
-        KCalCore::Journal kcal;
-        kcal.setUid("uid");
-        kcal.setDtStart(toDate(date));
-        kcal.setSummary("summary");
-        
-        Kolab::Journal kolab;
-        kolab.setUid("uid");
-        kolab.setStart(date);
-        kolab.setSummary("summary");
-        
-        QTest::newRow( "journal" ) << kcal << kolab;
-    }
-}
-
-
-void KCalConversionTest::testJournalConversion()
-{
-    QFETCH(KCalCore::Journal, kcal);
-    QFETCH(Kolab::Journal, kolab);
-    
-    const KCalCore::Journal::Ptr e = toKCalCore(kolab);
-    
-    QCOMPARE(e->uid(), kcal.uid());
-    QCOMPARE(e->dtStart(), kcal.dtStart());
-    QCOMPARE(e->summary(), kcal.summary());
-    
-    const Kolab::Journal &b = fromKCalCore(kcal);
-    QCOMPARE(b.uid(), kolab.uid());
-    QCOMPARE(b.start(), kolab.start());
-    QCOMPARE(b.summary(), kolab.summary());
-}
-
-
-void KCalConversionTest::testEventConflict_data()
-{
-    QTest::addColumn<Kolab::Event>( "e1" );
-    QTest::addColumn<Kolab::Event>( "e2" );
-    QTest::addColumn<bool>( "result" );
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1));
-        
-        QTest::newRow( "after" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1));
-        
-        QTest::newRow( "before" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
-        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
-        
-        QTest::newRow( "conflict" ) << e1 << e2 << true;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
-    }
-}
-
-void KCalConversionTest::testEventConflict()
-{
-    QFETCH(Kolab::Event, e1);
-    QFETCH(Kolab::Event, e2);
-    QFETCH(bool, result);
-    QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
-}
-
-
-
-void KCalConversionTest::testTimesInInterval_data()
-{
-    QTest::addColumn<Kolab::Event>( "event" );
-    QTest::addColumn<Kolab::cDateTime>( "start" );
-    QTest::addColumn<Kolab::cDateTime>( "end" );
-    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
-    {
-        {
-            Kolab::Event event;
-            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
-            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
-            Kolab::RecurrenceRule rrule;
-            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-            rrule.setInterval(1);
-            rrule.setCount(5);
-            event.setRecurrenceRule(rrule);
-
-            std::vector<Kolab::cDateTime> result;
-            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1)); 
-            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1));
-            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1)); 
-            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1));
-            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1)); 
-            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1) << Kolab::cDateTime(2011,1,5,1,1,1) << result;
-        }
-    }
-}
-
-void KCalConversionTest::testTimesInInterval()
-{
-    QFETCH(Kolab::Event, event);
-    QFETCH(Kolab::cDateTime, start);
-    QFETCH(Kolab::cDateTime, end);
-    QFETCH(std::vector<Kolab::cDateTime>, result);
-    QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
-}
-
-void KCalConversionTest::testTimesInIntervalBenchmark()
-{
-    Kolab::Event event;
-    event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
-    event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
-    Kolab::RecurrenceRule rrule;
-    rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-    rrule.setInterval(1);
-    rrule.setCount(500);
-    event.setRecurrenceRule(rrule);
-    
-    QBENCHMARK {
-        Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-    }
-    const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-    QVERIFY(result.size() == 500);
-//     qDebug() << QTest::toString(result);    
-}
-
-
-
-QTEST_MAIN( KCalConversionTest )
-
-#include "kcalconversiontest.moc"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
deleted file mode 100644
index fa926a5..0000000
--- a/c++/tests/kcalconversiontest.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef KCALCONVERSIONTEST_H
-#define KCALCONVERSIONTEST_H
-
-#include <QtCore/QObject>
-#include <QtTest/QtTest>
-
-class KCalConversionTest : public QObject
-{
-  Q_OBJECT
-  private slots:
-
-    void testDate_data();
-    void testDate();
-    
-    void testDuration_data();
-    void testDuration();
-    
-    void testConversion_data();
-    void testConversion();
-
-    void testTodoConversion_data();
-    void testTodoConversion();
-    
-    void testJournalConversion_data();
-    void testJournalConversion();
-    
-    void testDateTZ_data();
-    void testDateTZ();
-
-    void testEventConflict_data();
-    void testEventConflict();
-    
-    void testTimesInInterval_data();
-    void testTimesInInterval();
-    void testTimesInIntervalBenchmark();
-};
-
-#endif
\ No newline at end of file
diff --git a/libkolabkcal/kolabkcalconversion.cpp b/libkolabkcal/kolabkcalconversion.cpp
new file mode 100644
index 0000000..bb1e0c3
--- /dev/null
+++ b/libkolabkcal/kolabkcalconversion.cpp
@@ -0,0 +1,746 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabkcalconversion.h"
+
+#include <kcalcore/recurrence.h>
+#include <QtCore/QBitArray>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+#include <vector>
+#include <KDE/KSystemTimeZones>
+
+namespace Kolab {
+namespace KCalConversion {
+
+KDateTime toDate(const Kolab::cDateTime &dt)
+{
+    KDateTime date;
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return KDateTime();
+    }
+    if (dt.isDateOnly()) { //Date only
+        date.setDateOnly(true);
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
+    } else {
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
+        if (dt.isUTC()) { //UTC
+            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        } else if (!dt.timezone().empty()) { //Timezone
+            const KTimeZone &tz = KSystemTimeZones::zone(QString::fromStdString(dt.timezone())); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+            if (!tz.isValid()) {
+                qWarning() << "timezone not found" << QString::fromStdString(dt.timezone());
+                if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
+                    qWarning() << "ktimezoned is not available and required for timezone interpretation";
+                }
+            }
+            date.setTimeSpec(KDateTime::Spec(tz));
+        } else { //Floating
+            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
+        }
+    }
+    Q_ASSERT(date.timeSpec().isValid());
+    Q_ASSERT(date.isValid());
+    return date;
+}
+
+cDateTime fromDate(const KDateTime &dt)
+{
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return cDateTime();
+    }
+    cDateTime date;
+    if (dt.isDateOnly()) { //Date only
+        const QDate &d = dt.date();
+        date.setDate(d.year(), d.month(), d.day());
+    } else {
+        const QDate &d = dt.date();
+        date.setDate(d.year(), d.month(), d.day());
+        const QTime &t = dt.time();
+        date.setTime(t.hour(), t.minute(), t.second());
+        if (dt.timeType() == KDateTime::UTC) { //UTC
+            date.setUTC(true);
+        } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
+            //TODO handle local timezone?
+            date.setTimezone(dt.timeZone().name().toStdString()); //FIXME use system independent name according to spec
+        } else if (dt.timeType() != KDateTime::ClockTime) {
+            qWarning() << "invalid timespec, assuming floating time" << dt.timeType();
+            return cDateTime();
+        }
+    }
+    Q_ASSERT(date.isValid());
+    return date;
+}
+
+KCalCore::Duration toDuration(const Kolab::Duration &d)
+{
+    //TODO should we support negative durations?
+    if (d.hours() || d.minutes() || d.seconds()) {
+        return KCalCore::Duration(((((d.weeks() * 7 + d.days()) * 24 + d.hours()) * 60 + d.minutes()) * 60 + d.seconds()));
+    }
+    return KCalCore::Duration(d.weeks() * 7 + d.days(), KCalCore::Duration::Days);
+}
+
+Kolab::Duration fromDuration(const KCalCore::Duration &d)
+{
+    if (d.value() <= 0) {
+        return Kolab::Duration();
+    }
+    //We don't know how the seconds/days were distributed before, so no point in distributing them (probably)
+    //TODO should we support negative durations?
+    if (d.isDaily()) {
+        int days = d.value();
+        return Kolab::Duration(days, 0, 0, 0, false);
+    }
+    int seconds = d.value();
+//         int minutes = seconds / 60;
+//         seconds = seconds % 60;
+//         int hours = minutes / 60;
+//         minutes = minutes % 60;
+    return Kolab::Duration(0, 0, 0, seconds, false);
+
+}
+
+KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
+{
+    switch(c) {
+        case Kolab::ClassPublic:
+            return KCalCore::Incidence::SecrecyPublic;
+        case Kolab::ClassPrivate:
+            return KCalCore::Incidence::SecrecyPrivate;
+        case Kolab::ClassConfidential:
+            return KCalCore::Incidence::SecrecyConfidential;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Incidence::SecrecyPublic;
+}
+
+Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
+{
+    switch(c) {
+        case KCalCore::Incidence::SecrecyPublic:
+            return Kolab::ClassPublic;
+        case KCalCore::Incidence::SecrecyPrivate:
+            return Kolab::ClassPrivate;
+        case KCalCore::Incidence::SecrecyConfidential:
+            return Kolab::ClassConfidential;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::ClassPublic;
+}
+
+int toPriority(int priority)
+{
+    //Same mapping
+    return priority;
+}
+
+int fromPriority(int priority)
+{
+    //Same mapping
+    return priority;
+}
+
+KCalCore::Incidence::Status toStatus(Kolab::Status s)
+{
+    switch (s) {
+        case StatusUndefined:
+            return  KCalCore::Incidence::StatusNone;
+        case StatusNeedsAction:
+            return  KCalCore::Incidence::StatusNeedsAction;
+        case StatusCompleted:
+            return  KCalCore::Incidence::StatusCompleted;
+        case StatusInProcess:
+            return  KCalCore::Incidence::StatusInProcess;
+        case StatusCancelled:
+            return  KCalCore::Incidence::StatusCanceled;
+        case StatusTentative:
+            return  KCalCore::Incidence::StatusTentative;
+        case StatusConfirmed:
+            return  KCalCore::Incidence::StatusConfirmed;
+        case StatusDraft:
+            return  KCalCore::Incidence::StatusDraft;
+        case StatusFinal:
+            return  KCalCore::Incidence::StatusFinal;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Incidence::StatusNone;
+}
+
+Kolab::Status fromStatus(KCalCore::Incidence::Status s)
+{
+    switch (s) {
+        case KCalCore::Incidence::StatusNone:
+            return StatusUndefined;
+        case KCalCore::Incidence::StatusNeedsAction:
+            return StatusNeedsAction;
+        case KCalCore::Incidence::StatusCompleted:
+            return StatusCompleted;
+        case KCalCore::Incidence::StatusInProcess:
+            return StatusInProcess;
+        case KCalCore::Incidence::StatusCanceled:
+            return StatusCancelled;
+        case KCalCore::Incidence::StatusTentative:
+            return StatusTentative;
+        case KCalCore::Incidence::StatusConfirmed:
+            return StatusConfirmed;
+        case KCalCore::Incidence::StatusDraft:
+            return StatusDraft;
+        case KCalCore::Incidence::StatusFinal:
+            return StatusFinal;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return StatusUndefined;
+}
+
+QStringList toStringList(const std::vector<std::string> &l)
+{
+    QStringList list;
+    foreach(const std::string &s, l) {
+        list.append(QString::fromStdString(s));
+    }
+    return list;
+}
+
+std::vector<std::string> fromStringList(const QStringList &l)
+{
+    std::vector<std::string> list;
+    foreach(const QString &s, l) {
+        list.push_back(s.toStdString());
+    }
+    return list;
+}
+
+KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
+{
+    switch (p) {
+        case PartNeedsAction:
+            return KCalCore::Attendee::NeedsAction;
+        case PartAccepted:
+            return KCalCore::Attendee::Accepted;
+        case PartDeclined:
+            return KCalCore::Attendee::Declined;
+        case PartTentative:
+            return KCalCore::Attendee::Tentative;
+        case PartDelegated:
+            return KCalCore::Attendee::Delegated;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Attendee::NeedsAction;
+}
+
+Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
+{
+    switch (p) {
+        case KCalCore::Attendee::NeedsAction:
+            return PartNeedsAction;
+        case KCalCore::Attendee::Accepted:
+            return PartAccepted;
+        case KCalCore::Attendee::Declined:
+            return PartDeclined;
+        case KCalCore::Attendee::Tentative:
+            return PartTentative;
+        case KCalCore::Attendee::Delegated:
+            return PartDelegated;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return PartNeedsAction;
+}
+
+KCalCore::Attendee::Role toRole(Kolab::Role r)
+{
+    switch (r) {
+        case Required:
+            return KCalCore::Attendee::ReqParticipant;
+        case Chair:
+            return KCalCore::Attendee::Chair;
+        case Optional:
+            return KCalCore::Attendee::OptParticipant;
+        case NonParticipant:
+            return KCalCore::Attendee::NonParticipant;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::Attendee::ReqParticipant;
+}
+
+Kolab::Role fromRole(KCalCore::Attendee::Role r)
+{
+    switch (r) {
+        case KCalCore::Attendee::ReqParticipant:
+            return Required;
+        case KCalCore::Attendee::Chair:
+            return Chair;
+        case KCalCore::Attendee::OptParticipant:
+            return Optional;
+        case KCalCore::Attendee::NonParticipant:
+            return NonParticipant;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Required;
+}
+
+template <typename T>
+void setIncidence(KCalCore::Incidence &i, const T &e)
+{
+    if (!e.uid().empty()) {
+        i.setUid(QString::fromStdString(e.uid()));
+    }
+    
+    i.setCreated(toDate(e.created()));
+    i.setLastModified(toDate(e.lastModified()));
+    i.setRevision(e.sequence());
+    i.setSecrecy(toSecrecy(e.classification()));
+    i.setCategories(toStringList(e.categories()));
+    
+    if (e.start().isValid()) {
+        i.setDtStart(toDate(e.start()));
+    }
+
+    i.setSummary(QString::fromStdString(e.summary())); //TODO detect richtext
+    i.setDescription(QString::fromStdString(e.description())); //TODO detect richtext
+    i.setStatus(toStatus(e.status()));
+    foreach (const Kolab::Attendee a, e.attendees()) {
+        //We shouldn't rely on a uid if we're going with mail+name and not on mail+name if we're going with UID (of ical btw. and not kaddresee)
+        i.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(QString::fromStdString(a.contact().name()), 
+                                                                     QString::fromStdString(a.contact().email()),  //TODO handle uid
+                                                                     a.rsvp(),
+                                                                     toPartStat(a.partStat()),
+                                                                     toRole(a.role()) ))); //FIXME doesn't make sense to set both, either email or uid
+    }
+    foreach (const Kolab::Attachment a, e.attachments()) {
+        KCalCore::Attachment::Ptr ptr;
+        if (!a.uri().empty()) {
+            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString::fromStdString(a.uri()), QString::fromStdString(a.mimetype())));
+        } else {
+            ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), QString::fromStdString(a.mimetype())));
+        }
+        if (!a.label().empty()) {
+            ptr->setLabel(QString::fromStdString(a.label()));
+        }
+        i.addAttachment(ptr);
+    }
+//     i.addAlarm(); //TODO
+//     i.setCustomProperties(); //TODO
+}
+
+template <typename T, typename I>
+void getIncidence(T &i, const I &e)
+{
+    i.setUid(e.uid().toStdString());
+    i.setCreated(fromDate(e.created()));
+    i.setLastModified(fromDate(e.lastModified()));
+    i.setSequence(e.revision());
+    i.setClassification(fromSecrecy(e.secrecy()));
+    i.setCategories(fromStringList(e.categories()));
+    
+    i.setStart(fromDate(e.dtStart()));
+    i.setSummary(e.summary().toStdString());
+    i.setDescription(e.description().toStdString());
+    i.setStatus(fromStatus(e.status()));
+    std::vector<Kolab::Attendee> attendees;
+    foreach (const KCalCore::Attendee::Ptr ptr, e.attendees()) {
+        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference, ptr->email().toStdString(), ptr->name().toStdString())); //TODO handle uid
+        a.setRSVP(ptr->RSVP());
+        a.setPartStat(fromPartStat(ptr->status()));
+        a.setRole(fromRole(ptr->role()));
+//         a.setUid(ptr->uid().toStdString()); //TODO
+        attendees.push_back(a);
+    }
+    i.setAttendees(attendees);
+    std::vector<Kolab::Attachment> attachments;
+    foreach (const KCalCore::Attachment::Ptr ptr, e.attachments()) {
+        Kolab::Attachment a;
+        if (ptr->isUri()) {
+            a.setUri(ptr->uri().toStdString(), ptr->mimeType().toStdString());
+        } else {
+            a.setData(std::string(ptr->decodedData().data(), ptr->decodedData().size()), ptr->mimeType().toStdString());
+        }
+        a.setLabel(ptr->label().toStdString());
+        attachments.push_back(a);
+    }
+    i.setAttachments(attachments);
+    //TODO alarms
+    //TODO custom properties
+}
+
+int toWeekDay(Kolab::Weekday wday)
+{
+    switch (wday) {
+        case Kolab::Monday:
+            return  1;
+        case Kolab::Tuesday:
+            return 2;
+        case Kolab::Wednesday:
+            return 3;
+        case Kolab::Thursday:
+            return 4;
+        case Kolab::Friday:
+            return 5;
+        case Kolab::Saturday:
+            return 6;
+        case Kolab::Sunday:
+            return 7;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return 1;
+}
+
+Kolab::Weekday fromWeekDay(int wday)
+{
+    switch (wday) {
+        case 1:
+            return Kolab::Monday;
+        case 2:
+            return Kolab::Tuesday;
+        case 3:
+            return Kolab::Wednesday;
+        case 4:
+            return Kolab::Thursday;
+        case 5:
+            return Kolab::Friday;
+        case 6:
+            return Kolab::Saturday;
+        case 7:
+            return Kolab::Sunday;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::Monday;
+}
+
+KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
+{
+    switch(freq) {
+        case Kolab::RecurrenceRule::FreqNone:
+            qWarning() << "no recurrence?";
+            break;
+        case Kolab::RecurrenceRule::Yearly:
+            return KCalCore::RecurrenceRule::rYearly;
+        case Kolab::RecurrenceRule::Monthly:
+            return KCalCore::RecurrenceRule::rMonthly;
+        case Kolab::RecurrenceRule::Weekly:
+            return KCalCore::RecurrenceRule::rWeekly;
+        case Kolab::RecurrenceRule::Daily:
+            return KCalCore::RecurrenceRule::rDaily;
+        case Kolab::RecurrenceRule::Hourly:
+            return KCalCore::RecurrenceRule::rHourly;
+        case Kolab::RecurrenceRule::Minutely:
+            return KCalCore::RecurrenceRule::rMinutely;
+        case Kolab::RecurrenceRule::Secondly:
+            return KCalCore::RecurrenceRule::rSecondly;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return KCalCore::RecurrenceRule::rNone;
+}
+
+Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
+{
+    switch(freq) {
+        case KCalCore::RecurrenceRule::rNone:
+            qWarning() << "no recurrence?";
+            break;
+        case KCalCore::RecurrenceRule::rYearly:
+            return Kolab::RecurrenceRule::Yearly;
+        case KCalCore::RecurrenceRule::rMonthly:
+            return Kolab::RecurrenceRule::Monthly;
+        case KCalCore::RecurrenceRule::rWeekly:
+            return Kolab::RecurrenceRule::Weekly;
+        case KCalCore::RecurrenceRule::rDaily:
+            return Kolab::RecurrenceRule::Daily;
+        case KCalCore::RecurrenceRule::rHourly:
+            return Kolab::RecurrenceRule::Hourly;
+        case KCalCore::RecurrenceRule::rMinutely:
+            return Kolab::RecurrenceRule::Minutely;
+        case KCalCore::RecurrenceRule::rSecondly:
+            return Kolab::RecurrenceRule::Secondly;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::RecurrenceRule::FreqNone;
+}
+
+KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
+{
+    return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday()));
+}
+
+Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
+{
+    return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()));
+}
+
+template <typename T>
+void setRecurrence(KCalCore::Incidence &e, const T &event)
+{
+    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
+    if (rrule.isValid()) {
+        KCalCore::Recurrence *rec = e.recurrence();
+        
+        KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
+        Q_ASSERT(defaultRR);
+        
+        defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
+        defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
+        defaultRR->setFrequency(rrule.interval());
+        
+        if (rrule.end().isValid()) {
+            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
+        } else {
+            rec->setDuration(rrule.count());
+        }
+        
+        if (!rrule.bysecond().empty()) {
+            defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
+        }
+        if (!rrule.byminute().empty()) {
+            defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
+        }
+        if (!rrule.byhour().empty()) {
+            defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
+        }
+        if (!rrule.byday().empty()) {
+            QList<KCalCore::RecurrenceRule::WDayPos> daypos;
+            foreach(const Kolab::DayPos &dp, rrule.byday()) {
+                daypos.append(toWeekDayPos(dp));
+            }
+            defaultRR->setByDays(daypos);
+        }
+        if (!rrule.bymonthday().empty()) {
+            defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
+        }
+        if (!rrule.byyearday().empty()) {
+            defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
+        }
+        if (!rrule.byweekno().empty()) {
+            defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
+        }
+        if (!rrule.bymonth().empty()) {
+            defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
+        }
+    }
+    foreach (const Kolab::cDateTime &dt, event.recurrenceDates()) {
+        const KDateTime &date = toDate(dt);
+        if (date.isDateOnly()) {
+            e.recurrence()->addRDate(date.date());
+        } else {
+            e.recurrence()->addRDateTime(date);
+        }
+    }
+    foreach (const Kolab::cDateTime &dt, event.exceptionDates()) {
+        const KDateTime &date = toDate(dt);
+        if (date.isDateOnly()) {
+            e.recurrence()->addExDate(date.date());
+        } else {
+            e.recurrence()->addExDateTime(date);
+        }
+    }
+
+}
+
+template <typename T, typename I>
+void getRecurrence(T &i, const I &e)
+{
+    if (!e.recurs()) {
+        return;
+    }
+    KCalCore::Recurrence *rec = e.recurrence();
+    KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
+    if (!defaultRR) {
+        qWarning() << "no recurrence";
+        return;
+    }
+    Q_ASSERT(defaultRR);
+
+    Kolab::RecurrenceRule rrule;
+    rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
+    rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
+    rrule.setInterval(defaultRR->frequency());
+  
+    if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
+        if (defaultRR->duration() > 0) {
+            rrule.setCount(defaultRR->duration());
+        }
+    } else {
+        rrule.setEnd(fromDate(defaultRR->endDt()));
+    }
+    
+    rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
+    rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
+    rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
+    
+    std::vector<Kolab::DayPos> daypos;
+    foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
+        daypos.push_back(fromWeekDayPos(dp));
+    }
+    rrule.setByday(daypos);
+    
+    rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
+    rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
+    rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
+    rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
+    i.setRecurrenceRule(rrule);
+    
+    std::vector<Kolab::cDateTime> rdates;
+    foreach (const KDateTime &dt, rec->rDateTimes()) {
+        rdates.push_back(fromDate(dt));
+    }
+    foreach (const QDate &dt, rec->rDates()) {
+        rdates.push_back(fromDate(KDateTime(dt)));
+    }
+    i.setRecurrenceDates(rdates);
+    
+    std::vector<Kolab::cDateTime> exdates;
+    foreach (const KDateTime &dt, rec->exDateTimes()) {
+        exdates.push_back(fromDate(dt));
+    }
+    foreach (const QDate &dt, rec->exDates()) {
+        exdates.push_back(fromDate(KDateTime(dt)));
+    }
+    i.setExceptionDates(exdates);
+    
+    if (!rec->exRules().empty()) {
+        qWarning() << "exrules are not supported";
+    }
+}
+
+template <typename T>
+void setTodoEvent(KCalCore::Incidence &i, const T &e)
+{
+    i.setPriority(toPriority(e.priority()));
+    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
+    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizer().name()), QString::fromStdString(e.organizer().email())))); //TODO handle uid too
+    if (e.recurrenceID().isValid()) {
+        i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
+    }
+    setRecurrence(i, e);
+}
+
+template <typename T, typename I>
+void getTodoEvent(T &i, const I &e)
+{
+    i.setPriority(fromPriority(e.priority()));
+    i.setLocation(e.location().toStdString());
+    i.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, e.organizer()->email().toStdString(), e.organizer()->name().toStdString())); //TODO handle uid too
+    i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
+    getRecurrence(i, e);
+}
+
+KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
+{
+    KCalCore::Event::Ptr e(new KCalCore::Event);
+    setIncidence(*e, event);
+    setTodoEvent(*e, event);
+    if (event.end().isValid()) {
+        e->setDtEnd(toDate(event.end()));
+    }
+    if (event.duration().isValid()) {
+        e->setDuration(toDuration(event.duration()));
+    }
+    if (event.transparency()) {
+        e->setTransparency(KCalCore::Event::Transparent);
+    } else {
+        e->setTransparency(KCalCore::Event::Opaque);
+    }
+    return e;
+}
+
+Event fromKCalCore(const KCalCore::Event &event)
+{
+    Event e;
+    getIncidence(e, event);
+    getTodoEvent(e, event);
+    if (event.hasEndDate()) {
+        e.setEnd(fromDate(event.dtEnd()));
+    } else if (event.hasDuration()) {
+        e.setDuration(fromDuration(event.duration()));
+    }
+    if (event.transparency() == KCalCore::Event::Transparent) {
+        e.setTransparency(true);
+    } else {
+        e.setTransparency(false);
+    }
+    return e;
+}
+
+
+
+KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
+{
+    KCalCore::Todo::Ptr e(new KCalCore::Todo);
+    setIncidence(*e, todo);
+    setTodoEvent(*e, todo);
+    if (todo.due().isValid()) {
+        e->setDtDue(toDate(todo.due()));
+    }
+    return e;
+}
+
+Todo fromKCalCore ( const KCalCore::Todo &todo )
+{
+    Todo t;
+    getIncidence(t, todo);
+    getTodoEvent(t, todo);
+    t.setDue(fromDate(todo.dtDue(true)));
+    return t;
+}
+
+KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
+{
+    KCalCore::Journal::Ptr e(new KCalCore::Journal);
+    setIncidence(*e, journal);
+    //TODO contacts
+    return e;
+}
+
+Journal fromKCalCore ( const KCalCore::Journal &journal )
+{
+    Journal j;
+    getIncidence(j, journal);
+    //TODO contacts
+    return j;
+}
+
+
+
+}
+}
\ No newline at end of file
diff --git a/libkolabkcal/kolabkcalconversion.h b/libkolabkcal/kolabkcalconversion.h
new file mode 100644
index 0000000..fe1ae04
--- /dev/null
+++ b/libkolabkcal/kolabkcalconversion.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABKCALCONVERSION_H
+#define KOLABKCALCONVERSION_H
+
+#include <kolab/kolabevent.h>
+#include <kolab/kolabtodo.h>
+#include <kolab/kolabjournal.h>
+#include <kcalcore/event.h>
+#include <kcalcore/todo.h>
+#include <kcalcore/journal.h>
+
+namespace Kolab {
+    /**
+     * Conversion of Kolab-Containers to/from KCalCore Containers.
+     *
+     * TODO: There is no error handling other than qWarning used so far.
+     */
+    namespace KCalConversion {
+
+        KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
+        Kolab::Event fromKCalCore(const KCalCore::Event &);
+
+        KCalCore::Todo::Ptr toKCalCore(const Kolab::Todo &);
+        Kolab::Todo fromKCalCore(const KCalCore::Todo &);
+
+        KCalCore::Journal::Ptr toKCalCore(const Kolab::Journal &);
+        Kolab::Journal fromKCalCore(const KCalCore::Journal &);
+
+        KDateTime toDate(const Kolab::cDateTime &dt);
+        cDateTime fromDate(const KDateTime &dt);
+
+    };
+};
+
+#endif
\ No newline at end of file
diff --git a/libkolabkcal/tests/CMakeLists.txt b/libkolabkcal/tests/CMakeLists.txt
new file mode 100644
index 0000000..9340bad
--- /dev/null
+++ b/libkolabkcal/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+
+QT4_AUTOMOC(kcalconversiontest.cpp)
+add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabkcal ${XERCES_C})
+
diff --git a/libkolabkcal/tests/kcalconversiontest.cpp b/libkolabkcal/tests/kcalconversiontest.cpp
new file mode 100644
index 0000000..b6549c8
--- /dev/null
+++ b/libkolabkcal/tests/kcalconversiontest.cpp
@@ -0,0 +1,714 @@
+#include "kcalconversiontest.h"
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+#include <KDE/KSystemTimeZones>
+#include <kcalcore/recurrence.h>
+
+#include "kolabkcalconversion.h"
+#include "kolabkcalconversion.cpp"
+// #include <lib/calendaring.h>
+
+// #include "serializers.h"
+
+using namespace Kolab::KCalConversion;
+
+Q_DECLARE_METATYPE(Kolab::Duration);
+Q_DECLARE_METATYPE(Kolab::cDateTime);
+Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(Kolab::Todo);
+Q_DECLARE_METATYPE(Kolab::Journal);
+Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
+Q_DECLARE_METATYPE(KCalCore::Event);
+Q_DECLARE_METATYPE(KCalCore::Todo);
+Q_DECLARE_METATYPE(KCalCore::Journal);
+Q_DECLARE_METATYPE(KCalCore::Duration);
+
+namespace QTest {
+    
+    template<>
+    char *toString(const KDateTime &dt)
+    {
+        QByteArray ba = "KDateTime(";
+        ba += dt.toString().toAscii();
+        ba += dt.timeZone().name();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Attendee &at)
+    {
+        QByteArray ba = "Attendee(";
+        ba += at.name().toAscii() + ", ";
+        ba += at.email().toAscii() + ", ";
+        ba += QString::number(at.role()) + ", ";
+        ba += QString::number(at.status()) + ", ";
+        ba += QString::number(at.RSVP()) + ", ";
+        ba += at.delegate().toAscii() + ", ";
+        ba += at.delegator().toAscii() + ", ";
+        ba += at.uid().toAscii() + ", ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    
+    template<>
+    char *toString(const QList<int> &l)
+    {
+        QByteArray ba = "QList<int>(";
+        foreach(int i, l) {
+            ba += QString::number(i) + ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const QList<KCalCore::RecurrenceRule::WDayPos> &l)
+    {
+        QByteArray ba = "QList<int>(";
+        foreach(const KCalCore::RecurrenceRule::WDayPos &i, l) {
+            ba += QString::number(i.pos()) + " ";
+            ba += QString::number(i.day()) + ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::DateList &l)
+    {
+        QByteArray ba = "KCalCore::DateList(";
+        foreach(const QDate &i, l) {
+            ba += i.toString();
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::DateTimeList &l)
+    {
+        QByteArray ba = "KCalCore::DateTimeList(";
+        foreach(const KDateTime &i, l) {
+            ba += toString(i);
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Recurrence &at)
+    {
+        at.dump();
+        KCalCore::RecurrenceRule *r = at.defaultRRule();
+        QByteArray ba;
+        if (!r) {
+            ba += "Recurrence( )";
+        } else {
+            Q_ASSERT(r);
+            Q_ASSERT(at.rRules().size() == 1);
+            
+            ba += "Recurrence(";
+            ba += QString::number(r->recurrenceType()) + "\n";
+            ba += QString::number(r->frequency()) + "\n";
+            ba += QString::number(r->duration()) + "\n";
+            ba += QByteArray(toString(r->startDt())) + "\n";
+            ba += QByteArray(toString(r->endDt())) + "\n";
+            ba += QByteArray(toString(r->bySeconds())) + "\n";
+            ba += QByteArray(toString(r->byMinutes())) + "\n";
+            ba += QByteArray(toString(r->byHours())) + "\n";
+            ba += QByteArray(toString(r->byDays())) + "\n";
+            ba += QByteArray(toString(r->byMonthDays())) + "\n";
+            ba += QByteArray(toString(r->byYearDays())) + "\n";
+            ba += QByteArray(toString(r->byMonths())) + "\n";
+            ba += ")\n";
+            ba += QByteArray(toString(at.exDates())) + "\n";
+            ba += QByteArray(toString(at.exDateTimes())) + "\n";
+            ba += QByteArray(toString(at.rDates())) + "\n";
+            ba += QByteArray(toString(at.rDateTimes())) + "\n";
+            
+        }
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::RecurrenceRule &at)
+    {
+        QByteArray ba;
+        ba += "KolabRecurrenceRule(";
+        ba += QString::number(at.weekStart()) + "\n";
+        ba += QString::number(at.frequency()) + "\n";
+        ba += QString::number(at.interval()) + "\n";
+        ba += QString::number(at.count()) + "\n";
+        ba += QByteArray(toString(at.end())) + "\n";
+        ba += QByteArray(toString(at.bysecond())) + "\n";
+        ba += QByteArray(toString(at.byminute())) + "\n";
+        ba += QByteArray(toString(at.byhour())) + "\n";
+        ba += QByteArray(toString(at.byday())) + "\n";
+        ba += QByteArray(toString(at.bymonthday())) + "\n";
+        ba += QByteArray(toString(at.byyearday())) + "\n";
+        ba += QByteArray(toString(at.byweekno())) + "\n";
+        ba += QByteArray(toString(at.bymonth())) + "\n";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KCalCore::Duration &d)
+    {
+        QByteArray ba;
+        ba += "KCalCore::Duration(";
+        ba += QString::number(d.isDaily()) + ", ";
+        ba += QString::number(d.value()) + " ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+}
+
+template <typename T>
+void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
+{
+    QCOMPARE(list.size(), other.size());
+    for (int i = 0 ; i < list.size(); i++) {
+        QCOMPARE(*list.at(i), *other.at(i));
+    }
+}
+
+
+void KCalConversionTest::testDate_data()
+{
+    QTest::addColumn<Kolab::cDateTime>( "input" );
+    QTest::addColumn<KDateTime>( "result" );
+
+    QTest::newRow( "datetime with tz" ) << Kolab::cDateTime("Europe/Zurich",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Zurich"));
+    QTest::newRow( "floating datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, false) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::Spec(KDateTime::ClockTime));
+    QTest::newRow( "utc datetime" ) << Kolab::cDateTime(2006,1,8,12,0,0, true) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
+    QTest::newRow( "date only" ) << Kolab::cDateTime(2006,1,8) << KDateTime(QDate(2006, 1, 8));
+}
+
+
+void KCalConversionTest::testDate()
+{
+    QFETCH(Kolab::cDateTime, input);
+    QFETCH(KDateTime, result);
+    
+    const KDateTime &r = Kolab::KCalConversion::toDate(input);
+    QCOMPARE(r, result);
+    
+    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
+    QCOMPARE(r2, input);
+}
+
+void KCalConversionTest::testDuration_data()
+{
+    QTest::addColumn<Kolab::Duration>( "input" );
+    QTest::addColumn<KCalCore::Duration>( "result" );
+    QTest::addColumn<Kolab::Duration>( "fromResult" );
+    
+    QTest::newRow( "seconds" ) << Kolab::Duration(0,0,0,30,false) << KCalCore::Duration(30, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,30,false);
+    QTest::newRow( "minutes" ) << Kolab::Duration(0,0,1,30,false) << KCalCore::Duration(90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,90,false);
+    QTest::newRow( "hours" ) << Kolab::Duration(0,1,1,30,false) << KCalCore::Duration(60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,60*60+90,false);
+    QTest::newRow( "days" ) << Kolab::Duration(1,1,1,30,false) << KCalCore::Duration(24*60*60+60*60+90, KCalCore::Duration::Seconds) << Kolab::Duration(0,0,0,24*60*60+60*60+90,false);
+    QTest::newRow( "daysonly" ) << Kolab::Duration(30,0,0,0, false) << KCalCore::Duration(30, KCalCore::Duration::Days) << Kolab::Duration(30,0,0,0,false);
+    QTest::newRow( "weeks" ) << Kolab::Duration(30,false) << KCalCore::Duration(30*7, KCalCore::Duration::Days) << Kolab::Duration(30*7,0,0,0,false);
+}
+
+
+void KCalConversionTest::testDuration()
+{
+    QFETCH(Kolab::Duration, input);
+    QFETCH(KCalCore::Duration, result);
+    QFETCH(Kolab::Duration, fromResult);
+    
+    const KCalCore::Duration &r = Kolab::KCalConversion::toDuration(input);
+    QCOMPARE(r, result);
+    
+    const Kolab::Duration &r2 = Kolab::KCalConversion::fromDuration(result);
+    QCOMPARE(r2, fromResult);
+}
+
+
+void KCalConversionTest::testDateTZ_data()
+{
+    QTest::addColumn<Kolab::cDateTime>( "input" );
+    QTest::addColumn<KDateTime>( "result" );
+    QTest::addColumn<int>( "offset" );
+       
+    QTest::newRow( "berlin" ) << Kolab::cDateTime("Europe/Berlin",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Berlin")) << 3600;
+}
+
+void KCalConversionTest::testDateTZ()
+{
+    QFETCH(Kolab::cDateTime, input);
+    QFETCH(KDateTime, result);
+    QFETCH(int, offset);
+    
+    const KDateTime &r = Kolab::KCalConversion::toDate(input);
+    QCOMPARE(result.timeZone().name(), QString::fromStdString(input.timezone()));
+    QCOMPARE(r.timeZone().currentOffset(), offset);
+    
+    const Kolab::cDateTime &r2 = Kolab::KCalConversion::fromDate(result);
+    QCOMPARE(QString::fromStdString(r2.timezone()), result.timeZone().name());
+}
+
+
+void KCalConversionTest::testConversion_data()
+{
+    QTest::addColumn<KCalCore::Event>( "kcal" );
+    QTest::addColumn<Kolab::Event>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    Kolab::cDateTime date3(2012,2,2,12,12,10);
+    std::vector<int> intVector;
+    intVector.push_back(1);
+    intVector.push_back(-3);
+    intVector.push_back(2);
+    std::vector<std::string> stringVector;
+    stringVector.push_back("cat1");
+    stringVector.push_back("cat2");
+    stringVector.push_back("parent/child");
+    
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
+        kcal.setCategories(toStringList(stringVector));
+        kcal.setDtStart(toDate(date));
+        kcal.setDtEnd(toDate(date2));
+        kcal.setTransparency(KCalCore::Event::Transparent);
+        
+        kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setDuration(5);
+        kcal.recurrence()->addRDateTime(toDate(date2));
+        kcal.recurrence()->addRDate(toDate(date2).date());
+        kcal.recurrence()->addExDateTime(toDate(date3));
+        kcal.recurrence()->addExDate(toDate(date3).date());
+        
+        KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
+        QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
+        rr->setBySeconds(intList);
+        rr->setByMinutes(intList);
+        rr->setByHours(intList);
+        rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,1) << KCalCore::RecurrenceRule::WDayPos(5,4));
+        rr->setByMonthDays(intList);
+        rr->setByYearDays(intList);
+        rr->setByMonths(intList);
+        rr->setByWeekNumbers(intList);
+        
+        kcal.setSummary("summary");
+        kcal.setDescription("description");
+        kcal.setPriority(3);
+        kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
+        kcal.setLocation("location");
+        kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
+        kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant)));
+        //TODO KCalCore Delegate/Delegator
+        kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
+        KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
+        KCalCore::Person::List addressees;
+        addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
+        alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
+        kcal.addAlarm(alarm);
+        //TODO alarms
+        //TODO custom properties
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setClassification(Kolab::ClassConfidential);
+        kolab.setCategories(stringVector);
+        kolab.setStart(date);
+        kolab.setEnd(date2);
+        kolab.setTransparency(true);
+        
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setCount(5);
+        rrule.setBysecond(intVector);
+        rrule.setByminute(intVector);
+        rrule.setByhour(intVector);
+        rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
+        rrule.setBymonthday(intVector);
+        rrule.setByyearday(intVector);
+        rrule.setByweekno(intVector);
+        rrule.setBymonth(intVector);
+        
+        kolab.setRecurrenceRule(rrule);
+        kolab.setRecurrenceID(date2, true);
+        kolab.setRecurrenceDates(std::vector<Kolab::cDateTime>() << date2 << Kolab::cDateTime(date2.year(), date2.month(), date2.day()));
+        kolab.setExceptionDates(std::vector<Kolab::cDateTime>() << date3 << Kolab::cDateTime(date3.year(), date3.month(), date3.day()));
+        
+        kolab.setSummary("summary");
+        kolab.setDescription("description");
+        kolab.setPriority(3);
+        kolab.setStatus(Kolab::StatusConfirmed);
+        kolab.setLocation("location");
+        kolab.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"organizer at email", "organizer")); //TODO uid
+        
+        Kolab::Attendee a(Kolab::ContactReference(Kolab::ContactReference::EmailReference,"attendee at email", "attendee"));//TODO uid
+        kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
+        
+        Kolab::Attachment attach;
+        attach.setUri("uri", "mimetype/mime");
+        kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
+        
+    //     std::vector<std::string> receipents;
+    //     receipents.push_back("email at email");
+    //     Kolab::Alarm alarm2("summary", "description", receipents);
+    //     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
+
+        QTest::newRow( "with endDate and recurrence duration" ) << kcal << kolab;
+    }
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setDtStart(toDate(date));
+        kcal.setDuration(KCalCore::Duration(toDate(date), toDate(date2)));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(date3));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setStart(date);
+        kolab.setDuration(Kolab::Duration(0, 0, 1, 0));
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(date3);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("with duration and recurrence endDate") << kcal << kolab;
+    }
+    {
+        Kolab::cDateTime start(2011,1,1);
+        Kolab::cDateTime end(2011,1,3);
+        
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setDtStart(toDate(start));
+        kcal.setDtEnd(toDate(end));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(end));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setStart(start);
+        kolab.setEnd(end);
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(end);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("date only dates") << kcal << kolab;
+    }
+}
+
+void KCalConversionTest::testConversion()
+{
+    QFETCH(KCalCore::Event, kcal);
+    QFETCH(Kolab::Event, kolab);
+    
+    const KCalCore::Event::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->created(), kcal.created());
+    QCOMPARE(e->lastModified(), kcal.lastModified());
+    QCOMPARE(e->revision(), kcal.revision());
+    QCOMPARE(e->secrecy(), kcal.secrecy());
+    QCOMPARE(e->categories(), kcal.categories());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->dtEnd(), kcal.dtEnd());
+    QCOMPARE(e->duration(), kcal.duration());
+    QCOMPARE(e->transparency(), kcal.transparency());
+    QCOMPARE(*e->recurrence(), *kcal.recurrence());
+    QCOMPARE(e->recurrenceId(), kcal.recurrenceId());
+    QCOMPARE(e->recurrenceType(), kcal.recurrenceType());
+    QCOMPARE(e->summary(), kcal.summary());
+    QCOMPARE(e->description(), kcal.description());
+    QCOMPARE(e->priority(), kcal.priority());
+    QCOMPARE(e->status(), kcal.status());
+    QCOMPARE(e->location(), kcal.location());
+    QCOMPARE(e->organizer()->name(), kcal.organizer()->name());
+    QCOMPARE(e->organizer()->email(), kcal.organizer()->email());
+    comparePointerVectors(e->attendees(), kcal.attendees());
+    comparePointerVectors(e->attachments(), kcal.attachments());
+    
+//     QCOMPARE(e->alarms(), kcal.alarms()); //TODO
+//TODO custom properties
+
+    QBENCHMARK {
+        toKCalCore(kolab);
+    }
+    
+    const Kolab::Event &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.created(), kolab.created());
+    QCOMPARE(b.lastModified(), kolab.lastModified());
+    QCOMPARE(b.sequence(), kolab.sequence());
+    QCOMPARE(b.classification(), kolab.classification());
+    QCOMPARE(b.categories(), kolab.categories());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.end(), kolab.end());
+    QCOMPARE(b.duration(), kolab.duration());
+    QCOMPARE(b.transparency(), kolab.transparency());
+    
+    QCOMPARE(b.recurrenceRule(), kolab.recurrenceRule());
+    QCOMPARE(b.recurrenceID(), kolab.recurrenceID());
+    QCOMPARE(b.recurrenceDates(), kolab.recurrenceDates());
+    QCOMPARE(b.exceptionDates(), kolab.exceptionDates());
+    
+    QCOMPARE(b.summary(), kolab.summary());
+    QCOMPARE(b.description(), kolab.description());
+    QCOMPARE(b.status(), kolab.status());
+}
+
+
+void KCalConversionTest::testTodoConversion_data()
+{
+    QTest::addColumn<KCalCore::Todo>( "kcal" );
+    QTest::addColumn<Kolab::Todo>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Todo kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setDtDue(toDate(date2));
+        
+        Kolab::Todo kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setDue(date2);
+
+        QTest::newRow( "todo" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testTodoConversion()
+{
+    QFETCH(KCalCore::Todo, kcal);
+    QFETCH(Kolab::Todo, kolab);
+    
+    const KCalCore::Todo::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->dtDue(), kcal.dtDue());
+   
+    const Kolab::Todo &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.due(), kolab.due());
+}
+
+void KCalConversionTest::testJournalConversion_data()
+{
+    QTest::addColumn<KCalCore::Journal>( "kcal" );
+    QTest::addColumn<Kolab::Journal>( "kolab" );
+    
+    Kolab::cDateTime date(2011,2,2,12,11,10);
+    Kolab::cDateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Journal kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setSummary("summary");
+        
+        Kolab::Journal kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setSummary("summary");
+        
+        QTest::newRow( "journal" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testJournalConversion()
+{
+    QFETCH(KCalCore::Journal, kcal);
+    QFETCH(Kolab::Journal, kolab);
+    
+    const KCalCore::Journal::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->summary(), kcal.summary());
+    
+    const Kolab::Journal &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.summary(), kolab.summary());
+}
+
+
+void KCalConversionTest::testEventConflict_data()
+{
+    QTest::addColumn<Kolab::Event>( "e1" );
+    QTest::addColumn<Kolab::Event>( "e2" );
+    QTest::addColumn<bool>( "result" );
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1));
+        
+        QTest::newRow( "after" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1));
+        
+        QTest::newRow( "before" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1));
+        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1));
+        
+        QTest::newRow( "conflict" ) << e1 << e2 << true;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
+        
+        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
+    }
+    
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
+        
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
+        
+        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
+    }
+}
+
+void KCalConversionTest::testEventConflict()
+{
+//     QFETCH(Kolab::Event, e1);
+//     QFETCH(Kolab::Event, e2);
+//     QFETCH(bool, result);
+//     QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
+}
+
+
+
+void KCalConversionTest::testTimesInInterval_data()
+{
+    QTest::addColumn<Kolab::Event>( "event" );
+    QTest::addColumn<Kolab::cDateTime>( "start" );
+    QTest::addColumn<Kolab::cDateTime>( "end" );
+    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
+    {
+        {
+            Kolab::Event event;
+            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
+            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
+            Kolab::RecurrenceRule rrule;
+            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+            rrule.setInterval(1);
+            rrule.setCount(5);
+            event.setRecurrenceRule(rrule);
+
+            std::vector<Kolab::cDateTime> result;
+            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1)); 
+            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1));
+            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1)); 
+            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1));
+            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1)); 
+            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1) << Kolab::cDateTime(2011,1,5,1,1,1) << result;
+        }
+    }
+}
+
+void KCalConversionTest::testTimesInInterval()
+{
+//     QFETCH(Kolab::Event, event);
+//     QFETCH(Kolab::cDateTime, start);
+//     QFETCH(Kolab::cDateTime, end);
+//     QFETCH(std::vector<Kolab::cDateTime>, result);
+//     QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
+}
+
+void KCalConversionTest::testTimesInIntervalBenchmark()
+{
+//     Kolab::Event event;
+//     event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
+//     event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
+//     Kolab::RecurrenceRule rrule;
+//     rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+//     rrule.setInterval(1);
+//     rrule.setCount(500);
+//     event.setRecurrenceRule(rrule);
+//     
+//     QBENCHMARK {
+//         Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+//     }
+//     const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+//     QVERIFY(result.size() == 500);
+//     qDebug() << QTest::toString(result);    
+}
+
+// void KCalConversionTest::BenchmarkRoundtripKCAL()
+// {
+//     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+//     std::string result = Kolab::writeEvent(event);
+//     QBENCHMARK {
+//         Kolab::KCalConversion::toKCalCore(Kolab::readEvent(result, false));
+//     }
+// }
+
+QTEST_MAIN( KCalConversionTest )
+
+#include "kcalconversiontest.moc"
diff --git a/libkolabkcal/tests/kcalconversiontest.h b/libkolabkcal/tests/kcalconversiontest.h
new file mode 100644
index 0000000..fa926a5
--- /dev/null
+++ b/libkolabkcal/tests/kcalconversiontest.h
@@ -0,0 +1,38 @@
+#ifndef KCALCONVERSIONTEST_H
+#define KCALCONVERSIONTEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+class KCalConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+
+    void testDate_data();
+    void testDate();
+    
+    void testDuration_data();
+    void testDuration();
+    
+    void testConversion_data();
+    void testConversion();
+
+    void testTodoConversion_data();
+    void testTodoConversion();
+    
+    void testJournalConversion_data();
+    void testJournalConversion();
+    
+    void testDateTZ_data();
+    void testDateTZ();
+
+    void testEventConflict_data();
+    void testEventConflict();
+    
+    void testTimesInInterval_data();
+    void testTimesInInterval();
+    void testTimesInIntervalBenchmark();
+};
+
+#endif
\ No newline at end of file


commit 4c4bbcace46ca76f826c5661ccfbcf24e11b1de6
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 11:21:21 2012 +0100

    added upgradetool

diff --git a/libkolab/kolabformatV2/kolabformatv2.cpp b/libkolab/kolabformatV2/kolabformatv2.cpp
new file mode 100644
index 0000000..8d1054f
--- /dev/null
+++ b/libkolab/kolabformatV2/kolabformatv2.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "kolabformatv2.h"
+#include <quuid.h>
+
+namespace KolabV2 {
+    
+
+
+    
+KMime::Message::Ptr ConversionUtils::readMimeFile( const QString &fileName )
+{
+//     qDebug() << fileName;
+    QFile file( fileName );
+    file.open( QFile::ReadOnly );
+    const QByteArray data = file.readAll();
+    Q_ASSERT( !data.isEmpty() );
+    
+    KMime::Message *msg = new KMime::Message;
+    msg->setContent( data );
+    msg->parse();
+    return KMime::Message::Ptr(msg);
+}
+
+KMime::Content* ConversionUtils::findContentByType(const KMime::Message::Ptr &data, const QByteArray &type)
+{
+    const KMime::Content::List list = data->contents();
+//     qDebug() << list.size();
+    Q_FOREACH(KMime::Content *c, list)
+    {
+//         qDebug() << c->contentType()->mimeType() << type;
+        if (c->contentType()->mimeType() ==  type)
+            return c;
+    }
+    return 0;
+    
+}
+
+KMime::Content* ConversionUtils::findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type)
+{
+    const KMime::Content::List list = data->contents();
+    Q_FOREACH(KMime::Content *c, list)
+    {
+        if ( c->contentType()->name() == name ) {
+            type = c->contentType()->mimeType();
+            return c;
+        }
+    }
+    return 0;
+    
+}
+
+
+//TODO repalce
+void ConversionUtils::attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
+                          const KCalCore::Incidence::Ptr &incidence)
+{
+    QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
+    for (int i = 0; i < nodes.size(); i++ ) {
+        const QString name = nodes.at(i).toElement().text();
+        QByteArray type;
+        KMime::Content *content = findContentByName(data, name, type);
+        if (!content) // guard against malformed events with non-existent attachments
+        continue;
+        const QByteArray c = content->decodedContent().toBase64();
+        KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
+        attachment->setLabel( name );
+        incidence->addAttachment(attachment);
+        kDebug() << "ATTACHEMENT NAME" << name << type;
+    }
+}
+
+QByteArray ConversionUtils::getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype)
+{
+    KMime::Content *xmlContent = findContentByType( data, mimetype );
+    if ( xmlContent ) {
+        return xmlContent->decodedContent();
+    }
+    kDebug() << "document not found";
+    return QByteArray();
+}
+
+
+
+KCalCore::Incidence::Ptr ConversionUtils::eventFromMimeFile(const QString &mimeFileName)
+{
+    const KMime::Message::Ptr kolabItem = readMimeFile( mimeFileName );
+    KCalCore::Incidence::Ptr convertedIncidence = incidenceFromKolabImpl<KCalCore::Event::Ptr, KolabV2::Event>( kolabItem, QByteArray("application/x-vnd.kolab.event"), QString::fromLatin1("Europe/Berlin") );
+    return convertedIncidence;
+}
+
+QByteArray fromCid(const QString &cid)
+{
+    if (cid.left(4) != QString::fromLatin1("cid:")) { //Don't set if not a cid, happens when serializing format v2
+        return QByteArray();
+    }
+    return cid.right(cid.size()-4).toLatin1();
+}
+
+KMime::Message::Ptr ConversionUtils::createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml)
+{
+    KMime::Message::Ptr message = createMessage( xKolabType );
+    message->from()->addAddress( incidencePtr->organizer()->email().toUtf8(), incidencePtr->organizer()->name() );
+    message->subject()->fromUnicodeString( incidencePtr->uid(), "utf-8" );
+    
+    KMime::Content *content = createMainPart( mimetype, xml );
+    message->addContent( content );
+    
+    Q_FOREACH (KCalCore::Attachment::Ptr attachment, incidencePtr->attachments()) {
+        content = createAttachmentPart(fromCid(attachment->uri()), attachment->mimeType(), attachment->label(), attachment->decodedData() );
+        message->addContent( content );
+    }
+    
+    message->assemble();
+    return message;
+}
+
+KMime::Content* ConversionUtils::createExplanationPart()
+{
+    KMime::Content *content = new KMime::Content();
+    content->contentType()->setMimeType( "text/plain" );
+    content->contentType()->setCharset( "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CE7Bit );
+    content->setBody( "This is a Kolab Groupware object.\n"
+    "To view this object you will need an email client that can understand the Kolab Groupware format.\n"
+    "For a list of such email clients please visit\n"
+    "http://www.kolab.org/kolab2-clients.html\n" );
+    return content;
+}
+
+
+KMime::Message::Ptr ConversionUtils::createMessage(const QString& xKolabType)
+{
+    KMime::Message::Ptr message( new KMime::Message );
+    message->date()->setDateTime( KDateTime::currentLocalDateTime() );
+    KMime::Headers::Generic *h = new KMime::Headers::Generic( "X-Kolab-Type", message.get(), xKolabType, "utf-8" );
+    message->appendHeader( h );
+    message->userAgent()->from7BitString( "Akonadi Kolab Proxy Resource" );
+    message->contentType()->setMimeType( "multipart/mixed" );
+    message->contentType()->setBoundary( KMime::multiPartBoundary() );
+    
+    message->addContent( createExplanationPart() );
+    return message;
+}
+
+
+KMime::Content* ConversionUtils::createMainPart(const QString& mimeType, const QByteArray& decodedContent)
+{
+    KMime::Content* content = new KMime::Content();
+    content->contentType()->setMimeType( mimeType.toLatin1() );
+    content->contentType()->setName( "kolab.xml", "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr );
+    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
+    content->contentDisposition()->setFilename( "kolab.xml" );
+    content->setBody( decodedContent );
+    return content;
+}
+
+KMime::Content* ConversionUtils::createAttachmentPart(const QByteArray& cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent)
+{
+    KMime::Content* content = new KMime::Content();
+    if (!cid.isEmpty()) {
+        content->contentID()->setIdentifier( cid );
+    }
+    content->contentType()->setMimeType( mimeType.toLatin1() );
+    content->contentType()->setName( fileName, "us-ascii" );
+    content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 );
+    content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
+    content->contentDisposition()->setFilename( fileName );
+    content->setBody( decodedContent );
+    return content;
+}
+
+
+}
diff --git a/libkolab/kolabformatV2/kolabformatv2.h b/libkolab/kolabformatV2/kolabformatv2.h
new file mode 100644
index 0000000..d6ec87f
--- /dev/null
+++ b/libkolab/kolabformatV2/kolabformatv2.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABFORMATv2_H
+#define KOLABFORMATv2_H
+
+#include "kolabv2_export.h"
+
+#include <kcalcore/incidence.h>
+#include <kcalcore/event.h>
+#include <akonadi/item.h>
+#include <kmime/kmime_message.h>
+#include <QtCore/qfile.h>
+#include "event.h"
+// #include <kolabhandler.h>
+
+namespace KolabV2 {
+    
+  class KOLABV2_EXPORT ConversionUtils {
+    public:
+        
+        static QString eventKolabType() { return QString::fromLatin1("application/x-vnd.kolab.event"); };
+        static QString todoKolabType() { return QString::fromLatin1("application/x-vnd.kolab.task"); };
+        static QString journalKolabType() { return QString::fromLatin1("application/x-vnd.kolab.journal"); };
+        static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
+    
+        //TODO Generic
+        static KMime::Message::Ptr readMimeFile( const QString &fileName );
+        //TODO Generic
+        static KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type);
+        //TODO Generic
+        static KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteArray &type);
+        
+        //TODO replace
+        static void attachmentsFromKolab(const KMime::Message::Ptr& data, const QDomDocument &xmlDoc,
+                                const KCalCore::Incidence::Ptr &incidence);
+        
+        //TODO Generic
+        static QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype);
+        
+        /**
+         * Get Attachments from a Mime message
+         * 
+         * Set the attachments listed in @param attachments on @param incidence from @param mimeData
+         */
+        //TODO Generic
+        static void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attachments, const KMime::Message::Ptr &mimeData)
+        {
+            foreach (const QString &name, attachments) {
+                QByteArray type;
+                KMime::Content *content = KolabV2::ConversionUtils::findContentByName(mimeData, name, type);
+                if (!content) { // guard against malformed events with non-existent attachments
+                    qWarning() << "could not find attachment: "<< name;
+                    continue;
+                }
+                const QByteArray c = content->decodedContent().toBase64();
+                KCalCore::Attachment::Ptr attachment( new KCalCore::Attachment( c, QString::fromLatin1( type ) ) );
+                attachment->setLabel( name );
+                incidence->addAttachment(attachment);
+                kDebug() << "ATTACHEMENT NAME" << name << type;
+            }
+        }
+    
+        //TODO Generic
+        void setAttachments(KMime::Message::Ptr &mimeData, const KCalCore::Incidence::Ptr incidence)
+        {
+            
+        }
+        
+        
+        /**
+         * Parse XML, create KCalCore container and extract attachments
+         */
+        //TODO V2 specific
+        template <typename KCalPtr, typename Container>
+        static KCalPtr fromXML(const QByteArray &xmlData, QStringList &attachments)
+        {
+            const QDomDocument xmlDoc = KolabV2::KolabBase::loadDocument( QString::fromUtf8(xmlData) ); //TODO extract function from V2 format
+            Q_ASSERT ( !xmlDoc.isNull() );
+            const KCalPtr i = Container::fromXml( xmlDoc, QString() ); //For parsing we don't need the timezone, so we don't set one
+            Q_ASSERT ( i );
+            QDomNodeList nodes = xmlDoc.elementsByTagName("inline-attachment");
+            for (int i = 0; i < nodes.size(); i++ ) {
+                attachments.append(nodes.at(i).toElement().text());
+            }
+            return i;
+        }
+        
+        //TODO V2 specific
+        template <typename IncidencePtr, typename Converter>
+        static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &data, const QByteArray &mimetype, const QString &timezoneId )
+        {
+            KMime::Content *xmlContent = findContentByType( data, mimetype );
+            if ( !xmlContent ) {
+                qWarning() << "couldn't find part";
+                return IncidencePtr();
+            }
+            const QByteArray xmlData = xmlContent->decodedContent();
+            
+            QStringList attachments;
+            IncidencePtr ptr = fromXML<IncidencePtr, Converter>(xmlData, attachments); //TODO do we care about timezone?
+            getAttachments(ptr, attachments, data);
+            
+            return ptr;
+//             KMime::Content *xmlContent = findContentByType( data, mimetype );
+//             if ( xmlContent ) {
+//                 const QByteArray xmlData = xmlContent->decodedContent();
+// //                 qDebug() << xmlData;
+//                 const QDomDocument xmlDoc = Converter::loadDocument( QString::fromUtf8(xmlData) );
+//                 if ( !xmlDoc.isNull() ) {
+//                     IncidencePtr i = Converter::fromXml( xmlDoc, timezoneId );
+//                     attachmentsFromKolab( data, xmlDoc, i );
+//                     return i;
+//                 }
+//             }
+// //             qDebug() << "empty";
+//             return IncidencePtr();
+        }
+        
+        
+        static KCalCore::Incidence::Ptr eventFromMimeFile(const QString &mimeFileName);
+        
+        
+        ///Generic serializing functions
+        static KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml);
+        
+        static KMime::Content* createExplanationPart();
+        static KMime::Message::Ptr createMessage(const QString& mimeType);
+        static KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent);
+        static KMime::Content* createAttachmentPart(const QByteArray &cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent);
+
+    };
+    
+}
+#endif
diff --git a/upgradetool/CMakeLists.txt b/upgradetool/CMakeLists.txt
new file mode 100644
index 0000000..ffc557c
--- /dev/null
+++ b/upgradetool/CMakeLists.txt
@@ -0,0 +1,40 @@
+project (upgradetool)
+
+cmake_minimum_required(VERSION 2.6)
+
+find_package(Qt4 REQUIRED)
+find_package(KDE4 REQUIRED)
+
+include_directories(/opt/devel/global/include ${QT_INCLUDES} /usr/local/include/kolab .)
+link_directories(/opt/devel/global/lib)
+
+# find_library(KMIME_LIBS NAMES kmime)
+# if(KMIME_LIBS)
+#     set(KMIME_LIBS_FOUND ON)
+#     message("KMime found")
+# endif(KMIME_LIBS)
+
+# find_library(KOLABFORMATV2 NAMES kolabformat_v2 PATHS /opt/devel/global/lib)
+# if(KOLABFORMATV2)
+#     set(KOLABFORMATV2_FOUND ON)
+#     message("KOLABFORMATV2 found")
+# endif(KOLABFORMATV2)
+# set(KOLABFORMATV2 /opt/devel/global/lib/libkolabformat_v2.so)
+
+set(COMMON_DEPENDENCIES kolabxml kolabkcal ${KCALCORE} ${KDECORE} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${KMIME_LIBS} ${QT_GUI_LIBRARY} ${KOLABFORMATV2} kolabformatV2)
+
+add_executable(upgradetool upgradetool.cpp upgradeutilities.cpp)
+target_link_libraries(upgradetool  ${COMMON_DEPENDENCIES})
+
+
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+# set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+message("Buildings tests")
+
+QT4_AUTOMOC(upgradetooltests.cpp)
+add_executable(upgradetooltests upgradetooltests.cpp upgradeutilities.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
+target_link_libraries(upgradetooltests ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY}  ${COMMON_DEPENDENCIES})
+
diff --git a/upgradetool/upgradetool.cpp b/upgradetool/upgradetool.cpp
new file mode 100644
index 0000000..8b67917
--- /dev/null
+++ b/upgradetool/upgradetool.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/QStringList>
+#include <QtCore/qfile.h>
+#include <kmime/kmime_message.h>
+#include <kcalcore/icalformat.h>
+
+#include <kolabformatV2/event.h>
+#include <kolabformatV2/kolabformatv2.h>
+#include "upgradeutilities.h"
+
+#include <kolab/kolabkcalconversion.h>
+#include <kolab/kolabformat.h>
+#include <kolab/kolabevent.h>
+
+
+/**
+ * Usage:
+ * 
+ * Read mimefile:
+ * ./upgradetool -mimefile complex.ics.mime
+ * 
+ * Read mimemessage from stdin:
+ * cat complex.ics.mime  | ./upgradetool -mime
+ * 
+ */
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication app(argc, argv);
+
+    if (app.arguments().size() < 2) {
+        qWarning() << "need more arguments";
+        return -1;
+    }
+
+    QString command = app.arguments().at(1);
+    
+    QTextStream stream(stdin);
+    QString input;
+    if (app.arguments().size() >= 3) {
+        input = app.arguments().at(2);
+    } else {
+        input = stream.readAll();
+    }
+    
+    QTextStream s(stdout);
+    if (command == QString::fromLatin1("-xml")) {
+//         std::cout << Kolab::Upgrade::upgradeEventXML(data.toLocal8Bit(), QStringList());
+        kWarning() << "not implemented";
+        //TODO implement
+    } else if (command == QString::fromLatin1("-xmlfile")) {
+        kWarning() << "not implemented";
+        //TODO implement
+    } else if (command == QString::fromLatin1("-mime")) {
+        s << Kolab::Upgrade::upgradeMime(input.toLocal8Bit());
+    } else if (command == QString::fromLatin1("-mimefile")) {
+        QFile file( input );
+        file.open( QFile::ReadOnly );
+        const QByteArray data = file.readAll();
+        Q_ASSERT( !data.isEmpty() );
+        s << Kolab::Upgrade::upgradeMime(data);;
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/upgradetool/upgradetooltests.cpp b/upgradetool/upgradetooltests.cpp
new file mode 100644
index 0000000..384a025
--- /dev/null
+++ b/upgradetool/upgradetooltests.cpp
@@ -0,0 +1,69 @@
+#include "upgradetooltests.h"
+#include <kolabformatv2.h>
+#include "upgradeutilities.h"
+#include <kolabkcalconversion.h>
+#include <kolabformat.h>
+
+
+void UpgradeToolTests::testConvertEvent()
+{
+//     const KMime::Message::Ptr kolabItem = KolabV2::ConversionUtils::readMimeFile( "complex.ics.mime" );
+//     QVERIFY(kolabItem);
+//     //     std::cout << kolabItem->textContent();
+//     KCalCore::Event::Ptr convertedIncidence = KolabV2::ConversionUtils::incidenceFromKolabImpl<KCalCore::Event::Ptr, KolabV2::Event>( kolabItem, "application/x-vnd.kolab.event", QString::fromLatin1("Europe/Berlin") );
+//     QVERIFY(convertedIncidence);
+//     const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*convertedIncidence);
+//     QVERIFY(event.isValid());
+//     std::cout << Kolab::writeEvent(event);
+
+//     Kolab::Upgrade::upgradeEventXML()
+    
+    QFile file( "complex.ics.mime" );
+    file.open( QFile::ReadOnly );
+    const QByteArray data = file.readAll();
+    Q_ASSERT( !data.isEmpty() );
+    kDebug() << Kolab::Upgrade::upgradeMime(data);
+}
+
+void UpgradeToolTests::parsingBenchmarkComparison_data()
+{
+    QTest::addColumn<bool>("v2Parser");
+    QTest::newRow("v2") << true;
+    QTest::newRow("v3") << false;
+}
+
+void UpgradeToolTests::parsingBenchmarkComparison()
+{
+    const KMime::Message::Ptr kolabItem = KolabV2::ConversionUtils::readMimeFile( "complex.ics.mime" );
+    KMime::Content *xmlContent = KolabV2::ConversionUtils::findContentByType( kolabItem, "application/x-vnd.kolab.event" );
+    QVERIFY ( xmlContent );
+    const QByteArray xmlData = xmlContent->decodedContent();
+//     qDebug() << xmlData;
+    const QDomDocument xmlDoc = KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) );
+    QVERIFY ( !xmlDoc.isNull() );
+    const KCalCore::Event::Ptr i = KolabV2::Event::fromXml( xmlDoc, QString::fromLatin1("Europe/Berlin") );
+    QVERIFY ( i );
+    const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeEvent(event);
+    
+    QFETCH(bool, v2Parser);
+    
+//     Kolab::readEvent(v3String, false); //init parser (doesn't really change the results it seems)
+//     qDebug() << QString::fromUtf8(xmlData);
+//     qDebug() << "------------------------------------------------------------------------------------";
+//     qDebug() << QString::fromStdString(v3String);
+    if (v2Parser) {
+        QBENCHMARK {
+            KolabV2::Event::fromXml( KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) ), QString::fromLatin1("Europe/Berlin") );
+        }
+    } else {
+        QBENCHMARK {
+            Kolab::readEvent(v3String, false);
+        }
+    }
+}
+
+
+QTEST_MAIN( UpgradeToolTests )
+
+#include "upgradetooltests.moc"
diff --git a/upgradetool/upgradetooltests.h b/upgradetool/upgradetooltests.h
new file mode 100644
index 0000000..5392b47
--- /dev/null
+++ b/upgradetool/upgradetooltests.h
@@ -0,0 +1,21 @@
+#ifndef UPGRADETOOL_TEST_H
+#define UPGRADETOOL_TEST_H
+
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+
+class UpgradeToolTests : public QObject
+{
+    Q_OBJECT
+private slots:
+    
+    void testConvertEvent();
+    
+    void parsingBenchmarkComparison_data();
+    void parsingBenchmarkComparison();
+    
+};
+
+#endif
diff --git a/upgradetool/upgradeutilities.cpp b/upgradetool/upgradeutilities.cpp
new file mode 100644
index 0000000..f81d74e
--- /dev/null
+++ b/upgradetool/upgradeutilities.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "upgradeutilities.h"
+
+#include <kolabformatV2/event.h>
+#include <kolabformatV2/task.h>
+#include <kolabformatV2/journal.h>
+#include <kolabformatV2/kolabformatv2.h>
+
+#include <Qt/qdom.h>
+
+#include <kolabevent.h>
+#include <kolabkcalconversion.h>
+#include <kolabformat.h>
+
+namespace Kolab {
+    namespace Upgrade {
+
+void normalizeIncidence(KCalCore::Incidence::Ptr i)
+{
+    Q_FOREACH (KCalCore::Attendee::Ptr a, i->attendees()) {
+        a->setUid(QString()); //KCalCore sets the pointer as uid, we don't want that (if we wanted one, we'd want a real, globally unique one), so we clear the uid
+    }
+    
+    Q_FOREACH (KCalCore::Attachment::Ptr attachment, i->attachments()) {
+        attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
+    }
+}
+        
+/**
+ * Upgrades the format of a complete mime message containing a kolab object
+ */
+QString upgradeMime(const QByteArray &input)
+{
+    KMime::Message::Ptr msg = KMime::Message::Ptr(new KMime::Message);
+    msg->setContent( input );
+    msg->parse();
+    msg->content(KMime::ContentIndex());
+    
+    KMime::Headers::Base *xKolabHeader = msg->getHeaderByType("X-Kolab-Type");
+    if (!xKolabHeader) {
+        kWarning() << "could not find xKolabHeader";
+        return QString();
+    }
+    const QString &kolabType = xKolabHeader->asUnicodeString(); //TODO we probably shouldn't use unicodeString
+    KMime::Content *xmlContent = KolabV2::ConversionUtils::findContentByType( msg, kolabType.toLocal8Bit() );
+    if ( !xmlContent ) {
+        qWarning() << "no part found";
+        return QString();
+    }
+    const QByteArray xmlData = xmlContent->decodedContent();
+    QStringList attachments;
+    KCalCore::Incidence::Ptr i;
+    std::string v3String;
+    QString mimetype;
+    kDebug() << kolabType;
+    if (kolabType == KolabV2::ConversionUtils::eventKolabType()) { //Event
+        kDebug() << "event";
+        i = KolabV2::ConversionUtils::fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+        Q_ASSERT(i);
+        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
+        normalizeIncidence(i);
+        const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Event*>(i.data()));
+        v3String = Kolab::writeEvent(event);
+        mimetype = KolabV2::ConversionUtils::xCalMimeType();
+    } else if (kolabType == KolabV2::ConversionUtils::todoKolabType()) { //Todo 
+        kDebug() << "todo";
+        i = KolabV2::ConversionUtils::fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
+        Q_ASSERT(i);
+        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
+        normalizeIncidence(i);
+        const Kolab::Todo &todo = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Todo*>(i.data()));
+        v3String = Kolab::writeTodo(todo);
+        mimetype = KolabV2::ConversionUtils::xCalMimeType();
+    } else if (kolabType == KolabV2::ConversionUtils::journalKolabType()) { //Journal
+        kDebug() << "journal";
+        i = KolabV2::ConversionUtils::fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
+        Q_ASSERT(i);
+        KolabV2::ConversionUtils::getAttachments(i, attachments, msg);
+        normalizeIncidence(i);
+        const Kolab::Journal &journal = Kolab::KCalConversion::fromKCalCore(*dynamic_cast<KCalCore::Journal*>(i.data()));
+        v3String = Kolab::writeJournal(journal);
+        mimetype = KolabV2::ConversionUtils::xCalMimeType();
+    } else {
+        kWarning() << "no kolab object found " << kolabType;
+        return QString();
+    }
+
+    KMime::Message::Ptr message = KolabV2::ConversionUtils::createMessage(i, mimetype, kolabType, QString::fromStdString(v3String).toLocal8Bit());
+
+    QString result;
+    QTextStream s(&result);
+    message->toStream(s);
+    return result;
+
+}
+
+
+
+QString upgradeEventXML(const QByteArray &xmlData, QStringList &attachments)
+{
+    const KCalCore::Event::Ptr i = KolabV2::ConversionUtils::fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+    const Kolab::Event &event = Kolab::KCalConversion::fromKCalCore(*i);
+    const std::string &v3String = Kolab::writeEvent(event);
+    return QString::fromStdString(v3String);
+}
+
+
+    }
+}
\ No newline at end of file
diff --git a/upgradetool/upgradeutilities.h b/upgradetool/upgradeutilities.h
new file mode 100644
index 0000000..5ddebdd
--- /dev/null
+++ b/upgradetool/upgradeutilities.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UPGRADEUTILITIES_H
+#define UPGRADEUTILITIES_H
+#include <QString>
+
+namespace Kolab {
+    namespace Upgrade {
+/**
+ * Takes a v2 xml document and returns a v3 version
+ */
+QString upgradeEventXML(const QByteArray &xmlData);
+
+/**
+ * Takes a v2 mime message and returns a v3 version
+ */
+QString upgradeMime(const QByteArray &);
+
+
+
+    }
+}
+
+#endif
\ No newline at end of file


commit ae3d54362db4810cc02f400824fae4a0b43a3b0f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Mar 20 01:16:36 2012 +0100

    Changed namespace to KolabV2 to avoid conflicts.

diff --git a/libkolab/kolabformatV2/contact.cpp b/libkolab/kolabformatV2/contact.cpp
index e421629..16ace5c 100644
--- a/libkolab/kolabformatV2/contact.cpp
+++ b/libkolab/kolabformatV2/contact.cpp
@@ -39,7 +39,7 @@
 #include <QFile>
 #include <float.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 static const char* s_pictureAttachmentName = "kolab-picture.png";
 static const char* s_logoAttachmentName = "kolab-logo.png";
@@ -1182,7 +1182,7 @@ QImage Contact::loadPictureFromAddressee( const KABC::Picture& picture )
   return img;
 }
 
-QByteArray Kolab::Contact::loadSoundFromAddressee( const KABC::Sound& sound )
+QByteArray KolabV2::Contact::loadSoundFromAddressee( const KABC::Sound& sound )
 {
   QByteArray data;
   if ( !sound.isIntern() && !sound.url().isEmpty() ) {
@@ -1200,7 +1200,7 @@ QByteArray Kolab::Contact::loadSoundFromAddressee( const KABC::Sound& sound )
   return data;
 }
 
-QString Kolab::Contact::productID() const
+QString KolabV2::Contact::productID() const
 {
   // TODO: When KAB has the version number in a header file, don't hardcode (Bo)
   // Or we could use Addressee::productID? (David)
diff --git a/libkolab/kolabformatV2/contact.h b/libkolab/kolabformatV2/contact.h
index ba88a77..96f954a 100644
--- a/libkolab/kolabformatV2/contact.h
+++ b/libkolab/kolabformatV2/contact.h
@@ -30,8 +30,8 @@
     your version.
 */
 
-#ifndef KOLABCONTACT_H
-#define KOLABCONTACT_H
+#ifndef KOLABV2CONTACT_H
+#define KOLABV2CONTACT_H
 
 #include "kolabbase.h"
 #include <qimage.h>
@@ -42,7 +42,7 @@ namespace KABC {
   class Sound;
 }
 
-namespace Kolab {
+namespace KolabV2 {
 
 class Contact : public KolabBase {
 public:
diff --git a/libkolab/kolabformatV2/distributionlist.cpp b/libkolab/kolabformatV2/distributionlist.cpp
index 840c5a8..f011458 100644
--- a/libkolab/kolabformatV2/distributionlist.cpp
+++ b/libkolab/kolabformatV2/distributionlist.cpp
@@ -37,7 +37,7 @@
 #include <kabc/contactgroup.h>
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 static const char* s_unhandledTagAppName = "KOLABUNHANDLED"; // no hyphens in appnames!
 
@@ -67,7 +67,7 @@ QString DistributionList::name() const
   return mName;
 }
 
-void Kolab::DistributionList::loadDistrListMember( const QDomElement& element )
+void KolabV2::DistributionList::loadDistrListMember( const QDomElement& element )
 {
   Member member;
   for ( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
diff --git a/libkolab/kolabformatV2/distributionlist.h b/libkolab/kolabformatV2/distributionlist.h
index 33dc61d..c0a42e0 100644
--- a/libkolab/kolabformatV2/distributionlist.h
+++ b/libkolab/kolabformatV2/distributionlist.h
@@ -29,8 +29,8 @@
     your version.
 */
 
-#ifndef KOLABDISTRIBUTIONLIST_H
-#define KOLABDISTRIBUTIONLIST_H
+#ifndef KOLABV2DISTRIBUTIONLIST_H
+#define KOLABV2DISTRIBUTIONLIST_H
 
 #include "kolabbase.h"
 
@@ -38,7 +38,7 @@ namespace KABC {
   class ContactGroup;
 }
 
-namespace Kolab {
+namespace KolabV2 {
 
 class DistributionList : public KolabBase {
 public:
diff --git a/libkolab/kolabformatV2/event.cpp b/libkolab/kolabformatV2/event.cpp
index 103ced3..b09612d 100644
--- a/libkolab/kolabformatV2/event.cpp
+++ b/libkolab/kolabformatV2/event.cpp
@@ -36,7 +36,7 @@
 #include <kcalcore/event.h>
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 
 KCalCore::Event::Ptr Event::fromXml( const QDomDocument& xmlDoc, const QString& tz)
diff --git a/libkolab/kolabformatV2/event.h b/libkolab/kolabformatV2/event.h
index acc327b..be0d4bf 100644
--- a/libkolab/kolabformatV2/event.h
+++ b/libkolab/kolabformatV2/event.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLAB_EVENT_H
-#define KOLAB_EVENT_H
+#ifndef KOLABV2_EVENT_H
+#define KOLABV2_EVENT_H
 
 #include "incidence.h"
 
@@ -41,7 +41,7 @@
 class QDomElement;
 
 
-namespace Kolab {
+namespace KolabV2 {
 
 /**
  * This class represents an event, and knows how to load/save it
diff --git a/libkolab/kolabformatV2/incidence.cpp b/libkolab/kolabformatV2/incidence.cpp
index 9f4323f..fcd5803 100644
--- a/libkolab/kolabformatV2/incidence.cpp
+++ b/libkolab/kolabformatV2/incidence.cpp
@@ -43,7 +43,7 @@
 
 #include <QBitArray>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 
 Incidence::Incidence( const QString& tz, const KCalCore::Incidence::Ptr &incidence )
diff --git a/libkolab/kolabformatV2/incidence.h b/libkolab/kolabformatV2/incidence.h
index 2b96776..ad1fa72 100644
--- a/libkolab/kolabformatV2/incidence.h
+++ b/libkolab/kolabformatV2/incidence.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLAB_INCIDENCE_H
-#define KOLAB_INCIDENCE_H
+#ifndef KOLABV2_INCIDENCE_H
+#define KOLABV2_INCIDENCE_H
 
 #include <kcalcore/incidence.h>
 
@@ -40,7 +40,7 @@
 
 class QDomElement;
 
-namespace Kolab {
+namespace KolabV2 {
 
 /**
  * This abstract class represents an incidence which has the shared
diff --git a/libkolab/kolabformatV2/journal.cpp b/libkolab/kolabformatV2/journal.cpp
index c9c2c1b..471b05f 100644
--- a/libkolab/kolabformatV2/journal.cpp
+++ b/libkolab/kolabformatV2/journal.cpp
@@ -36,7 +36,7 @@
 
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 
 KCalCore::Journal::Ptr Journal::fromXml( const QDomDocument& xmlDoc, const QString& tz )
diff --git a/libkolab/kolabformatV2/journal.h b/libkolab/kolabformatV2/journal.h
index a049c86..bcd3e30 100644
--- a/libkolab/kolabformatV2/journal.h
+++ b/libkolab/kolabformatV2/journal.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLAB_JOURNAL_H
-#define KOLAB_JOURNAL_H
+#ifndef KOLABV2_JOURNAL_H
+#define KOLABV2_JOURNAL_H
 
 #include <kcalcore/journal.h>
 
@@ -40,7 +40,7 @@
 
 class QDomElement;
 
-namespace Kolab {
+namespace KolabV2 {
 
 /**
  * This class represents a journal entry, and knows how to load/save it
diff --git a/libkolab/kolabformatV2/kolabbase.cpp b/libkolab/kolabformatV2/kolabbase.cpp
index 4315f3e..a51d254 100644
--- a/libkolab/kolabformatV2/kolabbase.cpp
+++ b/libkolab/kolabformatV2/kolabbase.cpp
@@ -40,7 +40,7 @@
 #include <ksystemtimezone.h>
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 KolabBase::KolabBase( const QString& tz )
   : mCreationDate( QDateTime::currentDateTime() ),
diff --git a/libkolab/kolabformatV2/kolabbase.h b/libkolab/kolabformatV2/kolabbase.h
index 5044bc3..a1c3db9 100644
--- a/libkolab/kolabformatV2/kolabbase.h
+++ b/libkolab/kolabformatV2/kolabbase.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLABBASE_H
-#define KOLABBASE_H
+#ifndef KOLABV2BASE_H
+#define KOLABV2BASE_H
 
 
 #include <kcalcore/incidence.h>
@@ -48,7 +48,7 @@ namespace KABC {
   class ContactGroup;
 }
 
-namespace Kolab {
+namespace KolabV2 {
 
 class KolabBase {
 public:
diff --git a/libkolab/kolabformatV2/note.cpp b/libkolab/kolabformatV2/note.cpp
index 65afebe..419fa5c 100644
--- a/libkolab/kolabformatV2/note.cpp
+++ b/libkolab/kolabformatV2/note.cpp
@@ -37,7 +37,7 @@
 #include <kcalcore/journal.h>
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 
 KCalCore::Journal::Ptr Note::xmlToJournal( const QString& xml )
diff --git a/libkolab/kolabformatV2/note.h b/libkolab/kolabformatV2/note.h
index b0291c4..c88c659 100644
--- a/libkolab/kolabformatV2/note.h
+++ b/libkolab/kolabformatV2/note.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLAB_NOTE_H
-#define KOLAB_NOTE_H
+#ifndef KOLABV2_NOTE_H
+#define KOLABV2_NOTE_H
 
 #include <kcalcore/journal.h>
 
@@ -40,7 +40,7 @@
 
 class QDomElement;
 
-namespace Kolab {
+namespace KolabV2 {
 
 /**
  * This class represents a note, and knows how to load/save it
diff --git a/libkolab/kolabformatV2/task.cpp b/libkolab/kolabformatV2/task.cpp
index 974fdb2..fef0d30 100644
--- a/libkolab/kolabformatV2/task.cpp
+++ b/libkolab/kolabformatV2/task.cpp
@@ -36,7 +36,7 @@
 #include <kcalcore/todo.h>
 #include <kdebug.h>
 
-using namespace Kolab;
+using namespace KolabV2;
 
 // Kolab Storage Specification:
 //    "The priority can be a number between 1 and 5, with 1 being the highest priority."
diff --git a/libkolab/kolabformatV2/task.h b/libkolab/kolabformatV2/task.h
index bafc160..148d164 100644
--- a/libkolab/kolabformatV2/task.h
+++ b/libkolab/kolabformatV2/task.h
@@ -31,8 +31,8 @@
     your version.
 */
 
-#ifndef KOLAB_TASK_H
-#define KOLAB_TASK_H
+#ifndef KOLABV2_TASK_H
+#define KOLABV2_TASK_H
 
 #include <incidence.h>
 
@@ -45,7 +45,7 @@ namespace KCal {
   class ResourceKolab;
 }
 
-namespace Kolab {
+namespace KolabV2 {
 
 /**
  * This class represents a task, and knows how to load/save it





More information about the commits mailing list