Branch 'c++/master' - 25 commits - c++/CMakeLists.txt c++/compiled c++/lib c++/README c++/tests schemas/ical schemas/kolabformat-xcard.xsd schemas/kolabformat.xsd schemas/xCard.xsd

Christian Mollekopf mollekopf at kolabsys.com
Thu Dec 29 13:39:18 CET 2011


 c++/CMakeLists.txt                |   89 ++--
 c++/README                        |   18 
 c++/compiled/README               |    2 
 c++/compiled/XMLParserWrapper.cpp |    4 
 c++/lib/CMakeLists.txt            |  108 ++++-
 c++/lib/DEVELOPMENT               |   76 +++
 c++/lib/conversions.h             |  435 --------------------
 c++/lib/genericxcalconverions.h   |  443 +++++++++++++++++++++
 c++/lib/global_definitions.h      |    7 
 c++/lib/incidence_p.h             |    2 
 c++/lib/kcalconversions.h         |    4 
 c++/lib/kcalkolabformat.cpp       |   10 
 c++/lib/kcalkolabformat.h         |    4 
 c++/lib/kolabcontainers.cpp       |  284 -------------
 c++/lib/kolabcontainers.h         |  167 +++----
 c++/lib/kolabcontainers.i         |    6 
 c++/lib/kolabconversions.h        |  740 -----------------------------------
 c++/lib/kolabevent.cpp            |  327 +++++++++++++++
 c++/lib/kolabevent.h              |  109 +++++
 c++/lib/kolabformat.cpp           |  107 ++++-
 c++/lib/kolabformat.h             |   25 -
 c++/lib/kolabformat.i             |    8 
 c++/lib/kolabkcalconversion.h     |    7 
 c++/lib/kolabtodo.cpp             |   19 
 c++/lib/test.php                  |    5 
 c++/lib/test.py                   |    6 
 c++/lib/utils.cpp                 |   33 +
 c++/lib/utils.h                   |   16 
 c++/lib/xcalconversions.h         |  796 ++++++++++++++++++++++++++++++++++++++
 c++/lib/xcardconversions.h        |  140 ++++++
 c++/tests/CMakeLists.txt          |   25 -
 c++/tests/bindingstest.cpp        |   64 +--
 c++/tests/bindingstest.h          |    2 
 c++/tests/kcalconversiontest.cpp  |   20 
 schemas/ical/kolabformat-xcal.xsd |   31 +
 schemas/kolabformat-xcard.xsd     |   27 +
 schemas/kolabformat.xsd           |   17 
 schemas/xCard.xsd                 |  108 +++--
 38 files changed, 2563 insertions(+), 1728 deletions(-)

New commits:
commit dc93b755f9e70465cdf5b6cd9f0a646060dfaa49
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 13:31:30 2011 +0100

    Drafted some containers

diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
index e7a3b99..eed058b 100644
--- a/c++/lib/incidence_p.h
+++ b/c++/lib/incidence_p.h
@@ -39,6 +39,8 @@ namespace Kolab {
         std::vector<Attendee> attendees;
         std::vector<Attachment> attachments;
         std::vector<CustomProperty> customProperties;
+        
+        std::vector<Alarm> alarms;
     };
     
 }
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index fa31e12..402e126 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -4,7 +4,6 @@
 #include <vector>
 #include <boost/scoped_ptr.hpp>
 
-
 namespace Kolab {
 
 class DateTime {
@@ -60,12 +59,28 @@ enum Status {
     Final
 };
 
-struct DayPos
-{
+struct DayPos {
     void operator=(const DayPos &){};
     //TODO
 };
-    
+
+enum Related {
+    Start,
+    End
+};
+
+struct Alarm {
+    //TODO
+//     void setRelativeStart(const Duration &, Related);
+//     void setStart(const DateTime &);
+//     void setDuration(const Duration &, int numrepeat);
+//     
+//     //The following alarm types are mutual exclusive (implement as constructor?)
+//     void setDisplayAlarm(const std::string &text);
+//     void setAudioAlarm(const Attachment &audio);
+//     void setEmailAlarm(const std::string &summary, const std::string &description, const std::vector<std::string> attendees);
+};
+
 
 class RecurrenceRule {
 public:
@@ -143,23 +158,58 @@ private:
     boost::scoped_ptr<Private> d;
 };
 
-class Duration {
+struct Duration {
     //TODO
 };
 
+enum PartStatus {
+    PartNeedsAction,
+    PartAccepted,
+    PartDeclined,
+    PartTentative,
+    PartDelegated
+};
+
+enum Role {
+    Required,
+    Chair,
+    Optional,
+    NonParticipant
+};
+
 class Attendee {
-    //TODO
+// public:
+//     Attendee(const std::string &email);
+//     void setName(const std::string &);
+//     void setPartStat(PartStatus);
+//     void setUid(const std::string &);
+//     void setRole(Role);
 };
 
 class Attachment {
-    //TODO
+// public:
+//     /**
+//      * If @param embedd is set, the file is embedded during serialization.
+//      */
+//     void setFile(const std::string uri, const std::string &mimetype, bool embedd);
+//     ///Unencodedn binary content, Implies embedded
+//     void setUnencoded(const std::string &, const std::string &mimetype);
+//     ///Base64 encoded binary content, Implies embedded
+//     void setEncoded(const std::string &, const std::string &mimetype);
+//     ///User visible label
+//     void setLabel(const std::string &);
+//TODO
+
 };
 
-class CustomProperty {
-    //TODO
+struct CustomProperty {
+    std::string identifier;
+    std::string value;
 };
     
 
+//Prepared Kolab Objects
+
 class Journal {
     //TODO
 };
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
index d6f0cf1..8a6df74 100644
--- a/c++/lib/kolabevent.cpp
+++ b/c++/lib/kolabevent.cpp
@@ -12,6 +12,7 @@ struct Event::Private: public PrivateIncidence
     DateTime end;
     bool isTransparent;
     Duration duration;
+    std::vector< Event > exceptions;
 };
 
 Event::Event()
@@ -37,6 +38,11 @@ void Event::operator=(const Kolab::Event &other)
     *d = *other.d;
 }
 
+bool Event::isValid()
+{
+    return !d->uid.empty();
+}
+
 void Event::setUid(const std::string &uid)
 {
     d->uid = uid;
@@ -295,4 +301,27 @@ 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
index b7949b5..9634572 100644
--- a/c++/lib/kolabevent.h
+++ b/c++/lib/kolabevent.h
@@ -16,6 +16,8 @@ public:
     Event(const Event &);
     void operator=(const Event &);
     
+    bool isValid();
+    
     void setUid(const std::string &);
     std::string uid() const;
     
@@ -89,6 +91,13 @@ public:
     
     void setCustomProperties(const std::vector<CustomProperty> &);
     std::vector<CustomProperty> customProperties() const;
+    
+    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;


commit 3603018f78d904adb2045ae59b2b07ebe957cb11
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 13:05:16 2011 +0100

    remaining by*** rules (except byday)

diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index fad6b78..3f565c2 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -472,8 +472,34 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
         recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
     }
     
-    //TODO remainting by rules
+    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()) {
+        //TODO
+    }
+    
+    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;
 }
 


commit ebfdf185bd68ed88c99b024f8734a50275507069
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 13:04:26 2011 +0100

    conditionally compile swig bindings

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 873ebcc..39c729a 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -21,6 +21,12 @@ else (XERCES_C)
     "xerces NOT found!")
 endif(XERCES_C)
 
+find_program(SWIG swig /usr/bin/)
+if(SWIG)
+    set(SWIG_FOUND ON)
+    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)
 if(KDECORE)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index d591a30..fe6fbcd 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -58,12 +58,17 @@ endif()
 
 #-----------------------SWIG--------------------
 
+if (NOT SWIG_FOUND)
+    message(WARNING "Could not build SWIG bindings, because SWIG is missing.")
+    return()
+endif()
+
 set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
 
 #Generate Python wrapper
 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
+    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  ${KOLAB_CONTAINER_HEADERS}
@@ -76,7 +81,7 @@ ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURC
 #Generate PHP wrapper
 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
+    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 ${KOLAB_CONTAINER_HEADERS}


commit 54a592a0fc9d1b71461bc1cd1dc507f3b28aeb32
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 13:03:26 2011 +0100

    Updated development info.

diff --git a/c++/README b/c++/README
index 2faa412..ba1f383 100644
--- a/c++/README
+++ b/c++/README
@@ -1,6 +1,18 @@
-Build with
+Build with:
 
-mkdir build
-cd build
-cmake ..
-make
+$mkdir build
+$cd build
+$cmake ..
+$make
+
+
+Minimum requirements are:
+-cmake 2.8
+-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
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index 4edd1c1..7002b31 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -17,7 +17,7 @@ Library to provide converters to KCalCore containers as well as advanced functio
 
 === kolabxmlkcal (deprecated) ===
 
-First approach does a direct mapping from xml to KCalCore containers. 
+First approach which does a direct mapping from xml to KCalCore containers. 
 It tourned 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.
 
@@ -50,6 +50,18 @@ They we're also designed to be easily copieable and make therefore minimal use o
 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.
+
+=== 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.


commit fbd53ddc8fa10dfa5599b88abf82922960a71a78
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 12:10:47 2011 +0100

    organizer completed

diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 5dfa9c8..fad6b78 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -586,7 +586,14 @@ void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to t
     }
     
     if (!inc.organizerEmail().empty()) { //email is required
-        //TODO
+        typename properties::organizer_type organizer(inc.organizerEmail());
+        
+        typename properties::organizer_type::parameters_type p; //There is maybe already a timezone set
+        icalendar_2_0::CnParamType name(inc.organizerName());
+        p.baseParameter().push_back(name);
+
+        organizer.parameters(p);
+        prop.organizer(organizer);
     }
     
     if (!inc.attendees().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index de9b875..0690785 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -163,6 +163,8 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.priority(), re.priority());
     QCOMPARE(ev.status(), re.status());
     QCOMPARE(ev.location(), re.location());
+    QCOMPARE(ev.organizerEmail(), re.organizerEmail());
+    QCOMPARE(ev.organizerName(), re.organizerName());
 }
 
 


commit 114ad012bf70c8e14dd61af1796798fbfe45ee0d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 00:02:55 2011 +0100

    This and future

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index c747c6d..9e9519d 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -20,6 +20,8 @@ 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 NEEDSACTION = "NEEDS-ACTION";
 const char* const COMPLETED = "OPAQUE";
 const char* const INPROCESS = "IN-PROCESS";
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index db7bd28..5dfa9c8 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -360,8 +360,15 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     if (prop.recurrence_id()) {
-        //TODO THISANDFUTURE range
-        bool thisandfuture = true;
+        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<KolabTypes>(*prop.recurrence_id()), thisandfuture);
     }
     
@@ -517,8 +524,17 @@ void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to t
     }
     
     if (inc.recurrenceID().isValid()) {
-        //TODO THISANDFUTURE
-        prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
+        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<KolabTypes, 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.summary().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 0c2f31d..de9b875 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -119,7 +119,7 @@ void setIncidence(T &ev)
     ev.setRecurrenceRule(rule);
     ev.addRecurrenceDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
     ev.addExceptionDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
-    ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), false);
+    ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), true);
     ev.setSummary("summary");
     ev.setDescription("description");
     ev.setPriority(3);
@@ -157,6 +157,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
     QCOMPARE(ev.exceptionDates().at(0), re.exceptionDates().at(0));
     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());


commit c5bf0d5e58d56c6b4c9acbfc66f24edb0520fd2a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 22:17:33 2011 +0100

    updated background info

diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index fe61d7d..4edd1c1 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -1,4 +1,36 @@
+== 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 does a direct mapping from xml to KCalCore containers. 
+It tourned 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 ==
 
@@ -11,3 +43,35 @@ Datamembers are not directly exposed to provide binary compatibilty through the
 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 we're 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.
+== 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 debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
\ No newline at end of file


commit 79c7958724293bd834b05bba023fa38f8f475201
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 22:13:46 2011 +0100

    Renamed files to be a bit more consistent

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
deleted file mode 100644
index c747c6d..0000000
--- a/c++/lib/conversions.h
+++ /dev/null
@@ -1,441 +0,0 @@
-#ifndef KOLAB_CONVERSIONS_H
-#define KOLAB_CONVERSIONS_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>
-
-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 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";
-
-namespace Kolab {
-
-template <typename T>
-int convertToInt(T integer)
-{
-    try {
-        int i = boost::numeric_cast<int>(integer);
-        return i;
-    } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
-    }
-    return 0;
-}
-
-template <typename T> 
-T fromInt(int integer)
-{
-    try {
-        T i = boost::numeric_cast<T>(integer);
-        return i;
-    } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
-    }
-    return 0;
-}
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
-    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
-}
-
-///trait to convert date-time values
-template <typename T> 
-struct DateTimeConverter;
-
-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 {
-                std::cout << "/kolab.org/ timezone prefix is missing";
-            }
-            return tzid;
-        }
-    }
-    return std::string();
-}
-
-template <typename T> 
-typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
-    typedef DateTimeConverter<typename T::DateType> DC;
-    typename T::DatePtr date;
-    if (dtProperty.date_time()) {
-        date = DC::toDate(*dtProperty.date_time());
-    } else if (dtProperty.date()) {
-        date = DC::toDate(*dtProperty.date());
-    }
-
-    if (dtProperty.parameters()) {
-        const std::string &tzid = getTimezone(*dtProperty.parameters());
-        if (tzid.size()) {
-            DC::setTimezone(date, tzid);
-        }
-    }
-    return date;
-}
-
-// template <typename T, typename I> 
-// typename T::DatePtr toDate(const I &dtProperty)
-// {
-//     typedef DateTimeConverter<typename T::DateType> DC;
-//     typename T::DatePtr date;
-//     if (dtProperty.date_time()) {
-//         date = DC::toDate(*dtProperty.date_time());
-//     } else if (dtProperty.date()) {
-//         date = DC::toDate(*dtProperty.date());
-//     }
-// 
-//     if (dtProperty.parameters()) {
-//         const std::string &tzid = getTimezone(*dtProperty.parameters());
-//         if (tzid.size()) {
-//             DC::setTimezone(date, tzid);
-//         }
-//     }
-//     return date;
-// }
-
-template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    typename T::DatePtr date;
-    if (dtProperty.date_time()) {
-        date = DC::toDate(*dtProperty.date_time());
-    } else { //The utc-date-time element shouldn't even exist
-        date = DatePtr(new DateType());
-        std::cerr << "This element shouldn't even be existing";
-        //TODO Implement anyways?
-        return date;
-    }
-    DC::setUTC(date);
-    return date;
-}
-
-template <typename T, typename I>
-std::auto_ptr<I> fromDate(const typename T::DateType &dt)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::auto_ptr<I> ptr(new I);
-    
-    if (DC::isDateOnly(dt)) {
-        ptr->date(DC::fromDate(dt));
-    } else {
-        ptr->date_time(DC::fromDateTime(dt));
-
-        const std::string &timezone = DC::getTimezone(dt);
-        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 T>
-void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    if (DC::isDateOnly(dt)) {
-        date.date(DC::fromDate(dt));
-    } else {
-        date.date_time(DC::fromDateTime(dt));
-
-        const std::string &timezone = DC::getTimezone(dt);
-        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);
-            date.parameters(parameters);
-        }
-    }
-}
-
-template <typename T, typename I>
-std::vector<typename T::DateType> toDateTimeList(I datelistProperty)
-{
-    typedef typename T::DateType DateType;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::vector<DateType>  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(*DC::toDate(d));
-        }
-    } else if (!datelistProperty.date_time().empty()) {
-        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
-            typename DC::Ptr date = DC::toDate(d);
-            if (tzid.size()) {
-                date->setTimezone(tzid);
-            }
-            list.push_back(*date);
-        }
-    }
-    return list;
-}
-
-template <typename T, typename I>
-std::auto_ptr<I> fromDateTimeList(const std::vector<typename T::DateType> &dtlist)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::auto_ptr<I> ptr(new I);
-    BOOST_FOREACH(const DateType &dt, dtlist) {
-        if (DC::isDateOnly(dt)) {
-            ptr->date().push_back(DC::fromDate(dt));
-        } else {
-            ptr->date_time().push_back(DC::fromDateTime(dt));
-        }
-        //TODO handle utc
-        //TODO check for equality of timezones?
-    }
-    
-    if (!dtlist.empty() && !DC::getTimezone(dtlist.at(0)).empty()) {
-        const std::string &timezone = DC::getTimezone(dtlist.at(0));
-        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;
-}
-
-
-
-///trait to convert recurrence properties
-template <typename T>
-struct RecurrenceConverter;
-
-template <typename T>
-typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-{
-    using namespace icalendar_2_0;
-
-    typedef RecurrenceConverter< typename T::RecurrenceType> RC;
-    typedef DateTimeConverter< typename T::DateType> DC;
-    typedef typename T::DatePtr DatePtr;
-    typedef typename T::RecurrencePtr RecurrencePtr;
-    typedef typename T::RecurrenceType RecurrenceType;
-
-    RecurrencePtr r(new RecurrenceType());
-    RC::setType(r, rrule.freq());
-    if (rrule.until()) {
-        DatePtr date;
-        if ((*rrule.until()).date_time()) {
-            date = DC::toDate(*(*rrule.until()).date_time());
-        } else if ((*rrule.until()).date()) {
-            date = DC::toDate(*(*rrule.until()).date());
-        }
-        RC::setEndDt(r, date);
-    } else if (rrule.count()) {
-        RC::setCount(r, toInt(*rrule.count()));
-    }
-    if (rrule.interval()) {
-        RC::setInterval(r, toInt(*rrule.interval()));
-    } else {
-        RC::setInterval(r, 1); //FIXME should be initialized to 1 in KCalCore::RecurrenceRule class (default value of interval per RFC).
-    }
-    RC::setBysecond(r, rrule.bysecond());
-    RC::setByminute(r, rrule.byminute());
-    RC::setByhour(r, rrule.byhour());
-    RC::setByday(r, rrule.byday());
-    RC::setBymonthday(r, rrule.bymonthday());
-    RC::setByyearday(r, rrule.byyearday());
-    RC::setByweekno(r, rrule.byweekno());
-    RC::setBymonth(r, rrule.bymonth());
-    if (rrule.wkst()) {
-        RC::setWeekStart(r, *rrule.wkst());
-    }
-
-    return r;
-}
-
-///Trait for Incidence object
-template <typename T, typename I> 
-struct IncidenceConverter;
-
-///Trait for incidence properties specialized for Event/Todo/Journal
-template <typename T> struct IncidenceTrait;
-
-
-
-
-
-
-template <typename T>
-typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
-{
-    typedef typename T::IncidencePtr IncidencePtr;
-    typedef typename T::IncidenceType IncidenceType;
-    typedef typename T::KolabType KolabType;
-    
-    try {
-//         xml_schema::properties props;
-        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);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
-//             icalendar = icalendar_2_0::icalendar(s, 0, props);
-        } else {
-//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-//             icalendar = readCompiledIncidence(is, "string");
-//             icalendar = icalendar_2_0::icalendar(is, 0, props);
-        }
-        
-        if (!icalendar.get()) {
-            std::cerr << "failed to parse calendar!" << std::endl;
-            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);
-        }
-
-        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
-//         foreach (KCalCore::Event * event, events) {
-//             if (!event->hasRecurrenceId()) {
-//                 return event;
-//             }
-//         }
-
-        return *incidences.begin();
-    } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        std::cerr <<  "Failed to read incidence!" << std::endl;
-    }
-
-    return IncidencePtr();
-    
-}
-
-
-
-template <typename T>
-std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
-    
-    using namespace icalendar_2_0;
-    typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
-    typedef typename T::KolabType KolabType;
-
-    try {
-
-        typename KolabType::components_type eventComponents;
-
-        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
-        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, eventComponents);
-        T::writeIncidence(inc, incidence);
-        
-        VcalendarType::components_type components;
-        T::addIncidence(components, inc);
-        
-        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME);
-        VcalendarType::properties_type::version_type version(XCAL_VERSION);
-        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_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) {
-        std::cout << "failed to write Incidence";
-        return std::string();
-    } 
-}
-
-
-
-
-
-}
-
-#endif
\ No newline at end of file
diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
new file mode 100644
index 0000000..c747c6d
--- /dev/null
+++ b/c++/lib/genericxcalconverions.h
@@ -0,0 +1,441 @@
+#ifndef KOLAB_CONVERSIONS_H
+#define KOLAB_CONVERSIONS_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>
+
+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 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";
+
+namespace Kolab {
+
+template <typename T>
+int convertToInt(T integer)
+{
+    try {
+        int i = boost::numeric_cast<int>(integer);
+        return i;
+    } catch(boost::numeric::negative_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cerr << e.what();
+    }
+    return 0;
+}
+
+template <typename T> 
+T fromInt(int integer)
+{
+    try {
+        T i = boost::numeric_cast<T>(integer);
+        return i;
+    } catch(boost::numeric::negative_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cerr << e.what();
+    }
+    return 0;
+}
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
+}
+
+///trait to convert date-time values
+template <typename T> 
+struct DateTimeConverter;
+
+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 {
+                std::cout << "/kolab.org/ timezone prefix is missing";
+            }
+            return tzid;
+        }
+    }
+    return std::string();
+}
+
+template <typename T> 
+typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    typedef DateTimeConverter<typename T::DateType> DC;
+    typename T::DatePtr date;
+    if (dtProperty.date_time()) {
+        date = DC::toDate(*dtProperty.date_time());
+    } else if (dtProperty.date()) {
+        date = DC::toDate(*dtProperty.date());
+    }
+
+    if (dtProperty.parameters()) {
+        const std::string &tzid = getTimezone(*dtProperty.parameters());
+        if (tzid.size()) {
+            DC::setTimezone(date, tzid);
+        }
+    }
+    return date;
+}
+
+// template <typename T, typename I> 
+// typename T::DatePtr toDate(const I &dtProperty)
+// {
+//     typedef DateTimeConverter<typename T::DateType> DC;
+//     typename T::DatePtr date;
+//     if (dtProperty.date_time()) {
+//         date = DC::toDate(*dtProperty.date_time());
+//     } else if (dtProperty.date()) {
+//         date = DC::toDate(*dtProperty.date());
+//     }
+// 
+//     if (dtProperty.parameters()) {
+//         const std::string &tzid = getTimezone(*dtProperty.parameters());
+//         if (tzid.size()) {
+//             DC::setTimezone(date, tzid);
+//         }
+//     }
+//     return date;
+// }
+
+template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    typedef typename T::DateType DateType;
+    typedef typename T::DatePtr DatePtr;
+    typedef DateTimeConverter<DateType> DC;
+    
+    typename T::DatePtr date;
+    if (dtProperty.date_time()) {
+        date = DC::toDate(*dtProperty.date_time());
+    } else { //The utc-date-time element shouldn't even exist
+        date = DatePtr(new DateType());
+        std::cerr << "This element shouldn't even be existing";
+        //TODO Implement anyways?
+        return date;
+    }
+    DC::setUTC(date);
+    return date;
+}
+
+template <typename T, typename I>
+std::auto_ptr<I> fromDate(const typename T::DateType &dt)
+{
+    typedef typename T::DateType DateType;
+    typedef typename T::DatePtr DatePtr;
+    typedef DateTimeConverter<DateType> DC;
+    
+    std::auto_ptr<I> ptr(new I);
+    
+    if (DC::isDateOnly(dt)) {
+        ptr->date(DC::fromDate(dt));
+    } else {
+        ptr->date_time(DC::fromDateTime(dt));
+
+        const std::string &timezone = DC::getTimezone(dt);
+        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 T>
+void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
+{
+    typedef typename T::DateType DateType;
+    typedef typename T::DatePtr DatePtr;
+    typedef DateTimeConverter<DateType> DC;
+    
+    if (DC::isDateOnly(dt)) {
+        date.date(DC::fromDate(dt));
+    } else {
+        date.date_time(DC::fromDateTime(dt));
+
+        const std::string &timezone = DC::getTimezone(dt);
+        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);
+            date.parameters(parameters);
+        }
+    }
+}
+
+template <typename T, typename I>
+std::vector<typename T::DateType> toDateTimeList(I datelistProperty)
+{
+    typedef typename T::DateType DateType;
+    typedef DateTimeConverter<DateType> DC;
+    
+    std::vector<DateType>  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(*DC::toDate(d));
+        }
+    } else if (!datelistProperty.date_time().empty()) {
+        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
+            typename DC::Ptr date = DC::toDate(d);
+            if (tzid.size()) {
+                date->setTimezone(tzid);
+            }
+            list.push_back(*date);
+        }
+    }
+    return list;
+}
+
+template <typename T, typename I>
+std::auto_ptr<I> fromDateTimeList(const std::vector<typename T::DateType> &dtlist)
+{
+    typedef typename T::DateType DateType;
+    typedef typename T::DatePtr DatePtr;
+    typedef DateTimeConverter<DateType> DC;
+    
+    std::auto_ptr<I> ptr(new I);
+    BOOST_FOREACH(const DateType &dt, dtlist) {
+        if (DC::isDateOnly(dt)) {
+            ptr->date().push_back(DC::fromDate(dt));
+        } else {
+            ptr->date_time().push_back(DC::fromDateTime(dt));
+        }
+        //TODO handle utc
+        //TODO check for equality of timezones?
+    }
+    
+    if (!dtlist.empty() && !DC::getTimezone(dtlist.at(0)).empty()) {
+        const std::string &timezone = DC::getTimezone(dtlist.at(0));
+        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;
+}
+
+
+
+///trait to convert recurrence properties
+template <typename T>
+struct RecurrenceConverter;
+
+template <typename T>
+typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+    using namespace icalendar_2_0;
+
+    typedef RecurrenceConverter< typename T::RecurrenceType> RC;
+    typedef DateTimeConverter< typename T::DateType> DC;
+    typedef typename T::DatePtr DatePtr;
+    typedef typename T::RecurrencePtr RecurrencePtr;
+    typedef typename T::RecurrenceType RecurrenceType;
+
+    RecurrencePtr r(new RecurrenceType());
+    RC::setType(r, rrule.freq());
+    if (rrule.until()) {
+        DatePtr date;
+        if ((*rrule.until()).date_time()) {
+            date = DC::toDate(*(*rrule.until()).date_time());
+        } else if ((*rrule.until()).date()) {
+            date = DC::toDate(*(*rrule.until()).date());
+        }
+        RC::setEndDt(r, date);
+    } else if (rrule.count()) {
+        RC::setCount(r, toInt(*rrule.count()));
+    }
+    if (rrule.interval()) {
+        RC::setInterval(r, toInt(*rrule.interval()));
+    } else {
+        RC::setInterval(r, 1); //FIXME should be initialized to 1 in KCalCore::RecurrenceRule class (default value of interval per RFC).
+    }
+    RC::setBysecond(r, rrule.bysecond());
+    RC::setByminute(r, rrule.byminute());
+    RC::setByhour(r, rrule.byhour());
+    RC::setByday(r, rrule.byday());
+    RC::setBymonthday(r, rrule.bymonthday());
+    RC::setByyearday(r, rrule.byyearday());
+    RC::setByweekno(r, rrule.byweekno());
+    RC::setBymonth(r, rrule.bymonth());
+    if (rrule.wkst()) {
+        RC::setWeekStart(r, *rrule.wkst());
+    }
+
+    return r;
+}
+
+///Trait for Incidence object
+template <typename T, typename I> 
+struct IncidenceConverter;
+
+///Trait for incidence properties specialized for Event/Todo/Journal
+template <typename T> struct IncidenceTrait;
+
+
+
+
+
+
+template <typename T>
+typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
+{
+    typedef typename T::IncidencePtr IncidencePtr;
+    typedef typename T::IncidenceType IncidenceType;
+    typedef typename T::KolabType KolabType;
+    
+    try {
+//         xml_schema::properties props;
+        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);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
+//             icalendar = icalendar_2_0::icalendar(s, 0, props);
+        } else {
+//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+//             icalendar = readCompiledIncidence(is, "string");
+//             icalendar = icalendar_2_0::icalendar(is, 0, props);
+        }
+        
+        if (!icalendar.get()) {
+            std::cerr << "failed to parse calendar!" << std::endl;
+            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);
+        }
+
+        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+//         foreach (KCalCore::Event * event, events) {
+//             if (!event->hasRecurrenceId()) {
+//                 return event;
+//             }
+//         }
+
+        return *incidences.begin();
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        std::cerr <<  "Failed to read incidence!" << std::endl;
+    }
+
+    return IncidencePtr();
+    
+}
+
+
+
+template <typename T>
+std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
+    
+    using namespace icalendar_2_0;
+    typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
+    typedef typename T::KolabType KolabType;
+
+    try {
+
+        typename KolabType::components_type eventComponents;
+
+        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
+        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, eventComponents);
+        T::writeIncidence(inc, incidence);
+        
+        VcalendarType::components_type components;
+        T::addIncidence(components, inc);
+        
+        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME);
+        VcalendarType::properties_type::version_type version(XCAL_VERSION);
+        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_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) {
+        std::cout << "failed to write Incidence";
+        return std::string();
+    } 
+}
+
+
+
+
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 9065a5e..725dd11 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -1,7 +1,7 @@
 #ifndef KOLAB_KCALCONVERSIONS_H
 #define KOLAB_KCALCONVERSIONS_H
 
-#include "conversions.h"
+#include "genericxcalconverions.h"
 #include <KDE/KDateTime>
 #include <KDE/KDebug>
 #include <kcalcore/recurrencerule.h>
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
deleted file mode 100644
index 60f07f1..0000000
--- a/c++/lib/kolabconversions.h
+++ /dev/null
@@ -1,744 +0,0 @@
-
-
-#include "conversions.h"
-#include "kolabcontainers.h"
-#include <boost/foreach.hpp>
-#include "kolabtodo.h"
-#include "utils.h"
-namespace Kolab {
-
-class Incidence;
-
-struct KolabTypes
-{
-    typedef DateTime DateType;
-    typedef typename boost::shared_ptr<DateTime> DatePtr;
-    typedef RecurrenceRule RecurrenceType;
-    typedef typename std::auto_ptr<RecurrenceRule> RecurrencePtr;
-    typedef std::string StringType;
-    typedef Incidence IncidenceType;
-};
-    
-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;
-}
-
-std::string toString(const icalendar_2_0::TextPropertyType &s)
-{
-    return s.text();
-}
-
-// template <typename T>
-// std::auto_ptr<T> fromString(const std::string &s)
-// {
-//     std::auto_ptr<T> ptr(new T());
-//     p.text(s);
-//     return ptr;
-// }
-
-template <> struct DateTimeConverter<DateTime>
-{
-    typedef DateTime Type;
-    typedef typename boost::shared_ptr<DateTime> Ptr;
-
-    static Ptr toDate(const  xml_schema::date &dt)
-    {
-        Ptr date(new DateTime());
-        date->setDate(dt.year(), dt.month(), dt.day());
-        return date;
-    }
-
-    static Ptr toDate(const xml_schema::date_time &dt)
-    {
-        Ptr date(new DateTime());
-        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;
-    }
-    
-    static xml_schema::date_time fromDateTime(const DateTime &d)
-    {
-        xml_schema::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;
-    }
-
-    static xml_schema::date fromDate(const DateTime &d)
-    {
-        xml_schema::date date(d.year(), d.month(), d.day());
-        return date;
-    }
-
-    static void setTimezone(Ptr date, const std::string &tzid)
-    {
-        date->setTimezone(tzid);
-    }
-
-    static std::string getTimezone(const DateTime &dt)
-    {
-        return dt.timezone();
-    }
-
-    static void setUTC(Ptr date)
-    {
-        date->setUTC(true);
-    }
-
-    static bool isDateOnly(Type date)
-    {
-        return date.isDateOnly();
-    }
-
-};
-
-
-template <> struct RecurrenceConverter < RecurrenceRule >
-{
-
-    typedef typename KolabTypes::RecurrenceType Type;
-    typedef typename KolabTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
-
-    static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
-    {
-        using namespace icalendar_2_0;
-        
-        switch (freq) {
-            case FreqRecurType::YEARLY:
-                r->setFrequency(RecurrenceRule::Yearly);
-                break;
-            case FreqRecurType::MONTHLY:
-                r->setFrequency(RecurrenceRule::Monthly);
-                break;
-            case FreqRecurType::WEEKLY:
-                r->setFrequency(RecurrenceRule::Weekly);
-                break;
-            case FreqRecurType::DAILY:
-                r->setFrequency(RecurrenceRule::Daily);
-                break;
-            case FreqRecurType::HOURLY:
-                r->setFrequency(RecurrenceRule::Hourly);
-                break;
-            case FreqRecurType::MINUTELY:
-                r->setFrequency(RecurrenceRule::Minutely);
-                break;
-            case FreqRecurType::SECONDLY:
-                r->setFrequency(RecurrenceRule::Secondly);
-                break;
-            default:
-                std::cout << "invalid unhandled recurrenc type" << freq;
-        }
-    }
-    
-    static icalendar_2_0::RecurType::freq_type type(const Type &t)
-    {
-        using namespace icalendar_2_0;
-
-        switch (t.frequency()) {
-            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:
-                std::cout << "invalid unhandled recurrenc type";
-        }
-        return 0;
-    }
-    
-    static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
-    {
-        using namespace icalendar_2_0;
-
-        switch (wkst) {
-            case WeekdayRecurType::MO:
-                r->setWeekStart(RecurrenceRule::Monday);
-                break;
-            case WeekdayRecurType::TU:
-                r->setWeekStart(RecurrenceRule::Tuesday);
-                break;
-            case WeekdayRecurType::WE:
-                r->setWeekStart(RecurrenceRule::Wednesday);
-                break;
-            case WeekdayRecurType::TH:
-                r->setWeekStart(RecurrenceRule::Thursday);
-                break;
-            case WeekdayRecurType::FR:
-                r->setWeekStart(RecurrenceRule::Friday);
-                break;
-            case WeekdayRecurType::SA:
-                r->setWeekStart(RecurrenceRule::Saturday);
-                break;
-            case WeekdayRecurType::SU:
-                r->setWeekStart(RecurrenceRule::Sunday);
-                break;
-            default:
-                std::cout << "invalid unhandled weekday" << wkst;
-        }
-    }
-
-    static void setEndDt(Ptr r, KolabTypes::DatePtr date )
-    {
-        r->setEnd(*date);
-    }
-    
-    static void setCount(Ptr r, int count )
-    {
-        r->setCount(count);
-    }
-    
-    static void setInterval(Ptr r, int interval )
-    {
-        r->setInterval(interval);
-    }
-    
-    static void setBysecond(Ptr r, const icalendar_2_0::RecurType::bysecond_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
-        }
-        r->setBysecond(by);
-    }
-    
-    static void setByminute(Ptr r, const icalendar_2_0::RecurType::byminute_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::byminute_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
-        }
-        r->setByminute(by);
-    }
-    
-    static void setByhour(Ptr r, const icalendar_2_0::RecurType::byhour_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::byhour_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
-        }
-        r->setByhour(by);
-    }
-    
-    static void setByday(Ptr 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++) {
-            //TODO implement parser for format
-//             switch () {
-//                 
-//             }
-            //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
-        }
-        r->setByday(by);
-    }
-    
-    static void setBymonthday(Ptr r, const icalendar_2_0::RecurType::bymonthday_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::integer>(*it));
-        }
-        r->setBymonthday(by);
-    }
-    
-    static void setByyearday(Ptr r, const icalendar_2_0::RecurType::byyearday_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::byyearday_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::integer>(*it));
-        }
-        r->setByyearday(by);
-    }
-    
-    static void setByweekno(Ptr r, const icalendar_2_0::RecurType::byweekno_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::byweekno_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::integer>(*it));
-        }
-        r->setByweekno(by);
-    }
-    
-    static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::integer>(*it));
-        }
-        r->setBymonth(by);
-    }
-};
-
-
-void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string &email, std::string &name)
-{
-    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();
-            }
-        }
-    }
-    email = cal.cal_address();
-}
-
-
-template <typename I, typename T>
-void setIncidenceProperties(I &inc, const T &prop)
-{
-    typedef DateTimeConverter<Kolab::DateTime> DC;
-    
-    inc.setUid(toString(prop.uid()));
-    inc.setCreated(*toDate<KolabTypes>(prop.created()));
-    inc.setLastModified(*toDate<KolabTypes>(prop.dtstamp()));
-
-    if (prop.sequence()) {
-        inc.setSequence(toInt(*prop.sequence()));
-    }
-    
-    if (prop.class_()) {
-        std::string string(toString(*prop.class_()));
-        Kolab::Classification sec = Public;
-        if (string == PRIVATE) {
-            sec = Private;
-        } else if (string == CONFIDENTIAL) {
-            sec = Confidential;
-        }
-        inc.setClassification(sec);
-    }
-    
-    if (prop.categories()) {
-        inc.setCategories(toStringList(*prop.categories()));
-    }
-    
-    if (prop.dtstart()) {
-        const KolabTypes::DatePtr date = toDate<KolabTypes>(*prop.dtstart());
-        inc.setStart(*date); //TODO add to specification that allday depends on start date format
-    }
-
-    if (prop.rrule()) {
-       KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
-       inc.setRecurrenceRule(*rrule);
-    }
-
-    if (prop.rdate()) {
-        inc.setRecurrenceDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
-        if (!prop.rdate()->period().empty()) {
-            std::cout << "the period element must not be used, ignored." << std::endl;
-        }
-    }
-
-    if (prop.exdate()) {
-       inc.setExceptionDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
-    }
-    
-    if (prop.recurrence_id()) {
-        //TODO THISANDFUTURE range
-        bool thisandfuture = true;
-        inc.setRecurrenceID(*toDate<KolabTypes>(*prop.recurrence_id()), thisandfuture);
-    }
-    
-    if (prop.summary()) {
-        inc.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
-    }
-
-    if (prop.description()) {
-        inc.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
-    }
-    
-    if (prop.priority()) {
-        inc.setPriority(toInt(*prop.priority()));
-    }
-
-    if (prop.status()) {
-        const std::string &status =  toString(*prop.status());
-        if (status == NEEDSACTION) {
-            inc.setStatus(NeedsAction);
-        } else if (status == COMPLETED) {
-            inc.setStatus(Completed);
-        } else if (status == INPROCESS) {
-            inc.setStatus(InProcess);
-        } else if (status == CANCELLED) {
-            inc.setStatus(Cancelled);
-        } else if (status == TENTATIVE) {
-            inc.setStatus(Tentative);
-        } else if (status == CONFIRMED) {
-            inc.setStatus(Confirmed);
-        } else if (status == DRAFT) {
-            inc.setStatus(Draft);
-        } else if (status == FINAL) {
-            inc.setStatus(Final);
-        } else {
-            std::cout << "Unhandled status";
-        }
-    }
-
-    if (prop.location()) {
-        inc.setLocation(toString(*prop.location()));
-    }
-    
-    if (prop.organizer()) {
-        std::string email;
-        std::string name;
-        setCalAddress(*prop.organizer(), email, name);
-        inc.setOrganizer(email, name);
-    }
-    
-    if (prop.attendee().size()) {
-        //TODO
-    }
-    
-    if (prop.attach().size()) {
-        //TODO
-    }
-    
-    if (prop.x_custom().size()) {
-        //TODO
-    }
-
-}
-
-template <typename T, typename I>
-T fromList(const std::vector<int> &input) {
-    T list;
-    BOOST_FOREACH(int i, list) {
-        list.push_back(convertToInt<I>(i));
-    }
-    return list;
-}
-
-std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r)
-{
-    using namespace icalendar_2_0;
-    
-    typedef RecurrenceConverter< RecurrenceRule > RC;
-    typedef DateTimeConverter< DateTime> DC;
-    
-    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
-    
-    RecurPropertyType::recur_type &recur = rruleProp->recur();
-    const DateTime &endDate = r.end();
-    if (endDate.isValid()) {
-        RecurPropertyType::recur_type::until_type until;
-        if (endDate.isDateOnly()) {
-            until.date(DC::fromDate(endDate));
-        } else {
-            until.date_time(DC::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()));
-    }
-    
-    //TODO remainting by rules
-    
-    return rruleProp;
-}
-
-
-template <typename T, typename I>
-void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to template
-{
-    using namespace icalendar_2_0;
-    
-    typedef T properties; 
-    typedef DateTimeConverter< DateTime> DC;
-    
-    prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
-    
-    switch (inc.classification()) {
-        case Kolab::Confidential:
-            prop.class_(typename properties::class_type(CONFIDENTIAL));
-            break;
-        case Kolab::Private:
-            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<KolabTypes, typename properties::dtstart_type>(inc.start()));
-    }
-    
-    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<KolabTypes, typename properties::rdate_type>(inc.recurrenceDates()));
-    }
-    
-    if (!inc.exceptionDates().empty()) {
-        prop.exdate(fromDateTimeList<KolabTypes, typename properties::exdate_type>(inc.exceptionDates()));
-    }
-    
-    if (inc.recurrenceID().isValid()) {
-        //TODO THISANDFUTURE
-        prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
-    }
-    
-    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.priority() != 0) {
-        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
-    }
-    
-    if (inc.status() != UndefinedStatus) {
-        switch (inc.status()) {
-            case NeedsAction:
-                prop.status(typename properties::status_type(NEEDSACTION));
-                break;
-            case Completed:
-                prop.status(typename properties::status_type(COMPLETED));
-                break;
-            case InProcess:
-                prop.status(typename properties::status_type(INPROCESS));
-                break;
-            case Cancelled:
-                prop.status(typename properties::status_type(CANCELLED));
-                break;
-            case Tentative:
-                prop.status(typename properties::status_type(TENTATIVE));
-                break;
-            case Confirmed:
-                prop.status(typename properties::status_type(CONFIRMED));
-                break;
-            case Draft:
-                prop.status(typename properties::status_type(DRAFT));
-                break;
-            case Final:
-                prop.status(typename properties::status_type(FINAL));
-                break;
-            default:
-                std::cout << "unhandled status " << inc.status() << std::endl;
-        }
-
-    }
-    
-    if (!inc.location().empty()) {
-        prop.location(typename properties::location_type(inc.location()));
-    }
-    
-    if (!inc.organizerEmail().empty()) { //email is required
-        //TODO
-    }
-    
-    if (!inc.attendees().empty()) {
-        //TODO
-    }
-    
-    if (!inc.attachments().empty()) {
-        //TODO
-    }
-    
-    if (!inc.customProperties().empty()) {
-        //TODO
-    }
-
-}
-
-template <typename T> struct IncidenceConverter < Incidence, T >
-{
-    typedef DateTimeConverter< DateTime> DC;
-    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 DC::fromDateTime(getCurrentTime());
-    }
-    
-    static xml_schema::date_time created(const T &inc) {
-        if (inc.created().isValid()) {
-            return DC::fromDateTime(inc.created());
-        }
-        return DC::fromDateTime(getCurrentTime());
-    }
-
-};
-
-const char* const TRANSPARENT = "TRANSPARENT";
-const char* const OPAQUE = "OPAQUE";
-
-template < > struct IncidenceTrait <Kolab::Event>
-{
-    typedef typename icalendar_2_0::KolabEvent KolabType;
-    typedef typename Kolab::Event IncidenceType;
-    typedef typename boost::shared_ptr<Kolab::Event> IncidencePtr;
-    typedef typename Kolab::Incidence Incidence;
-    
-    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
-    {
-        KolabType::properties_type &prop = vevent.properties();
-        
-        getIncidenceProperties<KolabType::properties_type>(prop, event);
-
-        if (event.end().isValid()) {
-            prop.dtend(fromDate<KolabTypes, typename KolabType::properties_type::dtend_type>(event.end()));
-        }/* else if (event.duration().isValid()) {
-            //TODO
-        }*/
-        
-        if (event.transparency()) {
-            prop.transp( KolabType::properties_type::transp_type(TRANSPARENT));
-        }
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
-    {
-        components.vevent().push_back(inc);
-    }
-
-    static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
-    {
-        const KolabType::properties_type &prop = vevent.properties();
-
-        setIncidenceProperties<Kolab::Event, KolabType::properties_type>(event, prop);
-
-        if (prop.dtend()) {
-            event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
-//             event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
-//             if (event.dtEnd().timeType() != event.dtStart().timeType()) {
-//                 kWarning() << "dtEnd has wrong timespec";
-//             }
-        } else if (prop.duration()) {
-            //TODO implement
-    //          KCalCore::Duration duration.;
-    //          event.setDuration(duration << prop.duration());
-        }
-        //TODO check for equality of timespecs
-        
-        if (prop.transp()) {
-            if (toString(*prop.transp()) == TRANSPARENT) {
-                event.setTransparency(true);
-            } else {
-                event.setTransparency(false);
-                if (toString(*prop.transp()) != OPAQUE) {
-                    std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
-                }
-            }
-        }
-    }
-     
-    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 typename icalendar_2_0::KolabTodo KolabType;
-    typedef typename Kolab::Todo IncidenceType;
-    typedef typename boost::shared_ptr<Kolab::Todo> IncidencePtr;
-    typedef typename Kolab::Incidence Incidence;
-    
-    static void writeIncidence(KolabType& vevent, const Kolab::Todo &todo)
-    {
-        KolabType::properties_type &prop = vevent.properties();
-        
-        getIncidenceProperties<KolabType::properties_type>(prop, todo);
-
-        if (todo.due().isValid()) {
-            prop.due(fromDate<KolabTypes, typename KolabType::properties_type::due_type>(todo.due()));
-        }
-//         if (todo.transparency()) {
-//             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
-//         }
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
-    {
-        components.vtodo().push_back(inc);
-    }
-
-    static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
-    {
-        const KolabType::properties_type &prop = vevent.properties();
-
-        setIncidenceProperties<Kolab::Todo, KolabType::properties_type>(todo, prop);
-
-        if (prop.related_to()) {
-            //TODO
-        }
-        if (prop.due()) {
-            todo.setDue(*toDate<KolabTypes>(*prop.due()));
-        }
-        if (prop.percent_complete()) {
-            //TODO
-        }
-
-    }
-     
-    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();
-    }
-    
-};
-
-
-}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 00e6273..7f91eb9 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -2,10 +2,10 @@
 
 #include <iostream>
 #include "kolabcontainers.h"
-#include "kolabconversions.h"
+#include "xcalconversions.h"
 #include "kolabtodo.h"
 
-#include "kolabxcardconversions.h"
+#include "xcardconversions.h"
 
 namespace Kolab {
 
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 1ec2752..e7c1d88 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -13,6 +13,8 @@ namespace Kolab {
         KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
 //         Kolab::Event writeEvent(KCalCore::Event::Ptr);
         
+        //TODO converters in both directions for all containers
+        
     };
 };
 
diff --git a/c++/lib/kolabxcardconversions.h b/c++/lib/kolabxcardconversions.h
deleted file mode 100644
index 7d5038f..0000000
--- a/c++/lib/kolabxcardconversions.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef KOLABXCARDCONVERSION_H
-#define KOLABXCARDCONVERSION_H
-
-#include <bindings/kolabformat-xcard.hxx>
-#include "kolabcontainers.h"
-#include <XMLParserWrapper.h>
-#include <boost/shared_ptr.hpp>
-#include "global_definitions.h"
-#include "utils.h"
-
-const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
-const char* const INDIVIDUAL = "individual";
-const char* const GROUP = "group";
-
-namespace Kolab {
-    
-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> 
-void writeCard(vcard_4_0::vcard vcard, const T &);
-
-template <> 
-void writeCard<Kolab::Contact>(vcard_4_0::vcard vcard, const Kolab::Contact &contact)
-{
-    //TODO
-}
-
-template <> 
-void writeCard<Kolab::DistList>(vcard_4_0::vcard vcard, const Kolab::DistList &distlist)
-{
-    //TODO
-}
-
-
-std::string fromDateTime(const DateTime &dt)
-{
-    std::stringstream s;
-    s << dt.year() << dt.month() << dt.day() << "T" << dt.hour() << dt.minute() << dt.second();
-    if (!dt.isUTC()) { //always UTC
-        std::cout << "Date is not UTC but it should be, UTC assumed." << std::endl;
-    }
-    s << "Z";
-    return s.str();
-}
-
-
-template <typename T>
-std::string serializeCard(const T &card, const std::string prod = std::string()) {
-
-    using namespace vcard_4_0;
-
-    try {
-        vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
-        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_VERSION);
-        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME);
-        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.fn());
-        
-        
-        vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
-        writeCard<T>(vcard, card);
-        
-        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) {
-        std::cerr << "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)
-{
-    //TODO
-    return boost::shared_ptr<Kolab::Contact>();
-}
-
-template <>
-boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
-{
-    //TODO
-    return boost::shared_ptr<Kolab::DistList>();
-}
-
-template <typename T>
-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);
-            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);
-            if (doc.get()) {
-                vcards = vcard_4_0::vcards(doc);
-            }
-        }
-        
-        if (!vcards.get()) {
-            std::cerr << "failed to parse card!" << std::endl;
-            return boost::shared_ptr<T>();
-        }
-        return readCard<T>(vcards->vcard());
-    } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        std::cerr <<  "Failed to read card!" << std::endl;
-    }
-
-    return boost::shared_ptr<T>();
-}
-    
-} //Namespace
-
-#endif
\ No newline at end of file
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
new file mode 100644
index 0000000..db7bd28
--- /dev/null
+++ b/c++/lib/xcalconversions.h
@@ -0,0 +1,747 @@
+#ifndef XCALCONVERSIONS_H
+#define XCALCONVERSIONS_H
+
+#include "genericxcalconverions.h"
+#include "kolabcontainers.h"
+#include <boost/foreach.hpp>
+#include "kolabtodo.h"
+#include "utils.h"
+namespace Kolab {
+
+class Incidence;
+
+struct KolabTypes
+{
+    typedef DateTime DateType;
+    typedef typename boost::shared_ptr<DateTime> DatePtr;
+    typedef RecurrenceRule RecurrenceType;
+    typedef typename std::auto_ptr<RecurrenceRule> RecurrencePtr;
+    typedef std::string StringType;
+    typedef Incidence IncidenceType;
+};
+    
+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;
+}
+
+std::string toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return s.text();
+}
+
+// template <typename T>
+// std::auto_ptr<T> fromString(const std::string &s)
+// {
+//     std::auto_ptr<T> ptr(new T());
+//     p.text(s);
+//     return ptr;
+// }
+
+template <> struct DateTimeConverter<DateTime>
+{
+    typedef DateTime Type;
+    typedef typename boost::shared_ptr<DateTime> Ptr;
+
+    static Ptr toDate(const  xml_schema::date &dt)
+    {
+        Ptr date(new DateTime());
+        date->setDate(dt.year(), dt.month(), dt.day());
+        return date;
+    }
+
+    static Ptr toDate(const xml_schema::date_time &dt)
+    {
+        Ptr date(new DateTime());
+        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;
+    }
+    
+    static xml_schema::date_time fromDateTime(const DateTime &d)
+    {
+        xml_schema::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;
+    }
+
+    static xml_schema::date fromDate(const DateTime &d)
+    {
+        xml_schema::date date(d.year(), d.month(), d.day());
+        return date;
+    }
+
+    static void setTimezone(Ptr date, const std::string &tzid)
+    {
+        date->setTimezone(tzid);
+    }
+
+    static std::string getTimezone(const DateTime &dt)
+    {
+        return dt.timezone();
+    }
+
+    static void setUTC(Ptr date)
+    {
+        date->setUTC(true);
+    }
+
+    static bool isDateOnly(Type date)
+    {
+        return date.isDateOnly();
+    }
+
+};
+
+
+template <> struct RecurrenceConverter < RecurrenceRule >
+{
+
+    typedef typename KolabTypes::RecurrenceType Type;
+    typedef typename KolabTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
+
+    static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+    {
+        using namespace icalendar_2_0;
+        
+        switch (freq) {
+            case FreqRecurType::YEARLY:
+                r->setFrequency(RecurrenceRule::Yearly);
+                break;
+            case FreqRecurType::MONTHLY:
+                r->setFrequency(RecurrenceRule::Monthly);
+                break;
+            case FreqRecurType::WEEKLY:
+                r->setFrequency(RecurrenceRule::Weekly);
+                break;
+            case FreqRecurType::DAILY:
+                r->setFrequency(RecurrenceRule::Daily);
+                break;
+            case FreqRecurType::HOURLY:
+                r->setFrequency(RecurrenceRule::Hourly);
+                break;
+            case FreqRecurType::MINUTELY:
+                r->setFrequency(RecurrenceRule::Minutely);
+                break;
+            case FreqRecurType::SECONDLY:
+                r->setFrequency(RecurrenceRule::Secondly);
+                break;
+            default:
+                std::cout << "invalid unhandled recurrenc type" << freq;
+        }
+    }
+    
+    static icalendar_2_0::RecurType::freq_type type(const Type &t)
+    {
+        using namespace icalendar_2_0;
+
+        switch (t.frequency()) {
+            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:
+                std::cout << "invalid unhandled recurrenc type";
+        }
+        return 0;
+    }
+    
+    static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
+    {
+        using namespace icalendar_2_0;
+
+        switch (wkst) {
+            case WeekdayRecurType::MO:
+                r->setWeekStart(RecurrenceRule::Monday);
+                break;
+            case WeekdayRecurType::TU:
+                r->setWeekStart(RecurrenceRule::Tuesday);
+                break;
+            case WeekdayRecurType::WE:
+                r->setWeekStart(RecurrenceRule::Wednesday);
+                break;
+            case WeekdayRecurType::TH:
+                r->setWeekStart(RecurrenceRule::Thursday);
+                break;
+            case WeekdayRecurType::FR:
+                r->setWeekStart(RecurrenceRule::Friday);
+                break;
+            case WeekdayRecurType::SA:
+                r->setWeekStart(RecurrenceRule::Saturday);
+                break;
+            case WeekdayRecurType::SU:
+                r->setWeekStart(RecurrenceRule::Sunday);
+                break;
+            default:
+                std::cout << "invalid unhandled weekday" << wkst;
+        }
+    }
+
+    static void setEndDt(Ptr r, KolabTypes::DatePtr date )
+    {
+        r->setEnd(*date);
+    }
+    
+    static void setCount(Ptr r, int count )
+    {
+        r->setCount(count);
+    }
+    
+    static void setInterval(Ptr r, int interval )
+    {
+        r->setInterval(interval);
+    }
+    
+    static void setBysecond(Ptr r, const icalendar_2_0::RecurType::bysecond_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        r->setBysecond(by);
+    }
+    
+    static void setByminute(Ptr r, const icalendar_2_0::RecurType::byminute_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::byminute_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        r->setByminute(by);
+    }
+    
+    static void setByhour(Ptr r, const icalendar_2_0::RecurType::byhour_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::byhour_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        r->setByhour(by);
+    }
+    
+    static void setByday(Ptr 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++) {
+            //TODO implement parser for format
+//             switch () {
+//                 
+//             }
+            //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        r->setByday(by);
+    }
+    
+    static void setBymonthday(Ptr r, const icalendar_2_0::RecurType::bymonthday_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::integer>(*it));
+        }
+        r->setBymonthday(by);
+    }
+    
+    static void setByyearday(Ptr r, const icalendar_2_0::RecurType::byyearday_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::byyearday_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::integer>(*it));
+        }
+        r->setByyearday(by);
+    }
+    
+    static void setByweekno(Ptr r, const icalendar_2_0::RecurType::byweekno_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::byweekno_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::integer>(*it));
+        }
+        r->setByweekno(by);
+    }
+    
+    static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
+    {
+        std::vector<int> by;
+        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.push_back(convertToInt<xml_schema::integer>(*it));
+        }
+        r->setBymonth(by);
+    }
+};
+
+
+void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string &email, std::string &name)
+{
+    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();
+            }
+        }
+    }
+    email = cal.cal_address();
+}
+
+
+template <typename I, typename T>
+void setIncidenceProperties(I &inc, const T &prop)
+{
+    typedef DateTimeConverter<Kolab::DateTime> DC;
+    
+    inc.setUid(toString(prop.uid()));
+    inc.setCreated(*toDate<KolabTypes>(prop.created()));
+    inc.setLastModified(*toDate<KolabTypes>(prop.dtstamp()));
+
+    if (prop.sequence()) {
+        inc.setSequence(toInt(*prop.sequence()));
+    }
+    
+    if (prop.class_()) {
+        std::string string(toString(*prop.class_()));
+        Kolab::Classification sec = Public;
+        if (string == PRIVATE) {
+            sec = Private;
+        } else if (string == CONFIDENTIAL) {
+            sec = Confidential;
+        }
+        inc.setClassification(sec);
+    }
+    
+    if (prop.categories()) {
+        inc.setCategories(toStringList(*prop.categories()));
+    }
+    
+    if (prop.dtstart()) {
+        const KolabTypes::DatePtr date = toDate<KolabTypes>(*prop.dtstart());
+        inc.setStart(*date); //TODO add to specification that allday depends on start date format
+    }
+
+    if (prop.rrule()) {
+       KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
+       inc.setRecurrenceRule(*rrule);
+    }
+
+    if (prop.rdate()) {
+        inc.setRecurrenceDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
+        if (!prop.rdate()->period().empty()) {
+            std::cout << "the period element must not be used, ignored." << std::endl;
+        }
+    }
+
+    if (prop.exdate()) {
+       inc.setExceptionDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
+    }
+    
+    if (prop.recurrence_id()) {
+        //TODO THISANDFUTURE range
+        bool thisandfuture = true;
+        inc.setRecurrenceID(*toDate<KolabTypes>(*prop.recurrence_id()), thisandfuture);
+    }
+    
+    if (prop.summary()) {
+        inc.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
+    }
+
+    if (prop.description()) {
+        inc.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
+    }
+    
+    if (prop.priority()) {
+        inc.setPriority(toInt(*prop.priority()));
+    }
+
+    if (prop.status()) {
+        const std::string &status =  toString(*prop.status());
+        if (status == NEEDSACTION) {
+            inc.setStatus(NeedsAction);
+        } else if (status == COMPLETED) {
+            inc.setStatus(Completed);
+        } else if (status == INPROCESS) {
+            inc.setStatus(InProcess);
+        } else if (status == CANCELLED) {
+            inc.setStatus(Cancelled);
+        } else if (status == TENTATIVE) {
+            inc.setStatus(Tentative);
+        } else if (status == CONFIRMED) {
+            inc.setStatus(Confirmed);
+        } else if (status == DRAFT) {
+            inc.setStatus(Draft);
+        } else if (status == FINAL) {
+            inc.setStatus(Final);
+        } else {
+            std::cout << "Unhandled status";
+        }
+    }
+
+    if (prop.location()) {
+        inc.setLocation(toString(*prop.location()));
+    }
+    
+    if (prop.organizer()) {
+        std::string email;
+        std::string name;
+        setCalAddress(*prop.organizer(), email, name);
+        inc.setOrganizer(email, name);
+    }
+    
+    if (prop.attendee().size()) {
+        //TODO
+    }
+    
+    if (prop.attach().size()) {
+        //TODO
+    }
+    
+    if (prop.x_custom().size()) {
+        //TODO
+    }
+
+}
+
+template <typename T, typename I>
+T fromList(const std::vector<int> &input) {
+    T list;
+    BOOST_FOREACH(int i, list) {
+        list.push_back(convertToInt<I>(i));
+    }
+    return list;
+}
+
+std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r)
+{
+    using namespace icalendar_2_0;
+    
+    typedef RecurrenceConverter< RecurrenceRule > RC;
+    typedef DateTimeConverter< DateTime> DC;
+    
+    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
+    
+    RecurPropertyType::recur_type &recur = rruleProp->recur();
+    const DateTime &endDate = r.end();
+    if (endDate.isValid()) {
+        RecurPropertyType::recur_type::until_type until;
+        if (endDate.isDateOnly()) {
+            until.date(DC::fromDate(endDate));
+        } else {
+            until.date_time(DC::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()));
+    }
+    
+    //TODO remainting by rules
+    
+    return rruleProp;
+}
+
+
+template <typename T, typename I>
+void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to template
+{
+    using namespace icalendar_2_0;
+    
+    typedef T properties; 
+    typedef DateTimeConverter< DateTime> DC;
+    
+    prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
+    
+    switch (inc.classification()) {
+        case Kolab::Confidential:
+            prop.class_(typename properties::class_type(CONFIDENTIAL));
+            break;
+        case Kolab::Private:
+            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<KolabTypes, typename properties::dtstart_type>(inc.start()));
+    }
+    
+    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<KolabTypes, typename properties::rdate_type>(inc.recurrenceDates()));
+    }
+    
+    if (!inc.exceptionDates().empty()) {
+        prop.exdate(fromDateTimeList<KolabTypes, typename properties::exdate_type>(inc.exceptionDates()));
+    }
+    
+    if (inc.recurrenceID().isValid()) {
+        //TODO THISANDFUTURE
+        prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
+    }
+    
+    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.priority() != 0) {
+        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
+    }
+    
+    if (inc.status() != UndefinedStatus) {
+        switch (inc.status()) {
+            case NeedsAction:
+                prop.status(typename properties::status_type(NEEDSACTION));
+                break;
+            case Completed:
+                prop.status(typename properties::status_type(COMPLETED));
+                break;
+            case InProcess:
+                prop.status(typename properties::status_type(INPROCESS));
+                break;
+            case Cancelled:
+                prop.status(typename properties::status_type(CANCELLED));
+                break;
+            case Tentative:
+                prop.status(typename properties::status_type(TENTATIVE));
+                break;
+            case Confirmed:
+                prop.status(typename properties::status_type(CONFIRMED));
+                break;
+            case Draft:
+                prop.status(typename properties::status_type(DRAFT));
+                break;
+            case Final:
+                prop.status(typename properties::status_type(FINAL));
+                break;
+            default:
+                std::cout << "unhandled status " << inc.status() << std::endl;
+        }
+
+    }
+    
+    if (!inc.location().empty()) {
+        prop.location(typename properties::location_type(inc.location()));
+    }
+    
+    if (!inc.organizerEmail().empty()) { //email is required
+        //TODO
+    }
+    
+    if (!inc.attendees().empty()) {
+        //TODO
+    }
+    
+    if (!inc.attachments().empty()) {
+        //TODO
+    }
+    
+    if (!inc.customProperties().empty()) {
+        //TODO
+    }
+
+}
+
+template <typename T> struct IncidenceConverter < Incidence, T >
+{
+    typedef DateTimeConverter< DateTime> DC;
+    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 DC::fromDateTime(getCurrentTime());
+    }
+    
+    static xml_schema::date_time created(const T &inc) {
+        if (inc.created().isValid()) {
+            return DC::fromDateTime(inc.created());
+        }
+        return DC::fromDateTime(getCurrentTime());
+    }
+
+};
+
+const char* const TRANSPARENT = "TRANSPARENT";
+const char* const OPAQUE = "OPAQUE";
+
+template < > struct IncidenceTrait <Kolab::Event>
+{
+    typedef typename icalendar_2_0::KolabEvent KolabType;
+    typedef typename Kolab::Event IncidenceType;
+    typedef typename boost::shared_ptr<Kolab::Event> IncidencePtr;
+    typedef typename Kolab::Incidence Incidence;
+    
+    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
+    {
+        KolabType::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<KolabType::properties_type>(prop, event);
+
+        if (event.end().isValid()) {
+            prop.dtend(fromDate<KolabTypes, typename KolabType::properties_type::dtend_type>(event.end()));
+        }/* else if (event.duration().isValid()) {
+            //TODO
+        }*/
+        
+        if (event.transparency()) {
+            prop.transp( KolabType::properties_type::transp_type(TRANSPARENT));
+        }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+    {
+        components.vevent().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
+    {
+        const KolabType::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<Kolab::Event, KolabType::properties_type>(event, prop);
+
+        if (prop.dtend()) {
+            event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
+//             event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+//             if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+//                 kWarning() << "dtEnd has wrong timespec";
+//             }
+        } else if (prop.duration()) {
+            //TODO implement
+    //          KCalCore::Duration duration.;
+    //          event.setDuration(duration << prop.duration());
+        }
+        //TODO check for equality of timespecs
+        
+        if (prop.transp()) {
+            if (toString(*prop.transp()) == TRANSPARENT) {
+                event.setTransparency(true);
+            } else {
+                event.setTransparency(false);
+                if (toString(*prop.transp()) != OPAQUE) {
+                    std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
+                }
+            }
+        }
+    }
+     
+    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 typename icalendar_2_0::KolabTodo KolabType;
+    typedef typename Kolab::Todo IncidenceType;
+    typedef typename boost::shared_ptr<Kolab::Todo> IncidencePtr;
+    typedef typename Kolab::Incidence Incidence;
+    
+    static void writeIncidence(KolabType& vevent, const Kolab::Todo &todo)
+    {
+        KolabType::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<KolabType::properties_type>(prop, todo);
+
+        if (todo.due().isValid()) {
+            prop.due(fromDate<KolabTypes, typename KolabType::properties_type::due_type>(todo.due()));
+        }
+//         if (todo.transparency()) {
+//             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
+//         }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+    {
+        components.vtodo().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
+    {
+        const KolabType::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<Kolab::Todo, KolabType::properties_type>(todo, prop);
+
+        if (prop.related_to()) {
+            //TODO
+        }
+        if (prop.due()) {
+            todo.setDue(*toDate<KolabTypes>(*prop.due()));
+        }
+        if (prop.percent_complete()) {
+            //TODO
+        }
+
+    }
+     
+    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();
+    }
+    
+};
+
+
+}//Namespace
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
new file mode 100644
index 0000000..7d5038f
--- /dev/null
+++ b/c++/lib/xcardconversions.h
@@ -0,0 +1,140 @@
+#ifndef KOLABXCARDCONVERSION_H
+#define KOLABXCARDCONVERSION_H
+
+#include <bindings/kolabformat-xcard.hxx>
+#include "kolabcontainers.h"
+#include <XMLParserWrapper.h>
+#include <boost/shared_ptr.hpp>
+#include "global_definitions.h"
+#include "utils.h"
+
+const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+const char* const INDIVIDUAL = "individual";
+const char* const GROUP = "group";
+
+namespace Kolab {
+    
+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> 
+void writeCard(vcard_4_0::vcard vcard, const T &);
+
+template <> 
+void writeCard<Kolab::Contact>(vcard_4_0::vcard vcard, const Kolab::Contact &contact)
+{
+    //TODO
+}
+
+template <> 
+void writeCard<Kolab::DistList>(vcard_4_0::vcard vcard, const Kolab::DistList &distlist)
+{
+    //TODO
+}
+
+
+std::string fromDateTime(const DateTime &dt)
+{
+    std::stringstream s;
+    s << dt.year() << dt.month() << dt.day() << "T" << dt.hour() << dt.minute() << dt.second();
+    if (!dt.isUTC()) { //always UTC
+        std::cout << "Date is not UTC but it should be, UTC assumed." << std::endl;
+    }
+    s << "Z";
+    return s.str();
+}
+
+
+template <typename T>
+std::string serializeCard(const T &card, const std::string prod = std::string()) {
+
+    using namespace vcard_4_0;
+
+    try {
+        vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
+        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_VERSION);
+        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME);
+        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.fn());
+        
+        
+        vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+        writeCard<T>(vcard, card);
+        
+        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) {
+        std::cerr << "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)
+{
+    //TODO
+    return boost::shared_ptr<Kolab::Contact>();
+}
+
+template <>
+boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
+{
+    //TODO
+    return boost::shared_ptr<Kolab::DistList>();
+}
+
+template <typename T>
+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);
+            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);
+            if (doc.get()) {
+                vcards = vcard_4_0::vcards(doc);
+            }
+        }
+        
+        if (!vcards.get()) {
+            std::cerr << "failed to parse card!" << std::endl;
+            return boost::shared_ptr<T>();
+        }
+        return readCard<T>(vcards->vcard());
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        std::cerr <<  "Failed to read card!" << std::endl;
+    }
+
+    return boost::shared_ptr<T>();
+}
+    
+} //Namespace
+
+#endif
\ No newline at end of file


commit 7aef4bfe6c05d5b9a0e15f2cbb4d69c345f931b2
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 21:28:01 2011 +0100

    fully read/write cycle in php/python tests

diff --git a/c++/lib/test.php b/c++/lib/test.php
index 27ca971..7a5e36b 100644
--- a/c++/lib/test.php
+++ b/c++/lib/test.php
@@ -12,7 +12,8 @@ print $e->exceptionDates()->size();
 $string = writeEvent($e);
 print $string;
 $e1 = readEvent($string, false);
-
+$string = writeEvent($e1);
+print $string;
 ?>
 
 
diff --git a/c++/lib/test.py b/c++/lib/test.py
index 821bc94..5bc9799 100644
--- a/c++/lib/test.py
+++ b/c++/lib/test.py
@@ -8,3 +8,9 @@ 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


commit 2055d154841923f32b8c1c97cdbd351f35e720c2
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 21:27:32 2011 +0100

    disable verbose makefiles

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index f0a0776..873ebcc 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -36,7 +36,7 @@ endif(KCALCORE)
 
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
 
-set( CMAKE_VERBOSE_MAKEFILE on )
+# set( CMAKE_VERBOSE_MAKEFILE on )
 
 set(CMAKE_BUILD_TYPE Debug)
 


commit 0ebf2f27949b0fafa073374f52b2dfe6f81458be
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 19:39:59 2011 +0100

    Build system
    
    -Conditionally compile QT/KDE dependend stuff.
    -No undefined references as far as possible.
    -stricter compiling for core library

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index bdbb476..f0a0776 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -1,20 +1,45 @@
 project(kolabxmlbindings)
 
 cmake_minimum_required(VERSION 2.8)
+cmake_policy(SET CMP0017 NEW)
 
 find_package(Boost REQUIRED)
+find_package(Qt4)
 find_program( XSDCXX xsdcxx /usr/bin/)
-
 if(XSDCXX)
     message("xsd code generator found")
 else (XSDCXX)
-    message("xsd code generator NOT found. Aborted.")
-    return()
+    message(FATAL_ERROR
+    "xsd code generator NOT found!")
 endif(XSDCXX)
 
-set(CMAKE_BUILD_TYPE Debug)
+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)
+
+#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)
+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)
 
 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)
 
@@ -51,7 +76,7 @@ add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
 
 # Compile Schemas
 add_executable(xsdbin compiled/xsdbin.cxx)
-target_link_libraries(xsdbin xerces-c)
+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}   ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
@@ -72,5 +97,8 @@ include_directories( compiled )
 include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
 add_subdirectory(lib)
-add_subdirectory(tests)
+if (${QT_FOUND})
+    add_subdirectory(tests)
+endif()
 
+add_subdirectory(kcal)
\ No newline at end of file
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index e10ed53..d591a30 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -1,17 +1,19 @@
 
-
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #always generate shared libraries with -fPIC
-
 include_directories( ./ )
 include_directories( ../ )
 include_directories( ../build/ )
+include(${Boost_INCLUDE_DIRS})
 
 SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC " ) #always generate shared libraries with -fPIC
+
 #Library with serialization/deserialization code and kolab-containers
 add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxml xerces-c)
+target_link_libraries(kolabxml ${XERCES_C})
 
+#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 "-Wl,--no-undefined -Werror ")
 set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
 install(TARGETS kolabxml LIBRARY DESTINATION lib)
 
@@ -26,41 +28,39 @@ install( FILES
 
 # 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)
+# 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")
-
 # 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)
 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)
-target_link_libraries(kolabkcal kolabxml)
-
-#Library with serialization/deserialization code for KCalCore containers (deprecated)
-add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxmlkcal xerces-c)
-
-
+    #Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
+    add_library(kolabkcal SHARED kolabkcalconversion.cpp)
+    target_link_libraries(kolabkcal kolabxml ${KCALCORE} ${KDECORE})
 
+    #Library with serialization/deserialization code for KCalCore containers (deprecated)
+    add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+    target_link_libraries(kolabxmlkcal xerces-c ${KCALCORE} ${KDECORE})
+else()
+    message(WARNING "Could not build KCalCore/KDElibs dependend libraries, because kdepimlibs/kdelibs is missing.")
+endif()
 
 
 #-----------------------SWIG--------------------
 
-
 set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
 
+#Generate Python wrapper
 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
@@ -73,7 +73,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
 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})
 
-
+#Generate PHP wrapper
 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
@@ -86,12 +86,14 @@ 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})
 
 
-#PYTHON
+#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 xerces-c)
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
+target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
@@ -102,15 +104,12 @@ install( FILES
   test.py
   DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
 
-
-#PHP
-# set( PHP_INCLUDES "`php-config --includes`")
-set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${PHP_INCLUDES} )
+#Compile PHP Bindings
+# Since there is no php library we can't compile with -Wl,--no-undefined
 find_package(PHP4)
 include_directories(${PHP4_INCLUDE_PATH})
 add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
-target_link_libraries(phpbindings kolabxml xerces-c)
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
+target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
 
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index 8992c13..bb4e711 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -16,18 +16,20 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 
 KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
 {
-    
+    return KCalCore::Todo::Ptr();
 }
 
 
 std::string writeEvent(KCalCore::Event::Ptr event)
 {
 //      return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+    return std::string();
 }
 
 std::string writeTodo(KCalCore::Todo::Ptr todo)
 {
 //     return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
+    return std::string();
 }
 
 }
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 7d2f0af..1ec2752 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -1,5 +1,5 @@
-#ifndef KOLABKCALTOOLS_H
-#define KOLABKCALTOOLS_H
+#ifndef KOLABKCALCONVERSION_H
+#define KOLABKCALCONVERSION_H
 
 #include <kcalcore/recurrence.h>
 #include "kolabcontainers.h"
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index d2deb57..724087a 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,13 +1,17 @@
 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
-FIND_PACKAGE(Qt4 REQUIRED)
 include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+if (KDECORE_FOUND AND KCALCORE_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} kolabxml kolabkcal ${XERCES_C})
 
-QT4_AUTOMOC(bindingstest.cpp)
-add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabkcal kolabxml xerces-c kcalcore)
-
-QT4_AUTOMOC(kcalconversiontest.cpp)
-add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
+    QT4_AUTOMOC(kcalconversiontest.cpp)
+    add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal ${XERCES_C})
+else()
+    message(WARNING "Could not build tests because kdepimlibs is missing")
+endif()
\ No newline at end of file


commit 6ee155342d37739e24296a2f1bddee3e312a5c06
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 19:18:46 2011 +0100

    make compile with Wall

diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index b9a7353..fa31e12 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -179,6 +179,9 @@ class Note {
     //TODO
 };
 
+class Configuration {
+    //TODO
+};
 
 
     
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
index 7949e7c..d6f0cf1 100644
--- a/c++/lib/kolabevent.cpp
+++ b/c++/lib/kolabevent.cpp
@@ -32,6 +32,11 @@ Event::~Event()
 //     std::cout << "dtor" << std::endl;
 }
 
+void Event::operator=(const Kolab::Event &other)
+{
+    *d = *other.d;
+}
+
 void Event::setUid(const std::string &uid)
 {
     d->uid = uid;
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 80a85d3..00e6273 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -39,12 +39,18 @@ std::string writeTodo(const Kolab::Todo &event)
 
 Journal readJournal(const std::string& s, bool isUrl)
 {
-//     return *deserializeIncidence< IncidenceTrait<Kolab::Journal> >(s, isUrl);
+//     Kolab::IncidenceTrait<Kolab::Journal>::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Journal> >(s, isUrl);
+//     if (!ptr.get()) {
+//         return Kolab::Journal();
+//     }
+//     return *ptr;
+    return Journal();
 }
 
 std::string writeJournal(const Kolab::Journal &j)
 {
 //     return serializeIncidence< IncidenceTrait<Kolab::Journal> >(j);
+    return std::string();
 }
 
 
@@ -57,31 +63,57 @@ Kolab::Contact readContact(const std::string& s, bool isUrl)
     return *ptr;
 }
 
-std::string writeContact(const Kolab::Contact &contact)
+std::string writeContact(const Contact &contact)
 {
-    return serializeContact(contact);
+    return serializeCard(contact);
 }
 
 DistList readDistlist(const std::string& s, bool isUrl)
 {
-
+    boost::shared_ptr <Kolab::DistList> ptr = deserializeCard<Kolab::DistList>(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::DistList();
+    }
+    return *ptr;
 }
 
-std::string writeDistlist(const Kolab::DistList &list)
+std::string writeDistlist(const DistList &list)
 {
-
+//     return serializeCard(list);
+return std::string();
 }
 
 Note readNote(const std::string& s, bool isUrl)
 {
-
+//     boost::shared_ptr <Kolab::Note> ptr = deserializeNote(s, isUrl);
+//     if (!ptr.get()) {
+//         return Kolab::Note();
+//     }
+//     return *ptr;
+    return Note();
 }
 
-std::string writeNote(const Kolab::Note &note)
+std::string writeNote(const Note &note)
 {
+//     return serializeNote(note);
+return std::string();
+}
 
+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
index 269852e..2cd67e4 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -27,6 +27,9 @@ 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/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
index 22ae95e..d3b7a5e 100644
--- a/c++/lib/kolabtodo.cpp
+++ b/c++/lib/kolabtodo.cpp
@@ -7,9 +7,11 @@ namespace Kolab {
 struct Todo::Private: public PrivateIncidence
 {
     Private()
-    : PrivateIncidence() {}
+    : PrivateIncidence(),
+    percentComplete(0){}
     
     DateTime due;
+    int percentComplete;
 };
 
 Todo::Todo()
@@ -29,6 +31,11 @@ Todo::~Todo()
     
 }
 
+void Todo::operator=(const Kolab::Todo &other)
+{
+    *d = *other.d;
+}
+
 void Todo::setUid(const std::string &uid)
 {
     d->uid = uid;
@@ -170,6 +177,16 @@ 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;
diff --git a/c++/lib/kolabxcardconversions.h b/c++/lib/kolabxcardconversions.h
index 8fde188..7d5038f 100644
--- a/c++/lib/kolabxcardconversions.h
+++ b/c++/lib/kolabxcardconversions.h
@@ -58,7 +58,7 @@ std::string fromDateTime(const DateTime &dt)
 
 
 template <typename T>
-std::string serializeContact(const T &card, const std::string prod = std::string()) {
+std::string serializeCard(const T &card, const std::string prod = std::string()) {
 
     using namespace vcard_4_0;
 
@@ -95,14 +95,14 @@ template <>
 boost::shared_ptr<Kolab::Contact> readCard <Kolab::Contact> (const vcard_4_0::VcardsType::vcard_type &vcard)
 {
     //TODO
-    
+    return boost::shared_ptr<Kolab::Contact>();
 }
 
 template <>
 boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
 {
     //TODO
-    
+    return boost::shared_ptr<Kolab::DistList>();
 }
 
 template <typename T>


commit 81b1b11af022dafe0e7052d95ddbbdeadc6d3790
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 14:22:56 2011 +0100

    xCard skeleton prepared. A couple of smaller cleanups.

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 2eb4403..bdbb476 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -2,13 +2,7 @@ project(kolabxmlbindings)
 
 cmake_minimum_required(VERSION 2.8)
 
-set(CMAKE_BUILD_TYPE Debug)
-
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
-set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
-file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
-
-set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
+find_package(Boost REQUIRED)
 find_program( XSDCXX xsdcxx /usr/bin/)
 
 if(XSDCXX)
@@ -18,6 +12,14 @@ else (XSDCXX)
     return()
 endif(XSDCXX)
 
+set(CMAKE_BUILD_TYPE Debug)
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
+set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
+file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
+
+set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
+
 # Generate bindings
 
 file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index a28353a..69bc685 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -248,7 +248,7 @@ xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::ist
     }
     catch (const xml_schema::exception& e)
     {
-        cout << "schema exception" << endl;
+        cerr << "schema exception" << endl;
         cerr << e << endl;
     }
     catch (const std::ios_base::failure&)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index d6f1b7f..e10ed53 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -9,7 +9,7 @@ include_directories( ../build/ )
 SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 
 #Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml xerces-c)
 
 set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
@@ -22,6 +22,7 @@ install( FILES
   kolabcontainers.h
   DESTINATION include/kolab 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)
@@ -113,7 +114,6 @@ target_link_libraries(phpbindings kolabxml xerces-c)
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
 
-# set_target_properties(phpbindings PROPERTIES VERSION 3.0.0 SOVERSION 0)
 install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
 
 install( FILES
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 61bb280..c747c6d 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -376,8 +376,8 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 
         return *incidences.begin();
     } catch  (const xml_schema::exception& e) {
-        std::cout <<  e << std::endl;
-        std::cout <<  "Failed to read incidence!" << std::endl;
+        std::cerr <<  e << std::endl;
+        std::cerr <<  "Failed to read incidence!" << std::endl;
     }
 
     return IncidencePtr();
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index c674311..b9a7353 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -160,11 +160,27 @@ class CustomProperty {
 };
     
 
+class Journal {
+    //TODO
+};
 
 class Contact {
-    
+public:
+    std::string uid() const{return std::string();}
+    std::string fn() const{return std::string();}
+    //TODO
 };
 
+class DistList {
+    //TODO
+};
+
+class Note {
+    //TODO
+};
+
+
+
     
 }
 
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index ee883f6..60f07f1 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -3,11 +3,8 @@
 #include "conversions.h"
 #include "kolabcontainers.h"
 #include <boost/foreach.hpp>
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_io.hpp>
 #include "kolabtodo.h"
-#include <time.h>
-
+#include "utils.h"
 namespace Kolab {
 
 class Incidence;
@@ -589,21 +586,6 @@ void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to t
 
 }
 
-std::string getUID()
-{
-    boost::uuids::uuid u; // initialize uuid
-    return boost::uuids::to_string(u);
-}
-
-DateTime getCurrentTime()
-{
-    time_t rawtime;
-    struct tm * ptm;
-    time(&rawtime);
-    ptm = gmtime(&rawtime);
-    return DateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
-}
-
 template <typename T> struct IncidenceConverter < Incidence, T >
 {
     typedef DateTimeConverter< DateTime> DC;
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
index 3dbc2a9..7949e7c 100644
--- a/c++/lib/kolabevent.cpp
+++ b/c++/lib/kolabevent.cpp
@@ -17,18 +17,19 @@ struct Event::Private: public PrivateIncidence
 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::setUid(const std::string &uid)
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index f467ca0..80a85d3 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -11,7 +11,11 @@ namespace Kolab {
 
 Kolab::Event readEvent(const std::string& s, bool isUrl)
 {
-    return *deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
+    Kolab::IncidenceTrait <Kolab::Event >::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Event();
+    }
+    return *ptr;
 }
 
 std::string writeEvent(const Kolab::Event &event)
@@ -21,7 +25,11 @@ std::string writeEvent(const Kolab::Event &event)
 
 Kolab::Todo readTodo(const std::string& s, bool isUrl)
 {
-    return *deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    Kolab::IncidenceTrait<Kolab::Todo>::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Todo();
+    }
+    return *ptr;
 }
 
 std::string writeTodo(const Kolab::Todo &event)
@@ -29,9 +37,24 @@ std::string writeTodo(const Kolab::Todo &event)
     return serializeIncidence< IncidenceTrait<Kolab::Todo> >(event);
 }
 
-Kolab::Contact readContact(const std::string& s, bool isUrl)
+Journal readJournal(const std::string& s, bool isUrl)
 {
+//     return *deserializeIncidence< IncidenceTrait<Kolab::Journal> >(s, isUrl);
+}
 
+std::string writeJournal(const Kolab::Journal &j)
+{
+//     return serializeIncidence< IncidenceTrait<Kolab::Journal> >(j);
+}
+
+
+Kolab::Contact readContact(const std::string& s, bool isUrl)
+{
+    boost::shared_ptr <Kolab::Contact > ptr = deserializeCard<Kolab::Contact>(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Contact();
+    }
+    return *ptr;
 }
 
 std::string writeContact(const Kolab::Contact &contact)
@@ -39,6 +62,27 @@ std::string writeContact(const Kolab::Contact &contact)
     return serializeContact(contact);
 }
 
+DistList readDistlist(const std::string& s, bool isUrl)
+{
+
+}
+
+std::string writeDistlist(const Kolab::DistList &list)
+{
+
+}
+
+Note readNote(const std::string& s, bool isUrl)
+{
+
+}
+
+std::string writeNote(const Kolab::Note &note)
+{
+
+}
+
+
 
 }
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 559c09a..269852e 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -15,9 +15,18 @@ 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 &);
+
 }
 
 #endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabxcardconversions.h b/c++/lib/kolabxcardconversions.h
index 8b72675..8fde188 100644
--- a/c++/lib/kolabxcardconversions.h
+++ b/c++/lib/kolabxcardconversions.h
@@ -3,33 +3,137 @@
 
 #include <bindings/kolabformat-xcard.hxx>
 #include "kolabcontainers.h"
+#include <XMLParserWrapper.h>
+#include <boost/shared_ptr.hpp>
+#include "global_definitions.h"
+#include "utils.h"
 
 const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+const char* const INDIVIDUAL = "individual";
+const char* const GROUP = "group";
 
 namespace Kolab {
     
-std::string serializeContact(const Kolab::Contact &contact) {
-    
+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> 
+void writeCard(vcard_4_0::vcard vcard, const T &);
+
+template <> 
+void writeCard<Kolab::Contact>(vcard_4_0::vcard vcard, const Kolab::Contact &contact)
+{
+    //TODO
+}
+
+template <> 
+void writeCard<Kolab::DistList>(vcard_4_0::vcard vcard, const Kolab::DistList &distlist)
+{
+    //TODO
+}
+
+
+std::string fromDateTime(const DateTime &dt)
+{
+    std::stringstream s;
+    s << dt.year() << dt.month() << dt.day() << "T" << dt.hour() << dt.minute() << dt.second();
+    if (!dt.isUTC()) { //always UTC
+        std::cout << "Date is not UTC but it should be, UTC assumed." << std::endl;
+    }
+    s << "Z";
+    return s.str();
+}
+
+
+template <typename T>
+std::string serializeContact(const T &card, const std::string prod = std::string()) {
+
     using namespace vcard_4_0;
 
     try {
-        vcard_4_0::vcard::uid_type uid("sdsdfsdf");
-        vcard_4_0::vcard::n_type n;
-        vcard_4_0::vcard vcard(uid, n);
+        vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
+        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_VERSION);
+        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME);
+        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.fn());
+        
+        
+        vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+        writeCard<T>(vcard, card);
         
         VcardsType vcards(vcard);
 
         xml_schema::namespace_infomap map;
-         map[""].name = XCARD_NAMESPACE;
+        map[""].name = XCARD_NAMESPACE;
         
         std::ostringstream ostringstream;
         vcard_4_0::vcards(ostringstream, vcards, map);
         return ostringstream.str();
     } catch  (const xml_schema::exception& e) {
-        std::cout << "failed to write Contact";
+        std::cerr << "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)
+{
+    //TODO
+    
+}
+
+template <>
+boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
+{
+    //TODO
+    
+}
+
+template <typename T>
+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);
+            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);
+            if (doc.get()) {
+                vcards = vcard_4_0::vcards(doc);
+            }
+        }
+        
+        if (!vcards.get()) {
+            std::cerr << "failed to parse card!" << std::endl;
+            return boost::shared_ptr<T>();
+        }
+        return readCard<T>(vcards->vcard());
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        std::cerr <<  "Failed to read card!" << std::endl;
+    }
+
+    return boost::shared_ptr<T>();
+}
     
 } //Namespace
 
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
new file mode 100644
index 0000000..44246b1
--- /dev/null
+++ b/c++/lib/utils.cpp
@@ -0,0 +1,33 @@
+#include "utils.h"
+#include <string>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <time.h>
+
+namespace Kolab {
+
+std::string getUID()
+{
+    boost::uuids::uuid u; // initialize uuid
+    return boost::uuids::to_string(u);
+}
+
+std::string getUID(const std::string &s)
+{
+    if (s.empty()) {
+        return getUID();
+    }
+    return s;
+}
+
+
+DateTime getCurrentTime()
+{
+    time_t rawtime;
+    struct tm * ptm;
+    time(&rawtime);
+    ptm = gmtime(&rawtime);
+    return DateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
new file mode 100644
index 0000000..5ef5f2e
--- /dev/null
+++ b/c++/lib/utils.h
@@ -0,0 +1,16 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <string>
+#include <kolabcontainers.h>
+
+namespace Kolab {
+
+std::string getUID();
+std::string getUID(const std::string &);
+
+DateTime getCurrentTime();
+
+}
+
+#endif
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index cbbbd1e..3fe2af5 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -10,7 +10,7 @@
         <xs:complexContent mixed="false">
             <xs:extension base="BasePropertyType">
                 <xs:sequence>
-                    <xs:element name="string" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+                    <xs:element name="text" type="xs:string" default="3.0dev1"/>
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
@@ -140,7 +140,7 @@
                     <xs:sequence>
                         <xs:element name="prodid" type="ProdidPropType"/>
                         <xs:element name="version" type="VersionPropType"/>
-                        <xs:element name="x-kolab-version" type="VersionPropType"/>
+                        <xs:element name="x-kolab-version" type="KolabVersion"/>
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
index c4a6815..a7c4e9a 100644
--- a/schemas/kolabformat-xcard.xsd
+++ b/schemas/kolabformat-xcard.xsd
@@ -10,7 +10,7 @@
         <xs:complexContent mixed="false">
             <xs:extension base="BasePropertyType">
                 <xs:sequence>
-                    <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+                    <xs:element name="text" type="xs:string" default="3.0dev1"/>
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
@@ -37,7 +37,14 @@
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="uid" type="uidPropType"/>
-                        <xs:element name="n" type="nPropType"/>
+                        <xs:element name="x-kolab-version" type="KolabVersion"/>
+                        <xs:element name="prodid" type="prodidPropType"/>
+                        <xs:element name="rev" type="revPropType"/>
+                        <xs:element name="kind" type="kindPropType"/>
+                        <xs:element name="fn" type="fnPropType"/>
+                        <xs:element name="n" type="nPropType" minOccurs="0"/>
+                        <xs:element name="member" type="memberPropType" minOccurs="0"/>
+                        <xs:element name="x-custom" type="uidPropType" minOccurs="0"/>
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index 9a24e78..ad6d723 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -8,15 +8,28 @@
   <xs:element name="uri" type="xs:anyURI"/>
 
   <xs:element name="text" type="xs:string"/>
-  <xs:element name="date" type="xs:date"/>
+
+  <xs:simpleType name="DateType">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:element name="date" type="xcard:DateType"/>
   
   <xs:simpleType name="DateTimeType">
-    <xs:restriction base="xs:dateTime">
-      <xs:pattern value="(\-|\+)?\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z?"/>
+    <xs:restriction base="xs:string">
+      <xs:pattern value="(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?(Z|[+\-]\d\d(\d\d)?)?"/>
     </xs:restriction>
   </xs:simpleType>
-  
   <xs:element name="date-time" type="xcard:DateTimeType"/>
+  
+  
+  <xs:simpleType name="TimeStampType">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="\d{8}T\d{6}(Z|[+\-]\d\d(\d\d)?)?"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:element name="timestamp" type="xcard:DateTimeType"/>
 
 <!-- Parameters -->
 
@@ -88,7 +101,36 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <!-- Properties -->
+  
+  <xs:complexType name="memberPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="kindPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  
+  <xs:complexType name="revPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:timestamp" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
   
+  <xs:complexType name="prodidPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
   
   <xs:complexType name="fnPropType">
     <xs:complexContent mixed="false">
@@ -122,16 +164,5 @@
     </xs:complexContent>
   </xs:complexType>
 
-
-<!--     <xs:include schemaLocation="iCalendar-props.xsd"/> -->
-<!-- Base -->
-
-<!--    <xs:element name="vcard" type="xcard:VcardType" />    
-    <xs:complexType name="VcardType" mixed="false">
-        <xs:sequence>
-            <xs:element ref="xcard:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-    </xs:complexType>-->
-    
     
 </xs:schema>


commit f8f49f3358b11fda06c2fc34c94afc549b0b25d3
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 11:06:26 2011 +0100

    don't compare last modified dates

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 69ca1e9..0c2f31d 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -108,7 +108,6 @@ void setIncidence(T &ev)
 {
     ev.setUid("UID");
     ev.setCreated(Kolab::DateTime(2006,1,6,12,0,0)); //UTC
-    ev.setLastModified(Kolab::DateTime(2006,1,6,12,0,0));
     ev.setSequence(1);
     ev.setClassification(Kolab::Confidential);
     ev.addCategory("Category");
@@ -137,7 +136,7 @@ void checkIncidence(const T &ev, const T &re)
 {
     QCOMPARE(ev.uid(), re.uid());
     QCOMPARE(ev.created(), re.created());
-    QCOMPARE(ev.lastModified(), re.lastModified());
+    QVERIFY(re.lastModified().isValid());
     QCOMPARE(ev.sequence(), re.sequence());
     QCOMPARE(ev.classification(), re.classification());
     QCOMPARE(ev.categories().size(), re.categories().size());


commit dc1b4f1c26e25b8639152f5d089db7a2d13c9706
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 11:02:24 2011 +0100

    implementation for uuid, dtstamp and created date. Pass productid as parameter.

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index f109710..61bb280 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -387,7 +387,7 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 
 
 template <typename T>
-std::string serializeIncidence(const typename T::IncidenceType &incidence) {
+std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
     
     using namespace icalendar_2_0;
     typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
@@ -397,11 +397,11 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence) {
 
         typename KolabType::components_type eventComponents;
 
-        typename KolabType::properties_type::uid_type uid(IC::uid(incidence)); //TODO generate uid if empty
+        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
         typename KolabType::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(IC::dtstamp(incidence)); //TODO set current date time stamp
+        dtstamp.date_time(IC::dtstamp());
         typename KolabType::properties_type::created_type created;
-        created.date_time(IC::created(incidence)); //TODO set current date time stamp if uid was empty
+        created.date_time(IC::created(incidence));
         typename KolabType::properties_type eventProps(uid, created, dtstamp);
         
         KolabType inc(eventProps, eventComponents);
@@ -410,7 +410,7 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence) {
         VcalendarType::components_type components;
         T::addIncidence(components, inc);
         
-        VcalendarType::properties_type::prodid_type prodid(KOLAB_LIBNAME); //TODO take from caller plus add KOLAB_LIBNAME
+        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME);
         VcalendarType::properties_type::version_type version(XCAL_VERSION);
         VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_VERSION);
         
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 185ea2d..ee883f6 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -3,7 +3,10 @@
 #include "conversions.h"
 #include "kolabcontainers.h"
 #include <boost/foreach.hpp>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
 #include "kolabtodo.h"
+#include <time.h>
 
 namespace Kolab {
 
@@ -586,19 +589,40 @@ void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to t
 
 }
 
+std::string getUID()
+{
+    boost::uuids::uuid u; // initialize uuid
+    return boost::uuids::to_string(u);
+}
+
+DateTime getCurrentTime()
+{
+    time_t rawtime;
+    struct tm * ptm;
+    time(&rawtime);
+    ptm = gmtime(&rawtime);
+    return DateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
+}
+
 template <typename T> struct IncidenceConverter < Incidence, T >
 {
     typedef DateTimeConverter< DateTime> DC;
     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(const T &inc) {
-        return DC::fromDateTime(inc.lastModified());
+    static xml_schema::date_time dtstamp() {
+        return DC::fromDateTime(getCurrentTime());
     }
     
     static xml_schema::date_time created(const T &inc) {
-        return DC::fromDateTime(inc.created());
+        if (inc.created().isValid()) {
+            return DC::fromDateTime(inc.created());
+        }
+        return DC::fromDateTime(getCurrentTime());
     }
 
 };


commit 25cdbbd5cd7edabd2e4e0bd5bbf908febe67e02d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 11:01:04 2011 +0100

    fixed test

diff --git a/c++/lib/test.php b/c++/lib/test.php
index 8f80805..27ca971 100644
--- a/c++/lib/test.php
+++ b/c++/lib/test.php
@@ -10,8 +10,8 @@ $e->addExceptionDate( $d);
 print $e->exceptionDates()->size();
 
 $string = writeEvent($e);
-print $string
-// $e1 = readEvent($string, false);
+print $string;
+$e1 = readEvent($string, false);
 
 ?>
 


commit 24d850d000de789960f333bfe4413a74fe249349
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 00:57:03 2011 +0100

    Buildsystem refactoring. First working PHP example.

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 062a7b3..2eb4403 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -2,18 +2,21 @@ project(kolabxmlbindings)
 
 cmake_minimum_required(VERSION 2.8)
 
-FIND_PACKAGE(Qt4 REQUIRED)
-include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
-
 set(CMAKE_BUILD_TYPE Debug)
 
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
-set(CMAKE_BUILD_DIR build)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
+set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
 file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
 
 set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
-set( XSDCXX  /usr/bin/xsdcxx)
+find_program( XSDCXX xsdcxx /usr/bin/)
 
+if(XSDCXX)
+    message("xsd code generator found")
+else (XSDCXX)
+    message("xsd code generator NOT found. Aborted.")
+    return()
+endif(XSDCXX)
 
 # Generate bindings
 
@@ -22,12 +25,12 @@ file(GLOB SCHEMAS ${SCHEMA_DIR}/*.xsd)
 set( SCHEMAS ${SCHEMAS} ${XCAL_SCHEMAS})
 
 set( SCHEMA_SOURCEFILES  
-    bindings/xCard.cxx
-    bindings/kolabformat-xcal.cxx
-    bindings/kolabformat-xcard.cxx
-    bindings/iCalendar-params.cxx
-    bindings/iCalendar-props.cxx
-    bindings/iCalendar-valtypes.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
@@ -63,21 +66,9 @@ 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} )
 
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #needed becuase the swig bindings need -fPIC
-
-#Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxml xerces-c)
-
-#Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
-add_library(kolabkcal SHARED lib/kolabkcalconversion.cpp)
-target_link_libraries(kolabkcal kolabxml)
-
-#Library with serialization/deserialization code for KCalCore containers (deprecated)
-add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxmlkcal xerces-c)
-
-add_subdirectory(tests)
 add_subdirectory(lib)
+add_subdirectory(tests)
+
diff --git a/c++/README b/c++/README
new file mode 100644
index 0000000..2faa412
--- /dev/null
+++ b/c++/README
@@ -0,0 +1,6 @@
+Build with
+
+mkdir build
+cd build
+cmake ..
+make
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index ebce0f6..d6f1b7f 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -1,11 +1,71 @@
 
 
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #always generate shared libraries with -fPIC
+
+include_directories( ./ )
+include_directories( ../ )
+include_directories( ../build/ )
+
+SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
+
+#Library with serialization/deserialization code and kolab-containers
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxml xerces-c)
+
+set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
+install(TARGETS kolabxml LIBRARY DESTINATION lib)
+
+install( FILES
+  kolabformat.h
+  kolabevent.h
+  kolabtodo.h
+  kolabcontainers.h
+  DESTINATION include/kolab COMPONENT Devel)
+
+
+# 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 "${CMAKE_INSTALL_PREFIX}/lib")
+
+# 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)
+IF("${isSystemDir}" STREQUAL "-1")
+   SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+ENDIF("${isSystemDir}" STREQUAL "-1")
+
+
+#Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
+add_library(kolabkcal SHARED kolabkcalconversion.cpp)
+target_link_libraries(kolabkcal kolabxml)
+
+#Library with serialization/deserialization code for KCalCore containers (deprecated)
+add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxmlkcal xerces-c)
+
+
+
+
+
+#-----------------------SWIG--------------------
+
+
+set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
+
 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  kolabcontainers.h
+    DEPENDS kolabformat.i  ${KOLAB_CONTAINER_HEADERS}
     VERBATIM
     )
 
@@ -18,15 +78,12 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FI
     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 kolabcontainers.h
+    DEPENDS kolabformat.i ${KOLAB_CONTAINER_HEADERS}
     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})
 
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
-
-include_directories( ./ )
 
 #PYTHON
 find_package(PythonLibs)
@@ -37,6 +94,13 @@ target_link_libraries(pythonbindings kolabxml xerces-c)
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
+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)
+
 
 #PHP
 # set( PHP_INCLUDES "`php-config --includes`")
@@ -48,3 +112,11 @@ target_link_libraries(phpbindings kolabxml xerces-c)
 # ADD_DEPENDENCIES(bindings generate_python_bindings)
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+
+# set_target_properties(phpbindings PROPERTIES VERSION 3.0.0 SOVERSION 0)
+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)
diff --git a/c++/lib/kolabcontainers.i b/c++/lib/kolabcontainers.i
index 74638f6..fef7f71 100644
--- a/c++/lib/kolabcontainers.i
+++ b/c++/lib/kolabcontainers.i
@@ -2,10 +2,14 @@
  %module kolabcontainers
  %{
  /* Put header files here or function declarations like below */
- #include "kolabcontainers.h"
+    #include "kolabcontainers.h"
+    #include "kolabtodo.h"
+    #include "kolabevent.h"
  %}
 %include "std_string.i"
 
 /*%apply const std::string& {std::string* foo};*/
 
 %include "kolabcontainers.h"
+%include "kolabtodo.h"
+%include "kolabevent.h"
\ No newline at end of file
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index 816d967..d151556 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -7,6 +7,8 @@
 
     #include "kolabformat.h"
     #include "kolabcontainers.h"
+    #include "kolabevent.h"
+    #include "kolabtodo.h"
 
 %}
 
@@ -23,3 +25,6 @@ namespace std {
 /*%apply const std::string& {std::string* foo};*/
 
 %include "kolabcontainers.h"
+%include "kolabevent.h"
+%include "kolabtodo.h"
+%include "kolabformat.h"
diff --git a/c++/lib/test.php b/c++/lib/test.php
index d477c46..8f80805 100644
--- a/c++/lib/test.php
+++ b/c++/lib/test.php
@@ -9,6 +9,10 @@ print $e->exceptionDates()->size();
 $e->addExceptionDate( $d);
 print $e->exceptionDates()->size();
 
+$string = writeEvent($e);
+print $string
+// $e1 = readEvent($string, false);
+
 ?>
 
 
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 44fe84e..d2deb57 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,12 +1,9 @@
 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
-# QT4_WRAP_CPP(kcalconversiontest_MOC kcalconversiontest.h)
-#add_test("conversiontest" kcalconversiontest ${kolabproxy_shared_relative_SRCS} ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} kcalconversiontest.cpp)
-# add_executable(kcalconversiontest kcalconversiontest.cpp ${kcalconversiontest_MOC})
-# target_link_libraries(kcalconversiontest ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_KCALCORE_LIBS} kolabxml)
+FIND_PACKAGE(Qt4 REQUIRED)
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
 
-#QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
 QT4_AUTOMOC(bindingstest.cpp)
 add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
 target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabkcal kolabxml xerces-c kcalcore)


commit 98f55e626c4654e8bea43cf7d7821f823250ebea
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 00:56:14 2011 +0100

    moved event to own file

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 0123348..03809b5 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -361,291 +361,7 @@ bool RecurrenceRule::isValid() const
 
 
 
-struct Event::Private: public PrivateIncidence
-{
-    Private()
-    : PrivateIncidence(), 
-    isTransparent(false){}
-
-    DateTime end;
-    bool isTransparent;
-    Duration duration;
-};
-
-Event::Event()
-: d(new Event::Private())
-{
-    
-}
-
-Event::Event(const Event &other)
-: d(new Event::Private())
-{
-    *d = *other.d;
-}
-
-Event::~Event()
-{
-    
-}
-
-void Event::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Event::uid() const
-{
-    return d->uid;
-}
-
-void Event::setCreated(const Kolab::DateTime &created)
-{
-    d->created = created;
-}
-
-DateTime Event::created() const
-{
-    return d->created;
-}
-
-void Event::setLastModified(const Kolab::DateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-DateTime 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::DateTime &start)
-{
-    d->start = start;
-}
-
-DateTime Event::start() const
-{
-    return d->start;
-}
-
-void Event::setEnd(const Kolab::DateTime &end)
-{
-    d->end = end;
-}
-
-DateTime 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::DateTime &rID, bool thisandfuture)
-{
-    d->recurrenceID = rID;
-    d->thisAndFuture = thisandfuture;
-}
-
-DateTime 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< DateTime > &dates)
-{
-    d->recurrenceDates = dates;
-}
-
-void Event::addRecurrenceDate(const Kolab::DateTime &dt)
-{
-    d->recurrenceDates.push_back(dt);
-}
-
-std::vector< DateTime > Event::recurrenceDates() const
-{
-    return d->recurrenceDates;
-}
-
-void Event::setExceptionDates(const std::vector< DateTime > &dates)
-{
-    d->exceptionDates = dates;
-}
-
-void Event::addExceptionDate(const Kolab::DateTime &dt)
-{
-    d->exceptionDates.push_back(dt);
-}
-
-std::vector< DateTime > 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 std::string& email, const std::string& name)
-{
-    d->organizerEmail = email;
-    d->organizerName = name;
-}
-
-std::string Event::organizerEmail() const
-{
-    return d->organizerEmail;
-}
-
-std::string Event::organizerName() const
-{
-    return d->organizerName;
-}
-
-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;
-}
 
 
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index e291287..c674311 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -159,90 +159,6 @@ class CustomProperty {
     //TODO
 };
     
-class Event {
-public:
-    Event();
-    ~Event();
-    Event(const Event &);
-    void operator=(const Event &);
-    
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setCreated(const DateTime &);
-    DateTime created() const;
-    
-    void setLastModified(const DateTime &);
-    DateTime 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 DateTime &);
-    DateTime start() const;
-    
-    void setEnd(const DateTime &);
-    DateTime 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<DateTime> &);
-    void addRecurrenceDate(const DateTime &);
-    std::vector<DateTime> recurrenceDates() const;
-    
-    void setExceptionDates(const std::vector<DateTime> &);
-    void addExceptionDate(const DateTime &);
-    std::vector<DateTime> exceptionDates() const;
-    
-    void setRecurrenceID(const DateTime &, bool thisandfuture);
-    DateTime 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 std::string &email, const std::string &name);
-    std::string organizerEmail() const;
-    std::string organizerName() 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;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
 
 
 class Contact {
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
new file mode 100644
index 0000000..3dbc2a9
--- /dev/null
+++ b/c++/lib/kolabevent.cpp
@@ -0,0 +1,292 @@
+#include "kolabevent.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+struct Event::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence(), 
+    isTransparent(false){}
+
+    DateTime end;
+    bool isTransparent;
+    Duration duration;
+};
+
+Event::Event()
+: d(new Event::Private())
+{
+    
+}
+
+Event::Event(const Event &other)
+: d(new Event::Private())
+{
+    *d = *other.d;
+}
+
+Event::~Event()
+{
+    
+}
+
+void Event::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Event::uid() const
+{
+    return d->uid;
+}
+
+void Event::setCreated(const Kolab::DateTime &created)
+{
+    d->created = created;
+}
+
+DateTime Event::created() const
+{
+    return d->created;
+}
+
+void Event::setLastModified(const Kolab::DateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+DateTime 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::DateTime &start)
+{
+    d->start = start;
+}
+
+DateTime Event::start() const
+{
+    return d->start;
+}
+
+void Event::setEnd(const Kolab::DateTime &end)
+{
+    d->end = end;
+}
+
+DateTime 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::DateTime &rID, bool thisandfuture)
+{
+    d->recurrenceID = rID;
+    d->thisAndFuture = thisandfuture;
+}
+
+DateTime 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< DateTime > &dates)
+{
+    d->recurrenceDates = dates;
+}
+
+void Event::addRecurrenceDate(const Kolab::DateTime &dt)
+{
+    d->recurrenceDates.push_back(dt);
+}
+
+std::vector< DateTime > Event::recurrenceDates() const
+{
+    return d->recurrenceDates;
+}
+
+void Event::setExceptionDates(const std::vector< DateTime > &dates)
+{
+    d->exceptionDates = dates;
+}
+
+void Event::addExceptionDate(const Kolab::DateTime &dt)
+{
+    d->exceptionDates.push_back(dt);
+}
+
+std::vector< DateTime > 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 std::string& email, const std::string& name)
+{
+    d->organizerEmail = email;
+    d->organizerName = name;
+}
+
+std::string Event::organizerEmail() const
+{
+    return d->organizerEmail;
+}
+
+std::string Event::organizerName() const
+{
+    return d->organizerName;
+}
+
+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;
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
new file mode 100644
index 0000000..b7949b5
--- /dev/null
+++ b/c++/lib/kolabevent.h
@@ -0,0 +1,100 @@
+
+
+#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 &);
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const DateTime &);
+    DateTime created() const;
+    
+    void setLastModified(const DateTime &);
+    DateTime 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 DateTime &);
+    DateTime start() const;
+    
+    void setEnd(const DateTime &);
+    DateTime 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<DateTime> &);
+    void addRecurrenceDate(const DateTime &);
+    std::vector<DateTime> recurrenceDates() const;
+    
+    void setExceptionDates(const std::vector<DateTime> &);
+    void addExceptionDate(const DateTime &);
+    std::vector<DateTime> exceptionDates() const;
+    
+    void setRecurrenceID(const DateTime &, bool thisandfuture);
+    DateTime 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 std::string &email, const std::string &name);
+    std::string organizerEmail() const;
+    std::string organizerName() 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;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 36de14f..7d2f0af 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -3,6 +3,7 @@
 
 #include <kcalcore/recurrence.h>
 #include "kolabcontainers.h"
+#include "kolabevent.h"
 #include <kcalcore/event.h>
 
 namespace Kolab {


commit 7f6658c7917a34a80bf525536d458d4e0df83f04
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 28 00:55:22 2011 +0100

    return by value to make it easily wrappable by SWIG

diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 1c4b655..f467ca0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -9,9 +9,9 @@
 
 namespace Kolab {
 
-boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl)
+Kolab::Event readEvent(const std::string& s, bool isUrl)
 {
-    return deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
+    return *deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
 }
 
 std::string writeEvent(const Kolab::Event &event)
@@ -19,9 +19,9 @@ std::string writeEvent(const Kolab::Event &event)
     return serializeIncidence< IncidenceTrait<Kolab::Event> >(event);
 }
 
-boost::shared_ptr<Kolab::Todo> readTodo(const std::string& s, bool isUrl)
+Kolab::Todo readTodo(const std::string& s, bool isUrl)
 {
-    return deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    return *deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
 }
 
 std::string writeTodo(const Kolab::Todo &event)
@@ -29,7 +29,7 @@ std::string writeTodo(const Kolab::Todo &event)
     return serializeIncidence< IncidenceTrait<Kolab::Todo> >(event);
 }
 
-boost::shared_ptr< Kolab::Contact > readContact(const std::string& s, bool isUrl)
+Kolab::Contact readContact(const std::string& s, bool isUrl)
 {
 
 }
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 487ec79..559c09a 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -3,19 +3,19 @@
 #define KOLABFORMAT_H
 
 #include <string>
-#include <boost/shared_ptr.hpp>
 #include "kolabcontainers.h"
 #include "kolabtodo.h"
+#include "kolabevent.h"
 
 namespace Kolab {
 
-boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl);
+Kolab::Event readEvent(const std::string& s, bool isUrl);
 std::string writeEvent(const Kolab::Event &);
 
-boost::shared_ptr<Kolab::Todo> readTodo(const std::string& s, bool isUrl);
+Kolab::Todo readTodo(const std::string& s, bool isUrl);
 std::string writeTodo(const Kolab::Todo &);
 
-boost::shared_ptr<Kolab::Contact> readContact(const std::string& s, bool isUrl);
+Kolab::Contact readContact(const std::string& s, bool isUrl);
 std::string writeContact(const Kolab::Contact &);
 
 }
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 18b7386..69ca1e9 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -15,7 +15,6 @@
 #include <kdebug.h>
 #include <lib/kolabkcalconversion.h>
 
-
 namespace QTest {
      template<>
      char *toString(const Kolab::DateTime &dt)
@@ -46,17 +45,16 @@ void BindingsTest::writeContact()
 
 void BindingsTest::readEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    QVERIFY(event); 
-    QCOMPARE(event->created(), Kolab::DateTime(2006,2,6,0,11,21,true));
-    QCOMPARE(event->start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    QCOMPARE(event.created(), Kolab::DateTime(2006,2,6,0,11,21,true));
+    QCOMPARE(event.start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
     
-    const Kolab::RecurrenceRule &rrule = event->recurrenceRule();
+    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
     QCOMPARE(rrule.frequency(), Kolab::RecurrenceRule::Daily);
     QCOMPARE(rrule.count(), 5);
     QCOMPARE(rrule.interval(), 1);
     
-    QCOMPARE(event->summary(), std::string("Event #2"));
+    QCOMPARE(event.summary(), std::string("Event #2"));
 }
 
 void BindingsTest::writeEvent()
@@ -88,18 +86,18 @@ void BindingsTest::roundtripEvent()
 
 void BindingsTest::roundtripReverseEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
     kDebug() << "-------------------";
-    std::cout << Kolab::writeEvent(*event) << std::endl;
+    std::cout << Kolab::writeEvent(event) << std::endl;
     kDebug() << "-------------------";
 }
 
 void BindingsTest::BenchmarkRoundtrip()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
     std::string result;
     QBENCHMARK {
-        result = Kolab::writeEvent(*event);
+        result = Kolab::writeEvent(event);
         Kolab::readEvent(result, false);
     }
 }
@@ -179,8 +177,8 @@ void BindingsTest::eventCompletness()
     
     std::string result = Kolab::writeEvent(ev);
 //     std::cout << result << endl;
-    boost::shared_ptr<Kolab::Event> e = Kolab::readEvent(result, false);
-    const Kolab::Event &re = *e;
+    Kolab::Event e = Kolab::readEvent(result, false);
+    const Kolab::Event &re = e;
     checkIncidence(ev, re);
     QCOMPARE(ev.end(), re.end());
     QCOMPARE(ev.transparency(), re.transparency());
@@ -195,8 +193,8 @@ void BindingsTest::todoCompletness()
     
     std::string result = Kolab::writeTodo(ev);
 //     std::cout << result << endl;
-    boost::shared_ptr<Kolab::Todo> e = Kolab::readTodo(result, false);
-    const Kolab::Todo &re = *e;
+    Kolab::Todo e = Kolab::readTodo(result, false);
+    const Kolab::Todo &re = e;
     checkIncidence(ev, re);
     QCOMPARE(ev.due(), re.due());
     
@@ -204,18 +202,18 @@ void BindingsTest::todoCompletness()
 
 void BindingsTest::BenchmarkRoundtripKolab()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeEvent(*event);
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result = Kolab::writeEvent(event);
     QBENCHMARK {
         Kolab::readEvent(result, false);
     }
 }
 void BindingsTest::BenchmarkRoundtripKCAL()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeEvent(*event);
+    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));
+        Kolab::KCalConversion::toKCalCore(Kolab::readEvent(result, false));
     }
 }
 


commit 30dddfc9a750af08284c08031f8b419b756e75c0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 18:50:38 2011 +0100

    moved kcal conversion code to separate library.
    
    +some cleanup

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 7dac056..062a7b3 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -67,9 +67,15 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #needed becuase the swig bindings need -fPIC
 
-add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp lib/kolabkcalconversion.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+#Library with serialization/deserialization code and kolab-containers
+add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml xerces-c)
 
+#Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
+add_library(kolabkcal SHARED lib/kolabkcalconversion.cpp)
+target_link_libraries(kolabkcal kolabxml)
+
+#Library with serialization/deserialization code for KCalCore containers (deprecated)
 add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxmlkcal xerces-c)
 
diff --git a/c++/compiled/README b/c++/compiled/README
index d3a07b8..c2ff791 100644
--- a/c++/compiled/README
+++ b/c++/compiled/README
@@ -1,3 +1,5 @@
+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
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 4555ddf..f109710 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -42,11 +42,11 @@ int convertToInt(T integer)
         int i = boost::numeric_cast<int>(integer);
         return i;
     } catch(boost::numeric::negative_overflow& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     } catch(boost::numeric::positive_overflow& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     }
     return 0;
 }
@@ -58,11 +58,11 @@ T fromInt(int integer)
         T i = boost::numeric_cast<T>(integer);
         return i;
     } catch(boost::numeric::negative_overflow& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     } catch(boost::numeric::positive_overflow& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cout << e.what();
+        std::cerr << e.what();
     }
     return 0;
 }
@@ -142,8 +142,9 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
         date = DC::toDate(*dtProperty.date_time());
     } else { //The utc-date-time element shouldn't even exist
         date = DatePtr(new DateType());
-        std::cout << "This element shouldn't even be existing";
-        assert(0); //TODO implement anyways?
+        std::cerr << "This element shouldn't even be existing";
+        //TODO Implement anyways?
+        return date;
     }
     DC::setUTC(date);
     return date;
@@ -295,7 +296,7 @@ typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
     if (rrule.interval()) {
         RC::setInterval(r, toInt(*rrule.interval()));
     } else {
-        RC::setInterval(r, 1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+        RC::setInterval(r, 1); //FIXME should be initialized to 1 in KCalCore::RecurrenceRule class (default value of interval per RFC).
     }
     RC::setBysecond(r, rrule.bysecond());
     RC::setByminute(r, rrule.byminute());
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index b4dd3f9..816d967 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -2,10 +2,9 @@
 %module kolabformat
 %{
 
-    /* This macro ensures that return vectors remain a vector also in python and are note converted to tuples */
+    /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
     #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
 
-    /* Put header files here or function declarations like below */
     #include "kolabformat.h"
     #include "kolabcontainers.h"
 
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 754e08b..44fe84e 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -9,7 +9,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 #QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
 QT4_AUTOMOC(bindingstest.cpp)
 add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
+target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabkcal kolabxml xerces-c kcalcore)
 
 QT4_AUTOMOC(kcalconversiontest.cpp)
 add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})


commit f51d48fd04111c7daaefd01d12d22800f4da6178
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 17:11:35 2011 +0100

    cleanup

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 2b1467d..a28353a 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -27,7 +27,7 @@
 #include "grammar-input-stream.hxx"
 
 XMLParserWrapper::XMLParserWrapper()
-: ehp(eh),
+:   ehp(eh),
     parser(0),
     gp(0)
 {
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 1b18204..9065a5e 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -562,7 +562,7 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
 template <> struct IncidenceConverter < KCalCore::Incidence, KCalCore::Incidence >
 {
     typedef DateTimeConverter< KDateTime> DC;
-    static std::string uid(const KCalCore::Incidence &inc) {
+    static std::string uid(const KCalCore::Incidence &inc) { //FIXME thats possibly the kontact internal uid?
         return inc.uid().toStdString();
     }
     


commit 5d01488fb67baad77834d0523f0e3a58b1c831d8
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 17:11:15 2011 +0100

    xcard objects

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 3c6e1b2..7dac056 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -28,19 +28,19 @@ set( SCHEMA_SOURCEFILES
     bindings/iCalendar-params.cxx
     bindings/iCalendar-props.cxx
     bindings/iCalendar-valtypes.cxx
-    bindings/iCalendar-link-extension.cxx
-    bindings/iCalendar-bw-extensions.cxx
-    bindings/iCalendar-ms-extensions.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://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
+    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization  --namespace-map http://kolab.org=KolabXSD --root-element icalendar --root-element vcards --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
     COMMENT "Generating XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-    DEPENDS ${XCAL_SCHEMAS}
+    DEPENDS ${SCHEMAS}
     VERBATIM
     )
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 06b6929..e291287 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -245,7 +245,9 @@ private:
 };
 
 
-
+class Contact {
+    
+};
 
     
 }
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 50aaf49..1c4b655 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -5,6 +5,8 @@
 #include "kolabconversions.h"
 #include "kolabtodo.h"
 
+#include "kolabxcardconversions.h"
+
 namespace Kolab {
 
 boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl)
@@ -27,7 +29,14 @@ std::string writeTodo(const Kolab::Todo &event)
     return serializeIncidence< IncidenceTrait<Kolab::Todo> >(event);
 }
 
+boost::shared_ptr< Kolab::Contact > readContact(const std::string& s, bool isUrl)
+{
+
+}
+
+std::string writeContact(const Kolab::Contact &contact)
 {
+    return serializeContact(contact);
 }
 
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 343c15f..487ec79 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -9,14 +9,14 @@
 
 namespace Kolab {
 
-
-
 boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl);
 std::string writeEvent(const Kolab::Event &);
 
 boost::shared_ptr<Kolab::Todo> readTodo(const std::string& s, bool isUrl);
 std::string writeTodo(const Kolab::Todo &);
 
+boost::shared_ptr<Kolab::Contact> readContact(const std::string& s, bool isUrl);
+std::string writeContact(const Kolab::Contact &);
 
 }
 
diff --git a/c++/lib/kolabxcardconversions.h b/c++/lib/kolabxcardconversions.h
new file mode 100644
index 0000000..8b72675
--- /dev/null
+++ b/c++/lib/kolabxcardconversions.h
@@ -0,0 +1,36 @@
+#ifndef KOLABXCARDCONVERSION_H
+#define KOLABXCARDCONVERSION_H
+
+#include <bindings/kolabformat-xcard.hxx>
+#include "kolabcontainers.h"
+
+const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+
+namespace Kolab {
+    
+std::string serializeContact(const Kolab::Contact &contact) {
+    
+    using namespace vcard_4_0;
+
+    try {
+        vcard_4_0::vcard::uid_type uid("sdsdfsdf");
+        vcard_4_0::vcard::n_type n;
+        vcard_4_0::vcard vcard(uid, n);
+        
+        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) {
+        std::cout << "failed to write Contact";
+        return std::string();
+    } 
+}
+    
+} //Namespace
+
+#endif
\ No newline at end of file
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 2eb1812..18b7386 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -37,6 +37,12 @@ namespace QTest {
          return qstrdup(ba.data());
      }
  }
+ 
+void BindingsTest::writeContact()
+{
+    Kolab::Contact contact;
+    std::cout << Kolab::writeContact(contact) << std::endl;
+}
 
 void BindingsTest::readEvent()
 {
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 77e17a6..2146c48 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -9,6 +9,8 @@ class BindingsTest : public QObject
   Q_OBJECT
   private slots:
 
+    void writeContact();
+      
     //Kolabformat
     void readEvent();
     void writeEvent();
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
index e0abc67..c4a6815 100644
--- a/schemas/kolabformat-xcard.xsd
+++ b/schemas/kolabformat-xcard.xsd
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
     targetNamespace="urn:ietf:params:xml:ns:vcard-4.0"
     xmlns="urn:ietf:params:xml:ns:vcard-4.0"
     elementFormDefault="qualified">
@@ -30,6 +29,21 @@
         </xs:complexContent>
     </xs:complexType>
 
-    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />  
+    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />      
+    
+    <xs:complexType name="VcardsType">
+        <xs:sequence>
+            <xs:element name="vcard">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="uid" type="uidPropType"/>
+                        <xs:element name="n" type="nPropType"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:element name="vcards" type="VcardsType"/>
     
 </xs:schema>
\ No newline at end of file
diff --git a/schemas/kolabformat.xsd b/schemas/kolabformat.xsd
index 33d85c4..cacf52f 100644
--- a/schemas/kolabformat.xsd
+++ b/schemas/kolabformat.xsd
@@ -48,24 +48,7 @@
         </xs:complexContent>
     </xs:complexType>-->
     
-<!--    <xs:element name="contact" type="Contact"/>
-    <xs:complexType name="Contact">
-        <xs:complexContent mixed="false">
-            <xs:extension base="KolabBase">
-                <xs:sequence>
-                    <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>-->
-    
-<!--    <xs:element name="distlist" type="DistributionList"/>
 
-    <xs:complexType name="DistributionList">
-        <xs:sequence>
-            <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
-        </xs:sequence>
-    </xs:complexType>-->
     
     <xs:complexType name="CustomType" >
         <xs:sequence>
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index e7f4603..9a24e78 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -1,23 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<!-- iCalendar base schema is intended to work in conjunction
-     with conformant implementations of IETF RFC 5545
-     ( http://www.rfc-editor.org/rfc/rfc5545.txt ),
-     the normative specification of iCalendar. -->
 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0" targetNamespace="urn:ietf:params:xml:ns:vcard-4.0" elementFormDefault="qualified">
 
 <!-- Plain Types -->
 
-    <xs:element name="text" type="xs:string"/>
-    <!-- 3.3.4 DATE -->
-    <xs:element name="date" type="xs:date"/>
+  <xs:element name="uri" type="xs:anyURI"/>
+
+  <xs:element name="text" type="xs:string"/>
+  <xs:element name="date" type="xs:date"/>
   
-    <!-- 3.3.5 DATE-TIME -->
-  <!-- 
-  <xs:element name="date-time" type="xs:string"/>
- -->  
-   <xs:simpleType name="DateTimeType">
+  <xs:simpleType name="DateTimeType">
     <xs:restriction base="xs:dateTime">
       <xs:pattern value="(\-|\+)?\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z?"/>
     </xs:restriction>
@@ -27,13 +20,15 @@
 
 <!-- Parameters -->
 
-<xs:complexType name="BaseParameterType" abstract="true"/>
-    <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
-    <xs:complexType name="ArrayOfParameters">
-        <xs:sequence>
-            <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-    </xs:complexType>
+  <xs:complexType name="BaseParameterType" abstract="true"/>
+  
+  <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
+  
+  <xs:complexType name="ArrayOfParameters">
+      <xs:sequence>
+          <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+  </xs:complexType>
 
 <!-- Properties -->
   <xs:complexType name="BasePropertyType" abstract="true" >
@@ -69,6 +64,16 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <xs:complexType name="UriPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:uri" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
    <!-- Properties that take a date or date-time value -->
   <xs:complexType name="DateDatetimePropertyType" >
     <xs:complexContent mixed="false">
@@ -91,6 +96,12 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <xs:complexType name="uidPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
   <xs:complexType name="nPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:BasePropertyType">
@@ -115,12 +126,12 @@
 <!--     <xs:include schemaLocation="iCalendar-props.xsd"/> -->
 <!-- Base -->
 
-    <xs:element name="vcard" type="xcard:VcardType" />    
+<!--    <xs:element name="vcard" type="xcard:VcardType" />    
     <xs:complexType name="VcardType" mixed="false">
         <xs:sequence>
             <xs:element ref="xcard:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
-    </xs:complexType>
+    </xs:complexType>-->
     
     
 </xs:schema>


commit c43397549e4ab199bbdd4121f629a5a9f287aba0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 17:09:35 2011 +0100

    rename serialization functinos, centrally defined strings

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 6afd122..4555ddf 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -1,6 +1,8 @@
 #ifndef KOLAB_CONVERSIONS_H
 #define KOLAB_CONVERSIONS_H
 
+#include "global_definitions.h"
+
 #include <bindings/kolabformat-xcal.hxx>
 #include <bindings/iCalendar-props.hxx>
 #include <compiled/XMLParserWrapper.h>
@@ -13,6 +15,9 @@
 #include <fstream>
 #include <iostream>
 
+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 NEEDSACTION = "NEEDS-ACTION";
@@ -320,7 +325,7 @@ template <typename T> struct IncidenceTrait;
 
 
 template <typename T>
-typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
+typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 {
     typedef typename T::IncidencePtr IncidencePtr;
     typedef typename T::IncidenceType IncidenceType;
@@ -381,7 +386,7 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
 
 
 template <typename T>
-std::string writeIncidence(const typename T::IncidenceType &incidence) {
+std::string serializeIncidence(const typename T::IncidenceType &incidence) {
     
     using namespace icalendar_2_0;
     typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
@@ -391,11 +396,11 @@ std::string writeIncidence(const typename T::IncidenceType &incidence) {
 
         typename KolabType::components_type eventComponents;
 
-        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));//TODO thats possibly the kontact internal uid?
+        typename KolabType::properties_type::uid_type uid(IC::uid(incidence)); //TODO generate uid if empty
         typename KolabType::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(IC::dtstamp(incidence));
+        dtstamp.date_time(IC::dtstamp(incidence)); //TODO set current date time stamp
         typename KolabType::properties_type::created_type created;
-        created.date_time(IC::created(incidence));
+        created.date_time(IC::created(incidence)); //TODO set current date time stamp if uid was empty
         typename KolabType::properties_type eventProps(uid, created, dtstamp);
         
         KolabType inc(eventProps, eventComponents);
@@ -404,9 +409,9 @@ std::string writeIncidence(const typename T::IncidenceType &incidence) {
         VcalendarType::components_type components;
         T::addIncidence(components, inc);
         
-        VcalendarType::properties_type::prodid_type prodid(std::string("libakonadi")); //TODO take from caller plus add libakonadi
-        VcalendarType::properties_type::version_type version(std::string("2.0")); //TODO define globally
-        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(std::string("2.9.0")); //TODO define globally
+        VcalendarType::properties_type::prodid_type prodid(KOLAB_LIBNAME); //TODO take from caller plus add KOLAB_LIBNAME
+        VcalendarType::properties_type::version_type version(XCAL_VERSION);
+        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_VERSION);
         
         VcalendarType::properties_type properties(prodid, version, x_kolab_version);
         
@@ -415,7 +420,7 @@ std::string writeIncidence(const typename T::IncidenceType &incidence) {
         IcalendarType icalendar(vcalendar);
 
         xml_schema::namespace_infomap map;
-        map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+        map[""].name = XCAL_NAMESPACE;
         
         std::ostringstream ostringstream;
         icalendar_2_0::icalendar(ostringstream, icalendar, map);
diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
new file mode 100644
index 0000000..1e9da5f
--- /dev/null
+++ b/c++/lib/global_definitions.h
@@ -0,0 +1,7 @@
+#ifndef GLOBAL_DEFINITIONS_H
+#define GLOBAL_DEFINITIONS_H
+
+const char* const KOLAB_LIBNAME = "libkolabxml";
+const char* const KOLAB_VERSION = "2.9.0";
+
+#endif
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index 5d217d3..8992c13 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -6,10 +6,12 @@
 #include "kcalconversions.h"
 
 namespace Kolab {
+    
+namespace KCal {
 
 KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 {
-     return readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+     return deserializeIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
 }
 
 KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
@@ -28,4 +30,6 @@ std::string writeTodo(KCalCore::Todo::Ptr todo)
 //     return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
 }
 
+}
+
 }
\ No newline at end of file
diff --git a/c++/lib/kcalkolabformat.h b/c++/lib/kcalkolabformat.h
index d47802a..0d617c6 100644
--- a/c++/lib/kcalkolabformat.h
+++ b/c++/lib/kcalkolabformat.h
@@ -7,13 +7,13 @@
 #include <KDE/KCalCore/Todo>
 
 namespace Kolab {
-
+namespace KCal {
 KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
 KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl = true);
 
 std::string writeEvent(KCalCore::Event::Ptr);
 std::string writeTodo(KCalCore::Todo::Ptr);
-
+}
 }
 
 #endif // KCALKOLABFORMAT_H
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 3ef1e2a..50aaf49 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -1,31 +1,33 @@
 #include "kolabformat.h"
 
 #include <iostream>
-#include <bindings/kolabformat-xcal.hxx>
 #include "kolabcontainers.h"
 #include "kolabconversions.h"
 #include "kolabtodo.h"
 
 namespace Kolab {
 
-boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl)
+boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl)
 {
-    return readIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
+    return deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
 }
 
-std::string writeKolabEvent(const Kolab::Event &event)
+std::string writeEvent(const Kolab::Event &event)
 {
-    return writeIncidence< IncidenceTrait<Kolab::Event> >(event);
+    return serializeIncidence< IncidenceTrait<Kolab::Event> >(event);
 }
 
-boost::shared_ptr<Kolab::Todo> readKolabTodo(const std::string& s, bool isUrl)
+boost::shared_ptr<Kolab::Todo> readTodo(const std::string& s, bool isUrl)
 {
-    return readIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    return deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+}
+
+std::string writeTodo(const Kolab::Todo &event)
+{
+    return serializeIncidence< IncidenceTrait<Kolab::Todo> >(event);
 }
 
-std::string writeKolabTodo(const Kolab::Todo &event)
 {
-    return writeIncidence< IncidenceTrait<Kolab::Todo> >(event);
 }
 
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 03e245b..343c15f 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -9,11 +9,14 @@
 
 namespace Kolab {
 
-boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl);
-std::string writeKolabEvent(const Kolab::Event &);
 
-boost::shared_ptr<Kolab::Todo> readKolabTodo(const std::string& s, bool isUrl);
-std::string writeKolabTodo(const Kolab::Todo &);
+
+boost::shared_ptr<Kolab::Event> readEvent(const std::string& s, bool isUrl);
+std::string writeEvent(const Kolab::Event &);
+
+boost::shared_ptr<Kolab::Todo> readTodo(const std::string& s, bool isUrl);
+std::string writeTodo(const Kolab::Todo &);
+
 
 }
 
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 76b8726..2eb1812 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -40,7 +40,7 @@ namespace QTest {
 
 void BindingsTest::readEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
     QVERIFY(event); 
     QCOMPARE(event->created(), Kolab::DateTime(2006,2,6,0,11,21,true));
     QCOMPARE(event->start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
@@ -63,7 +63,7 @@ void BindingsTest::writeEvent()
     rrule.setInterval(3);
     rrule.setCount(5);
     event.setRecurrenceRule(rrule);
-    std::cout << Kolab::writeKolabEvent(event) << std::endl;
+    std::cout << Kolab::writeEvent(event) << std::endl;
 }
 
 void BindingsTest::roundtripEvent()
@@ -76,25 +76,25 @@ void BindingsTest::roundtripEvent()
     rrule.setInterval(3);
     rrule.setCount(5);
     event.setRecurrenceRule(rrule);
-    std::string result = Kolab::writeKolabEvent(event);
+    std::string result = Kolab::writeEvent(event);
     std::cout << result << std::endl;
 }
 
 void BindingsTest::roundtripReverseEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
     kDebug() << "-------------------";
-    std::cout << Kolab::writeKolabEvent(*event) << std::endl;
+    std::cout << Kolab::writeEvent(*event) << std::endl;
     kDebug() << "-------------------";
 }
 
 void BindingsTest::BenchmarkRoundtrip()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
     std::string result;
     QBENCHMARK {
-        result = Kolab::writeKolabEvent(*event);
-        Kolab::readKolabEvent(result, false);
+        result = Kolab::writeEvent(*event);
+        Kolab::readEvent(result, false);
     }
 }
 
@@ -171,9 +171,9 @@ void BindingsTest::eventCompletness()
     //TODO duration
     ev.setTransparency(true);
     
-    std::string result = Kolab::writeKolabEvent(ev);
+    std::string result = Kolab::writeEvent(ev);
 //     std::cout << result << endl;
-    boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
+    boost::shared_ptr<Kolab::Event> e = Kolab::readEvent(result, false);
     const Kolab::Event &re = *e;
     checkIncidence(ev, re);
     QCOMPARE(ev.end(), re.end());
@@ -187,9 +187,9 @@ void BindingsTest::todoCompletness()
     setIncidence(ev);
     ev.setDue(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
     
-    std::string result = Kolab::writeKolabTodo(ev);
+    std::string result = Kolab::writeTodo(ev);
 //     std::cout << result << endl;
-    boost::shared_ptr<Kolab::Todo> e = Kolab::readKolabTodo(result, false);
+    boost::shared_ptr<Kolab::Todo> e = Kolab::readTodo(result, false);
     const Kolab::Todo &re = *e;
     checkIncidence(ev, re);
     QCOMPARE(ev.due(), re.due());
@@ -198,18 +198,18 @@ void BindingsTest::todoCompletness()
 
 void BindingsTest::BenchmarkRoundtripKolab()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeKolabEvent(*event);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result = Kolab::writeEvent(*event);
     QBENCHMARK {
-        Kolab::readKolabEvent(result, false);
+        Kolab::readEvent(result, false);
     }
 }
 void BindingsTest::BenchmarkRoundtripKCAL()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result = Kolab::writeKolabEvent(*event);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result = Kolab::writeEvent(*event);
     QBENCHMARK {
-        Kolab::KCalConversion::toKCalCore(*Kolab::readKolabEvent(result, false));
+        Kolab::KCalConversion::toKCalCore(*Kolab::readEvent(result, false));
     }
 }
 
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index c5e5e9c..4a01e7b 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -48,14 +48,14 @@ void KCalConversionTest::BenchmarkRoundtripKCAL()
 //     }
     std::cout << result << std::endl;
     QBENCHMARK {
-        Kolab::readEvent(result, false);
+        Kolab::KCal::readEvent(result, false);
     }
 }
 
 void KCalConversionTest::readEvent()
 {
     
-    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
     QVERIFY(event);
     
     //Check basics
@@ -115,15 +115,15 @@ void KCalConversionTest::writeEvent()
     recurrence->addRRule(rule);
     
     kDebug() << "-------------------";
-    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << QString::fromStdString(Kolab::KCal::writeEvent(event));
     kDebug() << "-------------------";
 }
 
 void KCalConversionTest::roundtripReverseEvent()
 {
-    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
     kDebug() << "-------------------";
-    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << QString::fromStdString(Kolab::KCal::writeEvent(event));
     kDebug() << "-------------------";
 }
 
@@ -140,20 +140,20 @@ void KCalConversionTest::roundtripEvent()
     rule->setDuration(5);
     recurrence->addRRule(rule);
     
-    QString result = QString::fromStdString(Kolab::writeEvent(event));
+    QString result = QString::fromStdString(Kolab::KCal::writeEvent(event));
     kDebug() << result;
-    KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
+    KCalCore::Event::Ptr resEvent = Kolab::KCal::readEvent(result.toStdString(), false);
     QVERIFY(resEvent);
     QCOMPARE(event->dtStart(), resEvent->dtStart());
 }
 
 void KCalConversionTest::BenchmarkRoundtrip()
 {
-    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
     std::string result;
     QBENCHMARK {
-        result = Kolab::writeEvent(event);
-        Kolab::readEvent(result, false);
+        result = Kolab::KCal::writeEvent(event);
+        Kolab::KCal::readEvent(result, false);
     }
 }
 


commit 9a563a9b42d865513eada66f00348fe2178a03ab
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 14:51:22 2011 +0100

    added journal schema

diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index bea6fd3..cbbbd1e 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -106,6 +106,32 @@
             </xs:element>
         </xs:sequence>
     </xs:complexType> 
+    
+    <xs:complexType name="KolabJournal" >
+        <xs:sequence>
+            <xs:element name="properties">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="uid" type="UidPropType"/>
+                        <xs:element name="created" type="CreatedPropType"/>
+                        <xs:element name="dtstamp" type="DtstampPropType"/>
+                        <xs:element name="sequence" type="SequencePropType" minOccurs="0"/>
+                        <xs:element name="class" type="ClassPropType" minOccurs="0"/>
+                        <xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
+                        <xs:element name="related-to" type="RelatedToPropType" minOccurs="0"/>
+                        <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+                        <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
+                        <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+                        <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+                        <xs:element name="contact" type="ContactPropType" minOccurs="0"/>
+                        <xs:element name="attendee" type="AttendeePropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="attach" type="AttachPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="x-custom" type="CustomType" minOccurs="0" maxOccurs="unbounded"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType> 
 
     <xs:complexType name="VcalendarType" mixed="false">
         <xs:sequence>
@@ -123,6 +149,7 @@
                     <xs:choice>
                         <xs:element name="vevent" type="KolabEvent" maxOccurs="unbounded"/>
                         <xs:element name="vtodo" type="KolabTodo" maxOccurs="unbounded"/>
+                        <xs:element name="vjournal" type="KolabJournal"/>
                     </xs:choice>
                 </xs:complexType>
             </xs:element>


commit 264e651f64cf6535038f1e63757eb4c35b21a792
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 14:50:57 2011 +0100

    always use typedefs (numbered names may change)

diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index c22b5b5..185ea2d 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -615,18 +615,18 @@ template < > struct IncidenceTrait <Kolab::Event>
     
     static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
     {
-        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+        KolabType::properties_type &prop = vevent.properties();
         
-        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+        getIncidenceProperties<KolabType::properties_type>(prop, event);
 
         if (event.end().isValid()) {
-            prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties::dtend_type>(event.end()));
+            prop.dtend(fromDate<KolabTypes, typename KolabType::properties_type::dtend_type>(event.end()));
         }/* else if (event.duration().isValid()) {
             //TODO
         }*/
         
         if (event.transparency()) {
-            prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
+            prop.transp( KolabType::properties_type::transp_type(TRANSPARENT));
         }
     }
     
@@ -637,9 +637,9 @@ template < > struct IncidenceTrait <Kolab::Event>
 
     static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
     {
-        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+        const KolabType::properties_type &prop = vevent.properties();
 
-        setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
+        setIncidenceProperties<Kolab::Event, KolabType::properties_type>(event, prop);
 
         if (prop.dtend()) {
             event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
@@ -666,12 +666,12 @@ template < > struct IncidenceTrait <Kolab::Event>
         }
     }
      
-    static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &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::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
     {
         return components.vevent().end();
     }
@@ -685,17 +685,16 @@ template < > struct IncidenceTrait <Kolab::Todo>
     typedef typename boost::shared_ptr<Kolab::Todo> IncidencePtr;
     typedef typename Kolab::Incidence Incidence;
     
-    static void writeIncidence(KolabType& vevent, const Kolab::Todo &event)
+    static void writeIncidence(KolabType& vevent, const Kolab::Todo &todo)
     {
         KolabType::properties_type &prop = vevent.properties();
         
-        getIncidenceProperties<KolabType::properties_type>(prop, event);
+        getIncidenceProperties<KolabType::properties_type>(prop, todo);
 
-        if (event.due().isValid()) {
-            prop.due(fromDate<KolabTypes, typename icalendar_2_0::properties1::due_type>(event.due()));
+        if (todo.due().isValid()) {
+            prop.due(fromDate<KolabTypes, typename KolabType::properties_type::due_type>(todo.due()));
         }
-        
-//         if (event.transparency()) {
+//         if (todo.transparency()) {
 //             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
 //         }
     }
@@ -707,9 +706,9 @@ template < > struct IncidenceTrait <Kolab::Todo>
 
     static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
     {
-        const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
+        const KolabType::properties_type &prop = vevent.properties();
 
-        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
+        setIncidenceProperties<Kolab::Todo, KolabType::properties_type>(todo, prop);
 
         if (prop.related_to()) {
             //TODO
@@ -720,16 +719,15 @@ template < > struct IncidenceTrait <Kolab::Todo>
         if (prop.percent_complete()) {
             //TODO
         }
-        
 
     }
      
-    static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &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::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
     {
         return components.vtodo().end();
     }





More information about the commits mailing list