Branch 'c++/master' - 55 commits - c++/CMakeLists.txt c++/compiled c++/.gitignore c++/lib c++/tests schemas/base.xsd schemas/contact.xsd schemas/event.xsd schemas/ical schemas/incidence.xsd schemas/kolabformat-xcard.xsd schemas/kolabformat.xsd schemas/note.xsd schemas/task.xsd schemas/xCard.xsd testfiles/xcalCalendar.xml testfiles/xcalEvent.xml

Christian Mollekopf mollekopf at kolabsys.com
Tue Dec 27 13:28:29 CET 2011


 c++/.gitignore                              |    2 
 c++/CMakeLists.txt                          |   70 +-
 c++/compiled/README                         |   18 
 c++/compiled/XMLParserWrapper.cpp           |  260 +++++++++
 c++/compiled/XMLParserWrapper.h             |   76 ++
 c++/compiled/grammar-input-stream.cxx       |  115 ++++
 c++/compiled/grammar-input-stream.hxx       |   53 ++
 c++/compiled/xsdbin.cxx                     |  505 +++++++++++++++++++
 c++/lib/CMakeLists.txt                      |   50 +
 c++/lib/DEVELOPMENT                         |   13 
 c++/lib/conversions.h                       |  435 ++++++++++++++++
 c++/lib/incidence_p.h                       |   46 +
 c++/lib/kcalconversions.h                   |  665 +++++++++++++++++++++++++
 c++/lib/kcalkolabformat.cpp                 |   31 +
 c++/lib/kcalkolabformat.h                   |   19 
 c++/lib/kolabcontainers.cpp                 |  652 ++++++++++++++++++++++++
 c++/lib/kolabcontainers.h                   |  253 +++++++++
 c++/lib/kolabcontainers.i                   |   11 
 c++/lib/kolabconversions.h                  |  740 ++++++++++++++++++++++++++++
 c++/lib/kolabformat.cpp                     |   33 +
 c++/lib/kolabformat.h                       |   20 
 c++/lib/kolabformat.i                       |   26 
 c++/lib/kolabkcalconversion.cpp             |  362 +------------
 c++/lib/kolabkcalconversion.h               |    9 
 c++/lib/kolabtodo.cpp                       |  269 ++++++++++
 c++/lib/kolabtodo.h                         |   97 +++
 c++/lib/test.php                            |   16 
 c++/lib/test.py                             |   10 
 c++/tests/CMakeLists.txt                    |   16 
 c++/tests/bindingstest.cpp                  |  412 ++++++---------
 c++/tests/bindingstest.h                    |   22 
 c++/tests/kcalconversiontest.cpp            |  163 +++++-
 c++/tests/kcalconversiontest.h              |   10 
 c++/tests/testfiles/icalEvent.xml           |   93 +++
 c++/tests/testfiles/testkolabevent.xml      |   38 -
 schemas/base.xsd                            |   92 ---
 schemas/contact.xsd                         |   82 ---
 schemas/event.xsd                           |   25 
 schemas/ical/iCalendar-props.xsd            |   24 
 schemas/ical/iCalendar-valtypes.xsd         |   64 ++
 schemas/ical/iCalendar-wscal-extensions.xsd |    1 
 schemas/ical/iCalendar.xsd                  |   21 
 schemas/ical/kolabformat-xcal.xsd           |  142 +++++
 schemas/ical/kolabformat.xsd                |   39 -
 schemas/incidence.xsd                       |   95 ---
 schemas/kolabformat-xcard.xsd               |   35 +
 schemas/kolabformat.xsd                     |   79 ++
 schemas/note.xsd                            |   33 -
 schemas/task.xsd                            |   29 -
 schemas/xCard.xsd                           |  126 ++++
 testfiles/xcalCalendar.xml                  |  142 +++++
 testfiles/xcalEvent.xml                     |   34 +
 52 files changed, 5613 insertions(+), 1060 deletions(-)

New commits:
commit 19d4fe0288d49e7e8150d9dd7719fd3427e88ef7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 13:27:00 2011 +0100

    toKCalCore conversion function
    
    roundtrip test to check overhead of additional conversion

diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index 544d66c..d40d819 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -1,6 +1,5 @@
 #include "kolabkcalconversion.h"
 
-#include "bindings/incidence.hxx"
 #include <kcalcore/recurrence.h>
 #include <QtCore/QBitArray>
 #include <QtCore/QVector>
@@ -8,352 +7,45 @@
 
 namespace Kolab {
 namespace KCalConversion {
-    
-    enum CYCLE {
-        Yearly,
-        Monthly,
-        Weekly,
-        Daily
-    };
-    /*
-void setInterval(const KolabXSD::Interval &interval, KCalCore::RecurrenceRule::PeriodType type)
-{
-    
-}*/
-    
-//    KCalCore::Recurrence* recur = incidence->recurrence(); // yeah, this creates it
-//setup a KCalCore::Recurrence from a KolabXSD::Recurrence
-void toKCal(KCalCore::Recurrence* recur, const KolabXSD::Recurrence &recurrence) 
-{
-
-    for (KolabXSD::Recurrence::rule_const_iterator it = recurrence.rule().begin(); it != recurrence.rule().end(); it++) {
-        KCalCore::RecurrenceRule r;
-        
-        if (it->yearly()) {
-            if (it->yearly()->interval()) { //TODO yearly day
-                r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-                r.setFrequency(*(it->yearly()->interval()));
-                
-                /*if (it->monthly() && it->monthly()->list()) { //interval is not supported
-                    
-                    QList<int> months;
-                    for (KolabXSD::Recurrence::rule_const_iterator month = it->monthly()->list().begin(); month != it->monthly()->list().end(); month++) {
-                        months.append(*month);
-                    }
-                    r.setByMonths(months);
 
-                    Q_ASSERT(!it->weekly()); //Not supported TODO setByWeekNumbers
-                    
-                    
-                    if (it->daily() && it->daily()->list()) {
-                        QList<int> monthDays;
-                        for (KolabXSD::Recurrence::rule_const_iterator day = it->daily()->list().begin(); day != it->daily()->list().end(); day++) {
-                            monthDays.append(*day);
-                        }
-                        r.setByMonthDays(*day);
-                    }
-                    
-                }*/
-                
-            }
-            
-        }
-        
-        /*if (it->yearly()) {
-            if (it->yearly()->interval()) {
-                recur->setYearly(*(it->yearly()->interval()));
-            } else if (it->yearly()->list()) { //TODO
-                
-            }
-        }*/
-        
-        if (it->monthly()) {
-            const KolabXSD::Interval &interval = *(it->monthly());
-            
-            if (r.recurrenceType() == KCalCore::RecurrenceRule::rNone) {
-                if (interval.interval()) {
-                    r.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-                    r.setFrequency(*(interval.interval()));
-                } else {
-                    r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-                    r.setFrequency(1);
-                }
-            } 
-            
-            if (r.recurrenceType() == KCalCore::RecurrenceRule::rYearly) {
-
-                if (interval.interval()) {
-                     //TODO create list from interval
-                } else if (interval.list().size()) {
-                    QList<int> list;
-                    for (KolabXSD::Interval::list_const_iterator value = interval.list().begin(); value != interval.list().end(); value++) {
-                        list.append(*value);
-                    }
-                    r.setByMonths(list);
-                }
-            }
-            
-            
-        }
-        /*
-        if (it->weekly()) {
-            const KolabXSD::Interval &interval = *(it->weekly());
-            
-            if (r.recurrenceType() == KCalCore::RecurrenceRule::rNone) {
-                if (interval.interval()) {
-                    r.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-                    r.setFrequency(*(interval.interval()));
-                } else {
-                    r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-                    r.setFrequency(1);
-                }
-            } 
-            
-            if (r.recurrenceType() == KCalCore::RecurrenceRule::rYearly) {
-
-                if (interval.interval()) {
-                     //TODO create list from interval
-                } else if (interval.list()) {
-                    QList<int> list;
-                    for (KolabXSD::Recurrence::rule_const_iterator day = interval.list().begin(); day != interval.list().end(); day++) {
-                        list.append(*day);
-                    }
-                    r.setByMonths(list);
-                }
-            }
-            
-            
-        }*/
-        
-        /*
-        if (it->minutely() && it->minutely()->interval()) {
-            recur->setMinutely(*(it->minutely()->interval()));
-        }*/
-    }
-    
-
-    
-#if 0
-    // done below recur->setFrequency( mRecurrence.interval );
-    if ( mRecurrence.rule == "minutely" ) {
-      recur->setMinutely( mRecurrence.interval );
-    } else if ( mRecurrence.rule == "hourly" ) {
-      recur->setHourly( mRecurrence.interval );
-    } else if ( mRecurrence.rule == "daily" ) {
-      recur->setDaily( mRecurrence.interval );
-    } else if ( mRecurrence.rule == "weekly" ) {
-      QBitArray rDays = daysListToBitArray( mRecurrence.days );
-      recur->setWeekly( mRecurrence.interval, rDays );
-    } else if ( mRecurrence.rule == "monthly" ) {
-      recur->setMonthly( mRecurrence.interval );
-      if ( mRecurrence.type == "weekday" ) {
-        recur->addMonthlyPos( mRecurrence.dayNumber.toInt(), daysListToBitArray( mRecurrence.days ) );
-      } else if ( mRecurrence.type == "daynumber" ) {
-        recur->addMonthlyDate( mRecurrence.dayNumber.toInt() );
-      } else kWarning() <<"Unhandled monthly recurrence type" << mRecurrence.type;
-    } else if ( mRecurrence.rule == "yearly" ) {
-      recur->setYearly( mRecurrence.interval );
-      if ( mRecurrence.type == "monthday" ) {
-        recur->addYearlyDate( mRecurrence.dayNumber.toInt() );
-                for ( int i = 0; i < 12; ++i )
-          if ( s_monthName[ i ] == mRecurrence.month )
-            recur->addYearlyMonth( i+1 );
-      } else if ( mRecurrence.type == "yearday" ) {
-        recur->addYearlyDay( mRecurrence.dayNumber.toInt() );
-      } else if ( mRecurrence.type == "weekday" ) {
-              for ( int i = 0; i < 12; ++i )
-          if ( s_monthName[ i ] == mRecurrence.month )
-            recur->addYearlyMonth( i+1 );
-        recur->addYearlyPos( mRecurrence.dayNumber.toInt(), daysListToBitArray( mRecurrence.days ) );
-      } else kWarning() <<"Unhandled yearly recurrence type" << mRecurrence.type;
-    } else kWarning() <<"Unhandled recurrence rule" << mRecurrence.rule;
-
-    if ( mRecurrence.rangeType == "number" ) {
-      recur->setDuration( mRecurrence.range.toInt() );
-    } else if ( mRecurrence.rangeType == "date" ) {
-      recur->setEndDate( stringToDate( mRecurrence.range ) );
-    } // "none" is default since tje set*ly methods set infinite recurrence
-
-    incidence->recurrence()->setExDates( mRecurrence.exclusions );
-#endif
+KDateTime toDate(const Kolab::DateTime &dt)
+{
+    KDateTime date;
+    if (dt.isDateOnly()) {
+        date.setDateOnly(true);
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+    } else {
+        date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
+        if (dt.isUTC()) {
+            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        } else if (dt.timezone().empty()) {
+            date.setTimeSpec(KDateTime::Spec(KTimeZone(QString::fromStdString(dt.timezone()))));
+        }
+    }
+    return date;
 }
 
-//setup a KolabXSD:Recurrence from a KCalCore recurrence
-KolabXSD::Recurrence fromKCal( KCalCore::Recurrence* recur )
+void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
 {
-    KolabXSD::Recurrence recurrence;
-
-    KolabXSD::Interval interval;
-    interval.interval() = recur->frequency();
-    switch ( recur->recurrenceType() ) {
-    case KCalCore::Recurrence::rMinutely: {
-        KolabXSD::Rule rule;
-        rule.minutely(interval);
-        recurrence.rule().push_back(rule);
-        break;
+    if (!e.uid().empty()) {
+        i.setUid(QString::fromStdString(e.uid()));
     }
-    case KCalCore::Recurrence::rHourly: {
-        KolabXSD::Rule rule;
-        rule.hourly(interval);
-        recurrence.rule().push_back(rule);
-        break;
-    }
-    case KCalCore::Recurrence::rDaily: {
-        KolabXSD::Rule rule;
-        rule.daily(interval);
-        recurrence.rule().push_back(rule);
-        break;
-    }
-    case KCalCore::Recurrence::rWeekly: { // every X weeks
-        KolabXSD::Rule rule;
-        rule.weekly(interval);
-        KolabXSD::Interval days;
-        {
-            QBitArray arr = recur->days();
-            for ( uint idx = 0 ; idx < 7 ; ++idx )
-                if ( arr.testBit( idx ) )
-                    days.list().push_back(idx);
-        }
-        rule.daily(days);
-        recurrence.rule().push_back(rule);
-        break;
-    }
-    case KCalCore::Recurrence::rMonthlyPos: {
-
-        foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, recur->monthPositions()) {
-            KolabXSD::Rule rule;
-            rule.monthly(interval);
-            KolabXSD::Interval weeks;
-            weeks.list().push_back(monthPos.pos());
-            rule.weekly(weeks);
-            KolabXSD::Interval days;
-            days.list().push_back(monthPos.day());
-            rule.daily(days);
-            recurrence.rule().push_back(rule);
-        }
-        /*
-        recurrence.monthly(interval);
-
-        KolabXSD::Interval days;
-
-        QMap <int, int> m_dayPosMap;
-        foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, recur->monthPositions()) {
-            m_dayPosMap.insertMulti(monthPos.day(), monthPos.pos());
-        }
-
-        foreach( int day, m_dayPosMap.uniqueKeys()) {
-            KolabXSD::Interval weeks;
-            if (m_dayPosMap.values(day).contains(0)) {
-                weeks.interval(1);
-            } else {
-                foreach (int pos, m_dayPosMap.values(day)) {
-                    weeks.list.push_back(pos);
-                }
-            }
-            recurrence.weekly(weeks);
-        }
-
-        if ( !monthPositions.isEmpty() ) {
-            foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, monthPositions) {
-                if (monthPos.pos() != 0) { //pos == 0 => every week
-                    KolabXSD::Interval weeks;
-                    foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, monthPos.) {
-                        weeks.list().push_back(monthPos.pos);
-                    }
-                    recurrence.weekly(weeks);
-                } else {
-
-                }
-
-                days.list().push_back(monthPos.day());
-            }
-
-        }
-
-        recurrence.daily(days);*/
-        break;
-    }
-    case KCalCore::Recurrence::rMonthlyDay: {
-        KolabXSD::Rule rule;
-        rule.monthly(interval);
-        KolabXSD::Interval weeks;
-        weeks.interval(0);
-        rule.weekly(weeks);
-        QList<int> monthDays = recur->monthDays();
-        if ( !monthDays.isEmpty() ) {
-            KolabXSD::Interval days;
-            foreach( int day, monthDays) {
-                days.list().push_back(day);
-            }
-            rule.daily(days);
-        }
-        recurrence.rule().push_back(rule);
-        break;
-    }
-    /*
-    case KCalCore::Recurrence::rYearlyMonth: // (day n of Month Y)
-    {
-        KolabXSD::Recurrence recurrence;
-        mRecurrence.rule = "yearly";
-        mRecurrence.type = "monthday";
-        QList<int> rmd = recur->yearDates();
-        int day = !rmd.isEmpty() ? rmd.first() : recur->startDate().day();
-        mRecurrence.dayNumber = QString::number( day );
-        QList<int> months = recur->yearMonths();
-        if ( !months.isEmpty() )
-            mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified
-        recurrences.append(recurrence);
-        break;
+    
+    if (e.start().isValid()) {
+        i.setDtStart(toDate(e.start()));
     }
-    case KCalCore::Recurrence::rYearlyDay: // YearlyDay (day N of the year). Not supported by Outlook
-        mRecurrence.rule = "yearly";
-        mRecurrence.type = "yearday";
-        mRecurrence.dayNumber = QString::number( recur->yearDays().first() );
-        break;
-    case KCalCore::Recurrence::rYearlyPos: // (weekday X of week N of month Y)
-        mRecurrence.rule = "yearly";
-        mRecurrence.type = "weekday";
-        QList<int> months = recur->yearMonths();
-        if ( !months.isEmpty() )
-            mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified
-        QList<KCalCore::RecurrenceRule::WDayPos> monthPositions = recur->yearPositions();
-        if ( !monthPositions.isEmpty() ) {
-            KCalCore::RecurrenceRule::WDayPos monthPos = monthPositions.first();
-            // TODO: Handle multiple days in the same week
-            mRecurrence.dayNumber = QString::number( monthPos.pos() );
-            mRecurrence.days.append( s_weekDayName[ monthPos.day()-1 ] );
 
-            //mRecurrence.dayNumber = QString::number( *recur->yearNums().getFirst() );
-            // Not handled: monthPos.negative (nth days before end of month)
-        }
-        break;*/
-    }
-    /* TODO for each recurrence rule
-    int howMany = recur->duration();
-    if ( howMany > 0 ) {
-        recurrence.count(howMany);
-    } else if ( howMany == 0 ) {
-        const KDateTime &dt = recur->endDateTime();
-        KolabXSD::Recurrence::enddate_type endDate(dt.date().year(), dt.date().month(), dt.date().day(), dt.time().hour(), dt.time().minute(), dt.time().second());
-        recurrence.enddate(endDate);
-    }
-    */
-   /* 
-    foreach (const QDate &date, recur->exDates()) {
-        KolabXSD::Exception exception;
-        //exception.date(); //TODO
-        
-        recurrence.exception().push_back(exception);
-    }*/
-    
-    return recurrence;
 }
 
-KCalCore::Recurrence getRecurrence(KolabXSD::Recurrence* recur)
+KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
 {
-
+    KCalCore::Event::Ptr e(new KCalCore::Event);
+    setIncidence(*e, event);    
+    return e;
 }
 
 
+
 }
 }
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index bd46003..36de14f 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -1,17 +1,16 @@
 #ifndef KOLABKCALTOOLS_H
 #define KOLABKCALTOOLS_H
 
-#include <bindings/incidence.hxx>
 #include <kcalcore/recurrence.h>
+#include "kolabcontainers.h"
+#include <kcalcore/event.h>
 
 namespace Kolab {
     namespace KCalConversion {
         
-        //setup a KCalCore::Recurrence from a KolabXSD::Recurrence
-        void toKCal(KCalCore::Recurrence* recur, const KolabXSD::Recurrence &recurrence);
         
-        //setup a KolabXSD:Recurrence from a KCalCore recurrence
-        KolabXSD::Recurrence fromKCal( KCalCore::Recurrence* recur );
+        KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
+//         Kolab::Event writeEvent(KCalCore::Event::Ptr);
         
     };
 };
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 463636f..76b8726 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -13,6 +13,7 @@
 #include <xercesc/dom/DOMImplementation.hpp>
 #include <lib/kolabformat.h>
 #include <kdebug.h>
+#include <lib/kolabkcalconversion.h>
 
 
 namespace QTest {
@@ -195,6 +196,22 @@ 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);
+    QBENCHMARK {
+        Kolab::readKolabEvent(result, false);
+    }
+}
+void BindingsTest::BenchmarkRoundtripKCAL()
+{
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result = Kolab::writeKolabEvent(*event);
+    QBENCHMARK {
+        Kolab::KCalConversion::toKCalCore(*Kolab::readKolabEvent(result, false));
+    }
+}
 
 
 QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4e6205b..77e17a6 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -17,6 +17,9 @@ class BindingsTest : public QObject
     void BenchmarkRoundtrip();
     void eventCompletness();
     void todoCompletness();
+    
+    void BenchmarkRoundtripKolab();
+    void BenchmarkRoundtripKCAL();
 };
 
 #endif
\ No newline at end of file


commit 8c6fab2ef8532371f5f5ede58681bf7a2b78bd7a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 13:25:57 2011 +0100

    conversiontest benchmark

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index be1d3a6..3c6e1b2 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -67,10 +67,10 @@ 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 compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+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})
 target_link_libraries(kolabxml xerces-c)
 
-add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+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)
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 822015d..754e08b 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -11,6 +11,6 @@ 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)
 
-# QT4_AUTOMOC(kcalconversiontest.cpp)
-# add_executable(kcalconversiontest kcalconversiontest.cpp ${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 kcalcore)
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 15d90fe..c5e5e9c 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -8,6 +8,7 @@
 #include <lib/kcalkolabformat.h>
 
 
+
 void KCalConversionTest::testDate()
 {
     KDateTime dt1(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
@@ -23,6 +24,34 @@ void KCalConversionTest::testDate()
     QCOMPARE(date3.zone_present(), false);
 }
 
+void KCalConversionTest::BenchmarkRoundtripKCAL()
+{
+    std::ifstream ifs;
+//     ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
+    ifs.open ("../../tests/testfiles/icalEvent.xml");
+    std::string result;
+    
+    std::istream_iterator<std::string> DataBegin( ifs );
+    std::istream_iterator<std::string> DataEnd;
+
+    while( DataBegin != DataEnd ) {
+        result += *DataBegin;
+        result += "\n";
+        DataBegin++;
+    }
+    
+    
+//     std::string a;
+//     while (!ifs.eof()) {
+//         ifs >> a;
+//         result.append(a);
+//     }
+    std::cout << result << std::endl;
+    QBENCHMARK {
+        Kolab::readEvent(result, false);
+    }
+}
+
 void KCalConversionTest::readEvent()
 {
     
@@ -341,4 +370,4 @@ class KCalConversionTest : public QObject
 
 QTEST_MAIN( KCalConversionTest )
 
-#include "moc_kcalconversiontest.cxx"
+#include "kcalconversiontest.moc"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index f1f5a32..6545e5c 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -9,6 +9,9 @@ class KCalConversionTest : public QObject
   Q_OBJECT
   private slots:
       
+      
+    void BenchmarkRoundtripKCAL();
+
     void testConversion_data();
     void testConversion();
 


commit ba21cea52064e6acab8ec808053e0063fe7510c1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 13:25:09 2011 +0100

    missing todo properties

diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 170b489..c22b5b5 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -691,11 +691,9 @@ template < > struct IncidenceTrait <Kolab::Todo>
         
         getIncidenceProperties<KolabType::properties_type>(prop, event);
 
-//     /*    if (event.end().isValid()) {
-//             prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties1::dtend_type>(event.end()));
-//         }/* else if */(event.duration().isValid()) {
-//             //TODO
-//         }*/
+        if (event.due().isValid()) {
+            prop.due(fromDate<KolabTypes, typename icalendar_2_0::properties1::due_type>(event.due()));
+        }
         
 //         if (event.transparency()) {
 //             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
@@ -707,35 +705,23 @@ template < > struct IncidenceTrait <Kolab::Todo>
         components.vtodo().push_back(inc);
     }
 
-    static void readIncidence(Kolab::Todo &event, const icalendar_2_0::KolabTodo& vevent)
+    static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
     {
         const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
 
-        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(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;
-//                 }
-//             }
-//         }
+        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::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::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 10baba3..bea6fd3 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -79,7 +79,9 @@
                         <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="due" type="DuePropType" minOccurs="0"/>
                         <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
                         <xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
                         <xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
@@ -88,6 +90,7 @@
                         <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
                         <xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
                         <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+                        <xs:element name="percent-complete" type="PercentCompletePropType" minOccurs="0"/>
                         <xs:element name="location" type="LocationPropType" minOccurs="0"/>
                         <xs:element name="organizer" type="OrganizerPropType" minOccurs="0"/>
                         <xs:element name="attendee" type="AttendeePropType" minOccurs="0" maxOccurs="unbounded"/>


commit e39021dcfddcf79a9ecad99098bb9da245b6292b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 11:40:26 2011 +0100

    todo implementation

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 22e1947..be1d3a6 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -67,10 +67,10 @@ 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 compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+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)
 
-add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxmlkcal xerces-c)
 
 add_subdirectory(tests)
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 796ec9f..6afd122 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -308,7 +308,7 @@ typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
 }
 
 ///Trait for Incidence object
-template <typename T> 
+template <typename T, typename I> 
 struct IncidenceConverter;
 
 ///Trait for incidence properties specialized for Event/Todo/Journal
@@ -384,7 +384,7 @@ template <typename T>
 std::string writeIncidence(const typename T::IncidenceType &incidence) {
     
     using namespace icalendar_2_0;
-    typedef IncidenceConverter< typename T::Incidence > IC;
+    typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
     typedef typename T::KolabType KolabType;
 
     try {
diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
new file mode 100644
index 0000000..e7a3b99
--- /dev/null
+++ b/c++/lib/incidence_p.h
@@ -0,0 +1,46 @@
+#ifndef INCIDENCE_P
+#define INCIDENCE_P
+
+#include "kolabcontainers.h"
+
+namespace Kolab {
+    
+    struct PrivateIncidence
+    {
+        PrivateIncidence()
+        : sequence(0),
+        classification(Public),
+        thisAndFuture(false),
+        priority(0),
+        status(UndefinedStatus){}
+        
+        std::string uid;
+        DateTime created;
+        DateTime lastModified;
+        int sequence;
+        Classification classification;
+        std::vector< std::string > categories;
+        DateTime start;
+        
+        DateTime recurrenceID;
+        bool thisAndFuture;
+        std::string summary;
+        std::string description;
+        std::string location;
+        int priority;
+        Status status;
+        RecurrenceRule rrule;
+        std::vector< DateTime > recurrenceDates;
+        std::vector< DateTime > exceptionDates;
+        std::string organizerEmail;
+        std::string organizerName;
+        Duration duration;
+        
+        std::vector<Attendee> attendees;
+        std::vector<Attachment> attachments;
+        std::vector<CustomProperty> customProperties;
+    };
+    
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 2c3f7a4..1b18204 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -559,7 +559,7 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
     
 }
 
-template <> struct IncidenceConverter < KCalCore::Incidence >
+template <> struct IncidenceConverter < KCalCore::Incidence, KCalCore::Incidence >
 {
     typedef DateTimeConverter< KDateTime> DC;
     static std::string uid(const KCalCore::Incidence &inc) {
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index 82d9995..5d217d3 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -20,7 +20,7 @@ KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
 
 std::string writeEvent(KCalCore::Event::Ptr event)
 {
-     return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+//      return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
 }
 
 std::string writeTodo(KCalCore::Todo::Ptr todo)
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index cfd94ad..0123348 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -1,4 +1,5 @@
 #include "kolabcontainers.h"
+#include "incidence_p.h"
 
 namespace Kolab {
     
@@ -360,43 +361,15 @@ bool RecurrenceRule::isValid() const
 
 
 
-struct Event::Private
+struct Event::Private: public PrivateIncidence
 {
     Private()
-    : sequence(0),
-    classification(Public),
-    thisAndFuture(false),
-    priority(0),
-    status(UndefinedStatus),
+    : PrivateIncidence(), 
     isTransparent(false){}
-    
-    std::string uid;
-    DateTime created;
-    DateTime lastModified;
-    int sequence;
-    Classification classification;
-    std::vector< std::string > categories;
-    DateTime start;
+
     DateTime end;
-    
-    DateTime recurrenceID;
-    bool thisAndFuture;
-    std::string summary;
-    std::string description;
-    int priority;
-    Status status;
-    std::string location;
     bool isTransparent;
-    RecurrenceRule rrule;
-    std::vector< DateTime > recurrenceDates;
-    std::vector< DateTime > exceptionDates;
-    std::string organizerEmail;
-    std::string organizerName;
     Duration duration;
-    
-    std::vector<Attendee> attendees;
-    std::vector<Attachment> attachments;
-    std::vector<CustomProperty> customProperties;
 };
 
 Event::Event()
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 32251b0..06b6929 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -244,6 +244,9 @@ private:
     boost::scoped_ptr<Private> d;
 };
 
+
+
+
     
 }
 
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 0e34d4e..170b489 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -3,6 +3,7 @@
 #include "conversions.h"
 #include "kolabcontainers.h"
 #include <boost/foreach.hpp>
+#include "kolabtodo.h"
 
 namespace Kolab {
 
@@ -308,8 +309,8 @@ void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string
 }
 
 
-template <typename KolabType, typename T>
-void setIncidenceProperties(Kolab::Event &inc, const T &prop)
+template <typename I, typename T>
+void setIncidenceProperties(I &inc, const T &prop)
 {
     typedef DateTimeConverter<Kolab::DateTime> DC;
     
@@ -469,8 +470,8 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
 }
 
 
-template <typename T>
-void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
+template <typename T, typename I>
+void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to template
 {
     using namespace icalendar_2_0;
     
@@ -585,18 +586,18 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
 
 }
 
-template <> struct IncidenceConverter < Incidence >
+template <typename T> struct IncidenceConverter < Incidence, T >
 {
     typedef DateTimeConverter< DateTime> DC;
-    static std::string uid(const Event &inc) {
+    static std::string uid(const T &inc) {
         return inc.uid();
     }
     
-    static xml_schema::date_time dtstamp(const Event &inc) {
+    static xml_schema::date_time dtstamp(const T &inc) {
         return DC::fromDateTime(inc.lastModified());
     }
     
-    static xml_schema::date_time created(const Event &inc) {
+    static xml_schema::date_time created(const T &inc) {
         return DC::fromDateTime(inc.created());
     }
 
@@ -665,17 +666,89 @@ template < > struct IncidenceTrait <Kolab::Event>
         }
     }
      
-    static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+    static icalendar_2_0::components2::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) //TODO to base trait
+    static icalendar_2_0::components2::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 &event)
+    {
+        KolabType::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<KolabType::properties_type>(prop, event);
+
+//     /*    if (event.end().isValid()) {
+//             prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties1::dtend_type>(event.end()));
+//         }/* else if */(event.duration().isValid()) {
+//             //TODO
+//         }*/
+        
+//         if (event.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 &event, const icalendar_2_0::KolabTodo& vevent)
+    {
+        const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(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::components2::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)
+    {
+        return components.vtodo().end();
+    }
+    
+};
+
 
 }//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index ab43acc..3ef1e2a 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,6 +4,7 @@
 #include <bindings/kolabformat-xcal.hxx>
 #include "kolabcontainers.h"
 #include "kolabconversions.h"
+#include "kolabtodo.h"
 
 namespace Kolab {
 
@@ -17,6 +18,16 @@ std::string writeKolabEvent(const Kolab::Event &event)
     return writeIncidence< IncidenceTrait<Kolab::Event> >(event);
 }
 
+boost::shared_ptr<Kolab::Todo> readKolabTodo(const std::string& s, bool isUrl)
+{
+    return readIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+}
+
+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 cb8064c..03e245b 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -5,13 +5,16 @@
 #include <string>
 #include <boost/shared_ptr.hpp>
 #include "kolabcontainers.h"
-
+#include "kolabtodo.h"
 
 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 &);
+
 }
 
 #endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
new file mode 100644
index 0000000..22ae95e
--- /dev/null
+++ b/c++/lib/kolabtodo.cpp
@@ -0,0 +1,269 @@
+#include "kolabtodo.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+    
+    
+struct Todo::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence() {}
+    
+    DateTime due;
+};
+
+Todo::Todo()
+: d(new Todo::Private())
+{
+    
+}
+
+Todo::Todo(const Todo &other)
+: d(new Todo::Private())
+{
+    *d = *other.d;
+}
+
+Todo::~Todo()
+{
+    
+}
+
+void Todo::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Todo::uid() const
+{
+    return d->uid;
+}
+
+void Todo::setCreated(const Kolab::DateTime &created)
+{
+    d->created = created;
+}
+
+DateTime Todo::created() const
+{
+    return d->created;
+}
+
+void Todo::setLastModified(const Kolab::DateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+DateTime Todo::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Todo::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Todo::sequence() const
+{
+    return d->sequence;
+}
+
+void Todo::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Todo::classification() const
+{
+    return d->classification;
+}
+
+void Todo::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Todo::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Todo::categories() const
+{
+    return d->categories;
+}
+
+void Todo::setStart(const Kolab::DateTime &start)
+{
+    d->start = start;
+}
+
+DateTime Todo::start() const
+{
+    return d->start;
+}
+
+void Todo::setDue(const Kolab::DateTime &due)
+{
+    d->due = due;
+}
+
+DateTime Todo::due() const
+{
+    return d->due;
+}
+
+void Todo::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
+{
+    d->recurrenceID = rID;
+    d->thisAndFuture = thisandfuture;
+}
+
+DateTime Todo::recurrenceID() const
+{
+    return d->recurrenceID;
+}
+
+bool Todo::thisAndFuture() const
+{
+    return d->thisAndFuture;
+}
+
+void Todo::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Todo::summary() const
+{
+    return d->summary;
+}
+
+void Todo::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Todo::description() const
+{
+    return d->description;
+}
+
+void Todo::setPriority(int priority)
+{
+    d->priority = priority;
+}
+
+int Todo::priority() const
+{
+    return d->priority;
+}
+
+void Todo::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Todo::status() const
+{
+    return d->status;
+}
+
+void Todo::setLocation(const std::string &location)
+{
+    d->location = location;
+}
+
+std::string Todo::location() const
+{
+    return d->location;
+}
+
+void Todo::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+    d->rrule = rrule;
+}
+
+RecurrenceRule Todo::recurrenceRule() const
+{
+    return d->rrule;
+}
+
+void Todo::setRecurrenceDates(const std::vector< DateTime > &dates)
+{
+    d->recurrenceDates = dates;
+}
+
+void Todo::addRecurrenceDate(const Kolab::DateTime &dt)
+{
+    d->recurrenceDates.push_back(dt);
+}
+
+std::vector< DateTime > Todo::recurrenceDates() const
+{
+    return d->recurrenceDates;
+}
+
+void Todo::setExceptionDates(const std::vector< DateTime > &dates)
+{
+    d->exceptionDates = dates;
+}
+
+void Todo::addExceptionDate(const Kolab::DateTime &dt)
+{
+    d->exceptionDates.push_back(dt);
+}
+
+std::vector< DateTime > Todo::exceptionDates() const
+{
+    return d->exceptionDates;
+}
+
+void Todo::setOrganizer(const std::string& email, const std::string& name)
+{
+    d->organizerEmail = email;
+    d->organizerName = name;
+}
+
+std::string Todo::organizerEmail() const
+{
+    return d->organizerEmail;
+}
+
+std::string Todo::organizerName() const
+{
+    return d->organizerName;
+}
+
+void Todo::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Todo::attendees() const
+{
+    return d->attendees;
+}
+
+void Todo::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Todo::attachments() const
+{
+    return d->attachments;
+}
+
+void Todo::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Todo::customProperties() const
+{
+    return d->customProperties;
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
new file mode 100644
index 0000000..60c677a
--- /dev/null
+++ b/c++/lib/kolabtodo.h
@@ -0,0 +1,97 @@
+
+
+#ifndef KOLAB_TODO_H
+#define KOLAB_TODO_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+    
+
+class Todo {
+public:
+    Todo();
+    ~Todo();
+    Todo(const Todo &);
+    void operator=(const Todo &);
+    
+    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 setDue(const DateTime &);
+    DateTime due() 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 setPercentComplete(int);
+    int percentComplete() 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++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index f45cc85..463636f 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -98,11 +98,9 @@ void BindingsTest::BenchmarkRoundtrip()
 }
 
 // void BindingsTest::eventCompletness_data()
-
-
-void BindingsTest::eventCompletness()
+template <typename T>
+void setIncidence(T &ev)
 {
-    Kolab::Event 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));
@@ -110,9 +108,7 @@ void BindingsTest::eventCompletness()
     ev.setClassification(Kolab::Confidential);
     ev.addCategory("Category");
     ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
-    ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
-    //TODO duration
-    ev.setTransparency(true);
+    
     Kolab::RecurrenceRule rule;
     rule.setFrequency(Kolab::RecurrenceRule::Daily);
     rule.setCount(5);
@@ -129,12 +125,11 @@ void BindingsTest::eventCompletness()
     //Attendee
     //attach
     //x-prop
-    
-    std::string result = Kolab::writeKolabEvent(ev);
-    std::cout << result << endl;
-    boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
-    const Kolab::Event &re = *e;
-    
+}
+
+template <typename T>
+void checkIncidence(const T &ev, const T &re)
+{
     QCOMPARE(ev.uid(), re.uid());
     QCOMPARE(ev.created(), re.created());
     QCOMPARE(ev.lastModified(), re.lastModified());
@@ -143,8 +138,6 @@ void BindingsTest::eventCompletness()
     QCOMPARE(ev.categories().size(), re.categories().size());
     QCOMPARE(ev.categories().at(0), re.categories().at(0));
     QCOMPARE(ev.start(), re.start());
-    QCOMPARE(ev.end(), re.end());
-    QCOMPARE(ev.transparency(), re.transparency());
     
     const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
     const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
@@ -155,7 +148,6 @@ void BindingsTest::eventCompletness()
     QCOMPARE(r1.count(), r2.count());
     QCOMPARE(r1.end(), r2.end());
     
-//     QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
     QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
     QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));
     QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
@@ -166,6 +158,40 @@ void BindingsTest::eventCompletness()
     QCOMPARE(ev.priority(), re.priority());
     QCOMPARE(ev.status(), re.status());
     QCOMPARE(ev.location(), re.location());
+}
+
+
+
+void BindingsTest::eventCompletness()
+{
+    Kolab::Event ev;
+    setIncidence(ev);
+    ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    //TODO duration
+    ev.setTransparency(true);
+    
+    std::string result = Kolab::writeKolabEvent(ev);
+//     std::cout << result << endl;
+    boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
+    const Kolab::Event &re = *e;
+    checkIncidence(ev, re);
+    QCOMPARE(ev.end(), re.end());
+    QCOMPARE(ev.transparency(), re.transparency());
+    
+}
+
+void BindingsTest::todoCompletness()
+{
+    Kolab::Todo ev;
+    setIncidence(ev);
+    ev.setDue(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    
+    std::string result = Kolab::writeKolabTodo(ev);
+//     std::cout << result << endl;
+    boost::shared_ptr<Kolab::Todo> e = Kolab::readKolabTodo(result, false);
+    const Kolab::Todo &re = *e;
+    checkIncidence(ev, re);
+    QCOMPARE(ev.due(), re.due());
     
 }
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index e9ef0ed..4e6205b 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -16,6 +16,7 @@ class BindingsTest : public QObject
     void roundtripReverseEvent();
     void BenchmarkRoundtrip();
     void eventCompletness();
+    void todoCompletness();
 };
 
 #endif
\ No newline at end of file


commit 0dd6dfbcb04827d23ae229099783b63c6c9baa21
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 10:48:28 2011 +0100

    singleton to share initialization

diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 5476871..40038f4 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -40,6 +40,11 @@ public:
     XMLParserWrapper();
     ~XMLParserWrapper();
     
+    static XMLParserWrapper &inst(){
+        static XMLParserWrapper instance;
+        return instance;
+    };
+    
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
@@ -56,10 +61,6 @@ private:
     xercesc::XMLGrammarPool *gp;
 };
 
-//     static XMLParserWrapper inst(){
-//         static XMLParserWrapper instance;
-//         return instance;
-//     };
 
 #endif
 
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 9234573..796ec9f 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -330,17 +330,15 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
 //         xml_schema::properties props;
         std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
         if (isUrl) {
-            XMLParserWrapper wrapper;
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s);
+            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 {
-            XMLParserWrapper wrapper;
 //             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 = wrapper.parseString(s);
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
             if (doc.get()) {
                 icalendar = icalendar_2_0::icalendar(doc);
             }


commit 01b86d00fab7438cb61561b5c15fd16fb0fc78b5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 10:35:20 2011 +0100

    functions to copy exceptionDates and rDates

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 03d7c55..9234573 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -8,6 +8,7 @@
 #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>
@@ -105,6 +106,26 @@ typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProp
     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;
@@ -175,6 +196,67 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
     }
 }
 
+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
@@ -256,8 +338,8 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
 //             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
             XMLParserWrapper wrapper;
+//             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 = wrapper.parseString(s);
             if (doc.get()) {
                 icalendar = icalendar_2_0::icalendar(doc);
@@ -287,7 +369,6 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
 //                 return event;
 //             }
 //         }
-        
 
         return *incidences.begin();
     } catch  (const xml_schema::exception& e) {
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index c2bd4ee..0e34d4e 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -347,47 +347,14 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
     }
 
     if (prop.rdate()) {
-        const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
-        std::string tzid;
-        if (rdate.parameters()) {
-            tzid = getTimezone(*rdate.parameters());
-        }
-        if (!rdate.date().empty()) {
-            BOOST_FOREACH(const xml_schema::date &d, rdate.date()) {
-                inc.addRecurrenceDate(*DC::toDate(d));
-            }
-        } else if (!rdate.date_time().empty()) {
-            BOOST_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
-                DC::Ptr date = DC::toDate(d);
-                if (tzid.size()) {
-                    date->setTimezone(tzid);
-                }
-                inc.addRecurrenceDate(*date);
-            }
-        } else if (!rdate.period().empty()) {
+        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()) {
-        const icalendar_2_0::KolabEvent::properties_type::exdate_type &exdate = *prop.exdate();
-        std::string tzid;
-        if (exdate.parameters()) {
-            tzid = getTimezone(*exdate.parameters());
-        }
-        if (!exdate.date().empty()) {
-            BOOST_FOREACH(const xml_schema::date &d, exdate.date()) {
-                inc.exceptionDates().push_back(*DC::toDate(d));
-            }
-        } else if (!exdate.date_time().empty()) {
-            BOOST_FOREACH(const xml_schema::date_time &d, exdate.date_time()) {
-                DC::Ptr date = DC::toDate(d);
-                if (tzid.size()) {
-                    date->setTimezone(tzid);
-                }
-                inc.exceptionDates().push_back(*date);
-            }
-        }
+       inc.setExceptionDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
     }
     
     if (prop.recurrence_id()) {
@@ -508,6 +475,7 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     using namespace icalendar_2_0;
     
     typedef T properties; 
+    typedef DateTimeConverter< DateTime> DC;
     
     prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
     
@@ -539,11 +507,11 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     }
     
     if (!inc.recurrenceDates().empty()) {
-        //TODO
+        prop.rdate(fromDateTimeList<KolabTypes, typename properties::rdate_type>(inc.recurrenceDates()));
     }
     
     if (!inc.exceptionDates().empty()) {
-        //TODO
+        prop.exdate(fromDateTimeList<KolabTypes, typename properties::exdate_type>(inc.exceptionDates()));
     }
     
     if (inc.recurrenceID().isValid()) {


commit 1383fb863f5936f5c1343077d29f4da93f96aa4f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 10:34:02 2011 +0100

    With scoped_ptr the order of destruction is wrong

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index aef1b5a..2b1467d 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -27,7 +27,9 @@
 #include "grammar-input-stream.hxx"
 
 XMLParserWrapper::XMLParserWrapper()
-: ehp(eh)
+: ehp(eh),
+    parser(0),
+    gp(0)
 {
     // We need to initialize the Xerces-C++ runtime because we
     // are doing the XML-to-DOM parsing ourselves.
@@ -39,8 +41,10 @@ XMLParserWrapper::XMLParserWrapper()
 
 XMLParserWrapper::~XMLParserWrapper()
 {
-//     xercesc::XMLPlatformUtils::Terminate ();
-//FIXME if this is enabled we get a segfault, maybe because the scope_ptr are note yet destructed?
+    delete parser;
+    delete gp;
+    xercesc::XMLPlatformUtils::Terminate ();
+
 }
 
 
@@ -48,7 +52,7 @@ void XMLParserWrapper::init()
 {
     using namespace std;
     
-    if (parser.get()) {
+    if (parser) {
         return;
     }
     try
@@ -60,7 +64,7 @@ void XMLParserWrapper::init()
         //
         MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
 
-        gp.reset (new XMLGrammarPoolImpl (mm));
+        gp = new XMLGrammarPoolImpl (mm);
 
         try
         {
@@ -92,8 +96,8 @@ void XMLParserWrapper::init()
 
         // Xerces-C++ 3.0.0 and later.
         //
-        parser.reset(impl->createLSParser (
-            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+        parser = impl->createLSParser (
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
 
         DOMConfiguration* conf (parser->getDomConfig ());
 
@@ -157,9 +161,8 @@ void XMLParserWrapper::init()
 
         // Same as above but for Xerces-C++ 2 series.
         //
-        parser.reset (
-        impl->createDOMBuilder(
-            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+        parser = impl->createDOMBuilder(
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
 
 
         parser->setFeature (XMLUni::fgDOMComments, false);
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 8351cf9..5476871 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -49,12 +49,11 @@ private:
     xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
 
     #if _XERCES_VERSION >= 30000
-        boost::scoped_ptr<xercesc::DOMLSParser>  parser;
+        xercesc::DOMLSParser  *parser;
     #else
-        boost::scoped_ptr<xercesc::DOMBuilder>  parser;
+        xercesc::DOMBuilder  *parser;
     #endif
-        
-    boost::scoped_ptr<xercesc::XMLGrammarPool> gp;
+    xercesc::XMLGrammarPool *gp;
 };
 
 //     static XMLParserWrapper inst(){


commit 7e69bd2fb4558891a7e5dd24357c9497dfaeff1e
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 10:19:17 2011 +0100

    initialization

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 289e831..cfd94ad 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -38,7 +38,6 @@ DateTime::DateTime(int year, int month, int day, int hour, int minute, int secon
     d->minute = minute;
     d->second = second;
     d->isUtc = isUtc;
-    std::cout << "utc";
 }
 
 DateTime::DateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
@@ -51,7 +50,6 @@ DateTime::DateTime(const std::string& timezone, int year, int month, int day, in
     d->minute = minute;
     d->second = second;
     d->timezone = timezone;
-    std::cout << "tz";
 }
 
 DateTime::DateTime(int year, int month, int day)
@@ -175,6 +173,12 @@ bool DateTime::isValid() const
 
 struct RecurrenceRule::Private
 {
+    Private()
+    : freq(None),
+    weekstart(Monday),
+    count(-1),
+    interval(1){};
+    
     Frequencey freq;
     Weekday weekstart;
     DateTime end;
@@ -359,7 +363,12 @@ bool RecurrenceRule::isValid() const
 struct Event::Private
 {
     Private()
-    : classification(Public){}
+    : sequence(0),
+    classification(Public),
+    thisAndFuture(false),
+    priority(0),
+    status(UndefinedStatus),
+    isTransparent(false){}
     
     std::string uid;
     DateTime created;


commit eb998ba7db804a8acba2c3dc673925b5010dad27
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 27 10:18:39 2011 +0100

    check recurrence

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index fbd0c3c..f45cc85 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -145,6 +145,16 @@ void BindingsTest::eventCompletness()
     QCOMPARE(ev.start(), re.start());
     QCOMPARE(ev.end(), re.end());
     QCOMPARE(ev.transparency(), re.transparency());
+    
+    const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
+    const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
+    QCOMPARE(r1.isValid(), r2.isValid());
+    QCOMPARE(r1.frequency(), r2.frequency());
+    QCOMPARE(r1.interval(), r2.interval());
+    QCOMPARE(r1.weekStart(), r2.weekStart());
+    QCOMPARE(r1.count(), r2.count());
+    QCOMPARE(r1.end(), r2.end());
+    
 //     QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
     QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
     QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));


commit 9fd4fd76ac3be43174ee3fbcd7469d23f8828d79
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 19:28:15 2011 +0100

    define strings centrally

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index dba9717..03d7c55 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -12,7 +12,20 @@
 #include <fstream>
 #include <iostream>
 
-#define TZ_PREFIX "/kolab.org/"
+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 {
 
@@ -162,6 +175,8 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
     }
 }
 
+
+
 ///trait to convert recurrence properties
 template <typename T>
 struct RecurrenceConverter;
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 333d192..c2bd4ee 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -324,9 +324,9 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
     if (prop.class_()) {
         std::string string(toString(*prop.class_()));
         Kolab::Classification sec = Public;
-        if (string == "PRIVATE") {
+        if (string == PRIVATE) {
             sec = Private;
-        } else if (string == "CONFIDENTIAL") {
+        } else if (string == CONFIDENTIAL) {
             sec = Confidential;
         }
         inc.setClassification(sec);
@@ -410,21 +410,21 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
 
     if (prop.status()) {
         const std::string &status =  toString(*prop.status());
-        if (status == "NEEDS-ACTION") {
+        if (status == NEEDSACTION) {
             inc.setStatus(NeedsAction);
-        } else if (status == "COMPLETED") {
+        } else if (status == COMPLETED) {
             inc.setStatus(Completed);
-        } else if (status == "IN-PROCESS") {
+        } else if (status == INPROCESS) {
             inc.setStatus(InProcess);
-        } else if (status == "CANCELLED") {
+        } else if (status == CANCELLED) {
             inc.setStatus(Cancelled);
-        } else if (status == "TENTATIVE") {
+        } else if (status == TENTATIVE) {
             inc.setStatus(Tentative);
-        } else if (status == "CONFIRMED") {
+        } else if (status == CONFIRMED) {
             inc.setStatus(Confirmed);
-        } else if (status == "DRAFT") {
+        } else if (status == DRAFT) {
             inc.setStatus(Draft);
-        } else if (status == "FINAL") {
+        } else if (status == FINAL) {
             inc.setStatus(Final);
         } else {
             std::cout << "Unhandled status";
@@ -501,6 +501,7 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
     return rruleProp;
 }
 
+
 template <typename T>
 void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
 {
@@ -512,13 +513,13 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     
     switch (inc.classification()) {
         case Kolab::Confidential:
-            prop.class_(typename properties::class_type("CONFIDENTIAL"));
+            prop.class_(typename properties::class_type(CONFIDENTIAL));
             break;
         case Kolab::Private:
-            prop.class_(typename properties::class_type("PRIVATE"));
+            prop.class_(typename properties::class_type(PRIVATE));
             break;
         default:
-            prop.class_(typename properties::class_type("PUBLIC"));
+            prop.class_(typename properties::class_type(PUBLIC));
             break;
     }
     
@@ -565,28 +566,28 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     if (inc.status() != UndefinedStatus) {
         switch (inc.status()) {
             case NeedsAction:
-                prop.status(typename properties::status_type("NEEDS-ACTION"));
+                prop.status(typename properties::status_type(NEEDSACTION));
                 break;
             case Completed:
-                prop.status(typename properties::status_type("COMPLETED"));
+                prop.status(typename properties::status_type(COMPLETED));
                 break;
             case InProcess:
-                prop.status(typename properties::status_type("IN-PROCESS"));
+                prop.status(typename properties::status_type(INPROCESS));
                 break;
             case Cancelled:
-                prop.status(typename properties::status_type("CANCELLED"));
+                prop.status(typename properties::status_type(CANCELLED));
                 break;
             case Tentative:
-                prop.status(typename properties::status_type("TENTATIVE"));
+                prop.status(typename properties::status_type(TENTATIVE));
                 break;
             case Confirmed:
-                prop.status(typename properties::status_type("CONFIRMED"));
+                prop.status(typename properties::status_type(CONFIRMED));
                 break;
             case Draft:
-                prop.status(typename properties::status_type("DRAFT"));
+                prop.status(typename properties::status_type(DRAFT));
                 break;
             case Final:
-                prop.status(typename properties::status_type("FINAL"));
+                prop.status(typename properties::status_type(FINAL));
                 break;
             default:
                 std::cout << "unhandled status " << inc.status() << std::endl;


commit 585c72f015793783bc5daa797acf3c78ee9bc269
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 19:22:42 2011 +0100

    fixed transparency

diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 1a0e41b..333d192 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -527,9 +527,7 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     }
 
     if (inc.start().isValid()) {
-        typename properties::dtstart_type dtstart;
-        setDateTimeProperty<KolabTypes>(dtstart, inc.start());
-        prop.dtstart(dtstart);
+        prop.dtstart(fromDate<KolabTypes, typename properties::dtstart_type>(inc.start()));
     }
     
     if (inc.recurrenceRule().isValid()) {
@@ -548,7 +546,8 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
     }
     
     if (inc.recurrenceID().isValid()) {
-        //TODO
+        //TODO THISANDFUTURE
+        prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
     }
     
     if (!inc.summary().empty()) {
@@ -634,6 +633,9 @@ template <> struct IncidenceConverter < Incidence >
 
 };
 
+const char* const TRANSPARENT = "TRANSPARENT";
+const char* const OPAQUE = "OPAQUE";
+
 template < > struct IncidenceTrait <Kolab::Event>
 {
     typedef typename icalendar_2_0::KolabEvent KolabType;
@@ -648,12 +650,14 @@ template < > struct IncidenceTrait <Kolab::Event>
         getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
 
         if (event.end().isValid()) {
-            icalendar_2_0::properties::dtend_type dtend;
-            setDateTimeProperty<KolabTypes>(dtend, event.end());
-            prop.dtend(dtend);
+            prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties::dtend_type>(event.end()));
         }/* else if (event.duration().isValid()) {
             //TODO
         }*/
+        
+        if (event.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
@@ -681,7 +685,14 @@ template < > struct IncidenceTrait <Kolab::Event>
         //TODO check for equality of timespecs
         
         if (prop.transp()) {
-            //TODO implement
+            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;
+                }
+            }
         }
     }
      


commit 3776922a7b47425f5b9a2f6cac7916c55b9ce5f5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 19:22:26 2011 +0100

    return auto_ptr instead of setProperty function

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 642bd33..dba9717 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -110,6 +110,33 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
     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)


commit 958ec4fb4b14b3b041fb0125f514adfe7ee7dbd2
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 17:55:52 2011 +0100

    serialization code

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 59666a8..642bd33 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -12,7 +12,6 @@
 #include <fstream>
 #include <iostream>
 
-
 #define TZ_PREFIX "/kolab.org/"
 
 namespace Kolab {
@@ -226,7 +225,7 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
         }
         
         if (!icalendar.get()) {
-            std::cerr << "failed to parse calendar!";
+            std::cerr << "failed to parse calendar!" << std::endl;
             return IncidencePtr();
         }
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index a9e1498..32251b0 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -49,6 +49,7 @@ enum Classification {
 };
 
 enum Status {
+    UndefinedStatus,
     NeedsAction,
     Completed,
     InProcess,
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 2f822b7..1a0e41b 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -1,27 +1,6 @@
-// template <> struct DateTimeConverter<DateTime>
-// {
-//     typedef typename boost::shared_ptr<DateTime> Ptr;
-//     Ptr toDate(const  xml_schema::date &dt)
-//     {
-//         Ptr date(new DateTime());
-// 
-//         return date;
-//     }
-//     Ptr toDate(const xml_schema::date_time &dt)
-//     {
-//         Ptr date(new DateTime());
-//         return date;
-//     }
-//     
-//     void setTimezone(Ptr date, const std::string &tzid )
-//     {
-//         date->setTimezone(tzid);
-//     }
-// };
 
 
 #include "conversions.h"
-
 #include "kolabcontainers.h"
 #include <boost/foreach.hpp>
 
@@ -54,11 +33,19 @@ std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
     return ptr;
 }
 
-void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)
+std::string toString(const icalendar_2_0::TextPropertyType &s)
 {
-    p.text(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;
@@ -308,8 +295,17 @@ template <> struct RecurrenceConverter < RecurrenceRule >
 };
 
 
-
-
+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 KolabType, typename T>
@@ -430,6 +426,8 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
             inc.setStatus(Draft);
         } else if (status == "FINAL") {
             inc.setStatus(Final);
+        } else {
+            std::cout << "Unhandled status";
         }
     }
 
@@ -438,27 +436,29 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
     }
     
     if (prop.organizer()) {
-//         icalendar_2_0::KolabEvent::properties_type::organizer();
-//         inc.
-//         KCalCore::Person person;
+        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>
-xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const std::vector<int> &input) {
+T fromList(const std::vector<int> &input) {
+    T list;
     BOOST_FOREACH(int i, list) {
         list.push_back(convertToInt<I>(i));
     }
@@ -493,9 +493,11 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
     }
     
     if (!r.bysecond().empty()) {
-        RecurType::bysecond_sequence bysecond;
-        recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bysecond()));
+        recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
     }
+    
+    //TODO remainting by rules
+    
     return rruleProp;
 }
 
@@ -504,22 +506,28 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
 {
     using namespace icalendar_2_0;
     
+    typedef T properties; 
+    
     prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
     
     switch (inc.classification()) {
         case Kolab::Confidential:
-            prop.class_(properties::class_type("CONFIDENTIAL"));
+            prop.class_(typename properties::class_type("CONFIDENTIAL"));
             break;
         case Kolab::Private:
-            prop.class_(properties::class_type("PRIVATE"));
+            prop.class_(typename properties::class_type("PRIVATE"));
             break;
         default:
-            prop.class_(properties::class_type("PUBLIC"));
+            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()) {
-        properties::dtstart_type dtstart;
+        typename properties::dtstart_type dtstart;
         setDateTimeProperty<KolabTypes>(dtstart, inc.start());
         prop.dtstart(dtstart);
     }
@@ -531,6 +539,82 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
         //TODO check if startdate matches the one of the event (it MUST)
     }
     
+    if (!inc.recurrenceDates().empty()) {
+        //TODO
+    }
+    
+    if (!inc.exceptionDates().empty()) {
+        //TODO
+    }
+    
+    if (inc.recurrenceID().isValid()) {
+        //TODO
+    }
+    
+    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("NEEDS-ACTION"));
+                break;
+            case Completed:
+                prop.status(typename properties::status_type("COMPLETED"));
+                break;
+            case InProcess:
+                prop.status(typename properties::status_type("IN-PROCESS"));
+                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 <> struct IncidenceConverter < Incidence >
@@ -568,7 +652,7 @@ template < > struct IncidenceTrait <Kolab::Event>
             setDateTimeProperty<KolabTypes>(dtend, event.end());
             prop.dtend(dtend);
         }/* else if (event.duration().isValid()) {
-            
+            //TODO
         }*/
     }
     
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 3a6e33a..fbd0c3c 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -97,6 +97,69 @@ void BindingsTest::BenchmarkRoundtrip()
     }
 }
 
+// void BindingsTest::eventCompletness_data()
+
+
+void BindingsTest::eventCompletness()
+{
+    Kolab::Event 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");
+    ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+    ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    //TODO duration
+    ev.setTransparency(true);
+    Kolab::RecurrenceRule rule;
+    rule.setFrequency(Kolab::RecurrenceRule::Daily);
+    rule.setCount(5);
+    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.setSummary("summary");
+    ev.setDescription("description");
+    ev.setPriority(3);
+    ev.setStatus(Kolab::Confirmed);
+    ev.setLocation("location");
+    ev.setOrganizer("email","organizer");
+    //Attendee
+    //attach
+    //x-prop
+    
+    std::string result = Kolab::writeKolabEvent(ev);
+    std::cout << result << endl;
+    boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
+    const Kolab::Event &re = *e;
+    
+    QCOMPARE(ev.uid(), re.uid());
+    QCOMPARE(ev.created(), re.created());
+    QCOMPARE(ev.lastModified(), re.lastModified());
+    QCOMPARE(ev.sequence(), re.sequence());
+    QCOMPARE(ev.classification(), re.classification());
+    QCOMPARE(ev.categories().size(), re.categories().size());
+    QCOMPARE(ev.categories().at(0), re.categories().at(0));
+    QCOMPARE(ev.start(), re.start());
+    QCOMPARE(ev.end(), re.end());
+    QCOMPARE(ev.transparency(), re.transparency());
+//     QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
+    QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
+    QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));
+    QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
+    QCOMPARE(ev.exceptionDates().at(0), re.exceptionDates().at(0));
+    QCOMPARE(ev.recurrenceID(), re.recurrenceID());
+    QCOMPARE(ev.summary(), re.summary());
+    QCOMPARE(ev.description(), re.description());
+    QCOMPARE(ev.priority(), re.priority());
+    QCOMPARE(ev.status(), re.status());
+    QCOMPARE(ev.location(), re.location());
+    
+}
+
+
 
 QTEST_MAIN( BindingsTest )
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 8fa93bc..e9ef0ed 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -15,6 +15,7 @@ class BindingsTest : public QObject
     void roundtripEvent();
     void roundtripReverseEvent();
     void BenchmarkRoundtrip();
+    void eventCompletness();
 };
 
 #endif
\ No newline at end of file


commit af9d9ff9b72961c8e4709e31370830773cab6070
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 17:54:51 2011 +0100

    use back_inserter

diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 4634636..2f822b7 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -42,16 +42,16 @@ struct KolabTypes
 std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
 {
     std::vector<std::string> d;
-    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-        d.push_back(*it);
-    }
+    std::copy(s.text().begin(), s.text().end(), std::back_inserter(d));
     return d;
 }
 
-std::string toString(const icalendar_2_0::TextPropertyType &s)
+template <typename T>
+std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
 {
-    return s.text();
+    std::auto_ptr<T> ptr(new T());
+    std::copy(list.begin(), list.end(), std::back_inserter(ptr->text()));
+    return ptr;
 }
 
 void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)


commit 1f014ddc157718799091d128df444fb9ad1cf6db
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 26 17:53:56 2011 +0100

    Don't pass around pointers of local objects

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 4ac45fe..aef1b5a 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -27,6 +27,7 @@
 #include "grammar-input-stream.hxx"
 
 XMLParserWrapper::XMLParserWrapper()
+: ehp(eh)
 {
     // We need to initialize the Xerces-C++ runtime because we
     // are doing the XML-to-DOM parsing ourselves.
@@ -149,7 +150,7 @@ void XMLParserWrapper::init()
         // Set error handler.
         //
 //         tree::error_handler<char> eh;
-        xml::dom::bits::error_handler_proxy<char> ehp (eh);
+//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
         conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
 
     #else // _XERCES_VERSION >= 30000
@@ -173,7 +174,7 @@ void XMLParserWrapper::init()
         parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
 
         //tree::error_handler<char> eh;
-        xml::dom::bits::error_handler_proxy<char> ehp (eh);
+//         xml::dom::bits::error_handler_proxy<char> ehp (eh);
         parser->setErrorHandler (&ehp);
 
     #endif // _XERCES_VERSION >= 30000
@@ -208,7 +209,7 @@ xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parse
 xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
 {
     std::istringstream is(s);
-    return parse(is, "");
+    return parse(is, ""); //TODO set identifier?
 }
 
 
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index a416097..8351cf9 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -6,6 +6,7 @@
 #include <bindings/kolabformat-xcal.hxx>
 #include <xsd/cxx/tree/error-handler.hxx>
 #include <boost/scoped_ptr.hpp>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
 
 #if _XERCES_VERSION >= 30000
 #  include <xercesc/dom/DOMLSParser.hpp>
@@ -38,15 +39,15 @@ class XMLParserWrapper {
 public:
     XMLParserWrapper();
     ~XMLParserWrapper();
-
+    
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
     xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
 private:
     void init();
-    
     xsd::cxx::tree::error_handler<char> eh;
-    
+    xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
+
     #if _XERCES_VERSION >= 30000
         boost::scoped_ptr<xercesc::DOMLSParser>  parser;
     #else


commit 513176c5d03333010beb4f556c36bf9c99971e96
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 18:23:44 2011 +0100

    comments

diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 643b61e..a416097 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -21,6 +21,19 @@
 #  include <xercesc/internal/XMLGrammarPool.hpp>
 #endif
 
+/**
+ * This wrapper controls the lifetime of the parser object.
+ * 
+ * Initializing the parser is much more expensive than parsing a single XML document, therefore the parser should be reused if possible.
+ * 
+ * It might make sense to use a singleton internally to keep the parser alive between usages. Alternatively this object can be kept alive for as long as it makes sense.
+ * 
+ * This class also encapsulates the initialization of the whole parser, which must be done manually because precomiled schemas are used (which greatly improves the initialization performance).
+ * 
+ * Writing the document is static and doesn't need any initialization and is therefore not wrapped by this object.
+ * 
+ */
+
 class XMLParserWrapper {
 public:
     XMLParserWrapper();


commit fb047d2cab523de8e8fcfdade7e1101cbe55995f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 18:23:25 2011 +0100

    recompile if interface changed

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 9ab88fc..ebce0f6 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -5,7 +5,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
     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
+    DEPENDS kolabformat.i  kolabcontainers.h
     VERBATIM
     )
 
@@ -18,7 +18,7 @@ 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
+    DEPENDS kolabformat.i kolabcontainers.h
     VERBATIM
     )
 SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)


commit fc1d2a09fb5ed9e7f614ca53d7a5acd19f95ea36
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 18:23:15 2011 +0100

    remaining event setters/getters

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 32e9dd9..289e831 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -377,9 +377,17 @@ struct Event::Private
     int priority;
     Status status;
     std::string location;
+    bool isTransparent;
     RecurrenceRule rrule;
     std::vector< DateTime > recurrenceDates;
     std::vector< DateTime > exceptionDates;
+    std::string organizerEmail;
+    std::string organizerName;
+    Duration duration;
+    
+    std::vector<Attendee> attendees;
+    std::vector<Attachment> attachments;
+    std::vector<CustomProperty> customProperties;
 };
 
 Event::Event()
@@ -484,6 +492,17 @@ 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;
@@ -590,10 +609,61 @@ 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 118c597..a9e1498 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -62,6 +62,7 @@ enum Status {
 struct DayPos
 {
     void operator=(const DayPos &){};
+    //TODO
 };
     
 
@@ -141,6 +142,10 @@ private:
     boost::scoped_ptr<Private> d;
 };
 
+class Duration {
+    //TODO
+};
+
 class Attendee {
     //TODO
 };
@@ -185,11 +190,11 @@ public:
     void setEnd(const DateTime &);
     DateTime end() const;
     
-    void setDuration(int){}; //TODO duration type
-    int duration() const{};
+    void setDuration(const Duration &);
+    Duration duration() const;
     
-    void setTransparency(bool isTransparent){};
-    bool transparency() const{};
+    void setTransparency(bool isTransparent);
+    bool transparency() const;
     
     void setRecurrenceRule(const RecurrenceRule &);
     RecurrenceRule recurrenceRule() const;
@@ -221,18 +226,18 @@ public:
     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 setOrganizer(const std::string &email, const std::string &name);
+    std::string organizerEmail() const;
+    std::string organizerName() const;
     
-    void setAttendee(const std::vector<Attendee> &){};
-    std::vector<Attendee> attendee() const{};
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
     
-    void setAttachment(const std::vector<Attachment> &){};
-    std::vector<Attachment> attachments() const {};
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
     
-    void setCustomProperty(const std::vector<CustomProperty> &){};
-    std::vector<CustomProperty> customProperties() const{};
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
 private:
     struct Private;
     boost::scoped_ptr<Private> d;


commit 503c7d9b22f74b190211a3f25824b3e035020e37
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 17:33:25 2011 +0100

    fixed php bindings compilation

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index eddd649..9ab88fc 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -38,13 +38,13 @@ SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
 
-
-
 #PHP
-#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
-# find_package(PHP4)
-# include_directories(${PHP4_INCLUDE_PATH})
-# add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
-# # ADD_DEPENDENCIES(bindings generate_python_bindings)
-# SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-# SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+# set( PHP_INCLUDES "`php-config --includes`")
+set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${PHP_INCLUDES} )
+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)
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")


commit a1ddd3cedf6fa73ef753ac2300743f3370cc401d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 17:32:59 2011 +0100

    testfiles for reference

diff --git a/c++/lib/test.php b/c++/lib/test.php
new file mode 100644
index 0000000..d477c46
--- /dev/null
+++ b/c++/lib/test.php
@@ -0,0 +1,16 @@
+//run using "php -d enable_dl=On -d extension=./kolabformat.so  test.php"
+
+<?php
+include("kolabformat.php");
+
+$e = new Event();
+$d = new c_DateTime(1,1,1);
+print $e->exceptionDates()->size();
+$e->addExceptionDate( $d);
+print $e->exceptionDates()->size();
+
+?>
+
+
+
+
diff --git a/c++/lib/test.py b/c++/lib/test.py
new file mode 100644
index 0000000..821bc94
--- /dev/null
+++ b/c++/lib/test.py
@@ -0,0 +1,10 @@
+import kolabformat
+e = kolabformat.Event()
+
+ex = e.exceptionDates()
+ex.size()
+ex.push_back(kolabformat.DateTime(1,1,1))
+ex.size()
+e.exceptionDates().size()
+e.setExceptionDates(ex)
+e.exceptionDates().size()


commit 723c24a853e384e1cfeeff8bcd12163b9733f8b7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 17:32:27 2011 +0100

    check pointers

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index bcb81f6..59666a8 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -204,22 +204,23 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
     typedef typename T::KolabType KolabType;
     
     try {
-        //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
-        xml_schema::properties props;
-
+//         xml_schema::properties props;
         std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
         if (isUrl) {
-            std::cout << "open file " << s;
             XMLParserWrapper wrapper;
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s); 
-            icalendar = icalendar_2_0::icalendar(doc);
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.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
+//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
             XMLParserWrapper wrapper;
             xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
-            icalendar = icalendar_2_0::icalendar(doc);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
 //             icalendar = readCompiledIncidence(is, "string");
 //             icalendar = icalendar_2_0::icalendar(is, 0, props);
         }


commit 1361ff6aed4e1639e18b9997271a7e1a2d26a623
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 16:43:11 2011 +0100

    fix python bindings

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index c058719..22e1947 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -65,7 +65,9 @@ ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
 include_directories( ./ )
 include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
-add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+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 compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml xerces-c)
 
 add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 58086b0..eddd649 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -1,14 +1,4 @@
 
-# add_custom_command(OUTPUT qt_wrap.c
-#     COMMAND swig -c++ -python -I$QTPATH/include  qt.i
-#     COMMENT "Generating qt python bindings"
-#     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-#     DEPENDS qt.i
-#     VERBATIM
-#     )
-
-
-set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h) 
 
 set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
@@ -18,14 +8,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
     DEPENDS kolabformat.i
     VERBATIM
     )
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp
-    COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp kolabcontainers.i
-    COMMENT "Generating python bindings"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS kolabcontainers.i
-    VERBATIM
-    )
-set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${KOLAB_SWIG_PYTHON_SOURCE_FILE} python_kolabcontainers_wrapper.cpp) 
+
 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})
 
@@ -48,18 +31,20 @@ include_directories( ./ )
 #PYTHON
 find_package(PythonLibs)
 include_directories(${PYTHON_INCLUDE_DIRS})
-add_library(pythonbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${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)
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
 
 
+
 #PHP
 #set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
-find_package(PHP4)
-include_directories(${PHP4_INCLUDE_PATH})
-add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+# find_package(PHP4)
+# include_directories(${PHP4_INCLUDE_PATH})
+# add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
+# # ADD_DEPENDENCIES(bindings generate_python_bindings)
+# SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+# SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
new file mode 100644
index 0000000..fe61d7d
--- /dev/null
+++ b/c++/lib/DEVELOPMENT
@@ -0,0 +1,13 @@
+
+
+== Kolab Containers ==
+
+While SWIG can handle all possible return values, the resulting code uses either a newly allocated object (return by value / or return by const reference), or passes back a pointer (return by reference/pointer).
+So return by const reference doesn't save anything for the bindings (it could potentially for c++ code).
+Returning references contains the danger of dangling pointers if the reference outlives the object.
+
+Datamembers are not directly exposed to provide binary compatibilty through the d-pointer.
+
+Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value).
+
+Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 973048c..32e9dd9 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -295,12 +295,12 @@ std::vector< int > RecurrenceRule::byhour() const
     return d->byhour;
 }
 
-void RecurrenceRule::setByday(const std::vector< RecurrenceRule::DayPos > &by)
+void RecurrenceRule::setByday(const std::vector< DayPos > &by)
 {
     d->byday = by;
 }
 
-std::vector< RecurrenceRule::DayPos > RecurrenceRule::byday() const
+std::vector< DayPos > RecurrenceRule::byday() const
 {
     return d->byday;
 }
@@ -378,6 +378,8 @@ struct Event::Private
     Status status;
     std::string location;
     RecurrenceRule rrule;
+    std::vector< DateTime > recurrenceDates;
+    std::vector< DateTime > exceptionDates;
 };
 
 Event::Event()
@@ -386,6 +388,12 @@ Event::Event()
     
 }
 
+Event::Event(const Event &other)
+: d(new Event::Private())
+{
+    *d = *other.d;
+}
+
 Event::~Event()
 {
     
@@ -552,6 +560,40 @@ 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;
+}
+
+
+
+
+
 
 
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 7b11638..118c597 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -4,6 +4,7 @@
 #include <vector>
 #include <boost/scoped_ptr.hpp>
 
+
 namespace Kolab {
 
 class DateTime {
@@ -58,6 +59,12 @@ enum Status {
     Final
 };
 
+struct DayPos
+{
+    void operator=(const DayPos &){};
+};
+    
+
 class RecurrenceRule {
 public:
     
@@ -112,11 +119,6 @@ public:
     void setByhour(const std::vector<int> &);
     std::vector<int> byhour() const;
     
-    struct DayPos
-    {
-        void operator=(const DayPos &){};
-    };
-    
     void setByday(const std::vector<DayPos> &);
     std::vector<DayPos> byday() const;
     
@@ -183,19 +185,21 @@ public:
     void setEnd(const DateTime &);
     DateTime end() const;
     
-    void setDuration(int); //TODO duration type
-    int duration() const;
+    void setDuration(int){}; //TODO duration type
+    int duration() const{};
     
-    void setTransparency(bool isTransparent);
-    bool transparency() const;
+    void setTransparency(bool isTransparent){};
+    bool transparency() const{};
     
     void setRecurrenceRule(const RecurrenceRule &);
     RecurrenceRule recurrenceRule() const;
     
-    void setRecrrenceDates(const std::vector<DateTime> &);
+    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);
@@ -217,18 +221,18 @@ public:
     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 setOrganizer(const std::string &email, const std::string &name){};
+    std::string organizerEmail() const{};
+    std::string organizerName() const{};
     
-    void setAttendee(const std::vector<Attendee> &);
-    std::vector<Attendee> attendee() const;
+    void setAttendee(const std::vector<Attendee> &){};
+    std::vector<Attendee> attendee() const{};
     
-    void setAttachment(const std::vector<Attachment> &);
-    std::vector<Attachment> attachments() const;
+    void setAttachment(const std::vector<Attachment> &){};
+    std::vector<Attachment> attachments() const {};
     
-    void setCustomProperty(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
+    void setCustomProperty(const std::vector<CustomProperty> &){};
+    std::vector<CustomProperty> customProperties() const{};
 private:
     struct Private;
     boost::scoped_ptr<Private> d;
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 220e520..4634636 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -181,6 +181,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
             default:
                 std::cout << "invalid unhandled recurrenc type";
         }
+        return 0;
     }
     
     static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
@@ -258,7 +259,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
     
     static void setByday(Ptr r, const icalendar_2_0::RecurType::byday_sequence &list)
     {
-        std::vector<RecurrenceRule::DayPos> by;
+        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 () {
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index 3024baf..b4dd3f9 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -1,15 +1,26 @@
 /* kolabformat.i */
- %module kolabformat
- %{
- /* Put header files here or function declarations like below */
- #include "kolabformat.h"
- %}
-%include "std_string.i"
+%module kolabformat
+%{
 
-/*%apply const std::string& {std::string* foo};*/
-namespace Kolab {
+    /* This macro ensures that return vectors remain a vector also in python and are note converted to tuples */
+    #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
 
+    /* Put header files here or function declarations like below */
+    #include "kolabformat.h"
+    #include "kolabcontainers.h"
 
-}
+%}
+
+%include "std_string.i"
+%include "std_vector.i"
+
+namespace std {
+    %template(vectori) vector<int>;
+    %template(vectors) vector<string>;
+    %template(vectordate) vector<Kolab::DateTime>;
+    %template(vectordaypos) vector<Kolab::DayPos>;
+};
+
+/*%apply const std::string& {std::string* foo};*/
 
-/*extern void readEvent(const QString &string, KCalCore::Event &); */
+%include "kolabcontainers.h"


commit 297bc90c6b42c3edf3685d7b427a51bf62b0a21d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 16:41:35 2011 +0100

    implement rdate /exdate parsing

diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 98391e3..220e520 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -348,36 +348,51 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
        KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
        inc.setRecurrenceRule(*rrule);
     }
-//     
-//     if (prop.rdate()) {
-//         const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
-//         std::string tzid;
-//         if (rdate.parameters()) {
-//             tzid = getTimezone(*rdate.parameters());
-//         }
-//         if (rdate.date().size()) {
-//             Q_FOREACH(const xml_schema::date &d, rdate.date()) {
-//                 recurrence->addRDate(DC::toDate(d)->date());
-//             }
-//         } else if (rdate.date_time().size()) {
-//             Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
-//             DC::Ptr date = DC::toDate(d);
-//             if (tzid.size()) {
-//                 DC::setTimezone(date, tzid);
-//             }
-//             recurrence->addRDateTime(*date);
-//         }
-//         } else if (rdate.period().size()) {
-//             kDebug() << "the period element must not be used, ignored.";
-//         }
-//     }
-//     
-//     if (prop.exdate()) {
-//         //TODO
-// //         recurrence->addExDate();
-// //         recurrence->addExDateTime();
-//     }
-//     
+
+    if (prop.rdate()) {
+        const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+        std::string tzid;
+        if (rdate.parameters()) {
+            tzid = getTimezone(*rdate.parameters());
+        }
+        if (!rdate.date().empty()) {
+            BOOST_FOREACH(const xml_schema::date &d, rdate.date()) {
+                inc.addRecurrenceDate(*DC::toDate(d));
+            }
+        } else if (!rdate.date_time().empty()) {
+            BOOST_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+                DC::Ptr date = DC::toDate(d);
+                if (tzid.size()) {
+                    date->setTimezone(tzid);
+                }
+                inc.addRecurrenceDate(*date);
+            }
+        } else if (!rdate.period().empty()) {
+            std::cout << "the period element must not be used, ignored." << std::endl;
+        }
+    }
+    
+    if (prop.exdate()) {
+        const icalendar_2_0::KolabEvent::properties_type::exdate_type &exdate = *prop.exdate();
+        std::string tzid;
+        if (exdate.parameters()) {
+            tzid = getTimezone(*exdate.parameters());
+        }
+        if (!exdate.date().empty()) {
+            BOOST_FOREACH(const xml_schema::date &d, exdate.date()) {
+                inc.exceptionDates().push_back(*DC::toDate(d));
+            }
+        } else if (!exdate.date_time().empty()) {
+            BOOST_FOREACH(const xml_schema::date_time &d, exdate.date_time()) {
+                DC::Ptr date = DC::toDate(d);
+                if (tzid.size()) {
+                    date->setTimezone(tzid);
+                }
+                inc.exceptionDates().push_back(*date);
+            }
+        }
+    }
+    
     if (prop.recurrence_id()) {
         //TODO THISANDFUTURE range
         bool thisandfuture = true;


commit 2d1862ad6dcf6e4837a5acfeb0227030b986781b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 16:41:08 2011 +0100

    update testfile to not use unsupported properties

diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 8f6d8c7..1c72be8 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -40,15 +40,16 @@
                  <count>5</count>
                </recur>
              </rrule>
-<!--             <rdate>
+             <rdate>
                <parameters>
-                 <tzid><text>US/Eastern</text></tzid>
+                 <tzid><text>/kolab.org/US/Eastern</text></tzid>
                </parameters>
-               <period>
+               <date-time>2007-02-06T00:11:21</date-time>
+       <!--        <period>
                  <start>2006-01-02T15:00:00</start>
                  <duration>PT2H</duration>
-               </period>
-             </rdate>-->
+               </period>-->
+             </rdate>
              <summary>
                <text>Event #2</text>
              </summary>


commit 9ba5c27e57caa2f249cf0b3a4e91dee12a4dfd68
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 16:40:51 2011 +0100

    fix testfile position for out of source build

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 7b7e75e..3a6e33a 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -39,7 +39,7 @@ namespace QTest {
 
 void BindingsTest::readEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../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));
@@ -81,7 +81,7 @@ void BindingsTest::roundtripEvent()
 
 void BindingsTest::roundtripReverseEvent()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
     kDebug() << "-------------------";
     std::cout << Kolab::writeKolabEvent(*event) << std::endl;
     kDebug() << "-------------------";
@@ -89,7 +89,7 @@ void BindingsTest::roundtripReverseEvent()
 
 void BindingsTest::BenchmarkRoundtrip()
 {
-    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
     std::string result;
     QBENCHMARK {
         result = Kolab::writeKolabEvent(*event);


commit 409bb56ef87f137608a252921cbf7787ded70e81
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 11:45:42 2011 +0100

    handle exceptions, initialize only once

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 43fe477..4ac45fe 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -46,7 +46,10 @@ XMLParserWrapper::~XMLParserWrapper()
 void XMLParserWrapper::init()
 {
     using namespace std;
-
+    
+    if (parser.get()) {
+        return;
+    }
     try
     {
         using namespace xercesc;
@@ -179,13 +182,10 @@ void XMLParserWrapper::init()
         //
         
     }
-    catch (const xml_schema::exception& e)
-    {
+    catch (const xml_schema::exception& e) {
         cout << "schema exception" << endl;
         cerr << e << endl;
-    }
-    catch (const std::ios_base::failure&)
-    {
+    } catch (const std::ios_base::failure&) {
         cerr << ": unable to open or read failure" << endl;
     }
     
@@ -193,10 +193,16 @@ void XMLParserWrapper::init()
 
 xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
 {
-    std::ifstream ifs;
-    ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
-    ifs.open (url.c_str());
-    return parse(ifs, url);
+    try {
+        std::ifstream ifs;
+        ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
+        ifs.open (url.c_str());
+        return parse(ifs, url);
+    } catch (const std::ios_base::failure&)
+    {
+        std::cerr << ": unable to open or read failure" << std::endl;
+    }
+    return xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument >();
 }
 
 xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)


commit 3f17f9f70979f227b84debac0eaf0ba43f766227
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 11:35:49 2011 +0100

    build directory to gitignore

diff --git a/c++/.gitignore b/c++/.gitignore
index 51ea4cc..a007fea 100644
--- a/c++/.gitignore
+++ b/c++/.gitignore
@@ -1 +1 @@
-bindings/*
+build/*


commit 97ba08fe7c778946e85204d8d25b5412daa6e38b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 11:35:13 2011 +0100

    fix compile

diff --git a/schemas/kolabformat.xsd b/schemas/kolabformat.xsd
index f780c2a..33d85c4 100644
--- a/schemas/kolabformat.xsd
+++ b/schemas/kolabformat.xsd
@@ -6,8 +6,8 @@
     xmlns="http://kolab.org"
     elementFormDefault="qualified">
 
-    <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
-    <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+<!--    <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+    <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>-->
     
     
     <xs:complexType name="KolabBase">
@@ -37,7 +37,7 @@
         </xs:complexContent>
     </xs:complexType>-->
     
-    <xs:element name="note" type="Note"/>
+<!--    <xs:element name="note" type="Note"/>
     <xs:complexType name="Note">
         <xs:complexContent mixed="false">
             <xs:extension base="KolabBase">
@@ -46,7 +46,7 @@
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
-    </xs:complexType>
+    </xs:complexType>-->
     
 <!--    <xs:element name="contact" type="Contact"/>
     <xs:complexType name="Contact">


commit c57363b0a795c5a730f3f2382a80bbcaeaef33e0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 11:35:01 2011 +0100

    out of source build

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 64e4c12..c058719 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -8,8 +8,8 @@ include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
 set(CMAKE_BUILD_TYPE Debug)
 
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
-
-file(MAKE_DIRECTORY bindings)
+set(CMAKE_BUILD_DIR build)
+file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
 
 set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
 set( XSDCXX  /usr/bin/xsdcxx)
@@ -37,7 +37,7 @@ set( SCHEMA_SOURCEFILES
 # --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 bindings ${SCHEMAS}
+    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}
     COMMENT "Generating XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS}
@@ -48,22 +48,22 @@ add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
 add_executable(xsdbin compiled/xsdbin.cxx)
 target_link_libraries(xsdbin xerces-c)
 
-add_custom_command(OUTPUT compiled/kolabformat-xcal-schema.cxx
-    COMMAND ${xsdbin} ./xsdbin --verbose --array-name iCalendar_schema --output-dir compiled/   ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+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
     COMMENT "Compiling Kolab XSD schema"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS} xsdbin
     VERBATIM
     )
-set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} compiled/kolabformat-xcal-schema.cxx)
+set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BUILD_DIR}/kolabformat-xcal-schema.cxx)
 
 # ---------
 
 SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
-
 ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
 
 include_directories( ./ )
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
 add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml xerces-c)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 9804106..58086b0 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,18 +7,19 @@
 #     VERBATIM
 #     )
 
+
 set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h) 
 
 set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
-add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
-    COMMAND swig -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
+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
     VERBATIM
     )
-add_custom_command(OUTPUT python_kolabcontainers_wrapper.cpp
-    COMMAND swig -v -c++ -python -o python_kolabcontainers_wrapper.cpp kolabcontainers.i
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp
+    COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp kolabcontainers.i
     COMMENT "Generating python bindings"
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     DEPENDS kolabcontainers.i
@@ -30,8 +31,8 @@ ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURC
 
 
 set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) 
-add_custom_command(OUTPUT ${KOLAB_SWIG_PHP_SOURCE_FILE}
-    COMMAND swig -v -c++ -php -o ${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
+    COMMAND swig -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
     COMMENT "Generating php bindings"
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     DEPENDS kolabformat.i
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index a922628..822015d 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,5 +1,5 @@
 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)
@@ -8,7 +8,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 
 #QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
 QT4_AUTOMOC(bindingstest.cpp)
-add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
+add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
 target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
 
 # QT4_AUTOMOC(kcalconversiontest.cpp)


commit e84d3476e911fab9d413fa25de74b5c99a2cfc79
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 10:16:25 2011 +0100

    removed some old unused testcode

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 4a2d369..7b7e75e 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -3,8 +3,6 @@
 #include <QObject>
 #include <QtTest/QtTest>
 
-#include "bindings/note.hxx"
-#include "bindings/iCalendar.hxx"
 #include "bindings/iCalendar-props.hxx"
 #include "bindings/iCalendar-valtypes.hxx"
 #include "bindings/kolabformat.hxx"
@@ -13,324 +11,10 @@
 
 #include <xercesc/dom/DOMException.hpp>
 #include <xercesc/dom/DOMImplementation.hpp>
-#include <bindings/contact.hxx>
-#include <kcalcore/event.h>
 #include <lib/kolabformat.h>
 #include <kdebug.h>
 
 
-// void BindingsTest::writeNoteTest()
-// {
-//     xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
-//     KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
-//     KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
-//     KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
-//     KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-// 
-//     xml_schema::namespace_infomap map;
-//     map[""].name = "http://kolab.org";
-//     map[""].schema = "note.xsd";
-// 
-//     KolabXSD_test::note (std::cout, note, map);
-// 
-//   /*  QFETCH(KCalCore::Recurrence, kcalrecurrence);
-//     
-//     KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
-//     QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
-//     */
-// }
-
-// void BindingsTest::readNoteTest()
-// {
-//     try {
-//         xml_schema::properties props;
-// //         props.no_namespace_schema_location ("../../schemas/note.xsd");
-// //         props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
-//         std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
-//         
-//         xml_schema::namespace_infomap map;
-//         map[""].name = "http://kolab.org";
-//         map[""].schema = "note.xsd";
-// 
-//         KolabXSD_test::note (std::cout, *note, map);
-//     } catch  (const xml_schema::exception& e) {
-//         std::cout << e << endl;
-//         QVERIFY(false);
-//     } 
-// }
-// 
-// void BindingsTest::writeReadNoteTest()
-// {
-// 
-// }
-// 
-// void BindingsTest::writeKolabXCalEvent()
-// {
-// //     try {
-// //     //Components
-// //     icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-// // 
-// //     icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-// //     component.valarm().push_back(alarm);
-// // 
-// //     //Properties
-// // 
-// //     //Recurrence
-// //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// //     recur.count(2);
-// //     recur.byhour().push_back("3");
-// //     icalendar_2_0::RrulePropType rrule(recur);
-// // 
-// //     //Startdate
-// //     xml_schema::date_time dt(2011,8,12,2,12,15);
-// //     icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
-// //     icalendar_2_0::DtstartPropType startdate;
-// //     startdate.date_time(datetime);
-// //     //Startdate timezone
-// //     ::icalendar_2_0::ArrayOfParameters parameters;
-// //     ::icalendar_2_0::TzidParamType tzid("US/Eastern");
-// //     parameters.baseParameter().push_back(tzid);
-// //     startdate.parameters(parameters);
-// //     
-// //     
-// //     //Custom value
-// //     KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-// // 
-// //     //Assembling event properties
-// //     ::icalendar_2_0::ArrayOfProperties properties;
-// //     properties.baseProperty().push_back(startdate);
-// //     properties.baseProperty().push_back(rrule);
-// //     properties.baseProperty().push_back(custom);
-// // 
-// //     //Assembling the complete event
-// //     icalendar_2_0::VeventType event(component);
-// //     event.properties(properties);
-// //     
-// //     KolabXSD::Event kolabEvent(event);
-// //     xml_schema::namespace_infomap map;
-// //     map["kolab"].name = "http://kolab.org";
-// //     map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// //     //map["xcal"].schema = "iCalendar.xsd";
-// // 
-// //     KolabXSD::event (std::cout, kolabEvent, map);
-// //     
-// //             
-// // //     icalendar_2_0::VstrictTodoType todo;
-// // //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// // //     todo.rrule().;
-// //     
-// //     } catch  (const xml_schema::exception& e) {
-// //         std::cout << e << endl;
-// //         QVERIFY(false);
-// //     } 
-// }
-// 
-// 
-// void BindingsTest::readKolabXCalEvent()
-// {
-// //     try {
-// // //         xml_schema::properties props;
-// // //         props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-// // //         props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-// // //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
-// // 
-// //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-// //         
-// //         const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
-// //         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-// // 
-// //         /*for(int i = 0; i < propertyList.size(); i++) {
-// //             const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-// //         }*/
-// //         std::cout << propertyList.size() << std::endl;
-// //         for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
-// //             if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
-// //                 std::cout << "Rrule" << std::endl;
-// //                 std::cout << d->recur().freq() << std::endl;
-// //                 std::cout << d->recur().count() << std::endl;
-// //                 //std::cout << d->recur().byhour() << std::endl;
-// //             } else {
-// //                 std::cout << "other" << std::endl;
-// //                 const icalendar_2_0::BasePropertyType &baseProperty = (*i);
-// //             }
-// //         }
-// //         
-// //         xml_schema::namespace_infomap map;
-// //         map["kolab"].name = "http://kolab.org";
-// // //         map[""].schema = "kolabevent.xsd";
-// //         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// // //         map["xcal"].schema = "iCalendar.xsd";
-// // 
-// //         KolabXSD::event (std::cout, *event, map);
-// // 
-// //     } catch  (const xml_schema::exception& e) {
-// //         std::cout << e << std::endl;
-// //         QVERIFY(false);
-// //     } 
-// }
-// 
-// #if 0
-// void BindingsTest::writeXCalEvent()
-// {
-//     try {
-//     //Components
-//     icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-// 
-//     icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-//     component.valarm().push_back(alarm);
-// 
-//     //Properties
-// 
-//     //Recurrence
-//     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-//     recur.count(2);
-//     recur.byhour().push_back("3");
-//     icalendar_2_0::RrulePropType rrule(recur);
-//     
-//     //Startdate
-//     icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
-//     icalendar_2_0::DtstartPropType startdate;
-//     startdate.date(date);
-//     
-//     ::icalendar_2_0::ArrayOfProperties properties;
-//     properties.baseProperty().push_back(startdate);
-//     properties.baseProperty().push_back(rrule);
-//     
-//     
-//     //Assembling the complete event
-//     icalendar_2_0::VeventType event(component);
-//     event.properties(properties);
-//     
-//     
-//     icalendar_2_0::VcalendarType::components_type comp;
-//     comp.vcalendarContainedComponent().push_back(event);
-//     
-//     icalendar_2_0::VcalendarType vcalendar(comp);
-//     
-//     icalendar_2_0::IcalendarType icalendar;
-//     icalendar.vcalendar().push_back(vcalendar);
-//     
-//     /*
-//      * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
-//      * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
-//      * No idea why this happens though.
-//      */
-//     xml_schema::namespace_infomap map;
-//     map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-//     //map[""].schema = "iCalendar.xsd";
-//     
-//     icalendar_2_0::vevent (std::cout, event, map);
-//     
-//     } catch  (const xml_schema::exception& e) {
-//         std::cout << e << endl;
-//         QVERIFY(false);
-//     } 
-//     #if 0
-//     catch (const xercesc_3_1::DOMException &e) {
-//         std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-//         return;
-//     }
-// #endif
-// }
-// 
-// 
-// void BindingsTest::readXCalEvent()
-// {
-// 
-//     try {
-//         xml_schema::properties props;
-// //         props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
-// //         props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
-// 
-//         std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
-// 
-//         xml_schema::namespace_infomap map;
-//         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-//         map[""].schema = "iCalendar.xsd";
-// 
-//         icalendar_2_0::vevent (std::cout, *event, map);
-// 
-//     } catch  (const xml_schema::exception& e) {
-//         std::cout << e << std::endl;
-//         QVERIFY(false);
-//     } 
-// 
-// }
-// 
-// #endif
-// 
-// void BindingsTest::xercesException()
-// {
-//     xercesc::XMLPlatformUtils::Initialize();
-//     XMLCh tempStr[100];
-// 
-//     xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
-//     
-//     xercesc::XMLString::transcode("root", tempStr, 99);
-//     xercesc::DOMDocument*   doc = impl->createDocument(0, tempStr, 0);
-//     
-// /*    XMLCh n[100];
-//     XMLCh ns[100];
-//     xercesc::XMLString::transcode("components", n, 99);
-//     xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
-//     try {
-//         xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
-//         QVERIFY(e);
-//         
-//         /*
-//         xercesc::DOMElement& s (    
-//         ::xsd::cxx::xml::dom::create_element (
-//           "components",
-//           "http://icalnamespace.org",
-//           e));
-//         */
-// 
-//     } catch (const xercesc_3_1::DOMException &e) {
-//         std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-//         return;
-//     }
-//     
-//     doc->release();
-// }
-// 
-// void BindingsTest::writeContact()
-// {
-//     try {
-// //         KolabXSD::Contact::vcard_type vcard;
-// //         
-// //         vcard_4_0::fnPropType fn("Fritz Muster");
-// //         vcard.baseProperty().push_back(fn);
-// //         
-// //         vcard_4_0::nPropType n;
-// //         n.given().push_back("john");
-// //         n.surname().push_back("doe");
-// //         vcard.baseProperty().push_back(n);
-// //         
-// //         vcard_4_0::bdayPropType bday;
-// //         vcard_4_0::bdayPropType::date_type date(1988,12,12);
-// //         bday.date(date);
-// //         vcard.baseProperty().push_back(bday);
-// //         
-// //         KolabXSD::Contact contact(vcard);
-// //         xml_schema::namespace_infomap map;
-// //         map["kolab"].name = "http://kolab.org";
-// //         map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
-// //         //map["xcal"].schema = "iCalendar.xsd";
-// // 
-// //         KolabXSD::contact (std::cout, contact, map);
-//        
-//     
-//     } catch  (const xml_schema::exception& e) {
-//         std::cout << e << endl;
-//         QVERIFY(false);
-//     } 
-// }
-// 
-// void BindingsTest::readContact()
-// {
-// 
-// }
-
 namespace QTest {
      template<>
      char *toString(const Kolab::DateTime &dt)
@@ -407,9 +91,8 @@ void BindingsTest::BenchmarkRoundtrip()
 {
     boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
     std::string result;
-    result = Kolab::writeKolabEvent(*event);
     QBENCHMARK {
-        
+        result = Kolab::writeKolabEvent(*event);
         Kolab::readKolabEvent(result, false);
     }
 }
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index f5aac9e..8fa93bc 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -8,21 +8,7 @@ class BindingsTest : public QObject
 {
   Q_OBJECT
   private slots:
-      
-//      void writeKolabXCalEvent();
-//      void readKolabXCalEvent();
-//     //void writeXCalEvent();
-//     //void readXCalEvent();
-//       
-//     void writeNoteTest();
-//     void readNoteTest();
-//     void writeReadNoteTest();
-//     void xercesException();
-//     
-//     void writeContact();
-//     void readContact();
-    
-    
+
     //Kolabformat
     void readEvent();
     void writeEvent();


commit 18e4788542e44966b751e3de0032cdf4b46d9fef
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 10:13:11 2011 +0100

    reorganize schemas

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index dd1512e..64e4c12 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -15,57 +15,36 @@ set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
 set( XSDCXX  /usr/bin/xsdcxx)
 
 
-# Generate Kolab bindings
-file(GLOB KOLAB_SCHEMAS ${SCHEMA_DIR}/*.xsd)
-set( KOLAB_SCHEMA_SOURCEFILES  
-    bindings/base.cxx
-    bindings/incidence.cxx
-    bindings/event.cxx
-    bindings/note.cxx )
-
-add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD_test --output-dir bindings ${KOLAB_SCHEMAS}
-    COMMENT "Generating Kolab XSD bindings"
-    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-    DEPENDS ${KOLAB_SCHEMAS}
-    VERBATIM
-    )
-
-
-
-
-# Generate XCal bindings
+# Generate bindings
 
 file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
-set( XCAL_SCHEMA_SOURCEFILES  
+file(GLOB SCHEMAS ${SCHEMA_DIR}/*.xsd)
+set( SCHEMAS ${SCHEMAS} ${XCAL_SCHEMAS})
+
+set( SCHEMA_SOURCEFILES  
     bindings/xCard.cxx
-#     bindings/kolabformat.cxx
     bindings/kolabformat-xcal.cxx
     bindings/kolabformat-xcard.cxx
-#     bindings/iCalendar.cxx
     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-availability-extension.cxx
-#     bindings/iCalendar-wscal-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 ${XCAL_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 bindings ${XCAL_SCHEMAS}
-    COMMENT "Generating xCal XSD bindings"
+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 bindings ${SCHEMAS}
+    COMMENT "Generating XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS}
     VERBATIM
     )
-set( SCHEMA_SOURCEFILES ${XCAL_SCHEMA_SOURCEFILES} ${KOLAB_SCHEMA_SOURCEFILES})
 
-# Compile Schema
+# Compile Schemas
 add_executable(xsdbin compiled/xsdbin.cxx)
 target_link_libraries(xsdbin xerces-c)
 
diff --git a/schemas/ical/kolabformat-xcard.xsd b/schemas/ical/kolabformat-xcard.xsd
deleted file mode 100644
index e0abc67..0000000
--- a/schemas/ical/kolabformat-xcard.xsd
+++ /dev/null
@@ -1,35 +0,0 @@
-<?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">
-
-    <xs:include schemaLocation="xCard.xsd" />
-
-    <xs:complexType name="KolabVersion" >
-        <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:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
-    
-    <xs:complexType name="CustomType" >
-        <xs:complexContent mixed="false">
-            <xs:extension base="BasePropertyType">
-                <xs:sequence>
-                    <xs:element name="identifier" type="xs:string"/>
-                    <xs:element name="value" type="xs:string"/>
-                </xs:sequence>
-           </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />  
-    
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
deleted file mode 100644
index f780c2a..0000000
--- a/schemas/ical/kolabformat.xsd
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
-    xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
-    <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
-    
-    
-    <xs:complexType name="KolabBase">
-        <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
-    </xs:complexType>
-
-<!--     <xs:element ref="xcal:vevent"/> -->
-    
-<!--    <xs:complexType name="Event">
-        <xs:complexContent mixed="false">
-            <xs:extension base="KolabBase">
-                <xs:sequence>
-                    <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>-->
-
-<!--    <xs:element name="todo" type="Todo"/>
-    <xs:complexType name="Todo">
-        <xs:complexContent mixed="false">
-            <xs:extension base="KolabBase">
-                <xs:sequence>
-                    <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>-->
-    
-    <xs:element name="note" type="Note"/>
-    <xs:complexType name="Note">
-        <xs:complexContent mixed="false">
-            <xs:extension base="KolabBase">
-                <xs:sequence>
-                    <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
-                </xs:sequence>
-            </xs:extension>
-        </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>
-            <xs:element name="identifier" type="xs:string"/>
-            <xs:element name="value" type="xs:string"/>
-        </xs:sequence>
-    </xs:complexType>
-
-    <xs:element name="x-kolab-custom" type="CustomType" />  
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/xCard.xsd b/schemas/ical/xCard.xsd
deleted file mode 100644
index e7f4603..0000000
--- a/schemas/ical/xCard.xsd
+++ /dev/null
@@ -1,126 +0,0 @@
-<?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"/>
-  
-    <!-- 3.3.5 DATE-TIME -->
-  <!-- 
-  <xs:element name="date-time" type="xs:string"/>
- -->  
-   <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>
-  </xs:simpleType>
-  
-  <xs:element name="date-time" type="xcard:DateTimeType"/>
-
-<!-- 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>
-
-<!-- Properties -->
-  <xs:complexType name="BasePropertyType" abstract="true" >
-    <xs:sequence>
-      <xs:element ref="xcard:parameters" 
-                  minOccurs="0" />
-    </xs:sequence>
-  </xs:complexType>
-  
-  <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
-
-  <xs:element name="baseProperty" type="xcard:BasePropertyType" />
-
-  <xs:element name="fn" type="xcard:fnPropType"
-              substitutionGroup="xcard:baseProperty" />
-              
-  <xs:element name="n" type="xcard:nPropType"
-              substitutionGroup="xcard:baseProperty" />
-              
-  <xs:element name="bday" type="xcard:bdayPropType"
-              substitutionGroup="xcard:baseProperty" />
-              
-  
-              
-  <!-- Properties that take a simple text value -->
-  <xs:complexType name="TextPropertyType" >
-    <xs:complexContent mixed="false">
-      <xs:extension base="xcard:BasePropertyType">
-        <xs:sequence> 
-          <xs:element ref="xcard:text" />
-        </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">
-      <xs:extension base="xcard:BasePropertyType">
-        <xs:sequence>
-          <xs:choice>
-            <xs:element ref="xcard:date-time"/>
-            <xs:element ref="xcard:date"/>
-          </xs:choice>
-        </xs:sequence>
-      </xs:extension>
-    </xs:complexContent>
-  </xs:complexType>
-  
-  
-  
-  <xs:complexType name="fnPropType">
-    <xs:complexContent mixed="false">
-      <xs:extension base="xcard:TextPropertyType"/>
-    </xs:complexContent>
-  </xs:complexType>
-  
-  <xs:complexType name="nPropType">
-    <xs:complexContent mixed="false">
-      <xs:extension base="xcard:BasePropertyType">
-        <xs:sequence> 
-            <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-      </xs:extension>   
-    </xs:complexContent>
-  </xs:complexType>
-
-  <xs:complexType name="bdayPropType">
-    <xs:complexContent mixed="false">
-      <xs:extension base="xcard:DateDatetimePropertyType"/>
-    </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>
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
new file mode 100644
index 0000000..e0abc67
--- /dev/null
+++ b/schemas/kolabformat-xcard.xsd
@@ -0,0 +1,35 @@
+<?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">
+
+    <xs:include schemaLocation="xCard.xsd" />
+
+    <xs:complexType name="KolabVersion" >
+        <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:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
+    
+    <xs:complexType name="CustomType" >
+        <xs:complexContent mixed="false">
+            <xs:extension base="BasePropertyType">
+                <xs:sequence>
+                    <xs:element name="identifier" type="xs:string"/>
+                    <xs:element name="value" type="xs:string"/>
+                </xs:sequence>
+           </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />  
+    
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/kolabformat.xsd b/schemas/kolabformat.xsd
new file mode 100644
index 0000000..f780c2a
--- /dev/null
+++ b/schemas/kolabformat.xsd
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
+    xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
+    targetNamespace="http://kolab.org"
+    xmlns="http://kolab.org"
+    elementFormDefault="qualified">
+
+    <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+    <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+    
+    
+    <xs:complexType name="KolabBase">
+        <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
+    </xs:complexType>
+
+<!--     <xs:element ref="xcal:vevent"/> -->
+    
+<!--    <xs:complexType name="Event">
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>-->
+
+<!--    <xs:element name="todo" type="Todo"/>
+    <xs:complexType name="Todo">
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>-->
+    
+    <xs:element name="note" type="Note"/>
+    <xs:complexType name="Note">
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </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>
+            <xs:element name="identifier" type="xs:string"/>
+            <xs:element name="value" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-custom" type="CustomType" />  
+
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
new file mode 100644
index 0000000..e7f4603
--- /dev/null
+++ b/schemas/xCard.xsd
@@ -0,0 +1,126 @@
+<?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"/>
+  
+    <!-- 3.3.5 DATE-TIME -->
+  <!-- 
+  <xs:element name="date-time" type="xs:string"/>
+ -->  
+   <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>
+  </xs:simpleType>
+  
+  <xs:element name="date-time" type="xcard:DateTimeType"/>
+
+<!-- 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>
+
+<!-- Properties -->
+  <xs:complexType name="BasePropertyType" abstract="true" >
+    <xs:sequence>
+      <xs:element ref="xcard:parameters" 
+                  minOccurs="0" />
+    </xs:sequence>
+  </xs:complexType>
+  
+  <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
+
+  <xs:element name="baseProperty" type="xcard:BasePropertyType" />
+
+  <xs:element name="fn" type="xcard:fnPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  <xs:element name="n" type="xcard:nPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  <xs:element name="bday" type="xcard:bdayPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  
+              
+  <!-- Properties that take a simple text value -->
+  <xs:complexType name="TextPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:text" />
+        </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">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence>
+          <xs:choice>
+            <xs:element ref="xcard:date-time"/>
+            <xs:element ref="xcard:date"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  
+  
+  <xs:complexType name="fnPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="nPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+            <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>   
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:complexType name="bdayPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:DateDatetimePropertyType"/>
+    </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 1fba5623d0ffa0725425768c67a420f02fd78429
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 10:01:04 2011 +0100

    Deleted the old schema files which we don't need anymore

diff --git a/schemas/base.xsd b/schemas/base.xsd
deleted file mode 100644
index 18b0a9f..0000000
--- a/schemas/base.xsd
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:complexType name="XMLBase" abstract="true">
-        <xs:sequence>
-            <!--
-                Mandatory elements
-            //-->
-            <xs:element name="uid" type="UID" />
-            <xs:element name="product-id" type="xs:string" />
-            <xs:element name="creation-date" type="xs:dateTime" />
-            <xs:element name="last-modification-date" type="xs:dateTime" />
-
-            <!--
-                Elements that do not require to be set by a client application,
-                as a default is provided.
-            //-->
-            <xs:element name="sensitivity" type="Sensitivity" default="public" />
-
-            <!--
-                Optional elements
-            //-->
-            <xs:element name="body" type="xs:string" minOccurs="0" />
-            <xs:element name="categories" type="Category" minOccurs="0" />
-            <xs:element name="inline-attachment" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
-            <xs:element name="link-attachment" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
-        </xs:sequence>
-
-        <!--
-            Version of the XML and bindings generated with this XSD.
-
-            Note: Does not seem to pass through to generated XML from PyXB
-            bindings.
-        //-->
-        <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
-
-    </xs:complexType>
-
-    <xs:simpleType name="UID">
-        <!--
-            Note^1 that a UID restriction that is too short increases the risk of
-            duplicate UIDs.
-
-            Note^2 that we may also want to restrict the contents of the UID to
-            allow only alphanumeric characters.
-        //-->
-        <xs:restriction base="xs:string">
-            <xs:minLength value="1" />
-            <xs:whiteSpace value="collapse" />
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:simpleType name="Category">
-        <xs:restriction base="xs:string">
-            <xs:pattern value="(\w+(,\w+)+)?" />
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:simpleType name="Color">
-        <xs:restriction base="xs:string">
-            <xs:length value="7" />
-            <xs:pattern value="#([a-f;0-9]){6}" />
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:simpleType name="Sensitivity">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="private"/>
-            <xs:enumeration value="confidential"/>
-            <xs:enumeration value="public"/>
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:complexType name="SMTPContact">
-        <xs:sequence>
-            <xs:element name="smtp-address" type="xs:string" />
-            <xs:element name="display-name" type="xs:string" minOccurs="0" />
-        </xs:sequence>
-    </xs:complexType>
-
-    <!--
-        Version of the XML and bindings generated with this XSD.
-
-        Note: Does not seem to pass through to generated XML from PyXB
-        bindings.
-    //-->
-    <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/contact.xsd b/schemas/contact.xsd
deleted file mode 100644
index 1b7c8fe..0000000
--- a/schemas/contact.xsd
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:include schemaLocation="base.xsd" />
-
-    <xs:element name="contact" type="Contact"/>
-
-    <xs:complexType name="Contact">
-        <xs:complexContent>
-            <xs:extension base="XMLBase">
-                <xs:sequence>
-                    <xs:element name="name" type="Name" minOccurs="0" />
-                    <xs:element name="free-busy-url" type="xs:string" minOccurs="0" />
-                    <xs:element name="organization" type="xs:string" minOccurs="0" />
-                    <xs:element name="web-page" type="xs:string" minOccurs="0" />
-                    <xs:element name="im-address" type="xs:string" minOccurs="0" />
-                    <xs:element name="department" type="xs:string" minOccurs="0" />
-                    <xs:element name="office-location" type="xs:string" minOccurs="0" />
-                    <xs:element name="profession" type="xs:string" minOccurs="0" />
-                    <xs:element name="job-title" type="xs:string" minOccurs="0" />
-                    <xs:element name="manager-name" type="xs:string" minOccurs="0" />
-                    <xs:element name="assistant" type="xs:string" minOccurs="0" />
-                    <xs:element name="nick-name" type="xs:string" minOccurs="0" />
-                    <xs:element name="spouse-name" type="xs:string" minOccurs="0" />
-                    <xs:element name="birthday" type="xs:string" minOccurs="0" />
-                    <xs:element name="anniversary" type="xs:string" minOccurs="0" />
-                    <xs:element name="picture" type="xs:string" minOccurs="0" />
-                    <xs:element name="children" type="xs:string" minOccurs="0" />
-                    <xs:element name="gender" type="xs:string" minOccurs="0" />
-                    <xs:element name="language" type="xs:string" minOccurs="0" />
-                    <xs:element name="phone" type="PhoneNumber" minOccurs="0" maxOccurs="unbounded" />
-                    <xs:element name="email" type="SMTPContact" minOccurs="0" maxOccurs="unbounded" />
-                    <xs:element name="address" type="Address" minOccurs="0" maxOccurs="unbounded" />
-                    <xs:element name="preferred-address" type="xs:string" minOccurs="0" />
-                    <xs:element name="latitude" type="xs:float" minOccurs="0" />
-                    <xs:element name="longitude" type="xs:float" minOccurs="0" />
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <xs:complexType name="Name">
-        <xs:sequence>
-            <xs:element name="given-name" type="xs:string" minOccurs="0" />
-            <xs:element name="middle-names" type="xs:string" minOccurs="0" />
-            <xs:element name="last-name" type="xs:string" minOccurs="0" />
-            <xs:element name="full-name" type="xs:string" minOccurs="0" />
-            <xs:element name="initials" type="xs:string" minOccurs="0" />
-            <xs:element name="prefix" type="xs:string" minOccurs="0" />
-            <xs:element name="suffix" type="xs:string" minOccurs="0" />
-        </xs:sequence>
-    </xs:complexType>
-
-    <xs:complexType name="PhoneNumber">
-        <xs:sequence>
-            <xs:element name="type" type="xs:string" minOccurs="0" />
-            <xs:element name="number" type="xs:string" />
-        </xs:sequence>
-    </xs:complexType>
-
-    <xs:complexType name="Address">
-        <!--
-            'type' is a reserved keyword... can we use 'label' instead, perhaps?
-
-            Note: I have not actually experienced any trouble with this yet.
-        //-->
-        <xs:sequence>
-            <xs:element name="type" type="xs:string" default="home" />
-            <xs:element name="street" type="xs:string" minOccurs="0" />
-            <xs:element name="postal-code" type="xs:string" minOccurs="0" />
-            <!--
-                Is locality supposed to mean city?
-            //-->
-            <xs:element name="locality" type="xs:string" minOccurs="0" />
-            <xs:element name="region" type="xs:string" minOccurs="0" />
-            <xs:element name="country" type="xs:string" minOccurs="0" />
-        </xs:sequence>
-    </xs:complexType>
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/event.xsd b/schemas/event.xsd
deleted file mode 100644
index b77f1b6..0000000
--- a/schemas/event.xsd
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:include schemaLocation="incidence.xsd" />
-
-    <xs:element name="event" type="Event"/>
-
-    <xs:complexType name="Event">
-        <xs:complexContent>
-            <xs:extension base="Incidence">
-                <xs:sequence>
-
-                    <xs:element name="show-time-as" type="xs:string"></xs:element>
-                    <xs:element name="color-label" type="xs:string"></xs:element>
-                    <xs:element name="start-date" type="xs:dateTime"></xs:element>
-                    <xs:element name="end-date" type="xs:dateTime"></xs:element>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/incidence.xsd b/schemas/incidence.xsd
deleted file mode 100644
index 1db62a5..0000000
--- a/schemas/incidence.xsd
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:include schemaLocation="base.xsd" />
-
-    <xs:complexType name="Incidence">
-        <xs:complexContent>
-            <xs:extension base="XMLBase">
-                <xs:sequence>
-                    <xs:element name="summary" type="xs:string" />
-                    <xs:element name="location" type="xs:string" />
-                    <xs:element name="creator" type="SMTPContact" />
-                    <xs:element name="organizer" type="SMTPContact" />
-                    <xs:element name="alarm" type="xs:string" />
-                    <xs:element name="recurrence" type="Recurrence" minOccurs="0" maxOccurs="1"/>
-                    <xs:element name="attendee" type="Attendee" />
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <xs:complexType name="Attendee">
-        <xs:complexContent>
-            <xs:extension base="SMTPContact">
-                <xs:sequence>
-                    <xs:element name="status" type="Status" />
-                    <xs:element name="request-response" type="xs:string" />
-                    <xs:element name="role" type="Role" />
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <xs:simpleType name="Status">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="none" />
-            <xs:enumeration value="tentative" />
-            <xs:enumeration value="accepted" />
-            <xs:enumeration value="declined" />
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:simpleType name="Role">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="required" />
-            <xs:enumeration value="optional" />
-            <xs:enumeration value="resource" />
-        </xs:restriction>
-    </xs:simpleType>
-
-
-    <xs:complexType name="Recurrence">
-        <xs:sequence>
-            <xs:element name="rule" type="Rule" maxOccurs="unbounded" minOccurs="0" />
-            <xs:element name="date" type="xs:dateTime" maxOccurs="unbounded" minOccurs="0" />
-            <xs:element name="exception" type="Exception" maxOccurs="unbounded" minOccurs="0" />
-        </xs:sequence>
-    </xs:complexType>
-    
-    <xs:complexType name="Interval">
-        <xs:choice>
-            <xs:element name="interval" type="xs:int"/>
-            <xs:element name="list" type="xs:int" maxOccurs="unbounded" minOccurs="1" />
-        </xs:choice>
-    </xs:complexType>
-
-    <xs:complexType name="Exception">
-        <xs:sequence>
-            <xs:element name="rule" type="Rule" />
-            <xs:element name="date" type="xs:dateTime" />
-            <xs:element name="subevent" type="xs:string" />
-        </xs:sequence>
-    </xs:complexType>
-
-    <xs:complexType name="Rule">
-        <xs:sequence>
-            <xs:element name="yearly" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="monthly" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="weekly" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="daily" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="hourly" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="minutely" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="secondly" type="Interval" maxOccurs="1" minOccurs="0" />
-            <xs:element name="occurence" type="xs:int" maxOccurs="unbounded" minOccurs="0" />
-            <xs:element name="weekstart" type="xs:int" maxOccurs="1" minOccurs="0" />
-            <xs:choice maxOccurs="1" minOccurs="0">
-                <xs:element name="count" type="xs:int" />
-                <xs:element name="enddate" type="xs:dateTime" />
-            </xs:choice>
-        </xs:sequence>
-    </xs:complexType>
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/note.xsd b/schemas/note.xsd
deleted file mode 100644
index 06765f9..0000000
--- a/schemas/note.xsd
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:include schemaLocation="base.xsd" />
-
-    <xs:element name="note" type="Note"/>
-
-    <xs:complexType name="Note">
-        <xs:complexContent>
-            <xs:extension base="XMLBase">
-                <xs:sequence>
-                    <xs:element name="summary" type="xs:string" default=""/>
-                    <xs:element name="background-color" type="Color" default="#000000"/>
-                    <xs:element name="foreground-color" type="Color" default="#ffff00"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-    <!-- xs:complexType name="ExtendedNote">
-        <xs:complexContent>
-            <xs:extension base="Note">
-                <xs:sequence>
-                    <xs:any namespace="##any" processContents="skip"
-            minOccurs="0" maxOccurs="unbounded"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType-->
-</xs:schema>
diff --git a/schemas/task.xsd b/schemas/task.xsd
deleted file mode 100644
index 009b779..0000000
--- a/schemas/task.xsd
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://kolab.org"
-    xmlns="http://kolab.org"
-    elementFormDefault="qualified">
-
-    <xs:include schemaLocation="incidence.xsd" />
-
-    <xs:element name="task" type="Task"/>
-
-    <xs:complexType name="Task">
-        <xs:complexContent>
-            <xs:extension base="Incidence">
-                <xs:sequence>
-
-                    <xs:element name="priority" type="xs:int"></xs:element>
-                    <xs:element name="completed" type="xs:int"></xs:element>
-                    <xs:element name="status" type="xs:string"></xs:element>
-                    <xs:element name="start-date" type="xs:dateTime" maxOccurs="1" minOccurs="0"></xs:element>
-                    <xs:element name="due-date" type="xs:dateTime"
-                        maxOccurs="1" minOccurs="0">
-                    </xs:element>
-                    <xs:element name="parent" type="xs:string"></xs:element>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
-    </xs:complexType>
-
-</xs:schema>
\ No newline at end of file


commit 1463199dc6ef1e64d0d4e80f0fba78cf8b93f0dc
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 01:42:42 2011 +0100

    Fixed cardinalities of Rdate and structure of exception date (schemas)

diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
index c31f344..86130ab 100644
--- a/schemas/ical/iCalendar-props.xsd
+++ b/schemas/ical/iCalendar-props.xsd
@@ -658,7 +658,14 @@
   <!-- 3.8.5.1 Exception Date/Times -->
   <xs:complexType name="ExdatePropType">
     <xs:complexContent mixed="false">
-      <xs:extension base="xcal:DateDatetimePropertyType"/>
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:choice>
+            <xs:element ref="xcal:date-time" maxOccurs="unbounded"/>
+            <xs:element ref="xcal:date" maxOccurs="unbounded"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:extension>
     </xs:complexContent>
   </xs:complexType>
     
@@ -668,9 +675,9 @@
         <xs:extension base="xcal:BasePropertyType">
             <xs:sequence>
                 <xs:choice>
-                    <xs:element ref="xcal:date"/>
-                    <xs:element ref="xcal:date-time"/>
-                    <xs:element ref="xcal:period"/>
+                    <xs:element ref="xcal:date" maxOccurs="unbounded"/>
+                    <xs:element ref="xcal:date-time" maxOccurs="unbounded"/>
+                    <xs:element ref="xcal:period" maxOccurs="unbounded"/>
                 </xs:choice>
             </xs:sequence>
         </xs:extension>


commit 6a6710999e18a2753c7a27caa0f7985cbcc1716d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 01:41:53 2011 +0100

    bindingstest/kolabformat only for KolabContainers, kcalconversiontest/kolabkcalformat for KCalCore containers
    Reading with compiled schemas.

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 3f9f736..bcb81f6 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -1,11 +1,18 @@
 #ifndef KOLAB_CONVERSIONS_H
 #define KOLAB_CONVERSIONS_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 <fstream>
+#include <iostream>
+
+
 #define TZ_PREFIX "/kolab.org/"
 
 namespace Kolab {
@@ -47,11 +54,25 @@ 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)
 {
@@ -64,16 +85,9 @@ typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProp
     }
 
     if (dtProperty.parameters()) {
-        for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.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";
-                }
-                DC::setTimezone(date, tzid);
-            }
+        const std::string &tzid = getTimezone(*dtProperty.parameters());
+        if (tzid.size()) {
+            DC::setTimezone(date, tzid);
         }
     }
     return date;
@@ -109,7 +123,7 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
         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);
@@ -122,6 +136,7 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
     }
 }
 
+///trait to convert recurrence properties
 template <typename T>
 struct RecurrenceConverter;
 
@@ -169,52 +184,128 @@ typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
     return r;
 }
 
-
+///Trait for Incidence object
 template <typename T> 
 struct IncidenceConverter;
 
+///Trait for incidence properties specialized for Event/Todo/Journal
+template <typename T> struct IncidenceTrait;
 
 
-// template <typename T> struct StringConverter
-// {
-//     QString toString(const xml_schema::string &s)
-//     {
-//         return QString::fromStdString(s);
-//     }
-//     
-//     void append(StringListType &list, const StringType &string) {
-//         
-//     }
-// }
-// 
-// template <typename T> typename T::StringListType toStringList(const icalendar_2_0::TextListPropertyType &s)
-// {
-//     using namespace icalendar_2_0;
-// 
-//     typedef StringConverter< typename T::RecurrenceType> SC;
-//     typedef typename T::StringListType StringListType;
-// 
-//     StringListType list;
-//     const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-//     for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-//         SC::append(list, SC::toString(*it));
-//     }
-//     return list;
-// }
 
 
 
 
+template <typename T>
+typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
+{
+    typedef typename T::IncidencePtr IncidencePtr;
+    typedef typename T::IncidenceType IncidenceType;
+    typedef typename T::KolabType KolabType;
+    
+    try {
+        //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
+        xml_schema::properties props;
+
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+        if (isUrl) {
+            std::cout << "open file " << s;
+            XMLParserWrapper wrapper;
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s); 
+            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
+            XMLParserWrapper wrapper;
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
+            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!";
+            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::cout <<  e << std::endl;
+        std::cout <<  "Failed to read incidence!" << std::endl;
+    }
+
+    return IncidencePtr();
+    
+}
+
+
+
+template <typename T>
+std::string writeIncidence(const typename T::IncidenceType &incidence) {
+    
+    using namespace icalendar_2_0;
+    typedef IncidenceConverter< typename T::Incidence > IC;
+    typedef typename T::KolabType KolabType;
+
+    try {
+
+        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::dtstamp_type dtstamp;
+        dtstamp.date_time(IC::dtstamp(incidence));
+        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(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 properties(prodid, version, x_kolab_version);
+        
+        VcalendarType vcalendar(properties, components);
+        
+        IcalendarType icalendar(vcalendar);
+
+        xml_schema::namespace_infomap map;
+        map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+        
+        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();
+    } 
+}
 
 
-/*
-xml_schema::date fromDate(const KDateTime &dt)
-{
-    const QDate &d = dt.date();
-    xml_schema::date date(d.year(), d.month(), d.day());
-    return date;
-}*/
 
 
 
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 676ee81..2c3f7a4 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -6,8 +6,10 @@
 #include <KDE/KDebug>
 #include <kcalcore/recurrencerule.h>
 #include <kcalcore/recurrence.h>
-#include <bindings/kolabformat-xcal.hxx>
 #include <kcalcore/incidence.h>
+#include <KDE/KCalCore/Event>
+#include <KDE/KCalCore/Todo>
+#include <kcalcore/person.h>
 
 namespace Kolab {
 
@@ -37,6 +39,16 @@ QString toString(const icalendar_2_0::TextPropertyType &s)
     return QString::fromStdString(s.text());
 }
 
+void setString(icalendar_2_0::TextPropertyType &p, const QString &s)
+{
+    p.text(s.toStdString());
+}
+
+// std::auto_ptr<icalendar_2_0::TextPropertyType> fromString(const QString &s)
+// {
+//     return std::auto_ptr<icalendar_2_0::TextPropertyType>(new icalendar_2_0::TextPropertyType(s.toStdString()));
+// }
+
 
 typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
 
@@ -115,7 +127,6 @@ template <> struct DateTimeConverter<KDateTime>
 
 template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
 {
-
     typedef typename KCalCoreTypes::RecurrenceType Type;
     typedef typename KCalCoreTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
 
@@ -126,25 +137,25 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
         
         switch (freq) {
             case FreqRecurType::YEARLY:
-                r->setRecurrenceType(RecurrenceRule::rYearly);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
                 break;
             case FreqRecurType::MONTHLY:
-                r->setRecurrenceType(RecurrenceRule::rMonthly);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
                 break;
             case FreqRecurType::WEEKLY:
-                r->setRecurrenceType(RecurrenceRule::rWeekly);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
                 break;
             case FreqRecurType::DAILY:
-                r->setRecurrenceType(RecurrenceRule::rDaily);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
                 break;
             case FreqRecurType::HOURLY:
-                r->setRecurrenceType(RecurrenceRule::rHourly);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
                 break;
             case FreqRecurType::MINUTELY:
-                r->setRecurrenceType(RecurrenceRule::rMinutely);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
                 break;
             case FreqRecurType::SECONDLY:
-                r->setRecurrenceType(RecurrenceRule::rSecondly);
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
                 break;
             default:
                 kWarning() << "invalid unhandled recurrenc type" << freq;
@@ -157,23 +168,24 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
         using namespace KCalCore;
         
         switch (t.recurrenceType()) {
-            case RecurrenceRule::rYearly:
+            case KCalCore::RecurrenceRule::rYearly:
                 return FreqRecurType::YEARLY;
-            case RecurrenceRule::rMonthly:
+            case KCalCore::RecurrenceRule::rMonthly:
                 return FreqRecurType::MONTHLY;
-            case RecurrenceRule::rWeekly:
+            case KCalCore::RecurrenceRule::rWeekly:
                 return FreqRecurType::WEEKLY;
-            case RecurrenceRule::rDaily:
+            case KCalCore::RecurrenceRule::rDaily:
                 return FreqRecurType::DAILY;
-            case RecurrenceRule::rHourly:
+            case KCalCore::RecurrenceRule::rHourly:
                 return FreqRecurType::HOURLY;
-            case RecurrenceRule::rMinutely:
+            case KCalCore::RecurrenceRule::rMinutely:
                 return FreqRecurType::MINUTELY;
-            case RecurrenceRule::rSecondly:
+            case KCalCore::RecurrenceRule::rSecondly:
                 return FreqRecurType::SECONDLY;
             default:
                 kWarning() << "invalid unhandled recurrenc type";
         }
+        return 0;
     }
     
     static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
@@ -374,6 +386,9 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename
 template <typename T>
 void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
 {
+    using namespace KCalCore;
+    typedef DateTimeConverter<KDateTime> DC;
+    
     inc.setUid(toString(prop.uid()));
     inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
     inc.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
@@ -413,15 +428,37 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
     }
     
     if (prop.rdate()) {
-        
+        const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+        std::string tzid;
+        if (rdate.parameters()) {
+            tzid = getTimezone(*rdate.parameters());
+        }
+        if (rdate.date().size()) {
+            Q_FOREACH(const xml_schema::date &d, rdate.date()) {
+                recurrence->addRDate(DC::toDate(d)->date());
+            }
+        } else if (rdate.date_time().size()) {
+            Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+            DC::Ptr date = DC::toDate(d);
+            if (tzid.size()) {
+                DC::setTimezone(date, tzid);
+            }
+            recurrence->addRDateTime(*date);
+        }
+        } else if (rdate.period().size()) {
+            kDebug() << "the period element must not be used, ignored.";
+        }
     }
     
     if (prop.exdate()) {
-        
+        //TODO
+//         recurrence->addExDate();
+//         recurrence->addExDateTime();
     }
     
     if (prop.recurrence_id()) {
-        
+        //TODO THISANDFUTURE range
+        inc.setRecurrenceId(*toDate<KCalCoreTypes>(*prop.recurrence_id()));
     }
     
     if (prop.summary()) {
@@ -433,19 +470,38 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
     }
     
     if (prop.priority()) {
-        
+        inc.setPriority(toInt(*prop.priority()));
     }
     
     if (prop.status()) {
-        
+        const QString &status =  toString(*prop.status());
+        if (status == "NEEDS-ACTION") {
+            inc.setStatus(Incidence::StatusNeedsAction);
+        } else if (status == "COMPLETED") {
+            inc.setStatus(Incidence::StatusCompleted);
+        } else if (status == "IN-PROCESS") {
+            inc.setStatus(Incidence::StatusInProcess);
+        } else if (status == "CANCELLED") {
+            inc.setStatus(Incidence::StatusCanceled);
+        } else if (status == "TENTATIVE") {
+            inc.setStatus(Incidence::StatusTentative);
+        } else if (status == "CONFIRMED") {
+            inc.setStatus(Incidence::StatusConfirmed);
+        } else if (status == "DRAFT") {
+            inc.setStatus(Incidence::StatusDraft);
+        } else if (status == "FINAL") {
+            inc.setStatus(Incidence::StatusFinal);
+        }
     }
     
     if (prop.location()) {
-        
+        inc.setLocation(toString(*prop.location()));
     }
     
     if (prop.organizer()) {
-        
+//         icalendar_2_0::KolabEvent::properties_type::organizer();
+//         inc.
+//         KCalCore::Person person;
     }
     
     if (prop.attendee().size()) {
@@ -459,7 +515,7 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
     if (prop.x_custom().size()) {
         
     }
-    
+
 }
 
 template <typename T>
@@ -472,15 +528,16 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
     
     switch (inc.secrecy()) {
         case Incidence::SecrecyConfidential:
-            prop.class_();
+            prop.class_(properties::class_type("CONFIDENTIAL"));
             break;
-        case Incidence::SecrecyPublic:
-            prop.class_();
         case Incidence::SecrecyPrivate:
-            prop.class_();
+            prop.class_(properties::class_type("PRIVATE"));
+            break;
+        default:
+            prop.class_(properties::class_type("PUBLIC"));
+            break;
     }
-    
-    
+
     if (inc.dtStart().isValid()) {
         properties::dtstart_type dtstart;
         setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
@@ -488,12 +545,12 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
     }
     
     if (inc.recurs()) {
-        Recurrence *r = inc.recurrence();
+        KCalCore::Recurrence *r = inc.recurrence();
         if (r->rRules().size() >= 1) {
             if (r->rRules().size() != 1) {
                 kWarning() << "too many recurrences: " << r->rRules().size();
             }
-            RecurrenceRule *rule = r->rRules().first();
+            KCalCore::RecurrenceRule *rule = r->rRules().first();
             //TODO check if startdate is allDay if recurrence is allDay
             //TODO check if startdate matches the one of the event (it MUST)
             prop.rrule(recurrenceProperty(*rule));
@@ -519,6 +576,90 @@ template <> struct IncidenceConverter < KCalCore::Incidence >
 
 };
 
+template < > struct IncidenceTrait <KCalCore::Event>
+{
+    typedef typename icalendar_2_0::KolabEvent KolabType;
+    typedef typename KCalCore::Event IncidenceType;
+    typedef typename KCalCore::Event::Ptr IncidencePtr;
+    typedef typename KCalCore::Incidence Incidence;
+    
+    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+    {
+        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+        if (event.hasEndDate() && event.dtEnd().isValid()) {
+            icalendar_2_0::properties::dtend_type dtend;
+            setDateTimeProperty<KCalCoreTypes>(dtend, event.dtEnd());
+            prop.dtend(dtend);
+        } else if (event.hasDuration()) {
+            
+        }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+    {
+        components.vevent().push_back(inc);
+    }
+
+    static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
+    {
+        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+        if (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()) {
+            //TODO implement
+        }
+    }
+     
+    static icalendar_2_0::components2::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)
+    {
+        return components.vevent().end();
+    }
+    
+};
+
+template < > struct IncidenceTrait <KCalCore::Todo>
+{
+    typedef typename icalendar_2_0::KolabTodo KolabType;
+    typedef typename KCalCore::Todo IncidenceType;
+    typedef typename KCalCore::Incidence Incidence;
+    
+    static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
+    {
+       icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
+       getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+       //TODO implement remaining todo properties
+
+    }
+
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+    {
+        components.vtodo().push_back(inc);
+    }
+    
+    //TODO implement reading
+};
+
 } //Namespace
 
 #endif
\ No newline at end of file
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
new file mode 100644
index 0000000..82d9995
--- /dev/null
+++ b/c++/lib/kcalkolabformat.cpp
@@ -0,0 +1,31 @@
+#include "kolabformat.h"
+
+#include <kcalcore/event.h>
+#include <KDE/KCalCore/Todo>
+
+#include "kcalconversions.h"
+
+namespace Kolab {
+
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
+{
+     return readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+}
+
+KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
+{
+    
+}
+
+
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+     return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+}
+
+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
new file mode 100644
index 0000000..d47802a
--- /dev/null
+++ b/c++/lib/kcalkolabformat.h
@@ -0,0 +1,19 @@
+
+#ifndef KCALKOLABFORMAT_H
+#define KCALKOLABFORMAT_H
+
+#include <string>
+#include <KDE/KCalCore/Event>
+#include <KDE/KCalCore/Todo>
+
+namespace Kolab {
+
+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/kolabconversions.h b/c++/lib/kolabconversions.h
new file mode 100644
index 0000000..98391e3
--- /dev/null
+++ b/c++/lib/kolabconversions.h
@@ -0,0 +1,601 @@
+// template <> struct DateTimeConverter<DateTime>
+// {
+//     typedef typename boost::shared_ptr<DateTime> Ptr;
+//     Ptr toDate(const  xml_schema::date &dt)
+//     {
+//         Ptr date(new DateTime());
+// 
+//         return date;
+//     }
+//     Ptr toDate(const xml_schema::date_time &dt)
+//     {
+//         Ptr date(new DateTime());
+//         return date;
+//     }
+//     
+//     void setTimezone(Ptr date, const std::string &tzid )
+//     {
+//         date->setTimezone(tzid);
+//     }
+// };
+
+
+#include "conversions.h"
+
+#include "kolabcontainers.h"
+#include <boost/foreach.hpp>
+
+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;
+    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+        d.push_back(*it);
+    }
+    return d;
+}
+
+std::string toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return s.text();
+}
+
+void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)
+{
+    p.text(s);
+}
+
+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";
+        }
+    }
+    
+    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<RecurrenceRule::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);
+    }
+};
+
+
+
+
+
+
+template <typename KolabType, typename T>
+void setIncidenceProperties(Kolab::Event &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()) {
+//         const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+//         std::string tzid;
+//         if (rdate.parameters()) {
+//             tzid = getTimezone(*rdate.parameters());
+//         }
+//         if (rdate.date().size()) {
+//             Q_FOREACH(const xml_schema::date &d, rdate.date()) {
+//                 recurrence->addRDate(DC::toDate(d)->date());
+//             }
+//         } else if (rdate.date_time().size()) {
+//             Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+//             DC::Ptr date = DC::toDate(d);
+//             if (tzid.size()) {
+//                 DC::setTimezone(date, tzid);
+//             }
+//             recurrence->addRDateTime(*date);
+//         }
+//         } else if (rdate.period().size()) {
+//             kDebug() << "the period element must not be used, ignored.";
+//         }
+//     }
+//     
+//     if (prop.exdate()) {
+//         //TODO
+// //         recurrence->addExDate();
+// //         recurrence->addExDateTime();
+//     }
+//     
+    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 == "NEEDS-ACTION") {
+            inc.setStatus(NeedsAction);
+        } else if (status == "COMPLETED") {
+            inc.setStatus(Completed);
+        } else if (status == "IN-PROCESS") {
+            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);
+        }
+    }
+
+    if (prop.location()) {
+        inc.setLocation(toString(*prop.location()));
+    }
+    
+    if (prop.organizer()) {
+//         icalendar_2_0::KolabEvent::properties_type::organizer();
+//         inc.
+//         KCalCore::Person person;
+    }
+    
+    if (prop.attendee().size()) {
+        
+    }
+    
+    if (prop.attach().size()) {
+        
+    }
+    
+    if (prop.x_custom().size()) {
+        
+    }
+
+}
+
+template <typename T, typename I>
+xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const std::vector<int> &input) {
+    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()) {
+        RecurType::bysecond_sequence bysecond;
+        recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bysecond()));
+    }
+    return rruleProp;
+}
+
+template <typename T>
+void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
+{
+    using namespace icalendar_2_0;
+    
+    prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
+    
+    switch (inc.classification()) {
+        case Kolab::Confidential:
+            prop.class_(properties::class_type("CONFIDENTIAL"));
+            break;
+        case Kolab::Private:
+            prop.class_(properties::class_type("PRIVATE"));
+            break;
+        default:
+            prop.class_(properties::class_type("PUBLIC"));
+            break;
+    }
+
+    if (inc.start().isValid()) {
+        properties::dtstart_type dtstart;
+        setDateTimeProperty<KolabTypes>(dtstart, inc.start());
+        prop.dtstart(dtstart);
+    }
+    
+    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)
+    }
+    
+}
+
+template <> struct IncidenceConverter < Incidence >
+{
+    typedef DateTimeConverter< DateTime> DC;
+    static std::string uid(const Event &inc) {
+        return inc.uid();
+    }
+    
+    static xml_schema::date_time dtstamp(const Event &inc) {
+        return DC::fromDateTime(inc.lastModified());
+    }
+    
+    static xml_schema::date_time created(const Event &inc) {
+        return DC::fromDateTime(inc.created());
+    }
+
+};
+
+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)
+    {
+        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+        if (event.end().isValid()) {
+            icalendar_2_0::properties::dtend_type dtend;
+            setDateTimeProperty<KolabTypes>(dtend, event.end());
+            prop.dtend(dtend);
+        }/* else if (event.duration().isValid()) {
+            
+        }*/
+    }
+    
+    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 icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::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()) {
+            //TODO implement
+        }
+    }
+     
+    static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+    {
+        return components.vevent().begin();
+    }
+    
+    static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+    {
+        return components.vevent().end();
+    }
+    
+};
+
+
+}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 0bb9303..ab43acc 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -1,295 +1,22 @@
-
-
 #include "kolabformat.h"
 
-#include <kcalcore/event.h>
 #include <iostream>
 #include <bindings/kolabformat-xcal.hxx>
-//#include "note.h"
-#include <kdebug.h>
-#include <limits>
-#include <kcalcore/recurrencerule.h>
-#include "kcalconversions.h"
-#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
-#include <KDE/KCalCore/Todo>
+#include "kolabcontainers.h"
+#include "kolabconversions.h"
 
 namespace Kolab {
-    
-// xml_schema::date::operator Date(Date &d, const  xml_schema::date &dt) { 
-//     Date d;
-//     d.year = year();
-//     return d;
-// }; //conversion operator
-    
-
-// bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-// {
-//     if (dtProperty.date_time() || dtProperty.date()) {
-//         return true;
-//     }
-//     return false;
-// }
-
 
-std::string serializeEvent()
+boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl)
 {
-    std::cout << "ksjdsldfj";
-    return "bla";
+    return readIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
 }
 
-void readICalendar(const std::string &s)
+std::string writeKolabEvent(const Kolab::Event &event)
 {
-
+    return writeIncidence< IncidenceTrait<Kolab::Event> >(event);
 }
 
 
-void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
-{
-//     try {
-//         if (!vevent.properties())
-//             return;
-//         const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
-//         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-// 
-//         for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
-//             if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
-//                 std::cout << "Start" << std::endl;
-//                 if (d->date_time()) {
-//                     const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
-//                     //datetime.day()
-//     //                 (*(d->date_time()))
-//                 } else if (d->date()) {
-//                     const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
-//                     event.date << date;
-//                 }
-// 
-//             } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
-//                 std::cout << "Rrule" << std::endl;
-//                 std::cout << d->recur().freq() << std::endl;
-//                 std::cout << d->recur().count() << std::endl;
-//                 //std::cout << d->recur().byhour() << std::endl;
-//             } else {
-//                 std::cout << "other" << std::endl;
-//                 const icalendar_2_0::BasePropertyType &baseProperty = *it;
-//             }
-//         }
-//     } catch  (const xml_schema::exception& e) {
-//         std::cout <<  e << std::endl;
-//     }
-}
-
-
-template <typename T> struct IncidenceTrait;
-
-template < > struct IncidenceTrait <KCalCore::Event>
-{
-    typedef typename icalendar_2_0::KolabEvent KolabType;
-    typedef typename KCalCore::Event IncidenceType;
-    typedef typename KCalCore::Event::Ptr IncidencePtr;
-    typedef typename KCalCore::Incidence Incidence;
-    
-    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
-    {
-        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-        
-        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
-
-        if (event.dtEnd().isValid()) {
-            icalendar_2_0::properties::dtend_type dtend;
-            setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
-            prop.dtend(dtend);
-        } else if (event.duration() != KCalCore::Duration()) {
-            
-        }
-    }
-    
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
-    {
-        components.vevent().push_back(inc);
-    }
-    
-    
-    static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
-    {
-        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
-        setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
-
-        if (prop.dtend()) {
-            KDateTime date;
-            kDebug() << "dtend";
-            event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
-            if (event.dtEnd().timeType() != event.dtStart().timeType()) {
-                kWarning() << "dtEnd has wrong timespec";
-            }
-        } else if (prop.duration()) {
-    //          KCalCore::Duration duration.;
-    //          event.setDuration(duration << prop.duration());
-        }
-        //TODO check for equality of timespecs
-        
-        if (prop.transp()) {
-            
-        }
-    }
-     
-    static icalendar_2_0::components2::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)
-    {
-        return components.vevent().end();
-    }
-    
-};
-
-template < > struct IncidenceTrait <KCalCore::Todo>
-{
-    typedef typename icalendar_2_0::KolabTodo KolabType;
-    typedef typename KCalCore::Todo IncidenceType;
-    typedef typename KCalCore::Incidence Incidence;
-    
-    static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
-    {
-       icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
-       getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
-
-    }
-
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
-    {
-        components.vtodo().push_back(inc);
-    }
-};
-
-
-template <typename T>
-typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
-{
-    typedef typename T::IncidencePtr IncidencePtr;
-    typedef typename T::IncidenceType IncidenceType;
-    typedef typename T::KolabType KolabType;
-    
-    try {
-        //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
-        xml_schema::properties props;
-
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
-        if (isUrl) {
-            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
-            std::istringstream is(s);
-            icalendar = icalendar_2_0::icalendar(is, 0, props);
-        }
-
-        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::cout <<  e << std::endl;
-        std::cout <<  "Failed to read incidence!" << std::endl;
-    }
-    return IncidencePtr();
-    
-}
-
-
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
-{
-    readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
-}
-
-KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
-{
-    
-}
-
-
-
-template <typename T>
-std::string writeIncidence(const typename T::IncidenceType &incidence) {
-    
-    using namespace icalendar_2_0;
-    typedef IncidenceConverter< typename T::Incidence > IC;
-    typedef typename T::KolabType KolabType;
-
-    try {
-
-        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::dtstamp_type dtstamp;
-        dtstamp.date_time(IC::dtstamp(incidence));
-        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(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 properties(prodid, version, x_kolab_version);
-        
-        VcalendarType vcalendar(properties, components);
-        
-        IcalendarType icalendar(vcalendar);
-
-        xml_schema::namespace_infomap map;
-        map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-        
-        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();
-    } 
-}
-
-std::string writeEvent(KCalCore::Event::Ptr event)
-{
-    return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
-}
-
-std::string writeTodo(KCalCore::Todo::Ptr todo)
-{
-    return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
-}
-
-
-
-
-
-void Test::test()
-{
-    std::cout << "test";
-}
-
-
-
 }
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 5c541c0..cb8064c 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -1,64 +1,16 @@
 
 #ifndef KOLABFORMAT_H
 #define KOLABFORMAT_H
-//#include <QString>
-#include <string>
-#include <xsd/cxx/tree/date-time.hxx>
-#include <KDE/KCalCore/Event>
 
-namespace KCalCore {
-    class Event;
-}
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "kolabcontainers.h"
 
-namespace icalendar_2_0 {
-    class VeventType;
-    class KolabEvent;
-}
 
 namespace Kolab {
 
-//class Note;
-
-/*
-enum TYPE {
-    NoteType,
-    TodoType,
-    EventType,
-    ContactType
-};*/
-
-
-//QString serializeNote(const Note &note);
-
-class Test
-{
-public:
-    void test();
-};
-
-
-struct Date {
-    int year;
-};
-
-struct Event {
-     Date date;
-};
-
-
-std::string serializeEvent();
-// void readEvent(const icalendar_2_0::VeventType &vevent);
-// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
-void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
-
-void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
-std::string writeEvent(KCalCore::Event::Ptr);
-
-void readICalendar(const std::string &s);
-
-//QString serializeEvent(const KCalCore::Event &note);
-//void readEvent(const QString &string, KCalCore::Event &);
+boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl);
+std::string writeKolabEvent(const Kolab::Event &);
 
 }
 
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index d14ae8f..3024baf 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -9,19 +9,7 @@
 /*%apply const std::string& {std::string* foo};*/
 namespace Kolab {
 
-std::string serializeEvent();
 
-class Test {
-public:
-    void test();
-};
-struct Date {
-    int year;
-};
-
-struct Event {
-    Date date;
-};
 }
 
 /*extern void readEvent(const QString &string, KCalCore::Event &); */
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index ce02581..a922628 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -10,3 +10,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 QT4_AUTOMOC(bindingstest.cpp)
 add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
 target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
+
+# QT4_AUTOMOC(kcalconversiontest.cpp)
+# add_executable(kcalconversiontest kcalconversiontest.cpp ${KCALCONVERSIONTEST_MOC})
+# target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 58fa3d1..4a2d369 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,55 +17,161 @@
 #include <kcalcore/event.h>
 #include <lib/kolabformat.h>
 #include <kdebug.h>
-#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
 
-void BindingsTest::writeNoteTest()
-{
-    xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
-    KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
-    KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
-    KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
-    KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-
-    xml_schema::namespace_infomap map;
-    map[""].name = "http://kolab.org";
-    map[""].schema = "note.xsd";
-
-    KolabXSD_test::note (std::cout, note, map);
-
-  /*  QFETCH(KCalCore::Recurrence, kcalrecurrence);
-    
-    KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
-    QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
-    */
-}
-
-void BindingsTest::readNoteTest()
-{
-    try {
-        xml_schema::properties props;
-//         props.no_namespace_schema_location ("../../schemas/note.xsd");
-//         props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
-        std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
-        
-        xml_schema::namespace_infomap map;
-        map[""].name = "http://kolab.org";
-        map[""].schema = "note.xsd";
 
-        KolabXSD_test::note (std::cout, *note, map);
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << endl;
-        QVERIFY(false);
-    } 
-}
-
-void BindingsTest::writeReadNoteTest()
-{
-
-}
+// void BindingsTest::writeNoteTest()
+// {
+//     xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
+//     KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
+//     KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
+//     KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
+//     KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
+// 
+//     xml_schema::namespace_infomap map;
+//     map[""].name = "http://kolab.org";
+//     map[""].schema = "note.xsd";
+// 
+//     KolabXSD_test::note (std::cout, note, map);
+// 
+//   /*  QFETCH(KCalCore::Recurrence, kcalrecurrence);
+//     
+//     KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
+//     QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
+//     */
+// }
 
-void BindingsTest::writeKolabXCalEvent()
-{
+// void BindingsTest::readNoteTest()
+// {
+//     try {
+//         xml_schema::properties props;
+// //         props.no_namespace_schema_location ("../../schemas/note.xsd");
+// //         props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
+//         std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
+//         
+//         xml_schema::namespace_infomap map;
+//         map[""].name = "http://kolab.org";
+//         map[""].schema = "note.xsd";
+// 
+//         KolabXSD_test::note (std::cout, *note, map);
+//     } catch  (const xml_schema::exception& e) {
+//         std::cout << e << endl;
+//         QVERIFY(false);
+//     } 
+// }
+// 
+// void BindingsTest::writeReadNoteTest()
+// {
+// 
+// }
+// 
+// void BindingsTest::writeKolabXCalEvent()
+// {
+// //     try {
+// //     //Components
+// //     icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
+// // 
+// //     icalendar_2_0::ArrayOfEventTodoContainedComponents component;
+// //     component.valarm().push_back(alarm);
+// // 
+// //     //Properties
+// // 
+// //     //Recurrence
+// //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// //     recur.count(2);
+// //     recur.byhour().push_back("3");
+// //     icalendar_2_0::RrulePropType rrule(recur);
+// // 
+// //     //Startdate
+// //     xml_schema::date_time dt(2011,8,12,2,12,15);
+// //     icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+// //     icalendar_2_0::DtstartPropType startdate;
+// //     startdate.date_time(datetime);
+// //     //Startdate timezone
+// //     ::icalendar_2_0::ArrayOfParameters parameters;
+// //     ::icalendar_2_0::TzidParamType tzid("US/Eastern");
+// //     parameters.baseParameter().push_back(tzid);
+// //     startdate.parameters(parameters);
+// //     
+// //     
+// //     //Custom value
+// //     KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
+// // 
+// //     //Assembling event properties
+// //     ::icalendar_2_0::ArrayOfProperties properties;
+// //     properties.baseProperty().push_back(startdate);
+// //     properties.baseProperty().push_back(rrule);
+// //     properties.baseProperty().push_back(custom);
+// // 
+// //     //Assembling the complete event
+// //     icalendar_2_0::VeventType event(component);
+// //     event.properties(properties);
+// //     
+// //     KolabXSD::Event kolabEvent(event);
+// //     xml_schema::namespace_infomap map;
+// //     map["kolab"].name = "http://kolab.org";
+// //     map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// //     //map["xcal"].schema = "iCalendar.xsd";
+// // 
+// //     KolabXSD::event (std::cout, kolabEvent, map);
+// //     
+// //             
+// // //     icalendar_2_0::VstrictTodoType todo;
+// // //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// // //     todo.rrule().;
+// //     
+// //     } catch  (const xml_schema::exception& e) {
+// //         std::cout << e << endl;
+// //         QVERIFY(false);
+// //     } 
+// }
+// 
+// 
+// void BindingsTest::readKolabXCalEvent()
+// {
+// //     try {
+// // //         xml_schema::properties props;
+// // //         props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
+// // //         props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
+// // //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+// // 
+// //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
+// //         
+// //         const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
+// //         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+// // 
+// //         /*for(int i = 0; i < propertyList.size(); i++) {
+// //             const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
+// //         }*/
+// //         std::cout << propertyList.size() << std::endl;
+// //         for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
+// //             if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
+// //                 std::cout << "Rrule" << std::endl;
+// //                 std::cout << d->recur().freq() << std::endl;
+// //                 std::cout << d->recur().count() << std::endl;
+// //                 //std::cout << d->recur().byhour() << std::endl;
+// //             } else {
+// //                 std::cout << "other" << std::endl;
+// //                 const icalendar_2_0::BasePropertyType &baseProperty = (*i);
+// //             }
+// //         }
+// //         
+// //         xml_schema::namespace_infomap map;
+// //         map["kolab"].name = "http://kolab.org";
+// // //         map[""].schema = "kolabevent.xsd";
+// //         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// // //         map["xcal"].schema = "iCalendar.xsd";
+// // 
+// //         KolabXSD::event (std::cout, *event, map);
+// // 
+// //     } catch  (const xml_schema::exception& e) {
+// //         std::cout << e << std::endl;
+// //         QVERIFY(false);
+// //     } 
+// }
+// 
+// #if 0
+// void BindingsTest::writeXCalEvent()
+// {
 //     try {
 //     //Components
 //     icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
@@ -80,342 +186,232 @@ void BindingsTest::writeKolabXCalEvent()
 //     recur.count(2);
 //     recur.byhour().push_back("3");
 //     icalendar_2_0::RrulePropType rrule(recur);
-// 
+//     
 //     //Startdate
-//     xml_schema::date_time dt(2011,8,12,2,12,15);
-//     icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+//     icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
 //     icalendar_2_0::DtstartPropType startdate;
-//     startdate.date_time(datetime);
-//     //Startdate timezone
-//     ::icalendar_2_0::ArrayOfParameters parameters;
-//     ::icalendar_2_0::TzidParamType tzid("US/Eastern");
-//     parameters.baseParameter().push_back(tzid);
-//     startdate.parameters(parameters);
-//     
+//     startdate.date(date);
 //     
-//     //Custom value
-//     KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-// 
-//     //Assembling event properties
 //     ::icalendar_2_0::ArrayOfProperties properties;
 //     properties.baseProperty().push_back(startdate);
 //     properties.baseProperty().push_back(rrule);
-//     properties.baseProperty().push_back(custom);
-// 
+//     
+//     
 //     //Assembling the complete event
 //     icalendar_2_0::VeventType event(component);
 //     event.properties(properties);
 //     
-//     KolabXSD::Event kolabEvent(event);
+//     
+//     icalendar_2_0::VcalendarType::components_type comp;
+//     comp.vcalendarContainedComponent().push_back(event);
+//     
+//     icalendar_2_0::VcalendarType vcalendar(comp);
+//     
+//     icalendar_2_0::IcalendarType icalendar;
+//     icalendar.vcalendar().push_back(vcalendar);
+//     
+//     /*
+//      * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
+//      * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
+//      * No idea why this happens though.
+//      */
 //     xml_schema::namespace_infomap map;
-//     map["kolab"].name = "http://kolab.org";
 //     map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-//     //map["xcal"].schema = "iCalendar.xsd";
-// 
-//     KolabXSD::event (std::cout, kolabEvent, map);
+//     //map[""].schema = "iCalendar.xsd";
 //     
-//             
-// //     icalendar_2_0::VstrictTodoType todo;
-// //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// //     todo.rrule().;
+//     icalendar_2_0::vevent (std::cout, event, map);
 //     
 //     } catch  (const xml_schema::exception& e) {
 //         std::cout << e << endl;
 //         QVERIFY(false);
 //     } 
-}
-
-
-void BindingsTest::readKolabXCalEvent()
-{
+//     #if 0
+//     catch (const xercesc_3_1::DOMException &e) {
+//         std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
+//         return;
+//     }
+// #endif
+// }
+// 
+// 
+// void BindingsTest::readXCalEvent()
+// {
+// 
 //     try {
-// //         xml_schema::properties props;
-// //         props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-// //         props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-// //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+//         xml_schema::properties props;
+// //         props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
+// //         props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
 // 
-//         std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-//         
-//         const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
-//         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+//         std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
 // 
-//         /*for(int i = 0; i < propertyList.size(); i++) {
-//             const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-//         }*/
-//         std::cout << propertyList.size() << std::endl;
-//         for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
-//             if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
-//                 std::cout << "Rrule" << std::endl;
-//                 std::cout << d->recur().freq() << std::endl;
-//                 std::cout << d->recur().count() << std::endl;
-//                 //std::cout << d->recur().byhour() << std::endl;
-//             } else {
-//                 std::cout << "other" << std::endl;
-//                 const icalendar_2_0::BasePropertyType &baseProperty = (*i);
-//             }
-//         }
-//         
 //         xml_schema::namespace_infomap map;
-//         map["kolab"].name = "http://kolab.org";
-// //         map[""].schema = "kolabevent.xsd";
 //         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// //         map["xcal"].schema = "iCalendar.xsd";
+//         map[""].schema = "iCalendar.xsd";
 // 
-//         KolabXSD::event (std::cout, *event, map);
+//         icalendar_2_0::vevent (std::cout, *event, map);
 // 
 //     } catch  (const xml_schema::exception& e) {
 //         std::cout << e << std::endl;
 //         QVERIFY(false);
 //     } 
-}
-
-#if 0
-void BindingsTest::writeXCalEvent()
-{
-    try {
-    //Components
-    icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-
-    icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-    component.valarm().push_back(alarm);
-
-    //Properties
-
-    //Recurrence
-    icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-    recur.count(2);
-    recur.byhour().push_back("3");
-    icalendar_2_0::RrulePropType rrule(recur);
-    
-    //Startdate
-    icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
-    icalendar_2_0::DtstartPropType startdate;
-    startdate.date(date);
-    
-    ::icalendar_2_0::ArrayOfProperties properties;
-    properties.baseProperty().push_back(startdate);
-    properties.baseProperty().push_back(rrule);
-    
-    
-    //Assembling the complete event
-    icalendar_2_0::VeventType event(component);
-    event.properties(properties);
-    
-    
-    icalendar_2_0::VcalendarType::components_type comp;
-    comp.vcalendarContainedComponent().push_back(event);
-    
-    icalendar_2_0::VcalendarType vcalendar(comp);
-    
-    icalendar_2_0::IcalendarType icalendar;
-    icalendar.vcalendar().push_back(vcalendar);
-    
-    /*
-     * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
-     * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
-     * No idea why this happens though.
-     */
-    xml_schema::namespace_infomap map;
-    map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-    //map[""].schema = "iCalendar.xsd";
-    
-    icalendar_2_0::vevent (std::cout, event, map);
-    
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << endl;
-        QVERIFY(false);
-    } 
-    #if 0
-    catch (const xercesc_3_1::DOMException &e) {
-        std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-        return;
-    }
-#endif
-}
-
-
-void BindingsTest::readXCalEvent()
-{
-
-    try {
-        xml_schema::properties props;
-//         props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
-//         props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
-
-        std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
-
-        xml_schema::namespace_infomap map;
-        map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-        map[""].schema = "iCalendar.xsd";
-
-        icalendar_2_0::vevent (std::cout, *event, map);
-
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << std::endl;
-        QVERIFY(false);
-    } 
-
-}
-
-#endif
+// 
+// }
+// 
+// #endif
+// 
+// void BindingsTest::xercesException()
+// {
+//     xercesc::XMLPlatformUtils::Initialize();
+//     XMLCh tempStr[100];
+// 
+//     xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
+//     
+//     xercesc::XMLString::transcode("root", tempStr, 99);
+//     xercesc::DOMDocument*   doc = impl->createDocument(0, tempStr, 0);
+//     
+// /*    XMLCh n[100];
+//     XMLCh ns[100];
+//     xercesc::XMLString::transcode("components", n, 99);
+//     xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
+//     try {
+//         xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
+//         QVERIFY(e);
+//         
+//         /*
+//         xercesc::DOMElement& s (    
+//         ::xsd::cxx::xml::dom::create_element (
+//           "components",
+//           "http://icalnamespace.org",
+//           e));
+//         */
+// 
+//     } catch (const xercesc_3_1::DOMException &e) {
+//         std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
+//         return;
+//     }
+//     
+//     doc->release();
+// }
+// 
+// void BindingsTest::writeContact()
+// {
+//     try {
+// //         KolabXSD::Contact::vcard_type vcard;
+// //         
+// //         vcard_4_0::fnPropType fn("Fritz Muster");
+// //         vcard.baseProperty().push_back(fn);
+// //         
+// //         vcard_4_0::nPropType n;
+// //         n.given().push_back("john");
+// //         n.surname().push_back("doe");
+// //         vcard.baseProperty().push_back(n);
+// //         
+// //         vcard_4_0::bdayPropType bday;
+// //         vcard_4_0::bdayPropType::date_type date(1988,12,12);
+// //         bday.date(date);
+// //         vcard.baseProperty().push_back(bday);
+// //         
+// //         KolabXSD::Contact contact(vcard);
+// //         xml_schema::namespace_infomap map;
+// //         map["kolab"].name = "http://kolab.org";
+// //         map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+// //         //map["xcal"].schema = "iCalendar.xsd";
+// // 
+// //         KolabXSD::contact (std::cout, contact, map);
+//        
+//     
+//     } catch  (const xml_schema::exception& e) {
+//         std::cout << e << endl;
+//         QVERIFY(false);
+//     } 
+// }
+// 
+// void BindingsTest::readContact()
+// {
+// 
+// }
+
+namespace QTest {
+     template<>
+     char *toString(const Kolab::DateTime &dt)
+     {
+         QByteArray ba = "DateTime(";
+         ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", ";
+         ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", ";
+         ba += QString(dt.isUTC()?QString("UTC"):QString("TZ: "+QString::fromStdString(dt.timezone()))).toAscii();
+         ba += ")";
+         return qstrdup(ba.data());
+     }
+     
+    template<>
+     char *toString(const std::string &s)
+     {
+         QByteArray ba = "string(";
+         ba += QString::fromStdString(s).toAscii();
+         ba += ")";
+         return qstrdup(ba.data());
+     }
+ }
 
-void BindingsTest::xercesException()
+void BindingsTest::readEvent()
 {
-    xercesc::XMLPlatformUtils::Initialize();
-    XMLCh tempStr[100];
-
-    xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("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));
     
-    xercesc::XMLString::transcode("root", tempStr, 99);
-    xercesc::DOMDocument*   doc = impl->createDocument(0, tempStr, 0);
+    const Kolab::RecurrenceRule &rrule = event->recurrenceRule();
+    QCOMPARE(rrule.frequency(), Kolab::RecurrenceRule::Daily);
+    QCOMPARE(rrule.count(), 5);
+    QCOMPARE(rrule.interval(), 1);
     
-/*    XMLCh n[100];
-    XMLCh ns[100];
-    xercesc::XMLString::transcode("components", n, 99);
-    xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
-    try {
-        xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
-        QVERIFY(e);
-        
-        /*
-        xercesc::DOMElement& s (    
-        ::xsd::cxx::xml::dom::create_element (
-          "components",
-          "http://icalnamespace.org",
-          e));
-        */
-
-    } catch (const xercesc_3_1::DOMException &e) {
-        std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-        return;
-    }
-    
-    doc->release();
-}
-
-void BindingsTest::writeContact()
-{
-    try {
-//         KolabXSD::Contact::vcard_type vcard;
-//         
-//         vcard_4_0::fnPropType fn("Fritz Muster");
-//         vcard.baseProperty().push_back(fn);
-//         
-//         vcard_4_0::nPropType n;
-//         n.given().push_back("john");
-//         n.surname().push_back("doe");
-//         vcard.baseProperty().push_back(n);
-//         
-//         vcard_4_0::bdayPropType bday;
-//         vcard_4_0::bdayPropType::date_type date(1988,12,12);
-//         bday.date(date);
-//         vcard.baseProperty().push_back(bday);
-//         
-//         KolabXSD::Contact contact(vcard);
-//         xml_schema::namespace_infomap map;
-//         map["kolab"].name = "http://kolab.org";
-//         map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
-//         //map["xcal"].schema = "iCalendar.xsd";
-// 
-//         KolabXSD::contact (std::cout, contact, map);
-       
-    
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << endl;
-        QVERIFY(false);
-    } 
+    QCOMPARE(event->summary(), std::string("Event #2"));
 }
 
-void BindingsTest::readContact()
+void BindingsTest::writeEvent()
 {
-
+    Kolab::Event event;
+    event.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+    event.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    Kolab::RecurrenceRule rrule;
+    rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+    rrule.setInterval(3);
+    rrule.setCount(5);
+    event.setRecurrenceRule(rrule);
+    std::cout << Kolab::writeKolabEvent(event) << std::endl;
 }
 
-
-void BindingsTest::readEvent()
+void BindingsTest::roundtripEvent()
 {
-    
-    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
-    QVERIFY(event);
-    
-    //Check basics
-    QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
-    QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
-    QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-    QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
-
-    //Check recurrence
-    //TODO do some "heavy" testing for recurrences, including possible edge cases.
-
-    //Check recurrence rule
-    foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
-        QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
-    }
-    QCOMPARE(event->recurrence()->rRules().size(), 1);
-    KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
-    QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
-    QCOMPARE(rule->duration(), 5);
-    KDateTime start(event->dtStart());
-    KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
-    QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
-    QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
-    const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
-    foreach (const KDateTime &d, ruleList) {
-        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-//         kDebug() << d << d.timeZone().name();
-    }
-    QCOMPARE(ruleList.first(), event->dtStart());
-    QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
-    //Check complete recurrence
-    const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);  
-    foreach (const KDateTime &d, list) {
-        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-//         kDebug() << d << d.timeZone().name();
-    }
-    
-    QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
-    kDebug() << event->summary();
-//     QCOMPARE(event->summary(), QString::fromUtf8("Test.&#x0a;Test.Test.")); //FIXME fix control character &#x0a; (linefeed)
-    kDebug() << event->description();
+    Kolab::Event event;
+    event.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+    event.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    Kolab::RecurrenceRule rrule;
+    rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+    rrule.setInterval(3);
+    rrule.setCount(5);
+    event.setRecurrenceRule(rrule);
+    std::string result = Kolab::writeKolabEvent(event);
+    std::cout << result << std::endl;
 }
 
-void BindingsTest::writeEvent()
+void BindingsTest::roundtripReverseEvent()
 {
-    KCalCore::Event::Ptr event(new KCalCore::Event);
-    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-    
-    KCalCore::Recurrence *recurrence = event->recurrence();
-    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
-    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-    rule->setFrequency(3);
-    rule->setDuration(5);
-    recurrence->addRRule(rule);
-    
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
     kDebug() << "-------------------";
-    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    std::cout << Kolab::writeKolabEvent(*event) << std::endl;
     kDebug() << "-------------------";
 }
 
-void BindingsTest::roundtripEvent()
+void BindingsTest::BenchmarkRoundtrip()
 {
-    KCalCore::Event::Ptr event(new KCalCore::Event);
-    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-    
-    KCalCore::Recurrence *recurrence = event->recurrence();
-    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
-    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-    rule->setFrequency(3);
-    rule->setDuration(5);
-    recurrence->addRRule(rule);
-    
-    QString result = QString::fromStdString(Kolab::writeEvent(event));
-    kDebug() << result;
-    KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
-    QVERIFY(resEvent);
-    QCOMPARE(event->dtStart(), resEvent->dtStart());
+    boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+    std::string result;
+    result = Kolab::writeKolabEvent(*event);
+    QBENCHMARK {
+        
+        Kolab::readKolabEvent(result, false);
+    }
 }
 
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index bb63dd2..f5aac9e 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -9,25 +9,26 @@ class BindingsTest : public QObject
   Q_OBJECT
   private slots:
       
-     void writeKolabXCalEvent();
-     void readKolabXCalEvent();
-    //void writeXCalEvent();
-    //void readXCalEvent();
-      
-    void writeNoteTest();
-    void readNoteTest();
-    void writeReadNoteTest();
-    void xercesException();
-    
-    void writeContact();
-    void readContact();
+//      void writeKolabXCalEvent();
+//      void readKolabXCalEvent();
+//     //void writeXCalEvent();
+//     //void readXCalEvent();
+//       
+//     void writeNoteTest();
+//     void readNoteTest();
+//     void writeReadNoteTest();
+//     void xercesException();
+//     
+//     void writeContact();
+//     void readContact();
     
     
     //Kolabformat
     void readEvent();
     void writeEvent();
     void roundtripEvent();
-
+    void roundtripReverseEvent();
+    void BenchmarkRoundtrip();
 };
 
 #endif
\ No newline at end of file
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 0599471..15d90fe 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -3,8 +3,130 @@
 #include <QtCore/QObject>
 #include <QtTest/QtTest>
 #include <kcalcore/recurrence.h>
-#include <lib/kolabkcalconversion.h>
 
+#include <lib/kcalconversions.h>
+#include <lib/kcalkolabformat.h>
+
+
+void KCalConversionTest::testDate()
+{
+    KDateTime dt1(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    xml_schema::date_time date1 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt1);
+    QCOMPARE(date1.zone_present(), true);
+    
+    KDateTime dt2(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0)));
+    xml_schema::date_time date2 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt2);
+    QCOMPARE(date2.zone_present(), false);
+    
+    KDateTime dt3(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
+    xml_schema::date_time date3 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt3);
+    QCOMPARE(date3.zone_present(), false);
+}
+
+void KCalConversionTest::readEvent()
+{
+    
+    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    QVERIFY(event);
+    
+    //Check basics
+    QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
+    QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
+    QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
+
+    //Check recurrence
+    //TODO do some "heavy" testing for recurrences, including possible edge cases.
+
+    //Check recurrence rule
+    foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
+        QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
+    }
+    QCOMPARE(event->recurrence()->rRules().size(), 1);
+    KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
+    QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
+    QCOMPARE(rule->duration(), 5);
+    KDateTime start(event->dtStart());
+    KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
+    QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
+    QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
+    const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
+    foreach (const KDateTime &d, ruleList) {
+        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+//         kDebug() << d << d.timeZone().name();
+    }
+    QCOMPARE(ruleList.first(), event->dtStart());
+    QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+    //Check complete recurrence
+    const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);  
+    foreach (const KDateTime &d, list) {
+        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+//         kDebug() << d << d.timeZone().name();
+    }
+    
+    QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
+    kDebug() << event->summary();
+//     QCOMPARE(event->summary(), QString::fromUtf8("Test.&#x0a;Test.Test.")); //FIXME fix control character &#x0a; (linefeed)
+    kDebug() << event->description();
+}
+
+void KCalConversionTest::writeEvent()
+{
+
+    KCalCore::Event::Ptr event(new KCalCore::Event);
+    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    
+    KCalCore::Recurrence *recurrence = event->recurrence();
+    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+    rule->setFrequency(3);
+    rule->setDuration(5);
+    recurrence->addRRule(rule);
+    
+    kDebug() << "-------------------";
+    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << "-------------------";
+}
+
+void KCalConversionTest::roundtripReverseEvent()
+{
+    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    kDebug() << "-------------------";
+    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << "-------------------";
+}
+
+void KCalConversionTest::roundtripEvent()
+{
+    KCalCore::Event::Ptr event(new KCalCore::Event);
+    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    
+    KCalCore::Recurrence *recurrence = event->recurrence();
+    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+    rule->setFrequency(3);
+    rule->setDuration(5);
+    recurrence->addRRule(rule);
+    
+    QString result = QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << result;
+    KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
+    QVERIFY(resEvent);
+    QCOMPARE(event->dtStart(), resEvent->dtStart());
+}
+
+void KCalConversionTest::BenchmarkRoundtrip()
+{
+    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+    std::string result;
+    QBENCHMARK {
+        result = Kolab::writeEvent(event);
+        Kolab::readEvent(result, false);
+    }
+}
 
 void KCalConversionTest::testConversion_data()
 {
@@ -18,12 +140,6 @@ void KCalConversionTest::testConversion_data()
     QTest::newRow( "test1" ) << recurrence;
     */
 }
-
-uint frequency(const KolabXSD::Recurrence &r) 
-{
-   
-    return 2;
-}
     
 void KCalConversionTest::testConversion()
 {
@@ -221,6 +337,8 @@ class KCalConversionTest : public QObject
     }*/
 };
 #endif
+
+
 QTEST_MAIN( KCalConversionTest )
 
-//#include "moc_kcalconversiontest.cxx"
+#include "moc_kcalconversiontest.cxx"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index 826147f..f1f5a32 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -12,6 +12,13 @@ class KCalConversionTest : public QObject
     void testConversion_data();
     void testConversion();
 
+    void testDate();
+    
+    void readEvent();
+    void writeEvent();
+    void roundtripEvent();
+    void roundtripReverseEvent();
+    void BenchmarkRoundtrip();
 };
 
 #endif
\ No newline at end of file


commit c992cd574b01816550198f77613ca5a2c82b8063
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 01:37:35 2011 +0100

    Preparations for compiled schemas

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 2bc4fe1..dd1512e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -14,6 +14,8 @@ file(MAKE_DIRECTORY bindings)
 set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
 set( XSDCXX  /usr/bin/xsdcxx)
 
+
+# Generate Kolab bindings
 file(GLOB KOLAB_SCHEMAS ${SCHEMA_DIR}/*.xsd)
 set( KOLAB_SCHEMA_SOURCEFILES  
     bindings/base.cxx
@@ -29,6 +31,11 @@ add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
     VERBATIM
     )
 
+
+
+
+# Generate XCal bindings
+
 file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
 set( XCAL_SCHEMA_SOURCEFILES  
     bindings/xCard.cxx
@@ -45,7 +52,10 @@ set( XCAL_SCHEMA_SOURCEFILES
 #     bindings/iCalendar-availability-extension.cxx
 #     bindings/iCalendar-wscal-extensions.cxx
 )
-# --cxx-suffix .cpp --hxx-suffix .h  
+
+#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 ${XCAL_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 bindings ${XCAL_SCHEMAS}
     COMMENT "Generating xCal XSD bindings"
@@ -53,15 +63,34 @@ add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
     DEPENDS ${XCAL_SCHEMAS}
     VERBATIM
     )
-
 set( SCHEMA_SOURCEFILES ${XCAL_SCHEMA_SOURCEFILES} ${KOLAB_SCHEMA_SOURCEFILES})
 
+# Compile Schema
+add_executable(xsdbin compiled/xsdbin.cxx)
+target_link_libraries(xsdbin xerces-c)
+
+add_custom_command(OUTPUT compiled/kolabformat-xcal-schema.cxx
+    COMMAND ${xsdbin} ./xsdbin --verbose --array-name iCalendar_schema --output-dir compiled/   ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+    COMMENT "Compiling Kolab XSD schema"
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    DEPENDS ${XCAL_SCHEMAS} xsdbin
+    VERBATIM
+    )
+set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} compiled/kolabformat-xcal-schema.cxx)
+
+# ---------
+
 SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 
 ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
 
 include_directories( ./ )
-add_library(kolabxml lib/kolabformat.cpp ${SCHEMA_SOURCEFILES})
-target_link_libraries(${kolabxml} xerces-c)
+
+add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxml xerces-c)
+
+add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxmlkcal xerces-c)
+
 add_subdirectory(tests)
 add_subdirectory(lib)
diff --git a/c++/compiled/README b/c++/compiled/README
new file mode 100644
index 0000000..d3a07b8
--- /dev/null
+++ b/c++/compiled/README
@@ -0,0 +1,18 @@
+According to the xsd example in xsd/examples/cxx/tree/embedded/
+
+xsdbin.cxx
+  Tool for converting one or more XML Schema files to the compressed binary
+  representation. The output is written as a pair of C++ source files 
+  containing the array with the binary data. Use the --help option to see
+  the tool's usage information.
+
+library-schema.hxx
+library-schema.cxx
+  Binary representation of the library.xsd schema. These files are generated
+  by the xsdbin tool.
+
+grammar-input-stream.hxx
+grammar-input-stream.cxx
+  Input stream implementation with the special-purpose schema grammar 
+  decompression algorithm. It is used to load the binary schema representation
+  produced by the xsdbin tool.
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
new file mode 100644
index 0000000..43fe477
--- /dev/null
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -0,0 +1,250 @@
+#include "XMLParserWrapper.h"
+
+#include <memory>   // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "kolabformat-xcal-schema.hxx"
+#include "grammar-input-stream.hxx"
+
+XMLParserWrapper::XMLParserWrapper()
+{
+    // We need to initialize the Xerces-C++ runtime because we
+    // are doing the XML-to-DOM parsing ourselves.
+    //
+    xercesc::XMLPlatformUtils::Initialize ();
+    init();
+}
+
+
+XMLParserWrapper::~XMLParserWrapper()
+{
+//     xercesc::XMLPlatformUtils::Terminate ();
+//FIXME if this is enabled we get a segfault, maybe because the scope_ptr are note yet destructed?
+}
+
+
+void XMLParserWrapper::init()
+{
+    using namespace std;
+
+    try
+    {
+        using namespace xercesc;
+        namespace xml = xsd::cxx::xml;
+        namespace tree = xsd::cxx::tree;
+        // Create and load the grammar pool.
+        //
+        MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+        gp.reset (new XMLGrammarPoolImpl (mm));
+
+        try
+        {
+            grammar_input_stream is (iCalendar_schema, sizeof (iCalendar_schema));
+            gp->deserializeGrammars(&is);
+        }
+        catch(const XSerializationException& e)
+        {
+            cerr << "unable to load schema: " << xml::transcode<char> (e.getMessage ()) << endl;
+            return;
+        }
+
+        // Lock the grammar pool. This is necessary if we plan to use the
+        // same grammar pool in multiple threads (this way we can reuse the
+        // same grammar in multiple parsers). Locking the pool disallows any
+        // modifications to the pool, such as an attempt by one of the threads
+        // to cache additional schemas.
+        //
+        gp->lockPool ();
+
+        // Get an implementation of the Load-Store (LS) interface.
+        //
+        const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+        DOMImplementation* impl (
+        DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+    #if _XERCES_VERSION >= 30000
+
+        // Xerces-C++ 3.0.0 and later.
+        //
+        parser.reset(impl->createLSParser (
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+
+        DOMConfiguration* conf (parser->getDomConfig ());
+
+        // Discard comment nodes in the document.
+        //
+        conf->setParameter (XMLUni::fgDOMComments, false);
+
+        // Enable datatype normalization.
+        //
+        conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+        // Do not create EntityReference nodes in the DOM tree. No
+        // EntityReference nodes will be created, only the nodes
+        // corresponding to their fully expanded substitution text
+        // will be created.
+        //
+        conf->setParameter (XMLUni::fgDOMEntities, false);
+
+        // Perform namespace processing.
+        //
+        conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+        // Do not include ignorable whitespace in the DOM tree.
+        //
+        conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+        // Enable validation.
+        //
+        conf->setParameter (XMLUni::fgDOMValidate, true);
+        conf->setParameter (XMLUni::fgXercesSchema, true);
+        conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+        // Xerces-C++ 3.1.0 is the first version with working multi import
+        // support.
+        //
+    #if _XERCES_VERSION >= 30100
+        conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+    #endif
+
+        // Use the loaded grammar during parsing.
+        //
+        conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+        // Disable loading schemas via other means (e.g., schemaLocation).
+        //
+        conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+        // We will release the DOM document ourselves.
+        //
+        conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+        
+        
+
+        // Set error handler.
+        //
+//         tree::error_handler<char> eh;
+        xml::dom::bits::error_handler_proxy<char> ehp (eh);
+        conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
+
+    #else // _XERCES_VERSION >= 30000
+
+        // Same as above but for Xerces-C++ 2 series.
+        //
+        parser.reset (
+        impl->createDOMBuilder(
+            DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+
+
+        parser->setFeature (XMLUni::fgDOMComments, false);
+        parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+        parser->setFeature (XMLUni::fgDOMEntities, false);
+        parser->setFeature (XMLUni::fgDOMNamespaces, true);
+        parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+        parser->setFeature (XMLUni::fgDOMValidation, true);
+        parser->setFeature (XMLUni::fgXercesSchema, true);
+        parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+        parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+        parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+        //tree::error_handler<char> eh;
+        xml::dom::bits::error_handler_proxy<char> ehp (eh);
+        parser->setErrorHandler (&ehp);
+
+    #endif // _XERCES_VERSION >= 30000
+
+        // Parse XML documents.
+        //
+        
+    }
+    catch (const xml_schema::exception& e)
+    {
+        cout << "schema exception" << endl;
+        cerr << e << endl;
+    }
+    catch (const std::ios_base::failure&)
+    {
+        cerr << ": unable to open or read failure" << endl;
+    }
+    
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
+{
+    std::ifstream ifs;
+    ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
+    ifs.open (url.c_str());
+    return parse(ifs, url);
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
+{
+    std::istringstream is(s);
+    return parse(is, "");
+}
+
+
+xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::istream &ifs, const std::string &name)
+{
+    using namespace std;
+
+    try
+    {
+        using namespace xercesc;
+        namespace xml = xsd::cxx::xml;
+        namespace tree = xsd::cxx::tree;
+
+        // Parse XML documents.
+        //
+        {
+            // Wrap the standard input stream.
+            //
+            xml::sax::std_input_source isrc (ifs, name);
+            Wrapper4InputSource wrap (&isrc, false);
+
+            // Parse XML to DOM.
+            //
+        #if _XERCES_VERSION >= 30000
+            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+        #else
+            xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+        #endif
+
+            eh.throw_if_failed<xml_schema::parsing> ();
+            return doc;
+        }
+    }
+    catch (const xml_schema::exception& e)
+    {
+        cout << "schema exception" << endl;
+        cerr << e << endl;
+    }
+    catch (const std::ios_base::failure&)
+    {
+        cerr << ": unable to open or read failure" << endl;
+    }
+
+    return xml_schema::dom::auto_ptr<xercesc::DOMDocument>();
+}
\ No newline at end of file
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
new file mode 100644
index 0000000..643b61e
--- /dev/null
+++ b/c++/compiled/XMLParserWrapper.h
@@ -0,0 +1,62 @@
+#ifndef XMLPARSER_WRAPPER_H
+#define XMLPARSER_WRAPPER_H
+
+#include <string>
+#include <auto_ptr.h>
+#include <bindings/kolabformat-xcal.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+#include <boost/scoped_ptr.hpp>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/dom/DOMLSParser.hpp>
+#  include <xercesc/dom/DOMLSException.hpp>
+#else
+#  include <xercesc/dom/DOMBuilder.hpp>
+#endif
+
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/framework/XMLGrammarPool.hpp>
+#else
+#  include <xercesc/internal/XMLGrammarPool.hpp>
+#endif
+
+class XMLParserWrapper {
+public:
+    XMLParserWrapper();
+    ~XMLParserWrapper();
+
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
+    xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
+private:
+    void init();
+    
+    xsd::cxx::tree::error_handler<char> eh;
+    
+    #if _XERCES_VERSION >= 30000
+        boost::scoped_ptr<xercesc::DOMLSParser>  parser;
+    #else
+        boost::scoped_ptr<xercesc::DOMBuilder>  parser;
+    #endif
+        
+    boost::scoped_ptr<xercesc::XMLGrammarPool> gp;
+};
+
+//     static XMLParserWrapper inst(){
+//         static XMLParserWrapper instance;
+//         return instance;
+//     };
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c++/compiled/grammar-input-stream.cxx b/c++/compiled/grammar-input-stream.cxx
new file mode 100644
index 0000000..0c94ea6
--- /dev/null
+++ b/c++/compiled/grammar-input-stream.cxx
@@ -0,0 +1,115 @@
+// file      : examples/cxx/tree/embedded/grammar-input-stream.cxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+      : data_ (data),
+        size_ (size),
+        pos_ (0),
+        vpos_ (0),
+        cseq_ (0),
+        add_zero_ (false)
+{
+}
+
+#if _XERCES_VERSION >= 30000
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+  return static_cast<XMLFilePos> (vpos_);
+}
+#else
+unsigned int grammar_input_stream::
+curPos () const
+{
+  return static_cast<unsigned int> (vpos_);
+}
+#endif
+
+#if _XERCES_VERSION >= 30000
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+#else
+unsigned int grammar_input_stream::
+readBytes (XMLByte* const buf, const unsigned int size)
+#endif
+{
+  std::size_t i (0);
+
+  // Add a zero from the alternating sequence if it didn't
+  // fit on the previous read.
+  //
+  if (add_zero_)
+  {
+    buf[i++] = 0;
+    add_zero_ = false;
+  }
+
+  // If have an unfinished sequential sequence, output it now.
+  //
+  if (cseq_ != 0 && !alt_)
+  {
+    for (; cseq_ != 0 && i < size; --cseq_)
+      buf[i++] = 0;
+  }
+
+  for (; i < size && pos_ < size_;)
+  {
+    XMLByte b = buf[i++] = data_[pos_++];
+
+    // See if we are in a compression sequence.
+    //
+    if (cseq_ != 0)
+    {
+      if (i < size)
+        buf[i++] = 0;
+      else
+        add_zero_ = true; // Add it on the next read.
+
+      cseq_--;
+      continue;
+    }
+
+    // If we are not in a compression sequence and this byte is
+    // not zero then we are done.
+    //
+    if (b != 0)
+      continue;
+
+    // We have a zero.
+    //
+    assert (pos_ < size_); // There has to be another byte.
+    unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+    alt_ = (v & 128) != 0;
+    cseq_ = v & 127;
+
+    // If it is a sequential sequence, output as many zeros as
+    // we can.
+    //
+    if (!alt_)
+    {
+      for (; cseq_ != 0 && i < size; --cseq_)
+        buf[i++] = 0;
+    }
+  }
+
+  vpos_ += i;
+
+#if _XERCES_VERSION >= 30000
+  return static_cast<XMLSize_t> (i);
+#else
+  return static_cast<unsigned int> (i);
+#endif
+}
+
+#if _XERCES_VERSION >= 30000
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+  return 0;
+}
+#endif
diff --git a/c++/compiled/grammar-input-stream.hxx b/c++/compiled/grammar-input-stream.hxx
new file mode 100644
index 0000000..a1b73c6
--- /dev/null
+++ b/c++/compiled/grammar-input-stream.hxx
@@ -0,0 +1,53 @@
+// file      : examples/cxx/tree/embedded/grammar-input-stream.hxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef GRAMMAR_INPUT_STREAM_HXX
+#define GRAMMAR_INPUT_STREAM_HXX
+
+#include <cstddef>
+#include <xercesc/util/BinInputStream.hpp>
+
+// Memory buffer input stream with the special-purpose schema
+// grammar decompression.
+//
+class grammar_input_stream: public xercesc::BinInputStream
+{
+public :
+  grammar_input_stream (const XMLByte* data, std::size_t size);
+
+#if _XERCES_VERSION >= 30000
+
+  virtual XMLFilePos
+  curPos () const;
+
+  virtual XMLSize_t
+  readBytes (XMLByte* const buf, const XMLSize_t size);
+
+  virtual const XMLCh*
+  getContentType () const;
+
+#else
+
+  virtual unsigned int
+  curPos () const;
+
+  virtual unsigned int
+  readBytes (XMLByte* const buf, const unsigned int size);
+
+#endif
+
+private :
+  const XMLByte* data_;
+  std::size_t size_;
+  std::size_t pos_;
+  std::size_t vpos_;
+
+  // Compression data.
+  //
+  size_t cseq_;   // Number of bytes left in a compression sequence.
+  bool alt_;      // Alternating or sequential sequence.
+  bool add_zero_; // Add a zero on the next read.
+};
+
+#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/c++/compiled/xsdbin.cxx b/c++/compiled/xsdbin.cxx
new file mode 100644
index 0000000..53e2533
--- /dev/null
+++ b/c++/compiled/xsdbin.cxx
@@ -0,0 +1,505 @@
+// file      : examples/cxx/tree/embedded/xsdbin.cxx
+// author    : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// This program loads the XML Schema file(s) and converts them to
+// the Xerces-C++ binary schema format which can then be embedded
+// into C++ programs and used to validate XML documents. The output
+// is written as a C++ source file containing the array with the
+// binary data.
+//
+
+#include <string>
+#include <memory>   // std::auto_ptr
+#include <cstddef>  // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XercesVersion.hpp>
+
+#include <xercesc/internal/BinMemOutputStream.hpp>
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#if _XERCES_VERSION >= 30000
+#  include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+#  include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+using namespace std;
+using namespace xercesc;
+
+class error_handler: public ErrorHandler
+{
+public:
+  error_handler ()
+      : failed_ (false)
+  {
+  }
+
+  bool
+  failed () const
+  {
+    return failed_;
+  }
+
+  enum severity {s_warning, s_error, s_fatal};
+
+  virtual void
+  warning (const SAXParseException&);
+
+  virtual void
+  error (const SAXParseException&);
+
+  virtual void
+  fatalError (const SAXParseException&);
+
+  virtual void
+  resetErrors ()
+  {
+    failed_ = false;
+  }
+
+  void
+  handle (const SAXParseException&, severity);
+
+private:
+  bool failed_;
+};
+
+void
+cxx_escape (string&);
+
+int
+main (int argc, char* argv[])
+{
+  const char* hxx_suffix = "-schema.hxx";
+  const char* cxx_suffix = "-schema.cxx";
+
+  string name;
+  string base;
+  string outdir;
+
+  class usage {};
+
+  int argi (1);
+  bool help (false);
+  bool multi_import (true);
+  bool verbose (false);
+
+  try
+  {
+    for (; argi < argc; ++argi)
+    {
+      string a (argv[argi]);
+
+      if (a == "--help")
+      {
+        help = true;
+        throw usage ();
+      }
+      else if (a == "--verbose")
+      {
+        verbose = true;
+      }
+      else if (a == "--hxx-suffix")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        hxx_suffix = argv[argi];
+      }
+      else if (a == "--cxx-suffix")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        cxx_suffix = argv[argi];
+      }
+      else if (a == "--output-dir")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        outdir = argv[argi];
+      }
+      else if (a == "--array-name")
+      {
+        if (++argi >= argc)
+          throw usage ();
+
+        name = argv[argi];
+      }
+      else if (a == "--disable-multi-import")
+      {
+        multi_import = false;
+      }
+      else
+        break;
+    }
+
+    if (argi >= argc)
+    {
+      cerr << "no input file specified" << endl;
+      throw usage ();
+    }
+
+    base = argv[argi];
+  }
+  catch (usage const&)
+  {
+    cerr << "Usage: " << argv[0] << " [options] <files>" << endl
+         << "Options:" << endl
+         << "  --help                 Print usage information and exit." << endl
+         << "  --verbose              Print progress information." << endl
+         << "  --output-dir <dir>     Write generated files to <dir>." << endl
+         << "  --hxx-suffix <sfx>     Header file suffix instead of '-schema.hxx'." << endl
+         << "  --cxx-suffix <sfx>     Source file suffix instead of '-schema.cxx'." << endl
+         << "  --array-name <name>    Binary data array name." << endl
+         << "  --disable-multi-import Disable multiple import support." << endl
+         << endl;
+
+    return help ? 0 : 1;
+  }
+
+  XMLPlatformUtils::Initialize ();
+
+  {
+    MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+    auto_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
+
+    // Load the schemas into grammar pool.
+    //
+    {
+      auto_ptr<SAX2XMLReader> parser (
+        XMLReaderFactory::createXMLReader (mm, gp.get ()));
+
+      parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+      parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+      parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
+      parser->setFeature (XMLUni::fgXercesSchema, true);
+      parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true);
+      parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+      // Xerces-C++ 3.1.0 is the first version with working multi import
+      // support.
+      //
+#if _XERCES_VERSION >= 30100
+      parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import);
+#endif
+
+      error_handler eh;
+      parser->setErrorHandler (&eh);
+
+      for (; argi < argc; ++argi)
+      {
+        if (verbose)
+          cerr << "loading " << argv[argi] << endl;
+
+        if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true))
+        {
+          cerr << argv[argi] << ": error: unable to load" << endl;
+          return 1;
+        }
+
+        if (eh.failed ())
+          return 1;
+      }
+    }
+
+    // Get the binary representation.
+    //
+    BinMemOutputStream data;
+
+    try
+    {
+      gp->serializeGrammars (&data);
+    }
+    catch (const XSerializationException& e)
+    {
+      char* msg (XMLString::transcode (e.getMessage ()));
+      cerr << "error: " << msg << endl;
+      XMLString::release (&msg);
+      return 1;
+    }
+
+    size_t n (static_cast<size_t> (data.curPos ()));
+    const unsigned char* buf (
+      static_cast<const unsigned char*> (data.getRawBuffer ()));
+
+    if (verbose)
+      cerr << "uncomressed data size " << n << " bytes" << endl;
+
+    // Compress zeros.
+    //
+    size_t cn (0);
+    unsigned char* cbuf = new unsigned char[n];
+
+    size_t cseq (0);  // Number of bytes left in a compression sequence.
+    bool alt (false); // Alternating or sequential sequence.
+
+    for (size_t i (0); i < n;)
+    {
+      unsigned char v (buf[i++]);
+
+      // See if we are in a compression sequence.
+      //
+      if (cseq != 0)
+      {
+        // See if this byte needs to be copied.
+        //
+        if (alt && cseq % 2 == 0)
+          cbuf[cn++] = v;
+
+        cseq--;
+        continue;
+      }
+
+      // If we are not in a compression sequence and this byte is
+      // not zero then simply copy it.
+      //
+      if (v != 0)
+      {
+        cbuf[cn++] = v;
+        continue;
+      }
+
+      // We have a zero.
+      //
+      cbuf[cn++] = 0;
+
+      // See if we can start a new compression sequence.
+      //
+      if (i < n)
+      {
+        if (buf[i] == 0)
+        {
+          // Sequential sequence. See how far it runs.
+          //
+          alt = false;
+
+          for (cseq = 1; cseq < 127 && cseq + i < n; cseq++)
+            if (buf[cseq + i] != 0)
+              break;
+        }
+        else if (i + 1 < n && buf[i + 1] == 0)
+        {
+          // Alternating sequence. See how far it runs.
+          //
+          alt = true;
+
+          for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++)
+          {
+            if (buf[cseq * 2 + i + 1] != 0)
+              break;
+
+            // For longer sequences prefer sequential to alternating.
+            //
+            if (cseq > 2 &&
+                buf[cseq * 2 + i] == 0 &&
+                buf[(cseq - 1) * 2 + i] == 0 &&
+                buf[(cseq - 2) * 2 + i] == 0)
+            {
+              cseq -= 2;
+              break;
+            }
+          }
+
+          cseq *= 2;
+        }
+      }
+
+      if (cseq != 0)
+      {
+        cbuf[cn++] = static_cast<unsigned char> (
+          alt ? (128  | cseq / 2) : cseq);
+      }
+      else
+        cbuf[cn++] = 0;
+    }
+
+    if (verbose)
+      cerr << "comressed data size " << cn << " bytes" << endl;
+
+    buf = cbuf;
+    n = cn;
+
+    // Figure out the file names.
+    //
+    string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\'));
+
+    if (p1 != string::npos && p1 > p)
+      p = p1;
+
+    if (p != string::npos)
+      base = string (base, p + 1);
+
+    p = base.rfind ('.');
+
+    if (p != string::npos)
+      base.resize (p);
+
+    string hxx (base + hxx_suffix);
+    string cxx (base + cxx_suffix);
+
+    if (!outdir.empty ())
+    {
+#if defined (WIN32) || defined (__WIN32__)
+      hxx = outdir + '\\' + hxx;
+      cxx = outdir + '\\' + cxx;
+#else
+      hxx = outdir + '/' + hxx;
+      cxx = outdir + '/' + cxx;
+#endif
+    }
+
+    if (name.empty ())
+    {
+      name = base + "_schema";
+      cxx_escape (name);
+    }
+
+    // Write header.
+    //
+    {
+      ofstream os (hxx.c_str ());
+
+      if (!os.is_open ())
+      {
+        cerr << hxx << ": error: unable to open" << endl;
+        return 1;
+      }
+
+      os << "// Automatically generated. Do not edit." << endl
+         << "//" << endl
+         << endl
+         << "#include <xercesc/util/XercesDefs.hpp>" << endl
+         << endl
+         << "extern const XMLByte " << name << "[" << n << "UL];" << endl;
+    }
+
+    {
+      ofstream os (cxx.c_str ());
+
+      if (!os.is_open ())
+      {
+        cerr << cxx << ": error: unable to open" << endl;
+        return 1;
+      }
+
+      os << "// Automatically generated. Do not edit." << endl
+         << "//" << endl
+         << endl
+         << "#include <xercesc/util/XercesDefs.hpp>" << endl
+         << "#include <xercesc/util/XercesVersion.hpp>" << endl
+         << endl
+         << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " <<
+        XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl
+         << "#  error incompatible Xerces-C++ version detected" << endl
+         << "#endif" << endl
+         << endl
+         << "extern const XMLByte " << name << "[" << n << "UL] =" << endl
+         << "{";
+
+      for (size_t i (0); i < n; ++i)
+      {
+        if (i != 0)
+          os << ',';
+
+        os << (i % 12 == 0 ? "\n  " : " ") << "0x";
+        os.width (2);
+        os.fill ('0');
+        os << hex << static_cast<unsigned short> (buf[i]);
+      }
+
+      os << endl
+         << "};" << endl
+         << endl;
+    }
+
+    delete[] cbuf;
+  }
+
+  XMLPlatformUtils::Terminate ();
+}
+
+void
+cxx_escape (string& s)
+{
+  for (string::size_type i (0); i < s.size (); ++i)
+  {
+    char& c (s[i]);
+
+    if (i == 0)
+    {
+      if (!((c >= 'a' && c <= 'z') ||
+            (c >= 'A' && c <= 'Z') ||
+            c == '_'))
+        c = '_';
+    }
+    else
+    {
+      if (!((c >= 'a' && c <= 'z') ||
+            (c >= 'A' && c <= 'Z') ||
+            (c >= '0' && c <= '9') ||
+            c == '_'))
+        c = '_';
+    }
+  }
+}
+
+void error_handler::
+warning (const SAXParseException& e)
+{
+  handle (e, s_warning);
+}
+
+void error_handler::
+error (const SAXParseException& e)
+{
+  failed_ = true;
+  handle (e, s_error);
+}
+
+void error_handler::
+fatalError (const SAXParseException& e)
+{
+  failed_ = true;
+  handle (e, s_fatal);
+}
+
+void error_handler::
+handle (const SAXParseException& e, severity s)
+{
+  const XMLCh* xid (e.getPublicId ());
+
+  if (xid == 0)
+    xid = e.getSystemId ();
+
+  char* id (XMLString::transcode (xid));
+  char* msg (XMLString::transcode (e.getMessage ()));
+
+  cerr << id << ":";
+
+#if _XERCES_VERSION >= 30000
+  cerr << e.getLineNumber () << ":" << e.getColumnNumber () << " ";
+#else
+  XMLSSize_t l (e.getLineNumber ());
+  XMLSSize_t c (e.getColumnNumber ());
+  cerr << (l == -1 ? 0 : l) << ":" << (c == -1 ? 0 : c) << " ";
+#endif
+
+  cerr << (s == s_warning ? "warning: " : "error: ") << msg << endl;
+
+  XMLString::release (&id);
+  XMLString::release (&msg);
+}


commit ea4c6f58b615398f3b148aa6142572a03392509a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 01:08:28 2011 +0100

    wall

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 24bea1e..2bc4fe1 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -7,6 +7,8 @@ include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
 
 set(CMAKE_BUILD_TYPE Debug)
 
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
+
 file(MAKE_DIRECTORY bindings)
 
 set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )


commit ee3f2e620658928d9e6bbb672ed46516a8b07f97
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 23 01:08:17 2011 +0100

    containers

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index c109067..9804106 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -17,6 +17,14 @@ add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
     DEPENDS kolabformat.i
     VERBATIM
     )
+add_custom_command(OUTPUT python_kolabcontainers_wrapper.cpp
+    COMMAND swig -v -c++ -python -o python_kolabcontainers_wrapper.cpp kolabcontainers.i
+    COMMENT "Generating python bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS kolabcontainers.i
+    VERBATIM
+    )
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${KOLAB_SWIG_PYTHON_SOURCE_FILE} python_kolabcontainers_wrapper.cpp) 
 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})
 
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
new file mode 100644
index 0000000..973048c
--- /dev/null
+++ b/c++/lib/kolabcontainers.cpp
@@ -0,0 +1,558 @@
+#include "kolabcontainers.h"
+
+namespace Kolab {
+    
+struct DateTime::Private {
+    Private()
+    : year(-1),
+    month(-1),
+    day(-1),
+    hour(-1),
+    minute(-1),
+    second(-1),
+    isUtc(false){}
+
+    int year;
+    int month;
+    int day;
+    int hour;
+    int minute;
+    int second;
+    bool isUtc;
+    std::string timezone;
+};
+
+DateTime::DateTime()
+: d(new DateTime::Private())
+{
+
+}
+
+DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc)
+: d(new DateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+    d->isUtc = isUtc;
+    std::cout << "utc";
+}
+
+DateTime::DateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
+: d(new DateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+    d->timezone = timezone;
+    std::cout << "tz";
+}
+
+DateTime::DateTime(int year, int month, int day)
+: d(new DateTime::Private())
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+}
+
+DateTime::DateTime(const Kolab::DateTime &other)
+: d(new DateTime::Private())
+{
+    *d = *other.d;
+}
+
+DateTime::~DateTime()
+{
+
+}
+
+
+void DateTime::operator=(const Kolab::DateTime &other)
+{
+   *d = *other.d;
+}
+
+bool DateTime::operator==(const Kolab::DateTime &other) const
+{
+    if ( d->year == other.year() &&
+        d->month == other.month() &&
+        d->day == other.day() &&
+        d->hour == other.hour() &&
+        d->minute == other.minute() &&
+        d->second== other.second() &&
+        d->isUtc== other.isUTC() &&
+        d->timezone== other.timezone()) {
+        return true;
+    }
+    return false;
+}
+
+
+
+int DateTime::year() const
+{
+    return d->year;
+}
+
+int DateTime::month() const
+{
+    return d->month;
+}
+
+int DateTime::day() const
+{
+    return d->day;
+}
+
+int DateTime::hour() const
+{
+    return d->hour;
+}
+
+int DateTime::minute() const
+{
+    return d->minute;
+}
+
+int DateTime::second() const
+{
+    return d->second;
+}
+
+bool DateTime::isDateOnly() const
+{
+    if ((d->hour < 0) && (d->minute < 0) && (d->second < 0)) {
+        return true;
+    }
+    return false;
+}
+
+void DateTime::setDate(int year, int month, int day)
+{
+    d->year = year;
+    d->month = month;
+    d->day = day;
+}
+void DateTime::setTime(int hour, int minute, int second)
+{
+    d->hour = hour;
+    d->minute = minute;
+    d->second = second;
+}
+void DateTime::setTimezone(const std::string &tz)
+{
+    d->timezone = tz;
+}
+void DateTime::setUTC(bool utc)
+{
+    d->isUtc = utc;
+}
+
+bool DateTime::isUTC() const
+{
+    return d->isUtc;
+}
+
+std::string DateTime::timezone() const
+{
+        return d->timezone;
+}
+
+bool DateTime::isValid() const
+{
+    if (d->year >= 0 && d->month >= 0 && d->day >= 0) {
+        return true;
+    }
+    return false;
+}
+
+struct RecurrenceRule::Private
+{
+    Frequencey freq;
+    Weekday weekstart;
+    DateTime end;
+    int count;
+    int interval;
+    std::vector<int> bysecond;
+    std::vector<int> byminute;
+    std::vector<int> byhour;
+    std::vector<DayPos> byday;
+    std::vector<int> bymonthday;
+    std::vector<int> byyearday;
+    std::vector<int> byweekno;
+    std::vector<int> bymonth;
+};
+
+RecurrenceRule::RecurrenceRule()
+:   d(new RecurrenceRule::Private)
+{
+    
+}
+
+RecurrenceRule::RecurrenceRule(const Kolab::RecurrenceRule &other)
+:   d(new RecurrenceRule::Private)
+{
+    *d = *other.d;
+}
+
+void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
+{
+    *d = *other.d;
+}
+
+
+
+RecurrenceRule::~RecurrenceRule()
+{
+    
+}
+
+void RecurrenceRule::setFrequency(RecurrenceRule::Frequencey freq)
+{
+    d->freq = freq;
+}
+
+RecurrenceRule::Frequencey RecurrenceRule::frequency() const
+{
+    return d->freq;
+}
+
+void RecurrenceRule::setWeekStart(RecurrenceRule::Weekday weekstart)
+{
+    d->weekstart = weekstart;
+}
+
+RecurrenceRule::Weekday RecurrenceRule::weekStart() const
+{
+    return d->weekstart;
+}
+
+void RecurrenceRule::setEnd(const Kolab::DateTime &end)
+{
+    d->end = end;
+}
+
+DateTime RecurrenceRule::end() const
+{
+    return d->end;
+}
+
+void RecurrenceRule::setCount(int count)
+{
+    d->count = count;
+}
+
+int RecurrenceRule::count() const
+{
+    return d->count;
+}
+
+void RecurrenceRule::setInterval(int interval)
+{
+    d->interval = interval;
+}
+
+int RecurrenceRule::interval() const
+{
+    return d->interval;
+}
+
+void RecurrenceRule::setBysecond(const std::vector< int >&by)
+{
+    d->bysecond = by;
+}
+
+
+std::vector< int > RecurrenceRule::bysecond() const
+{
+    return d->bysecond;
+}
+
+void RecurrenceRule::setByminute(const std::vector< int > &by)
+{
+    d->byminute = by;
+}
+
+std::vector< int > RecurrenceRule::byminute() const
+{
+    return d->byminute;
+}
+
+void RecurrenceRule::setByhour(const std::vector< int > &by)
+{
+    d->byhour = by;
+}
+
+std::vector< int > RecurrenceRule::byhour() const
+{
+    return d->byhour;
+}
+
+void RecurrenceRule::setByday(const std::vector< RecurrenceRule::DayPos > &by)
+{
+    d->byday = by;
+}
+
+std::vector< RecurrenceRule::DayPos > RecurrenceRule::byday() const
+{
+    return d->byday;
+}
+
+void RecurrenceRule::setBymonthday(const std::vector< int > &by)
+{
+    d->bymonthday = by;
+}
+
+std::vector< int > RecurrenceRule::bymonthday() const
+{
+    return d->bymonthday;
+}
+
+void RecurrenceRule::setByyearday(const std::vector< int > &by)
+{
+    d->byyearday = by;
+}
+
+std::vector< int > RecurrenceRule::byyearday() const
+{
+    return d->byyearday;
+}
+
+void RecurrenceRule::setByweekno(const std::vector< int > &by)
+{
+    d->byweekno = by;
+}
+
+std::vector< int > RecurrenceRule::byweekno() const
+{
+    return d->byweekno;
+}
+
+void RecurrenceRule::setBymonth(const std::vector< int > &by)
+{
+    d->bymonth = by;
+}
+
+std::vector< int > RecurrenceRule::bymonth() const
+{
+    return d->bymonth;
+}
+
+bool RecurrenceRule::isValid() const
+{
+    if (d->freq == None) {
+        return false;
+    }
+    return true;
+}
+
+
+
+
+struct Event::Private
+{
+    Private()
+    : classification(Public){}
+    
+    std::string uid;
+    DateTime created;
+    DateTime lastModified;
+    int sequence;
+    Classification classification;
+    std::vector< std::string > categories;
+    DateTime start;
+    DateTime end;
+    
+    DateTime recurrenceID;
+    bool thisAndFuture;
+    std::string summary;
+    std::string description;
+    int priority;
+    Status status;
+    std::string location;
+    RecurrenceRule rrule;
+};
+
+Event::Event()
+: d(new Event::Private())
+{
+    
+}
+
+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::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;
+}
+
+
+
+
+}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 639789c..7b11638 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -2,112 +2,237 @@
 #define KOLAB_CONTAINERS_H
 #include <string>
 #include <vector>
+#include <boost/scoped_ptr.hpp>
 
 namespace Kolab {
+
+class DateTime {
+public:
+    DateTime();
+    DateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc=true);
+    DateTime(const std::string &timezone, int year, int month, int day, int hour, int minute, int second);
+    DateTime(int year, int month, int day);
+    ~DateTime();
+    DateTime(const DateTime &);
+    void operator=(const DateTime &);
+    bool operator==(const DateTime &) const;
+   
     
-    /**
-     * Datatypes:
-     * -String
-     * -DateTime
-     * -
-     * 
-     */
-    
-    class DateTime {
-        void setDate(int year, int month, int day);
-        int year();
-        int month();
-        int day();
-        
-        bool isDateOnly();
-        
-        void setTime(int hour, int minute, int second);
-        int hour();
-        int minute();
-        int second();
-        
-        void setUTC(bool);
-        void setTimezone(const std::string &);
-        std::string getTimezone();
-    };
+    void setDate(int year, int month, int day);
+    int year() const;
+    int month() const;
+    int day() const;
+    
+    bool isDateOnly() const;
+    
+    void setTime(int hour, int minute, int second);
+    int hour() const;
+    int minute() const;
+    int second() const;
     
-    /**
+    void setUTC(bool);
+    bool isUTC() const;
+    void setTimezone(const std::string &);
+    std::string timezone() const;
+    
+    bool isValid() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+enum Classification {
+    Public,
+    Private,
+    Confidential
+};
+
+enum Status {
+    NeedsAction,
+    Completed,
+    InProcess,
+    Cancelled,
+    Tentative,
+    Confirmed,
+    Draft,
+    Final
+};
 
-      */
-    
-    class Event {
-        public:
-            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(int); //TODO enum?
-            int classification() const;
+class RecurrenceRule {
+public:
+    
+    RecurrenceRule();
+    RecurrenceRule(const RecurrenceRule &);
+    ~RecurrenceRule();
 
-            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();
-            duration() const;
-            
-            void setTransparency(bool isTransparent);
-            bool transparency() const;
-            
-            void setRecurrenceRule(const RecurrenceRule &);
-            RecurrenceRule recurrenceRule() const;
-            
-            void setRecrrenceDates(const std::vector<DateTime> &);
-            std::vector<DateTime> recurrenceDates() const;
-            
-            void setExceptionDates(const std::vector<DateTime> &);
-            std::vector<DateTime> exceptionDates() const;
-            
-            void setRecurrenceID(const std::string &);
-            std::string recurrenceID() 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(int); //TODO map to string
-            int 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 setAttendee(const std::vector<Attendee> &);
-            std::vector<Attendee> attendee() const;
-            
-            void setAttachment(const std::vector<Attachment> &);
-            std::vector<Attachment> attachments() const;
-            
-            void setCustomProperty(const std::vector<CustomProperty> &);
-            std::vector<CustomProperty> customProperties() const;
+    void operator=(const RecurrenceRule &);
+    
+    enum Frequencey {
+        None,
+        Yearly,
+        Monthly,
+        Weekly,
+        Daily,
+        Hourly,
+        Minutely,
+        Secondly
+    };
+    
+    void setFrequency(Frequencey);
+    Frequencey frequency() const;
+    
+    enum Weekday {
+        Monday,
+        Tuesday,
+        Wednesday,
+        Thursday,
+        Friday,
+        Saturday,
+        Sunday
+    };
+    
+    void setWeekStart(Weekday);
+    Weekday weekStart() const;
+    
+    void setEnd(const DateTime &);
+    DateTime end() const;
+    
+    void setCount(int count);
+    int count() const;
+    
+    void setInterval(int);
+    int interval() const;
+    
+    void setBysecond(const std::vector<int> &);
+    std::vector<int> bysecond() const;
+    
+    void setByminute(const std::vector<int> &);
+    std::vector<int> byminute() const;
+    
+    void setByhour(const std::vector<int> &);
+    std::vector<int> byhour() const;
+    
+    struct DayPos
+    {
+        void operator=(const DayPos &){};
     };
+    
+    void setByday(const std::vector<DayPos> &);
+    std::vector<DayPos> byday() const;
+    
+    void setBymonthday(const std::vector<int> &);
+    std::vector<int> bymonthday() const;
+    
+    void setByyearday(const std::vector<int> &);
+    std::vector<int> byyearday() const;
+    
+    void setByweekno(const std::vector<int> &);
+    std::vector<int> byweekno() const;
+    
+    void setBymonth(const std::vector<int> &);
+    std::vector<int> bymonth() const;
+    
+    bool isValid() const;
+    
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+class Attendee {
+    //TODO
+};
+
+class Attachment {
+    //TODO
+};
+
+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(int); //TODO duration type
+    int duration() const;
+    
+    void setTransparency(bool isTransparent);
+    bool transparency() const;
+    
+    void setRecurrenceRule(const RecurrenceRule &);
+    RecurrenceRule recurrenceRule() const;
+    
+    void setRecrrenceDates(const std::vector<DateTime> &);
+    std::vector<DateTime> recurrenceDates() const;
+    
+    void setExceptionDates(const std::vector<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 setAttendee(const std::vector<Attendee> &);
+    std::vector<Attendee> attendee() const;
+    
+    void setAttachment(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperty(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
 
     
 }
diff --git a/c++/lib/kolabcontainers.i b/c++/lib/kolabcontainers.i
new file mode 100644
index 0000000..74638f6
--- /dev/null
+++ b/c++/lib/kolabcontainers.i
@@ -0,0 +1,11 @@
+/* kolabformat.i */
+ %module kolabcontainers
+ %{
+ /* Put header files here or function declarations like below */
+ #include "kolabcontainers.h"
+ %}
+%include "std_string.i"
+
+/*%apply const std::string& {std::string* foo};*/
+
+%include "kolabcontainers.h"


commit 2409376669d3692c8a924d6e668f883df69f1ca7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 20 15:00:41 2011 +0100

    share code between all incidences

diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 425930a..676ee81 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -371,8 +371,8 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename
     return rruleProp;
 }
 
-
-void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::properties &prop)
+template <typename T>
+void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
 {
     inc.setUid(toString(prop.uid()));
     inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
@@ -462,7 +462,8 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::prope
     
 }
 
-void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Incidence &inc)
+template <typename T>
+void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
 {
     using namespace KCalCore;
     using namespace icalendar_2_0;
@@ -503,9 +504,20 @@ void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Inc
 
 template <> struct IncidenceConverter < KCalCore::Incidence >
 {
+    typedef DateTimeConverter< KDateTime> DC;
+    static std::string uid(const KCalCore::Incidence &inc) {
+        return inc.uid().toStdString();
+    }
+    
+    static xml_schema::date_time dtstamp(const KCalCore::Incidence &inc) {
+        return DC::fromDateTime(inc.lastModified());
+    }
+    
+    static xml_schema::date_time created(const KCalCore::Incidence &inc) {
+        return DC::fromDateTime(inc.created());
+    }
 
-
-
+};
 
 } //Namespace
 
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 543468b..0bb9303 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -11,6 +11,7 @@
 #include <kcalcore/recurrencerule.h>
 #include "kcalconversions.h"
 #include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
+#include <KDE/KCalCore/Todo>
 
 namespace Kolab {
     
@@ -77,8 +78,100 @@ void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
 //     }
 }
 
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
+
+template <typename T> struct IncidenceTrait;
+
+template < > struct IncidenceTrait <KCalCore::Event>
 {
+    typedef typename icalendar_2_0::KolabEvent KolabType;
+    typedef typename KCalCore::Event IncidenceType;
+    typedef typename KCalCore::Event::Ptr IncidencePtr;
+    typedef typename KCalCore::Incidence Incidence;
+    
+    static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+    {
+        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+        
+        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+        if (event.dtEnd().isValid()) {
+            icalendar_2_0::properties::dtend_type dtend;
+            setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
+            prop.dtend(dtend);
+        } else if (event.duration() != KCalCore::Duration()) {
+            
+        }
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+    {
+        components.vevent().push_back(inc);
+    }
+    
+    
+    static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
+    {
+        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+        if (prop.dtend()) {
+            KDateTime date;
+            kDebug() << "dtend";
+            event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+            if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+                kWarning() << "dtEnd has wrong timespec";
+            }
+        } else if (prop.duration()) {
+    //          KCalCore::Duration duration.;
+    //          event.setDuration(duration << prop.duration());
+        }
+        //TODO check for equality of timespecs
+        
+        if (prop.transp()) {
+            
+        }
+    }
+     
+    static icalendar_2_0::components2::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)
+    {
+        return components.vevent().end();
+    }
+    
+};
+
+template < > struct IncidenceTrait <KCalCore::Todo>
+{
+    typedef typename icalendar_2_0::KolabTodo KolabType;
+    typedef typename KCalCore::Todo IncidenceType;
+    typedef typename KCalCore::Incidence Incidence;
+    
+    static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
+    {
+       icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
+       getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+
+    }
+
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+    {
+        components.vtodo().push_back(inc);
+    }
+};
+
+
+template <typename T>
+typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
+{
+    typedef typename T::IncidencePtr IncidencePtr;
+    typedef typename T::IncidenceType IncidenceType;
+    typedef typename T::KolabType KolabType;
+    
     try {
         //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
         xml_schema::properties props;
@@ -95,13 +188,12 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 
         const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
 
-        QList <KCalCore::Event::Ptr> events;
-
-        for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
-            KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
-            const icalendar_2_0::KolabEvent &event = *it;
-            readEvent(*e, event);
-            events.append(e);
+        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
@@ -110,65 +202,51 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 //                 return event;
 //             }
 //         }
-        return events.first();
+        return *incidences.begin();
     } catch  (const xml_schema::exception& e) {
         std::cout <<  e << std::endl;
-        std::cout <<  "Failed to read event!" << std::endl;
+        std::cout <<  "Failed to read incidence!" << std::endl;
     }
-    return KCalCore::Event::Ptr();
+    return IncidencePtr();
+    
 }
 
 
-
-void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 {
-    const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
-    setIncidenceProperties(event, prop);
+    readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+}
 
-    if (prop.dtend()) {
-        KDateTime date;
-        kDebug() << "dtend";
-        event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
-        if (event.dtEnd().timeType() != event.dtStart().timeType()) {
-            kWarning() << "dtEnd has wrong timespec";
-        }
-    } else if (prop.duration()) {
-//          KCalCore::Duration duration.;
-//          event.setDuration(duration << prop.duration());
-    }
-    //TODO check for equality of timespecs
+KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
+{
     
-    if (prop.transp()) {
-        
-    }
-
 }
 
+
+
 template <typename T>
-std::string writeEvent(typename T::EventType event) {
+std::string writeIncidence(const typename T::IncidenceType &incidence) {
+    
     using namespace icalendar_2_0;
+    typedef IncidenceConverter< typename T::Incidence > IC;
+    typedef typename T::KolabType KolabType;
+
     try {
+
+        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::dtstamp_type dtstamp;
+        dtstamp.date_time(IC::dtstamp(incidence));
+        typename KolabType::properties_type::created_type created;
+        created.date_time(IC::created(incidence));
+        typename KolabType::properties_type eventProps(uid, created, dtstamp);
         
-        typedef DateTimeConverter< typename T::DateType > DC;
-        typedef IncidenceConverter< typename T::IncidenceType > IC;
-        
-        KolabEvent::components_type eventComponents;
-        IC::uid(event);
-        IC::dtstamp(event);
-        IC::created(event);
-        KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
-        KolabEvent::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(DC::fromDateTime(event->lastModified()));
-        KolabEvent::properties_type::created_type created;
-        created.date_time(DC::fromDateTime(event->created()));
-        KolabEvent::properties_type eventProps(uid, created, dtstamp);
-        
-        KolabEvent vevent(eventProps, eventComponents);
-        writeEvent(vevent, *event);
+        KolabType inc(eventProps, eventComponents);
+        T::writeIncidence(inc, incidence);
         
         VcalendarType::components_type components;
-        components.vevent().push_back(vevent);
+        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
@@ -182,37 +260,27 @@ std::string writeEvent(typename T::EventType event) {
 
         xml_schema::namespace_infomap map;
         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-//         map[""].schema = "note.xsd";
         
         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();
     } 
 }
 
 std::string writeEvent(KCalCore::Event::Ptr event)
 {
-    return writeEvent<KCalCoreTypes>(event);
+    return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
 }
 
-void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+std::string writeTodo(KCalCore::Todo::Ptr todo)
 {
-    
-    icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-    
-    getIncidenceProperties(prop, event);
+    return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
+}
 
-    if (event.dtEnd().isValid()) {
-        icalendar_2_0::properties::dtend_type dtend;
-        setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
-        prop.dtend(dtend);
-    } else if (event.duration() != KCalCore::Duration()) {
-        
-    }
 
-}
 
 
 
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 16a7cc5..10baba3 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -80,6 +80,19 @@
                         <xs:element name="class" type="ClassPropType" minOccurs="0"/>
                         <xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
                         <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+                        <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+                        <xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
+                        <xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
+                        <xs:element name="recurrence-id" type="RecurrenceIdPropType" minOccurs="0"/>
+                        <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
+                        <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+                        <xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
+                        <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+                        <xs:element name="location" type="LocationPropType" minOccurs="0"/>
+                        <xs:element name="organizer" type="OrganizerPropType" 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>


commit f77f6163d4064f93fcb57dd02a241630a60dd0ae
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Dec 20 11:40:08 2011 +0100

    temp

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index d064bcc..3f9f736 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -10,7 +10,8 @@
 
 namespace Kolab {
 
-int toInt(xml_schema::integer integer)
+template <typename T>
+int convertToInt(T integer)
 {
     try {
         int i = boost::numeric_cast<int>(integer);
@@ -25,9 +26,25 @@ int toInt(xml_schema::integer integer)
     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::cout << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cout << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cout << e.what();
+    }
+    return 0;
+}
+
 int toInt(const icalendar_2_0::IntegerPropertyType &prop)
 {
-    return toInt(prop.integer());
+    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
 }
 
 
@@ -111,75 +128,50 @@ 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());
-        assert(r.get());
-        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 RecurrenceRule class (default value of interval per RFC).
-        }
-        /*
-        {
-            QList<int> bysec;
-            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-                Q_ASSERT(*it <= std::numeric_limits<int>::max());
-                bysec.append(*it);
-            }
-            if (!bysec.isEmpty()) {
-                d.setBySeconds(bysec);
-            }
+    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());
         }
-        //TODO implement all the other by*** lists
-        if (rrule.wkst()) {
-            switch (*rrule.wkst()) {
-                case WeekdayRecurType::MO:
-                    d.setWeekStart(1);
-                    break;
-                case WeekdayRecurType::TU:
-                    d.setWeekStart(2);
-                    break;
-                case WeekdayRecurType::WE:
-                    d.setWeekStart(3);
-                    break;
-                case WeekdayRecurType::TH:
-                    d.setWeekStart(4);
-                    break;
-                case WeekdayRecurType::FR:
-                    d.setWeekStart(5);
-                    break;
-                case WeekdayRecurType::SA:
-                    d.setWeekStart(6);
-                    break;
-                case WeekdayRecurType::SU:
-                    d.setWeekStart(7);
-                    break;
-                default:
-                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
-            }
-        }*/
-        return r;
+        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 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;
+}
+
+
+template <typename T> 
+struct IncidenceConverter;
 
 
 
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 7fb8ea4..425930a 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -5,6 +5,9 @@
 #include <KDE/KDateTime>
 #include <KDE/KDebug>
 #include <kcalcore/recurrencerule.h>
+#include <kcalcore/recurrence.h>
+#include <bindings/kolabformat-xcal.hxx>
+#include <kcalcore/incidence.h>
 
 namespace Kolab {
 
@@ -15,8 +18,26 @@ struct KCalCoreTypes
     typedef typename KCalCore::RecurrenceRule RecurrenceType;
     typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
     typedef QString StringType;
+    typedef typename KCalCore::Incidence IncidenceType;
 };
 
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+    QStringList d;
+    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+        d.append(QString::fromStdString(*it));
+    }
+    return d;
+}
+
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return QString::fromStdString(s.text());
+}
+
+
 typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
 
 template <> struct DateTimeConverter<KDateTime>
@@ -91,6 +112,7 @@ template <> struct DateTimeConverter<KDateTime>
 };
 
 
+
 template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
 {
 
@@ -99,34 +121,92 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
 
     static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
     {
+        using namespace icalendar_2_0;
+        using namespace KCalCore;
+        
         switch (freq) {
-            case icalendar_2_0::FreqRecurType::YEARLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+            case FreqRecurType::YEARLY:
+                r->setRecurrenceType(RecurrenceRule::rYearly);
                 break;
-            case icalendar_2_0::FreqRecurType::MONTHLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+            case FreqRecurType::MONTHLY:
+                r->setRecurrenceType(RecurrenceRule::rMonthly);
                 break;
-            case icalendar_2_0::FreqRecurType::WEEKLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+            case FreqRecurType::WEEKLY:
+                r->setRecurrenceType(RecurrenceRule::rWeekly);
                 break;
-            case icalendar_2_0::FreqRecurType::DAILY:
-                kDebug() << "daily";
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+            case FreqRecurType::DAILY:
+                r->setRecurrenceType(RecurrenceRule::rDaily);
                 break;
-            case icalendar_2_0::FreqRecurType::HOURLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+            case FreqRecurType::HOURLY:
+                r->setRecurrenceType(RecurrenceRule::rHourly);
                 break;
-            case icalendar_2_0::FreqRecurType::MINUTELY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+            case FreqRecurType::MINUTELY:
+                r->setRecurrenceType(RecurrenceRule::rMinutely);
                 break;
-            case icalendar_2_0::FreqRecurType::SECONDLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+            case FreqRecurType::SECONDLY:
+                r->setRecurrenceType(RecurrenceRule::rSecondly);
                 break;
             default:
                 kWarning() << "invalid unhandled recurrenc type" << freq;
         }
     }
     
+    static icalendar_2_0::RecurType::freq_type type(const Type &t)
+    {
+        using namespace icalendar_2_0;
+        using namespace KCalCore;
+        
+        switch (t.recurrenceType()) {
+            case RecurrenceRule::rYearly:
+                return FreqRecurType::YEARLY;
+            case RecurrenceRule::rMonthly:
+                return FreqRecurType::MONTHLY;
+            case RecurrenceRule::rWeekly:
+                return FreqRecurType::WEEKLY;
+            case RecurrenceRule::rDaily:
+                return FreqRecurType::DAILY;
+            case RecurrenceRule::rHourly:
+                return FreqRecurType::HOURLY;
+            case RecurrenceRule::rMinutely:
+                return FreqRecurType::MINUTELY;
+            case RecurrenceRule::rSecondly:
+                return FreqRecurType::SECONDLY;
+            default:
+                kWarning() << "invalid unhandled recurrenc type";
+        }
+    }
+    
+    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(1);
+                break;
+            case WeekdayRecurType::TU:
+                r->setWeekStart(2);
+                break;
+            case WeekdayRecurType::WE:
+                r->setWeekStart(3);
+                break;
+            case WeekdayRecurType::TH:
+                r->setWeekStart(4);
+                break;
+            case WeekdayRecurType::FR:
+                r->setWeekStart(5);
+                break;
+            case WeekdayRecurType::SA:
+                r->setWeekStart(6);
+                break;
+            case WeekdayRecurType::SU:
+                r->setWeekStart(7);
+                break;
+            default:
+                kWarning() << "invalid unhandled weekday" << wkst;
+        }
+    }
+
     static void setEndDt(Ptr r, KCalCoreTypes::DatePtr date )
     {
         r->setEndDt(*date);
@@ -141,120 +221,291 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
     {
         r->setFrequency(interval);
     }
-
-};
-/*
-typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-{
-    typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
-    typedef typename KCalCoreTypes::DatePtr DatePtr;
-    typedef DateTimeConverter<typename KCalCoreTypes::DateType> DC;
     
-    RecurrencePtr r(new KCalCore::RecurrenceRule());
-    KCalCore::RecurrenceRule &d = *r;
-    using namespace icalendar_2_0;
-    switch (rrule.freq()) {
-        case FreqRecurType::YEARLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-            break;
-        case FreqRecurType::MONTHLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-            break;
-        case FreqRecurType::WEEKLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
-            break;
-        case FreqRecurType::DAILY:
-            kDebug() << "daily";
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-            break;
-        case FreqRecurType::HOURLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
-            break;
-        case FreqRecurType::MINUTELY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
-            break;
-        case FreqRecurType::SECONDLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
-            break;
-        default:
-            kWarning() << "invalid unhandled recurrenc type" << 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());
+    static void setBysecond(Ptr r, const icalendar_2_0::RecurType::bysecond_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setBySeconds(by);
         }
-        d.setEndDt(*date);
-    } else if (rrule.count()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setDuration(*rrule.count());
     }
     
-    if (rrule.interval()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setFrequency(*rrule.interval());
-    } else {
-        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+    static void setByminute(Ptr r, const icalendar_2_0::RecurType::byminute_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::byminute_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByMinutes(by);
+        }
     }
+    
+    static void setByhour(Ptr r, const icalendar_2_0::RecurType::byhour_sequence &list)
     {
-        QList<int> bysec;
-        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-            Q_ASSERT(*it <= std::numeric_limits<int>::max());
-            bysec.append(*it);
+        QList<int> by;
+        for (icalendar_2_0::RecurType::byhour_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::non_negative_integer>(*it));
         }
-        if (!bysec.isEmpty()) {
-            d.setBySeconds(bysec);
+        if (!by.isEmpty()) {
+            r->setByHours(by);
         }
     }
-    //TODO implement all the other by*** lists
-    if (rrule.wkst()) {
-        switch (*rrule.wkst()) {
-            case WeekdayRecurType::MO:
-                d.setWeekStart(1);
-                break;
-            case WeekdayRecurType::TU:
-                d.setWeekStart(2);
-                break;
-            case WeekdayRecurType::WE:
-                d.setWeekStart(3);
-                break;
-            case WeekdayRecurType::TH:
-                d.setWeekStart(4);
-                break;
-            case WeekdayRecurType::FR:
-                d.setWeekStart(5);
-                break;
-            case WeekdayRecurType::SA:
-                d.setWeekStart(6);
-                break;
-            case WeekdayRecurType::SU:
-                d.setWeekStart(7);
-                break;
-            default:
-                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+    
+    static void setByday(Ptr r, const icalendar_2_0::RecurType::byday_sequence &list)
+    {
+        QList<KCalCore::RecurrenceRule::WDayPos> by;
+        for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
+            KCalCore::RecurrenceRule::WDayPos pos;
+            //TODO implement parser for format
+//             switch () {
+//                 
+//             }
+            //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByDays(by);
+        }
+    }
+    
+    static void setBymonthday(Ptr r, const icalendar_2_0::RecurType::bymonthday_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByMonthDays(by);
+        }
+    }
+    
+    static void setByyearday(Ptr r, const icalendar_2_0::RecurType::byyearday_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::byyearday_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByYearDays(by);
         }
     }
-    return r;
-}*/
+    
+    static void setByweekno(Ptr r, const icalendar_2_0::RecurType::byweekno_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::byweekno_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByWeekNumbers(by);
+        }
+    }
+    
+    static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
+    {
+        QList<int> by;
+        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+            by.append(convertToInt<xml_schema::integer>(*it));
+        }
+        if (!by.isEmpty()) {
+            r->setByMonths(by);
+        }
+    }
+};
 
+// template <typename T, typename I>
+// QList <int> &toList(QList<int> &list, const xsd::cxx::tree::sequence <T> &input) {
+//     for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+//             bysec.append(convertToInt<I>(*it));
+//     }
+//     Q_FOREACH (I i, list) {
+//         list.push_back(fromInt<I>(i));
+//     }
+//     return list;
+// }
 
-QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+template <typename T, typename I>
+xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const QList<int> &input) {
+    Q_FOREACH (int i, list) {
+        list.push_back(convertToInt<I>(i));
+    }
+    return list;
+}
+
+
+std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename KCalCore::RecurrenceRule &r)
 {
-    QStringList d;
-    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-        d.append(QString::fromStdString(*it));
+    using namespace icalendar_2_0;
+    
+    typedef RecurrenceConverter< typename KCalCore::RecurrenceRule > RC;
+    typedef DateTimeConverter< KDateTime> DC;
+    
+    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
+    
+    RecurPropertyType::recur_type &recur = rruleProp->recur();
+    bool ok;
+    const KDateTime &endDate = r.endDt(&ok);
+    if (ok) {
+        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.duration() > 0) {
+        recur.count(fromInt<RecurType::count_type>(r.duration()));
     }
-    return d;
+    
+    if (r.frequency() > 1) {
+        recur.interval(fromInt<RecurType::interval_type>(r.frequency()));
+    }
+    
+    if (!r.bySeconds().isEmpty()) {
+        RecurType::bysecond_sequence bysecond;
+        recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bySeconds()));
+    }
+    return rruleProp;
 }
 
-QString toString(const icalendar_2_0::TextPropertyType &s)
+
+void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::properties &prop)
 {
-    return QString::fromStdString(s.text());
+    inc.setUid(toString(prop.uid()));
+    inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
+    inc.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
+
+    if (prop.sequence()) {
+        inc.setRevision(toInt(*prop.sequence()));
+    }
+    
+    if (prop.class_()) {
+        QString string(toString(*prop.class_()));
+        KCalCore::Incidence::Secrecy sec;
+        if (string == "PRIVATE") {
+            sec = KCalCore::Incidence::SecrecyPrivate;
+        } else if (string == "CONFIDENTIAL") {
+            sec = KCalCore::Incidence::SecrecyConfidential;
+        } else {
+            sec = KCalCore::Incidence::SecrecyPublic;
+        }
+        inc.setSecrecy(sec);
+    }
+    
+    if (prop.categories()) {
+        inc.setCategories(toStringList(*prop.categories()));
+    }
+    
+    if (prop.dtstart()) {
+        const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
+        inc.setDtStart(*date);
+        inc.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
+    }
+    
+    KCalCore::Recurrence *recurrence = inc.recurrence();
+    if (prop.rrule()) {
+       RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
+       rrule->setStartDt(recurrence->startDateTime());
+       recurrence->addRRule(rrule.release());
+    }
+    
+    if (prop.rdate()) {
+        
+    }
+    
+    if (prop.exdate()) {
+        
+    }
+    
+    if (prop.recurrence_id()) {
+        
+    }
+    
+    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()) {
+        
+    }
+    
+    if (prop.status()) {
+        
+    }
+    
+    if (prop.location()) {
+        
+    }
+    
+    if (prop.organizer()) {
+        
+    }
+    
+    if (prop.attendee().size()) {
+        
+    }
+    
+    if (prop.attach().size()) {
+        
+    }
+    
+    if (prop.x_custom().size()) {
+        
+    }
+    
+}
+
+void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Incidence &inc)
+{
+    using namespace KCalCore;
+    using namespace icalendar_2_0;
+    
+    prop.sequence(fromInt<xml_schema::integer>(inc.revision()));
+    
+    switch (inc.secrecy()) {
+        case Incidence::SecrecyConfidential:
+            prop.class_();
+            break;
+        case Incidence::SecrecyPublic:
+            prop.class_();
+        case Incidence::SecrecyPrivate:
+            prop.class_();
+    }
+    
+    
+    if (inc.dtStart().isValid()) {
+        properties::dtstart_type dtstart;
+        setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
+        prop.dtstart(dtstart);
+    }
+    
+    if (inc.recurs()) {
+        Recurrence *r = inc.recurrence();
+        if (r->rRules().size() >= 1) {
+            if (r->rRules().size() != 1) {
+                kWarning() << "too many recurrences: " << r->rRules().size();
+            }
+            RecurrenceRule *rule = r->rRules().first();
+            //TODO check if startdate is allDay if recurrence is allDay
+            //TODO check if startdate matches the one of the event (it MUST)
+            prop.rrule(recurrenceProperty(*rule));
+        }
+    }
+    
 }
 
+template <> struct IncidenceConverter < KCalCore::Incidence >
+{
+
+
+
 
 } //Namespace
 
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index feb5e01..543468b 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -10,6 +10,7 @@
 #include <limits>
 #include <kcalcore/recurrencerule.h>
 #include "kcalconversions.h"
+#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
 
 namespace Kolab {
     
@@ -76,14 +77,22 @@ void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
 //     }
 }
 
-KCalCore::Event::Ptr readEvent(const std::string& s)
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 {
     try {
         //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
         xml_schema::properties props;
-        props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
 
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/, 0, props));
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+        if (isUrl) {
+            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
+            std::istringstream is(s);
+            icalendar = icalendar_2_0::icalendar(is, 0, props);
+        }
+
         const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
 
         QList <KCalCore::Event::Ptr> events;
@@ -104,6 +113,7 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
         return events.first();
     } catch  (const xml_schema::exception& e) {
         std::cout <<  e << std::endl;
+        std::cout <<  "Failed to read event!" << std::endl;
     }
     return KCalCore::Event::Ptr();
 }
@@ -114,19 +124,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 {
     const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
 
-    event.setUid(toString(prop.uid()));
-    event.setCreated(*toDate<KCalCoreTypes>(prop.created()));
-    event.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
-
-    if (prop.sequence()) {
-        event.setRevision(toInt(*prop.sequence()));
-    }
-
-    if (prop.dtstart()) {
-        const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
-        event.setDtStart(*date);
-        event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
-    }
+    setIncidenceProperties(event, prop);
 
     if (prop.dtend()) {
         KDateTime date;
@@ -141,53 +139,28 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
     }
     //TODO check for equality of timespecs
     
-    if (prop.categories()) {
-        event.setCategories(toStringList(*prop.categories()));
-    }
-    if (prop.class_()) {
-        QString string(toString(*prop.class_()));
-        KCalCore::Incidence::Secrecy sec;
-        if (string == "PRIVATE") {
-            sec = KCalCore::Incidence::SecrecyPrivate;
-        } else if (string == "CONFIDENTIAL") {
-            sec = KCalCore::Incidence::SecrecyConfidential;
-        } else {
-            sec = KCalCore::Incidence::SecrecyPublic;
-        }
-        event.setSecrecy(sec);
-    }
-
-    KCalCore::Recurrence *recurrence = event.recurrence();
-    if (prop.rrule()) {
-       RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
-       rrule->setStartDt(recurrence->startDateTime());
-       recurrence->addRRule(rrule.release());
-    }
-
-    if (prop.summary()) {
-        event.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
+    if (prop.transp()) {
+        
     }
 
-    if (prop.description()) {
-        event.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
-    }
 }
 
-std::string writeEvent(KCalCore::Event::Ptr event)
-{
+template <typename T>
+std::string writeEvent(typename T::EventType event) {
     using namespace icalendar_2_0;
     try {
         
-        typedef DateTimeConverter<KDateTime> DC;
+        typedef DateTimeConverter< typename T::DateType > DC;
+        typedef IncidenceConverter< typename T::IncidenceType > IC;
         
         KolabEvent::components_type eventComponents;
-        
+        IC::uid(event);
+        IC::dtstamp(event);
+        IC::created(event);
         KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
         KolabEvent::properties_type::dtstamp_type dtstamp;
-        kDebug() << "dtstamp";
         dtstamp.date_time(DC::fromDateTime(event->lastModified()));
         KolabEvent::properties_type::created_type created;
-        kDebug() << "created";
         created.date_time(DC::fromDateTime(event->created()));
         KolabEvent::properties_type eventProps(uid, created, dtstamp);
         
@@ -219,16 +192,18 @@ std::string writeEvent(KCalCore::Event::Ptr event)
     } 
 }
 
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+    return writeEvent<KCalCoreTypes>(event);
+}
+
 void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
 {
+    
     icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-    prop.sequence(event.revision());
-    if (event.dtStart().isValid()) {
-        icalendar_2_0::properties::dtstart_type dtstart;
-        setDateTimeProperty<KCalCoreTypes>(dtstart, event.dtStart());
-        prop.dtstart(dtstart);
-    }
     
+    getIncidenceProperties(prop, event);
+
     if (event.dtEnd().isValid()) {
         icalendar_2_0::properties::dtend_type dtend;
         setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
@@ -236,6 +211,7 @@ void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
     } else if (event.duration() != KCalCore::Duration()) {
         
     }
+
 }
 
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index e5e70a0..5c541c0 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -50,7 +50,7 @@ std::string serializeEvent();
 // void readEvent(const icalendar_2_0::VeventType &vevent);
 // void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
 void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
-KCalCore::Event::Ptr readEvent(const std::string& s);
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
 
 void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
 std::string writeEvent(KCalCore::Event::Ptr);
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index b999f27..58fa3d1 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,6 +17,7 @@
 #include <kcalcore/event.h>
 #include <lib/kolabformat.h>
 #include <kdebug.h>
+#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
 
 void BindingsTest::writeNoteTest()
 {
@@ -385,11 +386,38 @@ void BindingsTest::writeEvent()
     event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
     event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
     
+    KCalCore::Recurrence *recurrence = event->recurrence();
+    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+    rule->setFrequency(3);
+    rule->setDuration(5);
+    recurrence->addRRule(rule);
+    
     kDebug() << "-------------------";
     kDebug() << QString::fromStdString(Kolab::writeEvent(event));
     kDebug() << "-------------------";
 }
 
+void BindingsTest::roundtripEvent()
+{
+    KCalCore::Event::Ptr event(new KCalCore::Event);
+    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    
+    KCalCore::Recurrence *recurrence = event->recurrence();
+    KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+    rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+    rule->setFrequency(3);
+    rule->setDuration(5);
+    recurrence->addRRule(rule);
+    
+    QString result = QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << result;
+    KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
+    QVERIFY(resEvent);
+    QCOMPARE(event->dtStart(), resEvent->dtStart());
+}
+
 
 QTEST_MAIN( BindingsTest )
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 520843b..bb63dd2 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -26,6 +26,7 @@ class BindingsTest : public QObject
     //Kolabformat
     void readEvent();
     void writeEvent();
+    void roundtripEvent();
 
 };
 
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 37ba686..16a7cc5 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -16,7 +16,7 @@
         </xs:complexContent>
     </xs:complexType>
 
-<!--    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
+    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
 
     <xs:complexType name="CustomType" >
         <xs:complexContent mixed="false">
@@ -29,8 +29,6 @@
         </xs:complexContent>
     </xs:complexType>
 
-    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />-->
-
     <xs:complexType name="KolabEvent" >
         <xs:sequence>
             <xs:element name="properties">
@@ -45,9 +43,20 @@
                         <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
                         <xs:element name="dtend" type="DtendPropType" minOccurs="0"/>
                         <xs:element name="duration" type="DurationPropType" minOccurs="0"/>
+                        <xs:element name="transp" type="TranspPropType" minOccurs="0"/>
                         <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+                        <xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
+                        <xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
+                        <xs:element name="recurrence-id" type="RecurrenceIdPropType" minOccurs="0"/>
                         <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
                         <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+                        <xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
+                        <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+                        <xs:element name="location" type="LocationPropType" minOccurs="0"/>
+                        <xs:element name="organizer" type="OrganizerPropType" 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>


commit 68823e7499becba936b31d20297384f9eaa20044
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 19 16:12:39 2011 +0100

    temp

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 542568d..d064bcc 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -1,44 +1,42 @@
 #ifndef KOLAB_CONVERSIONS_H
 #define KOLAB_CONVERSIONS_H
 
-#include "kolabformat.h"
 #include <bindings/iCalendar-props.hxx>
-#include <kdebug.h>
 #include <boost/shared_ptr.hpp>
-#include <kdatetime.h>
-// #include "kolabcontainers.h"
-// #include "kolabcontainers.h"
+#include <boost/numeric/conversion/converter_policies.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#define TZ_PREFIX "/kolab.org/"
 
 namespace Kolab {
-    
 
-template <typename T> struct DateTimeConverter;
-    
-// template <> struct DateTimeConverter<DateTime>
-// {
-//     typedef typename boost::shared_ptr<DateTime> Ptr;
-//     Ptr toDate(const  xml_schema::date &dt)
-//     {
-//         Ptr date(new DateTime());
-// 
-//         return date;
-//     }
-//     Ptr toDate(const xml_schema::date_time &dt)
-//     {
-//         Ptr date(new DateTime());
-//         return date;
-//     }
-//     
-//     void setTimezone(Ptr date, const std::string &tzid )
-//     {
-//         date->setTimezone(tzid);
-//     }
-// };
+int toInt(xml_schema::integer integer)
+{
+    try {
+        int i = boost::numeric_cast<int>(integer);
+        return i;
+    } catch(boost::numeric::negative_overflow& e) {
+        std::cout << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cout << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cout << e.what();
+    }
+    return 0;
+}
 
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    return toInt(prop.integer());
+}
 
-    
-    
-template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+
+
+template <typename T> 
+struct DateTimeConverter;
+
+template <typename T> 
+typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
 {
     typedef DateTimeConverter<typename T::DateType> DC;
     typename T::DatePtr date;
@@ -47,18 +45,16 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDateti
     } else if (dtProperty.date()) {
         date = DC::toDate(*dtProperty.date());
     }
-    
+
     if (dtProperty.parameters()) {
         for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
             if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
                 std::string tzid = tz->text();
-                //TODO
-//                     QString tzid(toString());
-//                     if (tzid.contains("/kolab.org/")) {
-//                         tzid.remove("/kolab.org/");
-//                     } else {
-//                         kWarning() << "/kolab.org/ timezone prefix is missing";
-//                     }
+                if (tzid.find(TZ_PREFIX) != std::string::npos) {
+                    tzid.erase(0, strlen(TZ_PREFIX));
+                } else {
+                    std::cout << "/kolab.org/ timezone prefix is missing";
+                }
                 DC::setTimezone(date, tzid);
             }
         }
@@ -70,7 +66,6 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
 {
     typedef typename T::DateType DateType;
     typedef typename T::DatePtr DatePtr;
-    
     typedef DateTimeConverter<DateType> DC;
     
     typename T::DatePtr date;
@@ -78,18 +73,43 @@ 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());
-        kWarning() << "This element shouldn't even be existing";
-        Q_ASSERT(0);
+        std::cout << "This element shouldn't even be existing";
+        assert(0); //TODO implement anyways?
     }
     DC::setUTC(date);
     return date;
 }
 
-template <typename T> struct RecurrenceConverter;
 
+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>
+struct RecurrenceConverter;
 
-template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+template <typename T>
+typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
 {
         using namespace icalendar_2_0;
 
@@ -99,31 +119,26 @@ template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::Rec
         typedef typename T::RecurrencePtr RecurrencePtr;
         typedef typename T::RecurrenceType RecurrenceType;
 
-        RecurrencePtr r(new RecurrenceType);
-
+        RecurrencePtr r(new RecurrenceType());
+        assert(r.get());
         RC::setType(r, rrule.freq());
         if (rrule.until()) {
-            RC::setUntil(r, *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(date);
+            RC::setEndDt(r, date);
         } else if (rrule.count()) {
-            RC::setCount(r, *rrule.count());
-/*TODO
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setDuration(*rrule.count());*/
+            RC::setCount(r, toInt(*rrule.count()));
         }
-       /* 
         if (rrule.interval()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setFrequency(*rrule.interval());
+            RC::setInterval(r, toInt(*rrule.interval()));
         } else {
-            d.setFrequency(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 RecurrenceRule class (default value of interval per RFC).
         }
+        /*
         {
             QList<int> bysec;
             for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
@@ -168,131 +183,38 @@ template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::Rec
 
 
 
-
-
-
-
-// namespace KCalCore {
-    
-    typedef boost::shared_ptr<KDateTime> DatePtr;
-
-    QString toString(const xml_schema::string &s)
-    {
-        return QString::fromStdString(s);
-    }
-
-    QString toString(const icalendar_2_0::TextPropertyType &s)
-    {
-        return toString(s.text());
-    }
-
-    QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
-    {
-        QStringList d;
-        const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-        for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-            d.append(QString::fromStdString(*it));
-        }
-        return d;
-    }
-    
-    DatePtr toDate(const  xml_schema::date &dt)
-    {
-        DatePtr date(new KDateTime());
-        date->setDateOnly(true);
-        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-        return date;
-    }
-
-    DatePtr toDate(const xml_schema::date_time &dt)
-    {
-        DatePtr date(new KDateTime());
-    //     kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
-        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-        if (dt.zone_present()) {
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-    //     kDebug() << date->date() << *date << dt.zone_present();
-        return date;
-    }
-
-
-
-
-
-
-
-
-// }
-
-
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
-    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
-    int i = prop.integer();
-    return i;
-}
-
-
-// template <class ValueType, class ReturnType> struct ConversionTraits {
-// //     typedef typename T::ReturnType ReturnType;
-// //     typedef typename T::ValueType ValueType;
-// //     
-//     static ReturnType to(ValueType v)
+// template <typename T> struct StringConverter
+// {
+//     QString toString(const xml_schema::string &s)
 //     {
-//         return v;
+//         return QString::fromStdString(s);
 //     }
-//     static ValueType from(ReturnType v)
-//     {
-//         return v;
+//     
+//     void append(StringListType &list, const StringType &string) {
+//         
 //     }
-// };
-
-
-
+// }
+// 
+// template <typename T> typename T::StringListType toStringList(const icalendar_2_0::TextListPropertyType &s)
+// {
+//     using namespace icalendar_2_0;
+// 
+//     typedef StringConverter< typename T::RecurrenceType> SC;
+//     typedef typename T::StringListType StringListType;
+// 
+//     StringListType list;
+//     const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+//     for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+//         SC::append(list, SC::toString(*it));
+//     }
+//     return list;
+// }
 
 
-xml_schema::date_time fromDateTime(const KDateTime &dt)
-{
-    const QDate &d = dt.date();
-    const QTime &t = dt.time();
-    xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
-//     date.zone_reset();
-    //TODO timezone
-    return date;
-}
 
-xml_schema::date fromDate(const KDateTime &dt)
-{
-    const QDate &d = dt.date();
-    xml_schema::date date(d.year(), d.month(), d.day());
-    return date;
-}
 
 
-std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> fromDateProperty(const KDateTime &dt)
-{
-    std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> date(new ::icalendar_2_0::DateDatetimePropertyType);
-    if (dt.isDateOnly()) {
-        date->date(fromDate(dt)); //setDateOnly
-    } else {
-        date->date_time(fromDateTime(dt)); //setDateTime
-    }
-    //TODO add timezone information //setTimeZone
-    return date;
-}
 
-void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const KDateTime &dt)
-{
-    if (dt.isDateOnly()) {
-        date.date(fromDate(dt));
-    } else {
-        date.date_time(fromDateTime(dt));
-    }
-    //TODO add timezone information
-}
 
 /*
 xml_schema::date fromDate(const KDateTime &dt)
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 82070ec..7fb8ea4 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -2,6 +2,9 @@
 #define KOLAB_KCALCONVERSIONS_H
 
 #include "conversions.h"
+#include <KDE/KDateTime>
+#include <KDE/KDebug>
+#include <kcalcore/recurrencerule.h>
 
 namespace Kolab {
 
@@ -11,15 +14,16 @@ struct KCalCoreTypes
     typedef typename boost::shared_ptr<KDateTime> DatePtr;
     typedef typename KCalCore::RecurrenceRule RecurrenceType;
     typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+    typedef QString StringType;
 };
 
 typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
 
-
 template <> struct DateTimeConverter<KDateTime>
 {
     typedef KDateTime Type;
     typedef typename boost::shared_ptr<KDateTime> Ptr;
+
     static Ptr toDate(const  xml_schema::date &dt)
     {
         Ptr date(new KDateTime());
@@ -27,7 +31,7 @@ template <> struct DateTimeConverter<KDateTime>
         date->setDate(QDate(dt.year(), dt.month(), dt.day()));
         return date;
     }
-    
+
     static Ptr toDate(const xml_schema::date_time &dt)
     {
         Ptr date(new KDateTime());
@@ -38,6 +42,26 @@ template <> struct DateTimeConverter<KDateTime>
         }
         return date;
     }
+    
+    static xml_schema::date_time fromDateTime(const KDateTime &dt)
+    {
+        const QDate &d = dt.date();
+        const QTime &t = dt.time();
+        xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
+        if (dt.timeType() == KDateTime::UTC) {
+            //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 KDateTime &dt)
+    {
+        const QDate &d = dt.date();
+        xml_schema::date date(d.year(), d.month(), d.day());
+        return date;
+    }
 
     static void setTimezone(Ptr date, const std::string &tzid)
     {
@@ -45,7 +69,12 @@ template <> struct DateTimeConverter<KDateTime>
         KDateTime::Spec spec(timezone);
         date->setTimeSpec(spec);
     }
-    
+
+    static std::string getTimezone(const KDateTime &dt)
+    {
+        return dt.timeZone().name().toStdString();
+    }
+
     static void setUTC(Ptr date)
     {
         if (date->timeSpec().type() != KDateTime::UTC) {
@@ -53,15 +82,21 @@ template <> struct DateTimeConverter<KDateTime>
             date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
         }
     }
+
+    static bool isDateOnly(Type date)
+    {
+        return date.isDateOnly();
+    }
+
 };
 
+
 template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
 {
-//     using namespace icalendar_2_0;
-    
-    typedef typename KCalCore::RecurrenceRule Type;
-    typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
-    
+
+    typedef typename KCalCoreTypes::RecurrenceType Type;
+    typedef typename KCalCoreTypes::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)
     {
         switch (freq) {
@@ -92,108 +127,135 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
         }
     }
     
-    static void setUntil(Ptr r, KCalCoreTypes::DatePtr date )
+    static void setEndDt(Ptr r, KCalCoreTypes::DatePtr date )
     {
         r->setEndDt(*date);
     }
-};
-
-    //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
-//     typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr; 
+    
+    static void setCount(Ptr r, int count )
+    {
+        r->setDuration(count);
+    }
+    
+    static void setInterval(Ptr r, int interval )
+    {
+        r->setFrequency(interval);
+    }
 
-    typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+};
+/*
+typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+    typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+    typedef typename KCalCoreTypes::DatePtr DatePtr;
+    typedef DateTimeConverter<typename KCalCoreTypes::DateType> DC;
+    
+    RecurrencePtr r(new KCalCore::RecurrenceRule());
+    KCalCore::RecurrenceRule &d = *r;
+    using namespace icalendar_2_0;
+    switch (rrule.freq()) {
+        case FreqRecurType::YEARLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+            break;
+        case FreqRecurType::MONTHLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+            break;
+        case FreqRecurType::WEEKLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+            break;
+        case FreqRecurType::DAILY:
+            kDebug() << "daily";
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+            break;
+        case FreqRecurType::HOURLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+            break;
+        case FreqRecurType::MINUTELY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+            break;
+        case FreqRecurType::SECONDLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+            break;
+        default:
+            kWarning() << "invalid unhandled recurrenc type" << 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());
+        }
+        d.setEndDt(*date);
+    } else if (rrule.count()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setDuration(*rrule.count());
+    }
+    
+    if (rrule.interval()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setFrequency(*rrule.interval());
+    } else {
+        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+    }
     {
-        typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
-        
-        RecurrencePtr r(new KCalCore::RecurrenceRule());
-        KCalCore::RecurrenceRule &d = *r;
-        using namespace icalendar_2_0;
-        switch (rrule.freq()) {
-            case FreqRecurType::YEARLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+        QList<int> bysec;
+        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+            Q_ASSERT(*it <= std::numeric_limits<int>::max());
+            bysec.append(*it);
+        }
+        if (!bysec.isEmpty()) {
+            d.setBySeconds(bysec);
+        }
+    }
+    //TODO implement all the other by*** lists
+    if (rrule.wkst()) {
+        switch (*rrule.wkst()) {
+            case WeekdayRecurType::MO:
+                d.setWeekStart(1);
                 break;
-            case FreqRecurType::MONTHLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+            case WeekdayRecurType::TU:
+                d.setWeekStart(2);
                 break;
-            case FreqRecurType::WEEKLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+            case WeekdayRecurType::WE:
+                d.setWeekStart(3);
                 break;
-            case FreqRecurType::DAILY:
-                kDebug() << "daily";
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+            case WeekdayRecurType::TH:
+                d.setWeekStart(4);
                 break;
-            case FreqRecurType::HOURLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+            case WeekdayRecurType::FR:
+                d.setWeekStart(5);
                 break;
-            case FreqRecurType::MINUTELY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+            case WeekdayRecurType::SA:
+                d.setWeekStart(6);
                 break;
-            case FreqRecurType::SECONDLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+            case WeekdayRecurType::SU:
+                d.setWeekStart(7);
                 break;
             default:
-                kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
-        }
-        if (rrule.until()) {
-            DatePtr date;
-            if ((*rrule.until()).date_time()) {
-                date = toDate(*(*rrule.until()).date_time());
-            } else if ((*rrule.until()).date()) {
-                date = toDate(*(*rrule.until()).date());
-            }
-            d.setEndDt(*date);
-        } else if (rrule.count()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setDuration(*rrule.count());
-        }
-        
-        if (rrule.interval()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setFrequency(*rrule.interval());
-        } else {
-            d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
         }
-        {
-            QList<int> bysec;
-            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-                Q_ASSERT(*it <= std::numeric_limits<int>::max());
-                bysec.append(*it);
-            }
-            if (!bysec.isEmpty()) {
-                d.setBySeconds(bysec);
-            }
-        }
-        //TODO implement all the other by*** lists
-        if (rrule.wkst()) {
-            switch (*rrule.wkst()) {
-                case WeekdayRecurType::MO:
-                    d.setWeekStart(1);
-                    break;
-                case WeekdayRecurType::TU:
-                    d.setWeekStart(2);
-                    break;
-                case WeekdayRecurType::WE:
-                    d.setWeekStart(3);
-                    break;
-                case WeekdayRecurType::TH:
-                    d.setWeekStart(4);
-                    break;
-                case WeekdayRecurType::FR:
-                    d.setWeekStart(5);
-                    break;
-                case WeekdayRecurType::SA:
-                    d.setWeekStart(6);
-                    break;
-                case WeekdayRecurType::SU:
-                    d.setWeekStart(7);
-                    break;
-                default:
-                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
-            }
-        }
-        return r;
     }
+    return r;
+}*/
+
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+    QStringList d;
+    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+        d.append(QString::fromStdString(*it));
+    }
+    return d;
+}
 
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return QString::fromStdString(s.text());
 }
 
+
+} //Namespace
+
 #endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 09c6ae0..feb5e01 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -9,7 +9,6 @@
 #include <kdebug.h>
 #include <limits>
 #include <kcalcore/recurrencerule.h>
-#include "conversions.h"
 #include "kcalconversions.h"
 
 namespace Kolab {
@@ -160,7 +159,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 
     KCalCore::Recurrence *recurrence = event.recurrence();
     if (prop.rrule()) {
-       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
+       RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
        rrule->setStartDt(recurrence->startDateTime());
        recurrence->addRRule(rrule.release());
     }
@@ -179,13 +178,17 @@ std::string writeEvent(KCalCore::Event::Ptr event)
     using namespace icalendar_2_0;
     try {
         
+        typedef DateTimeConverter<KDateTime> DC;
+        
         KolabEvent::components_type eventComponents;
         
         KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
         KolabEvent::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(fromDateTime(event->lastModified()));
+        kDebug() << "dtstamp";
+        dtstamp.date_time(DC::fromDateTime(event->lastModified()));
         KolabEvent::properties_type::created_type created;
-        created.date_time(fromDateTime(event->created()));
+        kDebug() << "created";
+        created.date_time(DC::fromDateTime(event->created()));
         KolabEvent::properties_type eventProps(uid, created, dtstamp);
         
         KolabEvent vevent(eventProps, eventComponents);
@@ -216,16 +219,23 @@ std::string writeEvent(KCalCore::Event::Ptr event)
     } 
 }
 
-
 void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
 {
     icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
     prop.sequence(event.revision());
     if (event.dtStart().isValid()) {
         icalendar_2_0::properties::dtstart_type dtstart;
-        setDateTimeProperty(dtstart, event.dtStart()); 
+        setDateTimeProperty<KCalCoreTypes>(dtstart, event.dtStart());
         prop.dtstart(dtstart);
     }
+    
+    if (event.dtEnd().isValid()) {
+        icalendar_2_0::properties::dtend_type dtend;
+        setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
+        prop.dtend(dtend);
+    } else if (event.duration() != KCalCore::Duration()) {
+        
+    }
 }
 
 
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 7701cf9..b999f27 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -18,7 +18,6 @@
 #include <lib/kolabformat.h>
 #include <kdebug.h>
 
-
 void BindingsTest::writeNoteTest()
 {
     xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
@@ -380,7 +379,16 @@ void BindingsTest::readEvent()
     kDebug() << event->description();
 }
 
-
+void BindingsTest::writeEvent()
+{
+    KCalCore::Event::Ptr event(new KCalCore::Event);
+    event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    
+    kDebug() << "-------------------";
+    kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+    kDebug() << "-------------------";
+}
 
 
 QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4afef3e..520843b 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -25,6 +25,8 @@ class BindingsTest : public QObject
     
     //Kolabformat
     void readEvent();
+    void writeEvent();
+
 };
 
 #endif
\ No newline at end of file


commit 4dbfad98ce19fb5e2334e3158b93f9bb5009c96b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 16 21:05:54 2011 +0100

    temp, moving kcal dependedn converters to own file (to avoid a qt/kde dependency)

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index ef8d680..542568d 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -5,11 +5,13 @@
 #include <bindings/iCalendar-props.hxx>
 #include <kdebug.h>
 #include <boost/shared_ptr.hpp>
-#include "kolabcontainers.h"
+#include <kdatetime.h>
+// #include "kolabcontainers.h"
 // #include "kolabcontainers.h"
 
 namespace Kolab {
     
+
 template <typename T> struct DateTimeConverter;
     
 // template <> struct DateTimeConverter<DateTime>
@@ -33,53 +35,17 @@ template <typename T> struct DateTimeConverter;
 //     }
 // };
 
-template <> struct DateTimeConverter<KDateTime>
-{
-    typedef typename KDateTime Type;
-    typedef typename boost::shared_ptr<KDateTime> Ptr;
-    static Ptr toDate(const  xml_schema::date &dt)
-    {
-        Ptr date(new KDateTime());
-        date->setDateOnly(true);
-        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-        return date;
-    }
-    
-    static Ptr toDate(const xml_schema::date_time &dt)
-    {
-        Ptr date(new KDateTime());
-        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-        if (dt.zone_present()) {
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-        return date;
-    }
 
-    static void setTimezone(Ptr date, const std::string &tzid)
-    {
-        KTimeZone timezone(QString::fromStdString(tzid));
-        KDateTime::Spec spec(timezone);
-        date->setTimeSpec(spec);
-    }
-    
-    static void setUTC(Ptr date)
-    {
-        if (date->timeSpec().type() != KDateTime::UTC) {
-            kWarning() << "utc date wrong formatting, corrected to utc";
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-    }
-};
     
     
-template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
 {
-    typename DateTimeConverter<T>::Ptr date;
+    typedef DateTimeConverter<typename T::DateType> DC;
+    typename T::DatePtr date;
     if (dtProperty.date_time()) {
-        date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+        date = DC::toDate(*dtProperty.date_time());
     } else if (dtProperty.date()) {
-        date = DateTimeConverter<T>::toDate(*dtProperty.date());
+        date = DC::toDate(*dtProperty.date());
     }
     
     if (dtProperty.parameters()) {
@@ -93,97 +59,63 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
 //                     } else {
 //                         kWarning() << "/kolab.org/ timezone prefix is missing";
 //                     }
-                DateTimeConverter<T>::setTimezone(date, tzid);
+                DC::setTimezone(date, tzid);
             }
         }
     }
     return date;
 }
 
-template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
 {
-    typename DateTimeConverter<T>::Ptr date;
+    typedef typename T::DateType DateType;
+    typedef typename T::DatePtr DatePtr;
+    
+    typedef DateTimeConverter<DateType> DC;
+    
+    typename T::DatePtr date;
     if (dtProperty.date_time()) {
-        date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+        date = DC::toDate(*dtProperty.date_time());
     } else { //The utc-date-time element shouldn't even exist
-        date = DateTimeConverter<T>::Ptr(new DateTimeConverter<T>::Type());
+        date = DatePtr(new DateType());
         kWarning() << "This element shouldn't even be existing";
         Q_ASSERT(0);
     }
-    DateTimeConverter<T>::setUTC(date);
+    DC::setUTC(date);
     return date;
 }
 
 template <typename T> struct RecurrenceConverter;
 
-template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
-{
-    typedef typename KCalCore::RecurrenceRule Type;
-    typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
-    static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
-    {
-        switch (freq) {
-            case FreqRecurType::YEARLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-                break;
-            case FreqRecurType::MONTHLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-                break;
-            case FreqRecurType::WEEKLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
-                break;
-            case FreqRecurType::DAILY:
-                kDebug() << "daily";
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-                break;
-            case FreqRecurType::HOURLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
-                break;
-            case FreqRecurType::MINUTELY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
-                break;
-            case FreqRecurType::SECONDLY:
-                r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
-                break;
-            default:
-                kWarning() << "invalid unhandled recurrenc type" << freq;
-        }
-    }
-    static void setUntil(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
-    {
-        DatePtr date;
-        if ((*rrule.until()).date_time()) {
-            date = toDate(*(*rrule.until()).date_time());
-        } else if ((*rrule.until()).date()) {
-            date = toDate(*(*rrule.until()).date());
-        }
-        d.setEndDt(*date);
-    }
-            
 
-};
-    
-    
-template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalendar_2_0::RecurType &rrule)
+
+template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
 {
-        RecurrenceConverter<T>::Ptr r(new RecurrenceConverter<T>::Type());
         using namespace icalendar_2_0;
-        
-        RecurrenceConverter<T>::setType(r, rrule.freq());
+
+        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()) {
-            RecurrenceConverter<T>::setUntil(r, *rrule.until());
-            DateTimeConverter<KCalCore>::DateType date;
+            RC::setUntil(r, *rrule.until());
+            DatePtr date;
             if ((*rrule.until()).date_time()) {
-                date = toDate(*(*rrule.until()).date_time());
+                date = DC::toDate(*(*rrule.until()).date_time());
             } else if ((*rrule.until()).date()) {
-                date = toDate(*(*rrule.until()).date());
+                date = DC::toDate(*(*rrule.until()).date());
             }
-            d.setEndDt(*date);
+            RC::setEndDt(date);
         } else if (rrule.count()) {
-            RecurrenceConverter<T>::setCount(r, *rrule.count());
-
+            RC::setCount(r, *rrule.count());
+/*TODO
             Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setDuration(*rrule.count());
+            d.setDuration(*rrule.count());*/
         }
        /* 
         if (rrule.interval()) {
@@ -291,99 +223,7 @@ template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalend
 
 
 
-    //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
-    typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr; 
 
-    RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-    {
-        RecurrencePtr r(new KCalCore::RecurrenceRule());
-        KCalCore::RecurrenceRule &d = *r;
-        using namespace icalendar_2_0;
-        switch (rrule.freq()) {
-            case FreqRecurType::YEARLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-                break;
-            case FreqRecurType::MONTHLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-                break;
-            case FreqRecurType::WEEKLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
-                break;
-            case FreqRecurType::DAILY:
-                kDebug() << "daily";
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-                break;
-            case FreqRecurType::HOURLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
-                break;
-            case FreqRecurType::MINUTELY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
-                break;
-            case FreqRecurType::SECONDLY:
-                d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
-                break;
-            default:
-                kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
-        }
-        if (rrule.until()) {
-            DatePtr date;
-            if ((*rrule.until()).date_time()) {
-                date = toDate(*(*rrule.until()).date_time());
-            } else if ((*rrule.until()).date()) {
-                date = toDate(*(*rrule.until()).date());
-            }
-            d.setEndDt(*date);
-        } else if (rrule.count()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setDuration(*rrule.count());
-        }
-        
-        if (rrule.interval()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            d.setFrequency(*rrule.interval());
-        } else {
-            d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
-        }
-        {
-            QList<int> bysec;
-            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-                Q_ASSERT(*it <= std::numeric_limits<int>::max());
-                bysec.append(*it);
-            }
-            if (!bysec.isEmpty()) {
-                d.setBySeconds(bysec);
-            }
-        }
-        //TODO implement all the other by*** lists
-        if (rrule.wkst()) {
-            switch (*rrule.wkst()) {
-                case WeekdayRecurType::MO:
-                    d.setWeekStart(1);
-                    break;
-                case WeekdayRecurType::TU:
-                    d.setWeekStart(2);
-                    break;
-                case WeekdayRecurType::WE:
-                    d.setWeekStart(3);
-                    break;
-                case WeekdayRecurType::TH:
-                    d.setWeekStart(4);
-                    break;
-                case WeekdayRecurType::FR:
-                    d.setWeekStart(5);
-                    break;
-                case WeekdayRecurType::SA:
-                    d.setWeekStart(6);
-                    break;
-                case WeekdayRecurType::SU:
-                    d.setWeekStart(7);
-                    break;
-                default:
-                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
-            }
-        }
-        return r;
-    }
 // }
 
 
@@ -396,16 +236,6 @@ int toInt(const icalendar_2_0::IntegerPropertyType &prop)
 }
 
 
-template <class T> struct ConversionTypeTraits {
-    typedef typename T::ReturnType ReturnType;
-    typedef typename T::ValueType ValueType;
-};
-
-template <> struct ConversionTypeTraits<xml_schema::date_time> {
-    typedef xml_schema::date_time ReturnType ;
-    typedef KDateTime ValueType;
-};
-
 // template <class ValueType, class ReturnType> struct ConversionTraits {
 // //     typedef typename T::ReturnType ReturnType;
 // //     typedef typename T::ValueType ValueType;
@@ -420,123 +250,8 @@ template <> struct ConversionTypeTraits<xml_schema::date_time> {
 //     }
 // };
 
-template <class T> struct ConversionTraits {
-     typedef typename T::ReturnType ReturnType;
-     typedef typename T::ValueType ValueType;
-//     
-    static ReturnType to(ValueType v)
-    {
-        return ReturnType(0,0,0,0);
-    }
-    static ValueType from(ReturnType v)
-    {
-        return v;
-    }
-};
-
-
-template < typename T > struct Convert;
-
-template <> struct Convert< KDateTime > {
-
-    static xml_schema::date_time to(KDateTime v)
-    {
-        return xml_schema::date_time(0,0,0,0);
-    }
-    
-    static DatePtr from(xml_schema::date_time dt)
-    {
-        DatePtr date(new KDateTime());
-        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-        if (dt.zone_present()) {
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-        return date;
-    }
-};
 
-template <> struct Convert< xml_schema::date_time > {
 
-    static xml_schema::date_time to(xml_schema::date_time v)
-    {
-        return xml_schema::date_time(0,0,0,0);
-    }
-    
-    static xml_schema::date_time from(xml_schema::date_time v)
-    {
-        //return T(0,0,0,0);
-    }
-    
-    static xml_schema::date_time convert(KDateTime)
-    {
-        //return T(0,0,0,0);
-    }
-    
-};
-
-template <> struct Convert< KCalCore::RecurrenceRule > {
-
-    static void to(KCalCore::RecurrenceRule &rule, icalendar_2_0::RecurType rrule)
-    {
-        if (rrule.until()) {
-            DatePtr date;
-            if ((*rrule.until()).date_time()) {
-                date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
-            } else if ((*rrule.until()).date()) {
-//                 date = toDate(*(*rrule.until()).date());
-            }
-            rule.setEndDt(*date);
-        } else if (rrule.count()) {
-            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-            rule.setDuration(*rrule.count());
-        }
-    }
-    
-
-};
-
-// template <> struct Container< KCalCore::RecurrenceRule > {
-// 
-//     typedef KDateTime DateType;
-//     KCalCore::RecurrenceRule rule;
-// };
-// 
-/*
-template < typename T > void setRecurrence(T &rule, icalendar_2_0::RecurType rrule)
-{
-    if (rrule.until()) {
-        Convert<T::DateType>::setUntil(rrule, 
-            DatePtr date;
-            if ((*rrule.until()).date_time()) {
-                date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
-            } else if ((*rrule.until()).date()) {
-//                 date = toDate(*(*rrule.until()).date());
-            }
-            rule.setEndDt(*date);
-    } else if (rrule.count()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        rule.setDuration(*rrule.count());
-    }
-    
-}*/
-
-void test()
-{
-    KDateTime kdt;
-    xml_schema::date_time dt(0,0,0,0);
-    dt = ConversionTraits< ConversionTypeTraits< xml_schema::date_time > >::to(kdt);
-    
-    dt = Convert< KDateTime >::to(kdt);
-}
-// template <class Container>
-// typename Container::Return con(Container &c) {
-//     typename Container::Value
-// };
-// 
-// template <typename Container>
-// template <xml_schema::date_time>
-// xml_schema::date_time fromDate(const KDateTime &dt)
 
 
 xml_schema::date_time fromDateTime(const KDateTime &dt)
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
new file mode 100644
index 0000000..82070ec
--- /dev/null
+++ b/c++/lib/kcalconversions.h
@@ -0,0 +1,199 @@
+#ifndef KOLAB_KCALCONVERSIONS_H
+#define KOLAB_KCALCONVERSIONS_H
+
+#include "conversions.h"
+
+namespace Kolab {
+
+struct KCalCoreTypes
+{
+    typedef KDateTime DateType;
+    typedef typename boost::shared_ptr<KDateTime> DatePtr;
+    typedef typename KCalCore::RecurrenceRule RecurrenceType;
+    typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+};
+
+typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+
+
+template <> struct DateTimeConverter<KDateTime>
+{
+    typedef KDateTime Type;
+    typedef typename boost::shared_ptr<KDateTime> Ptr;
+    static Ptr toDate(const  xml_schema::date &dt)
+    {
+        Ptr date(new KDateTime());
+        date->setDateOnly(true);
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        return date;
+    }
+    
+    static Ptr toDate(const xml_schema::date_time &dt)
+    {
+        Ptr date(new KDateTime());
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+        if (dt.zone_present()) {
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+        return date;
+    }
+
+    static void setTimezone(Ptr date, const std::string &tzid)
+    {
+        KTimeZone timezone(QString::fromStdString(tzid));
+        KDateTime::Spec spec(timezone);
+        date->setTimeSpec(spec);
+    }
+    
+    static void setUTC(Ptr date)
+    {
+        if (date->timeSpec().type() != KDateTime::UTC) {
+            kWarning() << "utc date wrong formatting, corrected to utc";
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+    }
+};
+
+template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
+{
+//     using namespace icalendar_2_0;
+    
+    typedef typename KCalCore::RecurrenceRule Type;
+    typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
+    
+    static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+    {
+        switch (freq) {
+            case icalendar_2_0::FreqRecurType::YEARLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+                break;
+            case icalendar_2_0::FreqRecurType::MONTHLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+                break;
+            case icalendar_2_0::FreqRecurType::WEEKLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+                break;
+            case icalendar_2_0::FreqRecurType::DAILY:
+                kDebug() << "daily";
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+                break;
+            case icalendar_2_0::FreqRecurType::HOURLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+                break;
+            case icalendar_2_0::FreqRecurType::MINUTELY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+                break;
+            case icalendar_2_0::FreqRecurType::SECONDLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+                break;
+            default:
+                kWarning() << "invalid unhandled recurrenc type" << freq;
+        }
+    }
+    
+    static void setUntil(Ptr r, KCalCoreTypes::DatePtr date )
+    {
+        r->setEndDt(*date);
+    }
+};
+
+    //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
+//     typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr; 
+
+    typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+    {
+        typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+        
+        RecurrencePtr r(new KCalCore::RecurrenceRule());
+        KCalCore::RecurrenceRule &d = *r;
+        using namespace icalendar_2_0;
+        switch (rrule.freq()) {
+            case FreqRecurType::YEARLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+                break;
+            case FreqRecurType::MONTHLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+                break;
+            case FreqRecurType::WEEKLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+                break;
+            case FreqRecurType::DAILY:
+                kDebug() << "daily";
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+                break;
+            case FreqRecurType::HOURLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+                break;
+            case FreqRecurType::MINUTELY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+                break;
+            case FreqRecurType::SECONDLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+                break;
+            default:
+                kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+        }
+        if (rrule.until()) {
+            DatePtr date;
+            if ((*rrule.until()).date_time()) {
+                date = toDate(*(*rrule.until()).date_time());
+            } else if ((*rrule.until()).date()) {
+                date = toDate(*(*rrule.until()).date());
+            }
+            d.setEndDt(*date);
+        } else if (rrule.count()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setDuration(*rrule.count());
+        }
+        
+        if (rrule.interval()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setFrequency(*rrule.interval());
+        } else {
+            d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+        }
+        {
+            QList<int> bysec;
+            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+                Q_ASSERT(*it <= std::numeric_limits<int>::max());
+                bysec.append(*it);
+            }
+            if (!bysec.isEmpty()) {
+                d.setBySeconds(bysec);
+            }
+        }
+        //TODO implement all the other by*** lists
+        if (rrule.wkst()) {
+            switch (*rrule.wkst()) {
+                case WeekdayRecurType::MO:
+                    d.setWeekStart(1);
+                    break;
+                case WeekdayRecurType::TU:
+                    d.setWeekStart(2);
+                    break;
+                case WeekdayRecurType::WE:
+                    d.setWeekStart(3);
+                    break;
+                case WeekdayRecurType::TH:
+                    d.setWeekStart(4);
+                    break;
+                case WeekdayRecurType::FR:
+                    d.setWeekStart(5);
+                    break;
+                case WeekdayRecurType::SA:
+                    d.setWeekStart(6);
+                    break;
+                case WeekdayRecurType::SU:
+                    d.setWeekStart(7);
+                    break;
+                default:
+                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+            }
+        }
+        return r;
+    }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 233fec5..09c6ae0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -10,6 +10,7 @@
 #include <limits>
 #include <kcalcore/recurrencerule.h>
 #include "conversions.h"
+#include "kcalconversions.h"
 
 namespace Kolab {
     
@@ -108,104 +109,22 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
     return KCalCore::Event::Ptr();
 }
 
-template <class T, class P> struct Properties {
-//      typedef typename T::ReturnType ReturnType;
-//      typedef typename T::ValueType ValueType;
-//     
-    static void set(T &object, P &value)
-    {
-        
-    }
-
-};
-
-template <> struct Properties < KCalCore::Event, icalendar_2_0::properties::uid_type > {
-    static void set(KCalCore::Event &object, icalendar_2_0::properties::uid_type &uid)
-    {
-         object.setUid(toString(uid));
-    }
-
-};
-
-template < typename P > struct PropertySetter
-{
-    template < typename T >
-    static void set( T t, P p ) {
-        set(t, p);
-    }
-};
 
-template < typename P > struct PropertySetter< P* >
-{
-    template < typename T >
-    static void set( T t, P *p ) {
-        if (p) {
-            set(t, *p);
-        }
-    }
-};
-
-// template< typename T > 
-// struct is_pointer< T* >{ 
-//   static const bool value = true; 
-// };
-
-template< typename T > 
-struct is_optional{ 
-  static const bool value = false; 
-};
-
-template< typename T > 
-struct is_optional< T* > { 
-  static const bool value = true; 
-};
-
-template< bool b > 
-struct algorithm_selector { 
-  template< typename T, typename P > 
-  static void set( T& object, P &property ) 
-  { 
-
-  } 
-};
-
-template<> 
-struct algorithm_selector< true > { 
-  template< typename T, typename P > 
-  static void set( T& object, P *property )   {
-      if (property) {
-          
-      }
-  } 
-};
-
-template <typename T>
-void readEvent(T &event,  const icalendar_2_0::KolabEvent &vevent)
-{
-    const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-    Properties<T, icalendar_2_0::properties::uid_type>::set(event, prop.uid());
-    
-    
-    algorithm_selector< is_optional< icalendar_2_0::properties::uid_type >::value >::set(event, prop.uid()); 
-    PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
-    PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
-    
-}
 
 void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 {
     const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
 
     event.setUid(toString(prop.uid()));
-    event.setCreated(*toDate(prop.created()));
-    event.setLastModified(*toDate(prop.dtstamp()));
+    event.setCreated(*toDate<KCalCoreTypes>(prop.created()));
+    event.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
 
     if (prop.sequence()) {
         event.setRevision(toInt(*prop.sequence()));
     }
 
     if (prop.dtstart()) {
-        const DatePtr date = toDate<KDateTime>(*prop.dtstart());
+        const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
         event.setDtStart(*date);
         event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
     }
@@ -213,7 +132,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
     if (prop.dtend()) {
         KDateTime date;
         kDebug() << "dtend";
-        event.setDtEnd(*toDate(*prop.dtend()));
+        event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
         if (event.dtEnd().timeType() != event.dtStart().timeType()) {
             kWarning() << "dtEnd has wrong timespec";
         }


commit cbd39249827c5c42e75d0d88f606735c1509dac4
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 16 17:48:21 2011 +0100

    first approach with templates

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index cd27c5b..ef8d680 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -5,6 +5,7 @@
 #include <bindings/iCalendar-props.hxx>
 #include <kdebug.h>
 #include <boost/shared_ptr.hpp>
+#include "kolabcontainers.h"
 // #include "kolabcontainers.h"
 
 namespace Kolab {
@@ -34,6 +35,7 @@ template <typename T> struct DateTimeConverter;
 
 template <> struct DateTimeConverter<KDateTime>
 {
+    typedef typename KDateTime Type;
     typedef typename boost::shared_ptr<KDateTime> Ptr;
     static Ptr toDate(const  xml_schema::date &dt)
     {
@@ -53,13 +55,21 @@ template <> struct DateTimeConverter<KDateTime>
         }
         return date;
     }
-    
-    static void setTimezone(Ptr date, const std::string &tzid )
+
+    static void setTimezone(Ptr date, const std::string &tzid)
     {
         KTimeZone timezone(QString::fromStdString(tzid));
         KDateTime::Spec spec(timezone);
         date->setTimeSpec(spec);
     }
+    
+    static void setUTC(Ptr date)
+    {
+        if (date->timeSpec().type() != KDateTime::UTC) {
+            kWarning() << "utc date wrong formatting, corrected to utc";
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+    }
 };
     
     
@@ -90,6 +100,146 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
     return date;
 }
 
+template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    typename DateTimeConverter<T>::Ptr date;
+    if (dtProperty.date_time()) {
+        date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+    } else { //The utc-date-time element shouldn't even exist
+        date = DateTimeConverter<T>::Ptr(new DateTimeConverter<T>::Type());
+        kWarning() << "This element shouldn't even be existing";
+        Q_ASSERT(0);
+    }
+    DateTimeConverter<T>::setUTC(date);
+    return date;
+}
+
+template <typename T> struct RecurrenceConverter;
+
+template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
+{
+    typedef typename KCalCore::RecurrenceRule Type;
+    typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
+    static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+    {
+        switch (freq) {
+            case FreqRecurType::YEARLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+                break;
+            case FreqRecurType::MONTHLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+                break;
+            case FreqRecurType::WEEKLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+                break;
+            case FreqRecurType::DAILY:
+                kDebug() << "daily";
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+                break;
+            case FreqRecurType::HOURLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+                break;
+            case FreqRecurType::MINUTELY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+                break;
+            case FreqRecurType::SECONDLY:
+                r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+                break;
+            default:
+                kWarning() << "invalid unhandled recurrenc type" << freq;
+        }
+    }
+    static void setUntil(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+    {
+        DatePtr date;
+        if ((*rrule.until()).date_time()) {
+            date = toDate(*(*rrule.until()).date_time());
+        } else if ((*rrule.until()).date()) {
+            date = toDate(*(*rrule.until()).date());
+        }
+        d.setEndDt(*date);
+    }
+            
+
+};
+    
+    
+template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+        RecurrenceConverter<T>::Ptr r(new RecurrenceConverter<T>::Type());
+        using namespace icalendar_2_0;
+        
+        RecurrenceConverter<T>::setType(r, rrule.freq());
+        if (rrule.until()) {
+            RecurrenceConverter<T>::setUntil(r, *rrule.until());
+            DateTimeConverter<KCalCore>::DateType date;
+            if ((*rrule.until()).date_time()) {
+                date = toDate(*(*rrule.until()).date_time());
+            } else if ((*rrule.until()).date()) {
+                date = toDate(*(*rrule.until()).date());
+            }
+            d.setEndDt(*date);
+        } else if (rrule.count()) {
+            RecurrenceConverter<T>::setCount(r, *rrule.count());
+
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setDuration(*rrule.count());
+        }
+       /* 
+        if (rrule.interval()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setFrequency(*rrule.interval());
+        } else {
+            d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+        }
+        {
+            QList<int> bysec;
+            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+                Q_ASSERT(*it <= std::numeric_limits<int>::max());
+                bysec.append(*it);
+            }
+            if (!bysec.isEmpty()) {
+                d.setBySeconds(bysec);
+            }
+        }
+        //TODO implement all the other by*** lists
+        if (rrule.wkst()) {
+            switch (*rrule.wkst()) {
+                case WeekdayRecurType::MO:
+                    d.setWeekStart(1);
+                    break;
+                case WeekdayRecurType::TU:
+                    d.setWeekStart(2);
+                    break;
+                case WeekdayRecurType::WE:
+                    d.setWeekStart(3);
+                    break;
+                case WeekdayRecurType::TH:
+                    d.setWeekStart(4);
+                    break;
+                case WeekdayRecurType::FR:
+                    d.setWeekStart(5);
+                    break;
+                case WeekdayRecurType::SA:
+                    d.setWeekStart(6);
+                    break;
+                case WeekdayRecurType::SU:
+                    d.setWeekStart(7);
+                    break;
+                default:
+                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+            }
+        }*/
+        return r;
+    }
+
+
+
+
+
+
+
+
 // namespace KCalCore {
     
     typedef boost::shared_ptr<KDateTime> DatePtr;
@@ -135,54 +285,10 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
         return date;
     }
 
-    DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-    {
-        DatePtr date;
-        if (dtProperty.date_time()) {
-            
-            date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date_time());//toDate(*dtProperty.date_time());
-        } else if (dtProperty.date()) {
-            date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date());//toDate(*dtProperty.date());
-            kDebug() << "date";
-        }
-        
-        if (dtProperty.parameters()) {
-            for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
-                if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
-                    QString tzid(toString(tz->text()));
-                    if (tzid.contains("/kolab.org/")) {
-                        tzid.remove("/kolab.org/");
-                    } else {
-                        kWarning() << "/kolab.org/ timezone prefix is missing";
-                    }
-                    KTimeZone timezone(tzid);
-                    KDateTime::Spec spec(timezone);
-                    date->setTimeSpec(spec);
-    //                 kDebug() << tzid;
-                }
-    //             kDebug() << "---------------_";
-            }
-        }
-        return date;
-    }
 
 
-    DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-    {
-        DatePtr date;
-        if (dtProperty.date_time()) {
-            date = toDate(*dtProperty.date_time());
-        } else { //The utc-date-time element shouldn't even exist
-            date = DatePtr(new KDateTime());
-            kWarning() << "This element shouldn't even be existing";
-            Q_ASSERT(0);
-        }
-        if (date->timeSpec().type() != KDateTime::UTC) {
-            kWarning() << "utc date wrong formatting, corrected to utc";
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-        return date;
-    }
+
+
 
 
     //boost::shared_ptr would be safer but lacks the possiblity to release the pointer


commit 08800b1f848ad50f33171e87b75046e7d93d31fc
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 16 17:12:25 2011 +0100

    temp

diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index dcff7b3..cd27c5b 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -4,200 +4,485 @@
 #include "kolabformat.h"
 #include <bindings/iCalendar-props.hxx>
 #include <kdebug.h>
+#include <boost/shared_ptr.hpp>
+// #include "kolabcontainers.h"
 
 namespace Kolab {
+    
+template <typename T> struct DateTimeConverter;
+    
+// template <> struct DateTimeConverter<DateTime>
+// {
+//     typedef typename boost::shared_ptr<DateTime> Ptr;
+//     Ptr toDate(const  xml_schema::date &dt)
+//     {
+//         Ptr date(new DateTime());
+// 
+//         return date;
+//     }
+//     Ptr toDate(const xml_schema::date_time &dt)
+//     {
+//         Ptr date(new DateTime());
+//         return date;
+//     }
+//     
+//     void setTimezone(Ptr date, const std::string &tzid )
+//     {
+//         date->setTimezone(tzid);
+//     }
+// };
 
-typedef std::auto_ptr<KDateTime> DatePtr;
-
-QString toString(const xml_schema::string &s)
-{
-    return QString::fromStdString(s);
-}
-
-QString toString(const icalendar_2_0::TextPropertyType &s)
-{
-    return toString(s.text());
-}
-
-DatePtr toDate(const  xml_schema::date &dt)
-{
-    DatePtr date(new KDateTime());
-    date->setDateOnly(true);
-    date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-    return date;
-}
-
-DatePtr toDate(const xml_schema::date_time &dt)
-{
-    DatePtr date(new KDateTime());
-//     kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
-    date->setDate(QDate(dt.year(), dt.month(), dt.day()));
-    date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-    if (dt.zone_present()) {
-        date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-    }
-//     kDebug() << date->date() << *date << dt.zone_present();
-    return date;
-}
-
-QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+template <> struct DateTimeConverter<KDateTime>
 {
-    QStringList d;
-    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-        d.append(QString::fromStdString(*it));
+    typedef typename boost::shared_ptr<KDateTime> Ptr;
+    static Ptr toDate(const  xml_schema::date &dt)
+    {
+        Ptr date(new KDateTime());
+        date->setDateOnly(true);
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        return date;
     }
-    return d;
-}
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
-    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
-    int i = prop.integer();
-    return i;
-}
-
-DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+    
+    static Ptr toDate(const xml_schema::date_time &dt)
+    {
+        Ptr date(new KDateTime());
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+        if (dt.zone_present()) {
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+        return date;
+    }
+    
+    static void setTimezone(Ptr date, const std::string &tzid )
+    {
+        KTimeZone timezone(QString::fromStdString(tzid));
+        KDateTime::Spec spec(timezone);
+        date->setTimeSpec(spec);
+    }
+};
+    
+    
+template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
 {
-    DatePtr date;
+    typename DateTimeConverter<T>::Ptr date;
     if (dtProperty.date_time()) {
-        date = toDate(*dtProperty.date_time());
+        date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
     } else if (dtProperty.date()) {
-        date = toDate(*dtProperty.date());
-        kDebug() << "date";
+        date = DateTimeConverter<T>::toDate(*dtProperty.date());
     }
     
     if (dtProperty.parameters()) {
         for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
             if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
-                QString tzid(toString(tz->text()));
-                if (tzid.contains("/kolab.org/")) {
-                    tzid.remove("/kolab.org/");
-                } else {
-                    kWarning() << "/kolab.org/ timezone prefix is missing";
-                }
-                KTimeZone timezone(tzid);
-                KDateTime::Spec spec(timezone);
-                date->setTimeSpec(spec);
-//                 kDebug() << tzid;
+                std::string tzid = tz->text();
+                //TODO
+//                     QString tzid(toString());
+//                     if (tzid.contains("/kolab.org/")) {
+//                         tzid.remove("/kolab.org/");
+//                     } else {
+//                         kWarning() << "/kolab.org/ timezone prefix is missing";
+//                     }
+                DateTimeConverter<T>::setTimezone(date, tzid);
             }
-//             kDebug() << "---------------_";
         }
     }
     return date;
 }
 
-DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
-    DatePtr date;
-    if (dtProperty.date_time()) {
-        date = toDate(*dtProperty.date_time());
-    } else { //The utc-date-time element shouldn't even exist
-        date = DatePtr(new KDateTime());
-        kWarning() << "This element shouldn't even be existing";
-        Q_ASSERT(0);
+// namespace KCalCore {
+    
+    typedef boost::shared_ptr<KDateTime> DatePtr;
+
+    QString toString(const xml_schema::string &s)
+    {
+        return QString::fromStdString(s);
     }
-    if (date->timeSpec().type() != KDateTime::UTC) {
-        kWarning() << "utc date wrong formatting, corrected to utc";
-        date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+
+    QString toString(const icalendar_2_0::TextPropertyType &s)
+    {
+        return toString(s.text());
     }
-    return date;
-}
 
+    QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+    {
+        QStringList d;
+        const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+        for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+            d.append(QString::fromStdString(*it));
+        }
+        return d;
+    }
+    
+    DatePtr toDate(const  xml_schema::date &dt)
+    {
+        DatePtr date(new KDateTime());
+        date->setDateOnly(true);
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        return date;
+    }
 
-void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
-{
-    using namespace icalendar_2_0;
-    switch (rrule.freq()) {
-        case FreqRecurType::YEARLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-            break;
-        case FreqRecurType::MONTHLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-            break;
-        case FreqRecurType::WEEKLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
-            break;
-        case FreqRecurType::DAILY:
-            kDebug() << "daily";
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-            break;
-        case FreqRecurType::HOURLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
-            break;
-        case FreqRecurType::MINUTELY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
-            break;
-        case FreqRecurType::SECONDLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
-            break;
-        default:
-            kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+    DatePtr toDate(const xml_schema::date_time &dt)
+    {
+        DatePtr date(new KDateTime());
+    //     kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+        if (dt.zone_present()) {
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+    //     kDebug() << date->date() << *date << dt.zone_present();
+        return date;
     }
-    if (rrule.until()) {
+
+    DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+    {
         DatePtr date;
-        if ((*rrule.until()).date_time()) {
-            date = toDate(*(*rrule.until()).date_time());
-        } else if ((*rrule.until()).date()) {
-            date = toDate(*(*rrule.until()).date());
+        if (dtProperty.date_time()) {
+            
+            date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date_time());//toDate(*dtProperty.date_time());
+        } else if (dtProperty.date()) {
+            date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date());//toDate(*dtProperty.date());
+            kDebug() << "date";
         }
-        d.setEndDt(*date);
-    } else if (rrule.count()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setDuration(*rrule.count());
-    }
-    
-    if (rrule.interval()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setFrequency(*rrule.interval());
-    } else {
-        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+        
+        if (dtProperty.parameters()) {
+            for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+                if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+                    QString tzid(toString(tz->text()));
+                    if (tzid.contains("/kolab.org/")) {
+                        tzid.remove("/kolab.org/");
+                    } else {
+                        kWarning() << "/kolab.org/ timezone prefix is missing";
+                    }
+                    KTimeZone timezone(tzid);
+                    KDateTime::Spec spec(timezone);
+                    date->setTimeSpec(spec);
+    //                 kDebug() << tzid;
+                }
+    //             kDebug() << "---------------_";
+            }
+        }
+        return date;
     }
+
+
+    DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
     {
-        QList<int> bysec;
-        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-            Q_ASSERT(*it <= std::numeric_limits<int>::max());
-            bysec.append(*it);
+        DatePtr date;
+        if (dtProperty.date_time()) {
+            date = toDate(*dtProperty.date_time());
+        } else { //The utc-date-time element shouldn't even exist
+            date = DatePtr(new KDateTime());
+            kWarning() << "This element shouldn't even be existing";
+            Q_ASSERT(0);
         }
-        if (!bysec.isEmpty()) {
-            d.setBySeconds(bysec);
+        if (date->timeSpec().type() != KDateTime::UTC) {
+            kWarning() << "utc date wrong formatting, corrected to utc";
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
         }
+        return date;
     }
-    //TODO implement all the other by*** lists
-    if (rrule.wkst()) {
-        switch (*rrule.wkst()) {
-            case WeekdayRecurType::MO:
-                d.setWeekStart(1);
+
+
+    //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
+    typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr; 
+
+    RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+    {
+        RecurrencePtr r(new KCalCore::RecurrenceRule());
+        KCalCore::RecurrenceRule &d = *r;
+        using namespace icalendar_2_0;
+        switch (rrule.freq()) {
+            case FreqRecurType::YEARLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
                 break;
-            case WeekdayRecurType::TU:
-                d.setWeekStart(2);
+            case FreqRecurType::MONTHLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
                 break;
-            case WeekdayRecurType::WE:
-                d.setWeekStart(3);
+            case FreqRecurType::WEEKLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
                 break;
-            case WeekdayRecurType::TH:
-                d.setWeekStart(4);
+            case FreqRecurType::DAILY:
+                kDebug() << "daily";
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
                 break;
-            case WeekdayRecurType::FR:
-                d.setWeekStart(5);
+            case FreqRecurType::HOURLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
                 break;
-            case WeekdayRecurType::SA:
-                d.setWeekStart(6);
+            case FreqRecurType::MINUTELY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
                 break;
-            case WeekdayRecurType::SU:
-                d.setWeekStart(7);
+            case FreqRecurType::SECONDLY:
+                d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
                 break;
             default:
-                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+                kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+        }
+        if (rrule.until()) {
+            DatePtr date;
+            if ((*rrule.until()).date_time()) {
+                date = toDate(*(*rrule.until()).date_time());
+            } else if ((*rrule.until()).date()) {
+                date = toDate(*(*rrule.until()).date());
+            }
+            d.setEndDt(*date);
+        } else if (rrule.count()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setDuration(*rrule.count());
+        }
+        
+        if (rrule.interval()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            d.setFrequency(*rrule.interval());
+        } else {
+            d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+        }
+        {
+            QList<int> bysec;
+            for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+                Q_ASSERT(*it <= std::numeric_limits<int>::max());
+                bysec.append(*it);
+            }
+            if (!bysec.isEmpty()) {
+                d.setBySeconds(bysec);
+            }
+        }
+        //TODO implement all the other by*** lists
+        if (rrule.wkst()) {
+            switch (*rrule.wkst()) {
+                case WeekdayRecurType::MO:
+                    d.setWeekStart(1);
+                    break;
+                case WeekdayRecurType::TU:
+                    d.setWeekStart(2);
+                    break;
+                case WeekdayRecurType::WE:
+                    d.setWeekStart(3);
+                    break;
+                case WeekdayRecurType::TH:
+                    d.setWeekStart(4);
+                    break;
+                case WeekdayRecurType::FR:
+                    d.setWeekStart(5);
+                    break;
+                case WeekdayRecurType::SA:
+                    d.setWeekStart(6);
+                    break;
+                case WeekdayRecurType::SU:
+                    d.setWeekStart(7);
+                    break;
+                default:
+                    kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+            }
         }
+        return r;
     }
+// }
+
+
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+    int i = prop.integer();
+    return i;
 }
 
-void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+
+template <class T> struct ConversionTypeTraits {
+    typedef typename T::ReturnType ReturnType;
+    typedef typename T::ValueType ValueType;
+};
+
+template <> struct ConversionTypeTraits<xml_schema::date_time> {
+    typedef xml_schema::date_time ReturnType ;
+    typedef KDateTime ValueType;
+};
+
+// template <class ValueType, class ReturnType> struct ConversionTraits {
+// //     typedef typename T::ReturnType ReturnType;
+// //     typedef typename T::ValueType ValueType;
+// //     
+//     static ReturnType to(ValueType v)
+//     {
+//         return v;
+//     }
+//     static ValueType from(ReturnType v)
+//     {
+//         return v;
+//     }
+// };
+
+template <class T> struct ConversionTraits {
+     typedef typename T::ReturnType ReturnType;
+     typedef typename T::ValueType ValueType;
+//     
+    static ReturnType to(ValueType v)
+    {
+        return ReturnType(0,0,0,0);
+    }
+    static ValueType from(ReturnType v)
+    {
+        return v;
+    }
+};
+
+
+template < typename T > struct Convert;
+
+template <> struct Convert< KDateTime > {
+
+    static xml_schema::date_time to(KDateTime v)
+    {
+        return xml_schema::date_time(0,0,0,0);
+    }
+    
+    static DatePtr from(xml_schema::date_time dt)
+    {
+        DatePtr date(new KDateTime());
+        date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+        if (dt.zone_present()) {
+            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+        }
+        return date;
+    }
+};
+
+template <> struct Convert< xml_schema::date_time > {
+
+    static xml_schema::date_time to(xml_schema::date_time v)
+    {
+        return xml_schema::date_time(0,0,0,0);
+    }
+    
+    static xml_schema::date_time from(xml_schema::date_time v)
+    {
+        //return T(0,0,0,0);
+    }
+    
+    static xml_schema::date_time convert(KDateTime)
+    {
+        //return T(0,0,0,0);
+    }
+    
+};
+
+template <> struct Convert< KCalCore::RecurrenceRule > {
+
+    static void to(KCalCore::RecurrenceRule &rule, icalendar_2_0::RecurType rrule)
+    {
+        if (rrule.until()) {
+            DatePtr date;
+            if ((*rrule.until()).date_time()) {
+                date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
+            } else if ((*rrule.until()).date()) {
+//                 date = toDate(*(*rrule.until()).date());
+            }
+            rule.setEndDt(*date);
+        } else if (rrule.count()) {
+            Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+            rule.setDuration(*rrule.count());
+        }
+    }
+    
+
+};
+
+// template <> struct Container< KCalCore::RecurrenceRule > {
+// 
+//     typedef KDateTime DateType;
+//     KCalCore::RecurrenceRule rule;
+// };
+// 
+/*
+template < typename T > void setRecurrence(T &rule, icalendar_2_0::RecurType rrule)
+{
+    if (rrule.until()) {
+        Convert<T::DateType>::setUntil(rrule, 
+            DatePtr date;
+            if ((*rrule.until()).date_time()) {
+                date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
+            } else if ((*rrule.until()).date()) {
+//                 date = toDate(*(*rrule.until()).date());
+            }
+            rule.setEndDt(*date);
+    } else if (rrule.count()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        rule.setDuration(*rrule.count());
+    }
+    
+}*/
+
+void test()
+{
+    KDateTime kdt;
+    xml_schema::date_time dt(0,0,0,0);
+    dt = ConversionTraits< ConversionTypeTraits< xml_schema::date_time > >::to(kdt);
+    
+    dt = Convert< KDateTime >::to(kdt);
+}
+// template <class Container>
+// typename Container::Return con(Container &c) {
+//     typename Container::Value
+// };
+// 
+// template <typename Container>
+// template <xml_schema::date_time>
+// xml_schema::date_time fromDate(const KDateTime &dt)
+
+
+xml_schema::date_time fromDateTime(const KDateTime &dt)
+{
+    const QDate &d = dt.date();
+    const QTime &t = dt.time();
+    xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
+//     date.zone_reset();
+    //TODO timezone
+    return date;
+}
+
+xml_schema::date fromDate(const KDateTime &dt)
+{
+    const QDate &d = dt.date();
+    xml_schema::date date(d.year(), d.month(), d.day());
+    return date;
+}
+
+
+std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> fromDateProperty(const KDateTime &dt)
+{
+    std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> date(new ::icalendar_2_0::DateDatetimePropertyType);
+    if (dt.isDateOnly()) {
+        date->date(fromDate(dt)); //setDateOnly
+    } else {
+        date->date_time(fromDateTime(dt)); //setDateTime
+    }
+    //TODO add timezone information //setTimeZone
+    return date;
+}
+
+void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const KDateTime &dt)
 {
-    toRRule(d, rrule.recur());
+    if (dt.isDateOnly()) {
+        date.date(fromDate(dt));
+    } else {
+        date.date_time(fromDateTime(dt));
+    }
+    //TODO add timezone information
 }
 
+/*
+xml_schema::date fromDate(const KDateTime &dt)
+{
+    const QDate &d = dt.date();
+    xml_schema::date date(d.year(), d.month(), d.day());
+    return date;
+}*/
+
+
+
 }
 
 #endif
\ No newline at end of file
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
new file mode 100644
index 0000000..639789c
--- /dev/null
+++ b/c++/lib/kolabcontainers.h
@@ -0,0 +1,115 @@
+#ifndef KOLAB_CONTAINERS_H
+#define KOLAB_CONTAINERS_H
+#include <string>
+#include <vector>
+
+namespace Kolab {
+    
+    /**
+     * Datatypes:
+     * -String
+     * -DateTime
+     * -
+     * 
+     */
+    
+    class DateTime {
+        void setDate(int year, int month, int day);
+        int year();
+        int month();
+        int day();
+        
+        bool isDateOnly();
+        
+        void setTime(int hour, int minute, int second);
+        int hour();
+        int minute();
+        int second();
+        
+        void setUTC(bool);
+        void setTimezone(const std::string &);
+        std::string getTimezone();
+    };
+    
+    /**
+
+      */
+    
+    class Event {
+        public:
+            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(int); //TODO enum?
+            int 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();
+            duration() const;
+            
+            void setTransparency(bool isTransparent);
+            bool transparency() const;
+            
+            void setRecurrenceRule(const RecurrenceRule &);
+            RecurrenceRule recurrenceRule() const;
+            
+            void setRecrrenceDates(const std::vector<DateTime> &);
+            std::vector<DateTime> recurrenceDates() const;
+            
+            void setExceptionDates(const std::vector<DateTime> &);
+            std::vector<DateTime> exceptionDates() const;
+            
+            void setRecurrenceID(const std::string &);
+            std::string recurrenceID() 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(int); //TODO map to string
+            int 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 setAttendee(const std::vector<Attendee> &);
+            std::vector<Attendee> attendee() const;
+            
+            void setAttachment(const std::vector<Attachment> &);
+            std::vector<Attachment> attachments() const;
+            
+            void setCustomProperty(const std::vector<CustomProperty> &);
+            std::vector<CustomProperty> customProperties() const;
+    };
+
+    
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 47305b7..233fec5 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -82,13 +82,12 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
         //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
         xml_schema::properties props;
         props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
-        
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
+
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/, 0, props));
         const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
-        
+
         QList <KCalCore::Event::Ptr> events;
-        
-        
+
         for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
             KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
             const icalendar_2_0::KolabEvent &event = *it;
@@ -109,6 +108,90 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
     return KCalCore::Event::Ptr();
 }
 
+template <class T, class P> struct Properties {
+//      typedef typename T::ReturnType ReturnType;
+//      typedef typename T::ValueType ValueType;
+//     
+    static void set(T &object, P &value)
+    {
+        
+    }
+
+};
+
+template <> struct Properties < KCalCore::Event, icalendar_2_0::properties::uid_type > {
+    static void set(KCalCore::Event &object, icalendar_2_0::properties::uid_type &uid)
+    {
+         object.setUid(toString(uid));
+    }
+
+};
+
+template < typename P > struct PropertySetter
+{
+    template < typename T >
+    static void set( T t, P p ) {
+        set(t, p);
+    }
+};
+
+template < typename P > struct PropertySetter< P* >
+{
+    template < typename T >
+    static void set( T t, P *p ) {
+        if (p) {
+            set(t, *p);
+        }
+    }
+};
+
+// template< typename T > 
+// struct is_pointer< T* >{ 
+//   static const bool value = true; 
+// };
+
+template< typename T > 
+struct is_optional{ 
+  static const bool value = false; 
+};
+
+template< typename T > 
+struct is_optional< T* > { 
+  static const bool value = true; 
+};
+
+template< bool b > 
+struct algorithm_selector { 
+  template< typename T, typename P > 
+  static void set( T& object, P &property ) 
+  { 
+
+  } 
+};
+
+template<> 
+struct algorithm_selector< true > { 
+  template< typename T, typename P > 
+  static void set( T& object, P *property )   {
+      if (property) {
+          
+      }
+  } 
+};
+
+template <typename T>
+void readEvent(T &event,  const icalendar_2_0::KolabEvent &vevent)
+{
+    const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+    Properties<T, icalendar_2_0::properties::uid_type>::set(event, prop.uid());
+    
+    
+    algorithm_selector< is_optional< icalendar_2_0::properties::uid_type >::value >::set(event, prop.uid()); 
+    PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
+    PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
+    
+}
+
 void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 {
     const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
@@ -122,7 +205,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
     }
 
     if (prop.dtstart()) {
-        const DatePtr date = toDate(*prop.dtstart());
+        const DatePtr date = toDate<KDateTime>(*prop.dtstart());
         event.setDtStart(*date);
         event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
     }
@@ -158,10 +241,9 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 
     KCalCore::Recurrence *recurrence = event.recurrence();
     if (prop.rrule()) {
-       KCalCore::RecurrenceRule *rrule = new KCalCore::RecurrenceRule();
+       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
        rrule->setStartDt(recurrence->startDateTime());
-       toRRule(*rrule, *prop.rrule());
-       recurrence->addRRule(rrule);
+       recurrence->addRRule(rrule.release());
     }
 
     if (prop.summary()) {
@@ -182,11 +264,13 @@ std::string writeEvent(KCalCore::Event::Ptr event)
         
         KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
         KolabEvent::properties_type::dtstamp_type dtstamp;
-//         dtstamp.date_time(event->lastModified());
+        dtstamp.date_time(fromDateTime(event->lastModified()));
         KolabEvent::properties_type::created_type created;
+        created.date_time(fromDateTime(event->created()));
         KolabEvent::properties_type eventProps(uid, created, dtstamp);
         
         KolabEvent vevent(eventProps, eventComponents);
+        writeEvent(vevent, *event);
         
         VcalendarType::components_type components;
         components.vevent().push_back(vevent);
@@ -214,9 +298,15 @@ std::string writeEvent(KCalCore::Event::Ptr event)
 }
 
 
-void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event& )
+void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
 {
-
+    icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+    prop.sequence(event.revision());
+    if (event.dtStart().isValid()) {
+        icalendar_2_0::properties::dtstart_type dtstart;
+        setDateTimeProperty(dtstart, event.dtStart()); 
+        prop.dtstart(dtstart);
+    }
 }
 
 


commit b8001543be7cda76067460921d603a8e8ed24f8a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 15 15:32:46 2011 +0100

    conversions in separate file, no more usage of << operator, use of auto_ptr instead for non copyable types

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 1049024..c109067 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,7 +7,7 @@
 #     VERBATIM
 #     )
 
-set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp) 
+set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h) 
 
 set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
new file mode 100644
index 0000000..dcff7b3
--- /dev/null
+++ b/c++/lib/conversions.h
@@ -0,0 +1,203 @@
+#ifndef KOLAB_CONVERSIONS_H
+#define KOLAB_CONVERSIONS_H
+
+#include "kolabformat.h"
+#include <bindings/iCalendar-props.hxx>
+#include <kdebug.h>
+
+namespace Kolab {
+
+typedef std::auto_ptr<KDateTime> DatePtr;
+
+QString toString(const xml_schema::string &s)
+{
+    return QString::fromStdString(s);
+}
+
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+    return toString(s.text());
+}
+
+DatePtr toDate(const  xml_schema::date &dt)
+{
+    DatePtr date(new KDateTime());
+    date->setDateOnly(true);
+    date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+    return date;
+}
+
+DatePtr toDate(const xml_schema::date_time &dt)
+{
+    DatePtr date(new KDateTime());
+//     kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+    date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+    date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+    if (dt.zone_present()) {
+        date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+    }
+//     kDebug() << date->date() << *date << dt.zone_present();
+    return date;
+}
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+    QStringList d;
+    const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+        d.append(QString::fromStdString(*it));
+    }
+    return d;
+}
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+    int i = prop.integer();
+    return i;
+}
+
+DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    DatePtr date;
+    if (dtProperty.date_time()) {
+        date = toDate(*dtProperty.date_time());
+    } else if (dtProperty.date()) {
+        date = toDate(*dtProperty.date());
+        kDebug() << "date";
+    }
+    
+    if (dtProperty.parameters()) {
+        for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+            if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+                QString tzid(toString(tz->text()));
+                if (tzid.contains("/kolab.org/")) {
+                    tzid.remove("/kolab.org/");
+                } else {
+                    kWarning() << "/kolab.org/ timezone prefix is missing";
+                }
+                KTimeZone timezone(tzid);
+                KDateTime::Spec spec(timezone);
+                date->setTimeSpec(spec);
+//                 kDebug() << tzid;
+            }
+//             kDebug() << "---------------_";
+        }
+    }
+    return date;
+}
+
+DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    DatePtr date;
+    if (dtProperty.date_time()) {
+        date = toDate(*dtProperty.date_time());
+    } else { //The utc-date-time element shouldn't even exist
+        date = DatePtr(new KDateTime());
+        kWarning() << "This element shouldn't even be existing";
+        Q_ASSERT(0);
+    }
+    if (date->timeSpec().type() != KDateTime::UTC) {
+        kWarning() << "utc date wrong formatting, corrected to utc";
+        date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+    }
+    return date;
+}
+
+
+void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
+{
+    using namespace icalendar_2_0;
+    switch (rrule.freq()) {
+        case FreqRecurType::YEARLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+            break;
+        case FreqRecurType::MONTHLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+            break;
+        case FreqRecurType::WEEKLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+            break;
+        case FreqRecurType::DAILY:
+            kDebug() << "daily";
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+            break;
+        case FreqRecurType::HOURLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+            break;
+        case FreqRecurType::MINUTELY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+            break;
+        case FreqRecurType::SECONDLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+            break;
+        default:
+            kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+    }
+    if (rrule.until()) {
+        DatePtr date;
+        if ((*rrule.until()).date_time()) {
+            date = toDate(*(*rrule.until()).date_time());
+        } else if ((*rrule.until()).date()) {
+            date = toDate(*(*rrule.until()).date());
+        }
+        d.setEndDt(*date);
+    } else if (rrule.count()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setDuration(*rrule.count());
+    }
+    
+    if (rrule.interval()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setFrequency(*rrule.interval());
+    } else {
+        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+    }
+    {
+        QList<int> bysec;
+        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+            Q_ASSERT(*it <= std::numeric_limits<int>::max());
+            bysec.append(*it);
+        }
+        if (!bysec.isEmpty()) {
+            d.setBySeconds(bysec);
+        }
+    }
+    //TODO implement all the other by*** lists
+    if (rrule.wkst()) {
+        switch (*rrule.wkst()) {
+            case WeekdayRecurType::MO:
+                d.setWeekStart(1);
+                break;
+            case WeekdayRecurType::TU:
+                d.setWeekStart(2);
+                break;
+            case WeekdayRecurType::WE:
+                d.setWeekStart(3);
+                break;
+            case WeekdayRecurType::TH:
+                d.setWeekStart(4);
+                break;
+            case WeekdayRecurType::FR:
+                d.setWeekStart(5);
+                break;
+            case WeekdayRecurType::SA:
+                d.setWeekStart(6);
+                break;
+            case WeekdayRecurType::SU:
+                d.setWeekStart(7);
+                break;
+            default:
+                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+        }
+    }
+}
+
+void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+{
+    toRRule(d, rrule.recur());
+}
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index d466f7a..47305b7 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -9,6 +9,7 @@
 #include <kdebug.h>
 #include <limits>
 #include <kcalcore/recurrencerule.h>
+#include "conversions.h"
 
 namespace Kolab {
     
@@ -18,225 +19,6 @@ namespace Kolab {
 //     return d;
 // }; //conversion operator
     
-Date &operator <<(Date &d, const  xml_schema::date &dt)
-{
-    d.year = dt.year();
-    return d;
-}
-
-// Date &operator =(Date &d, const  xml_schema::date &dt)
-// {
-//     d.year = dt.year();
-//     return d;
-// }
-    
-//Event & operator<<(const MyClass &rhs);
-Date &operator <<(Date &d, const  icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
-    if (dtProperty.date_time()) {
-        const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(dtProperty.date_time());
-        //datetime.day()
-//                 (*(d->date_time()))
-    } else if (dtProperty.date()) {
-        const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(dtProperty.date());
-//                 e.date = date;
-        d.year = date.year();
-//         const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
-// //                 dt.setTimeSpec(spec);
-//         event.setDtStart(dt);
-    }
-    return d;
-}
-
-
-KDateTime &operator <<(KDateTime &d, const  xml_schema::date &dt)
-{
-    d.setDateOnly(true);
-    d.setDate(QDate(dt.year(), dt.month(), dt.day()));
-    return d;
-}
-
-KDateTime &operator <<(KDateTime &d, const  xml_schema::date_time &dt)
-{
-    kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
-    d.setDate(QDate(dt.year(), dt.month(), dt.day()));
-    d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-    if (dt.zone_present()) {
-        d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-    }
-    kDebug() << d.date() << d << dt.zone_present();
-    return d;
-}
-
-QString &operator <<(QString &d, const xml_schema::string &s)
-{
-    d.append(QString::fromStdString(s) );
-    return d;
-}
-
-QStringList &operator <<(QStringList &d, const ::xsd::cxx::tree::sequence< xml_schema::string >&s)
-{
-    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = s.begin(); it != s.end(); it++) {
-        d.append(QString::fromStdString(*it));
-    }
-    return d;
-}
-
-int &operator <<(int &i, const icalendar_2_0::IntegerPropertyType &prop) {
-    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
-    i = prop.integer();
-}
-
-KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
-    if (dtProperty.date_time()) {
-        d << *dtProperty.date_time();
-        kDebug() << "date_time";
-    } else if (dtProperty.date()) {
-        d << *dtProperty.date();
-        kDebug() << "date";
-    }
-    
-    if (dtProperty.parameters()) {
-        for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
-            if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
-                QString tzid;
-                tzid << tz->text();
-                if (tzid.contains("/kolab.org/")) {
-                    tzid.remove("/kolab.org/");
-                } else {
-                    kWarning() << "/kolab.org/ timezone prefix is missing";
-                }
-                KTimeZone timezone(tzid);
-                KDateTime::Spec spec(timezone);
-                d.setTimeSpec(spec);
-//                 kDebug() << tzid;
-            }
-//             kDebug() << "---------------_";
-        }
-    }
-    return d;
-}
-
-KDateTime &operator <<(KDateTime &d, const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
-    if (dtProperty.date_time()) {
-        d << *dtProperty.date_time();
-    } else { //The utc-date-time element shouldn't even exist
-        kWarning() << "This element shouldn't even be existing";
-        Q_ASSERT(0);
-    }
-    if (d.timeSpec().type() != KDateTime::UTC) {
-        kWarning() << "utc date wrong formatting, corrected to utc";
-        d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-    }
-    return d;
-}
-
-QStringList &operator <<(QStringList &d, const icalendar_2_0::TextListPropertyType &s)
-{
-    return d << s.text();
-}
-
-QString &operator <<(QString &d, const icalendar_2_0::TextPropertyType &s)
-{
-    return d << s.text();
-}
-
-
-KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
-{
-    using namespace icalendar_2_0;
-    switch (rrule.freq()) {
-        case FreqRecurType::YEARLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
-            break;
-        case FreqRecurType::MONTHLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
-            break;
-        case FreqRecurType::WEEKLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
-            break;
-        case FreqRecurType::DAILY:
-            kDebug() << "daily";
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
-            break;
-        case FreqRecurType::HOURLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
-            break;
-        case FreqRecurType::MINUTELY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
-            break;
-        case FreqRecurType::SECONDLY:
-            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
-            break;
-        default:
-            kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
-    }
-    if (rrule.until()) {
-        KDateTime date;
-        if ((*rrule.until()).date_time()) {
-            date << *(*rrule.until()).date_time();
-        } else if ((*rrule.until()).date()) {
-            date << *(*rrule.until()).date();
-        }
-        d.setEndDt(date);
-    } else if (rrule.count()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setDuration(*rrule.count());
-    }
-    
-    if (rrule.interval()) {
-        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
-        d.setFrequency(*rrule.interval());
-    } else {
-        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
-    }
-    {
-        QList<int> bysec;
-        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
-            Q_ASSERT(*it <= std::numeric_limits<int>::max());
-            bysec.append(*it);
-        }
-        if (!bysec.isEmpty()) {
-            d.setBySeconds(bysec);
-        }
-    }
-    //TODO implement all the other by*** lists
-    if (rrule.wkst()) {
-        switch (*rrule.wkst()) {
-            case WeekdayRecurType::MO:
-                d.setWeekStart(1);
-                break;
-            case WeekdayRecurType::TU:
-                d.setWeekStart(2);
-                break;
-            case WeekdayRecurType::WE:
-                d.setWeekStart(3);
-                break;
-            case WeekdayRecurType::TH:
-                d.setWeekStart(4);
-                break;
-            case WeekdayRecurType::FR:
-                d.setWeekStart(5);
-                break;
-            case WeekdayRecurType::SA:
-                d.setWeekStart(6);
-                break;
-            case WeekdayRecurType::SU:
-                d.setWeekStart(7);
-                break;
-            default:
-                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
-        }
-    }
-    return d;
-}
-
-KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
-{
-    return d << rrule.recur();
-}
 
 // bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
 // {
@@ -329,37 +111,26 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
 
 void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 {
-
     const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-    {
-        QString string;
-        event.setUid(string << prop.uid());
-    }
-    {
-        KDateTime date;
-        event.setCreated(date << prop.created());
-    }
-    kDebug() << "last mod";
-    {
-        KDateTime date;
-        event.setLastModified(date << prop.dtstamp());
-    }
+
+    event.setUid(toString(prop.uid()));
+    event.setCreated(*toDate(prop.created()));
+    event.setLastModified(*toDate(prop.dtstamp()));
+
     if (prop.sequence()) {
-        int i;
-        event.setRevision(i << *prop.sequence());
+        event.setRevision(toInt(*prop.sequence()));
     }
-    
+
     if (prop.dtstart()) {
-        KDateTime date;
-        kDebug() << "dtstart";
-        event.setDtStart(date << *prop.dtstart());
-        event.setAllDay(date.isDateOnly()); //TODO add to specification that allday depends on start date format
+        const DatePtr date = toDate(*prop.dtstart());
+        event.setDtStart(*date);
+        event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
     }
-    
+
     if (prop.dtend()) {
         KDateTime date;
         kDebug() << "dtend";
-        event.setDtEnd(date << *prop.dtend());
+        event.setDtEnd(*toDate(*prop.dtend()));
         if (event.dtEnd().timeType() != event.dtStart().timeType()) {
             kWarning() << "dtEnd has wrong timespec";
         }
@@ -370,12 +141,10 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
     //TODO check for equality of timespecs
     
     if (prop.categories()) {
-        QStringList list;
-        event.setCategories(list << *prop.categories());
+        event.setCategories(toStringList(*prop.categories()));
     }
     if (prop.class_()) {
-        QString string;
-        string << *prop.class_();
+        QString string(toString(*prop.class_()));
         KCalCore::Incidence::Secrecy sec;
         if (string == "PRIVATE") {
             sec = KCalCore::Incidence::SecrecyPrivate;
@@ -389,30 +158,21 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 
     KCalCore::Recurrence *recurrence = event.recurrence();
     if (prop.rrule()) {
-       KCalCore::RecurrenceRule* rrule = new KCalCore::RecurrenceRule();
-       rrule->setStartDt(recurrence->startDateTime()); //TODO shouldn't this happen as part of addRRule?
-       *rrule << *prop.rrule();
+       KCalCore::RecurrenceRule *rrule = new KCalCore::RecurrenceRule();
+       rrule->setStartDt(recurrence->startDateTime());
+       toRRule(*rrule, *prop.rrule());
        recurrence->addRRule(rrule);
     }
 
     if (prop.summary()) {
-        QString string;
-        string << *prop.summary();
-        event.setSummary(string); //TODO detect richtext and set flag accordingly
+        event.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
     }
-    
+
     if (prop.description()) {
-        QString string;
-        string << *prop.description();
-        event.setDescription(string); //TODO detect richtext and set flag accordingly
+        event.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
     }
 }
 
-std::string &operator <<(std::string &d, const QString &s)
-{
-    return d = s.toStdString();
-}
-
 std::string writeEvent(KCalCore::Event::Ptr event)
 {
     using namespace icalendar_2_0;


commit 48ec06505893ca38e3c19b40c2c2d3deae65d3cd
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 15 14:17:14 2011 +0100

    write event started

diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 02170f0..d466f7a 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -408,6 +408,58 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
     }
 }
 
+std::string &operator <<(std::string &d, const QString &s)
+{
+    return d = s.toStdString();
+}
+
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+    using namespace icalendar_2_0;
+    try {
+        
+        KolabEvent::components_type eventComponents;
+        
+        KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
+        KolabEvent::properties_type::dtstamp_type dtstamp;
+//         dtstamp.date_time(event->lastModified());
+        KolabEvent::properties_type::created_type created;
+        KolabEvent::properties_type eventProps(uid, created, dtstamp);
+        
+        KolabEvent vevent(eventProps, eventComponents);
+        
+        VcalendarType::components_type components;
+        components.vevent().push_back(vevent);
+        
+        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 properties(prodid, version, x_kolab_version);
+        
+        VcalendarType vcalendar(properties, components);
+        
+        IcalendarType icalendar(vcalendar);
+
+        xml_schema::namespace_infomap map;
+        map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+//         map[""].schema = "note.xsd";
+        
+        std::ostringstream ostringstream;
+        icalendar_2_0::icalendar(ostringstream, icalendar, map);
+        return ostringstream.str();
+    } catch  (const xml_schema::exception& e) {
+        return std::string();
+    } 
+}
+
+
+void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event& )
+{
+
+}
+
+
 
 void Test::test()
 {
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index fa940f2..e5e70a0 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -51,6 +51,10 @@ std::string serializeEvent();
 // void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
 void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
 KCalCore::Event::Ptr readEvent(const std::string& s);
+
+void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
+std::string writeEvent(KCalCore::Event::Ptr);
+
 void readICalendar(const std::string &s);
 
 //QString serializeEvent(const KCalCore::Event &note);
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 7cb8685..8f6d8c7 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -10,7 +10,7 @@
            <text>2.0</text>
          </version>
          <x-kolab-version > <!--xmlns="http://kolab.org"-->
-             <version>3.0dev1</version>
+             <text>3.0dev1</text>
          </x-kolab-version>
        </properties>
        <components>
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 519a279..37ba686 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="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+                    <xs:element name="string" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
@@ -89,7 +89,7 @@
                     <xs:sequence>
                         <xs:element name="prodid" type="ProdidPropType"/>
                         <xs:element name="version" type="VersionPropType"/>
-                        <xs:element name="x-kolab-version" type="KolabVersion"/>
+                        <xs:element name="x-kolab-version" type="VersionPropType"/>
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>


commit 17d1202bd30c5e9f8fef29fa38aec6db217f3cb1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 14 17:30:20 2011 +0100

    implemented by* recurrence types

diff --git a/schemas/ical/iCalendar-valtypes.xsd b/schemas/ical/iCalendar-valtypes.xsd
index d194837..b0ae12c 100644
--- a/schemas/ical/iCalendar-valtypes.xsd
+++ b/schemas/ical/iCalendar-valtypes.xsd
@@ -135,20 +135,20 @@
           <xs:element ref="xcal:count" />
         </xs:choice>
       </xs:sequence>
-      <xs:element name="interval" type="xs:string" minOccurs="0"/>
-      <xs:element name="bysecond" type="xs:string" 
+      <xs:element name="interval" type="xs:positiveInteger" minOccurs="0"/>
+      <xs:element name="bysecond" type="xcal:BysecondRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
-      <xs:element name="byminute" type="xs:string"  
+      <xs:element name="byminute" type="xcal:ByminuteRecurType"  
                   minOccurs="0" maxOccurs="unbounded" />
-      <xs:element name="byhour" type="xs:string" 
+      <xs:element name="byhour" type="xcal:ByhourRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
-      <xs:element name="byday" type="xs:string" 
+      <xs:element name="byday" type="xcal:BydayRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
-      <xs:element name="byyearday" type="xs:string" 
+      <xs:element name="byyearday" type="xcal:ByyeardayRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
       <xs:element name="bymonthday" type="xcal:BymonthdayRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
-      <xs:element name="byweekno" type="xs:string" 
+      <xs:element name="byweekno" type="xcal:ByweeknoRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
       <xs:element name="bymonth" type="xcal:BymonthRecurType" 
                   minOccurs="0" maxOccurs="unbounded" />
@@ -194,6 +194,48 @@
 			<xs:enumeration value="SA"/>
 		</xs:restriction>
 	</xs:simpleType>
+    
+  <xs:simpleType name="BysecondRecurType">
+    <xs:restriction base="xs:nonNegativeInteger">
+        <xs:maxInclusive value="60"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:simpleType name="ByminuteRecurType">
+    <xs:restriction base="xs:nonNegativeInteger">
+        <xs:maxInclusive value="59"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:simpleType name="ByhourRecurType">
+    <xs:restriction base="xs:nonNegativeInteger">
+        <xs:maxInclusive value="23"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:simpleType name="BydayRecurType">
+    <xs:restriction base="xs:string">
+        <xs:pattern value="((\-)?N)?(SU|MO|TU|WE|TH|FR|SA)"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+ <!-- <xs:complexType name="BydayRecurType">
+    <xs:complexContent>
+        <xs:sequence>
+            <xs:element
+            <xs:element type="xs:integer"  >
+            <xs:restriction base="xs:positiveInteger">
+            </xs:restriction>
+        </xs:sequence>
+    </xs:complexContent>
+  </xs:complexType>-->
+  
+  <xs:simpleType name="ByyeardayRecurType">
+    <xs:restriction base="xs:integer">
+        <xs:minInclusive value="-366"/>
+        <xs:maxInclusive value="366"/>
+    </xs:restriction>
+  </xs:simpleType>
   
   <xs:simpleType name="BymonthdayRecurType">
     <xs:restriction base="xs:integer">
@@ -202,12 +244,20 @@
     </xs:restriction>
   </xs:simpleType>
   
+  <xs:simpleType name="ByweeknoRecurType">
+    <xs:restriction base="xs:integer">
+        <xs:minInclusive value="-53"/>
+        <xs:maxInclusive value="53"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
   <xs:simpleType name="BymonthRecurType">
     <xs:restriction base="xs:integer">
       <xs:minInclusive value="1"/>
       <xs:maxInclusive value="12"/>
     </xs:restriction>
   </xs:simpleType>
+
   
 	<!-- 3.3.11 TEXT -->
 	<xs:element name="text" type="xs:string"/>


commit b67e051d5628dd03cb57eb09f8f724eb3ec69692
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Dec 14 17:29:55 2011 +0100

    Start of implementation according to new specification

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 313939c..24bea1e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -30,10 +30,10 @@ add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
 file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
 set( XCAL_SCHEMA_SOURCEFILES  
     bindings/xCard.cxx
-    bindings/kolabformat.cxx
+#     bindings/kolabformat.cxx
     bindings/kolabformat-xcal.cxx
     bindings/kolabformat-xcard.cxx
-    bindings/iCalendar.cxx
+#     bindings/iCalendar.cxx
     bindings/iCalendar-params.cxx
     bindings/iCalendar-props.cxx
     bindings/iCalendar-valtypes.cxx
@@ -45,7 +45,7 @@ set( XCAL_SCHEMA_SOURCEFILES
 )
 # --cxx-suffix .cpp --hxx-suffix .h  
 add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
+    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 bindings ${XCAL_SCHEMAS}
     COMMENT "Generating xCal XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS}
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 71d77a4..02170f0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,10 +4,11 @@
 
 #include <kcalcore/event.h>
 #include <iostream>
-#include <bindings/kolabformat.hxx>
+#include <bindings/kolabformat-xcal.hxx>
 //#include "note.h"
 #include <kdebug.h>
-#include "typeinfo"
+#include <limits>
+#include <kcalcore/recurrencerule.h>
 
 namespace Kolab {
     
@@ -50,6 +51,7 @@ Date &operator <<(Date &d, const  icalendar_2_0::DateDatetimePropertyType &dtPro
 
 KDateTime &operator <<(KDateTime &d, const  xml_schema::date &dt)
 {
+    d.setDateOnly(true);
     d.setDate(QDate(dt.year(), dt.month(), dt.day()));
     return d;
 }
@@ -59,17 +61,33 @@ KDateTime &operator <<(KDateTime &d, const  xml_schema::date_time &dt)
     kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
     d.setDate(QDate(dt.year(), dt.month(), dt.day()));
     d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
-    kDebug() << d.date() << d;
+    if (dt.zone_present()) {
+        d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+    }
+    kDebug() << d.date() << d << dt.zone_present();
     return d;
 }
 
-QString &operator <<(QString &d, const  xml_schema::string &s)
+QString &operator <<(QString &d, const xml_schema::string &s)
 {
     d.append(QString::fromStdString(s) );
     return d;
 }
 
-KDateTime &operator <<(KDateTime &d, const  icalendar_2_0::DateDatetimePropertyType &dtProperty)
+QStringList &operator <<(QStringList &d, const ::xsd::cxx::tree::sequence< xml_schema::string >&s)
+{
+    for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = s.begin(); it != s.end(); it++) {
+        d.append(QString::fromStdString(*it));
+    }
+    return d;
+}
+
+int &operator <<(int &i, const icalendar_2_0::IntegerPropertyType &prop) {
+    Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+    i = prop.integer();
+}
+
+KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
 {
     if (dtProperty.date_time()) {
         d << *dtProperty.date_time();
@@ -78,13 +96,17 @@ KDateTime &operator <<(KDateTime &d, const  icalendar_2_0::DateDatetimePropertyT
         d << *dtProperty.date();
         kDebug() << "date";
     }
+    
     if (dtProperty.parameters()) {
-        
-        
         for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
             if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
                 QString tzid;
                 tzid << tz->text();
+                if (tzid.contains("/kolab.org/")) {
+                    tzid.remove("/kolab.org/");
+                } else {
+                    kWarning() << "/kolab.org/ timezone prefix is missing";
+                }
                 KTimeZone timezone(tzid);
                 KDateTime::Spec spec(timezone);
                 d.setTimeSpec(spec);
@@ -96,6 +118,135 @@ KDateTime &operator <<(KDateTime &d, const  icalendar_2_0::DateDatetimePropertyT
     return d;
 }
 
+KDateTime &operator <<(KDateTime &d, const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    if (dtProperty.date_time()) {
+        d << *dtProperty.date_time();
+    } else { //The utc-date-time element shouldn't even exist
+        kWarning() << "This element shouldn't even be existing";
+        Q_ASSERT(0);
+    }
+    if (d.timeSpec().type() != KDateTime::UTC) {
+        kWarning() << "utc date wrong formatting, corrected to utc";
+        d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+    }
+    return d;
+}
+
+QStringList &operator <<(QStringList &d, const icalendar_2_0::TextListPropertyType &s)
+{
+    return d << s.text();
+}
+
+QString &operator <<(QString &d, const icalendar_2_0::TextPropertyType &s)
+{
+    return d << s.text();
+}
+
+
+KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
+{
+    using namespace icalendar_2_0;
+    switch (rrule.freq()) {
+        case FreqRecurType::YEARLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+            break;
+        case FreqRecurType::MONTHLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+            break;
+        case FreqRecurType::WEEKLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+            break;
+        case FreqRecurType::DAILY:
+            kDebug() << "daily";
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+            break;
+        case FreqRecurType::HOURLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+            break;
+        case FreqRecurType::MINUTELY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+            break;
+        case FreqRecurType::SECONDLY:
+            d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+            break;
+        default:
+            kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+    }
+    if (rrule.until()) {
+        KDateTime date;
+        if ((*rrule.until()).date_time()) {
+            date << *(*rrule.until()).date_time();
+        } else if ((*rrule.until()).date()) {
+            date << *(*rrule.until()).date();
+        }
+        d.setEndDt(date);
+    } else if (rrule.count()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setDuration(*rrule.count());
+    }
+    
+    if (rrule.interval()) {
+        Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+        d.setFrequency(*rrule.interval());
+    } else {
+        d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+    }
+    {
+        QList<int> bysec;
+        for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+            Q_ASSERT(*it <= std::numeric_limits<int>::max());
+            bysec.append(*it);
+        }
+        if (!bysec.isEmpty()) {
+            d.setBySeconds(bysec);
+        }
+    }
+    //TODO implement all the other by*** lists
+    if (rrule.wkst()) {
+        switch (*rrule.wkst()) {
+            case WeekdayRecurType::MO:
+                d.setWeekStart(1);
+                break;
+            case WeekdayRecurType::TU:
+                d.setWeekStart(2);
+                break;
+            case WeekdayRecurType::WE:
+                d.setWeekStart(3);
+                break;
+            case WeekdayRecurType::TH:
+                d.setWeekStart(4);
+                break;
+            case WeekdayRecurType::FR:
+                d.setWeekStart(5);
+                break;
+            case WeekdayRecurType::SA:
+                d.setWeekStart(6);
+                break;
+            case WeekdayRecurType::SU:
+                d.setWeekStart(7);
+                break;
+            default:
+                kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+        }
+    }
+    return d;
+}
+
+KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+{
+    return d << rrule.recur();
+}
+
+// bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+// {
+//     if (dtProperty.date_time() || dtProperty.date()) {
+//         return true;
+//     }
+//     return false;
+// }
+
+
 std::string serializeEvent()
 {
     std::cout << "ksjdsldfj";
@@ -104,134 +255,157 @@ std::string serializeEvent()
 
 void readICalendar(const std::string &s)
 {
-    try {
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s, xml_schema::flags::dont_validate));
-        if (icalendar->vcalendar().size() != 1) {
-            std::cout << "invalid amount vcalendars" << std::endl;
-        }
-        const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
-        
-        
-        //TODO extract timezone information first, so we can pass that information to the rest
-        for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
-            if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&(*it))) {
-                KCalCore::Event event;
-                readEvent(event, *d);
-            }
-        }
-    } catch  (const xml_schema::exception& e) {
-        
-        std::cout <<"exceotuib" <<  e << std::endl;
-    }/* catch  (const xsd::cxx::tree::parsing_char<char> & e) {
-        std::cout << e << std::endl;
-    } */
+
 }
 
 
 void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
 {
-    try {
-        if (!vevent.properties())
-            return;
-        const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
-        const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
-        for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
-            if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
-                std::cout << "Start" << std::endl;
-                if (d->date_time()) {
-                    const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
-                    //datetime.day()
-    //                 (*(d->date_time()))
-                } else if (d->date()) {
-                    const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
-                    event.date << date;
-                }
-
-            } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
-                std::cout << "Rrule" << std::endl;
-                std::cout << d->recur().freq() << std::endl;
-                std::cout << d->recur().count() << std::endl;
-                //std::cout << d->recur().byhour() << std::endl;
-            } else {
-                std::cout << "other" << std::endl;
-                const icalendar_2_0::BasePropertyType &baseProperty = *it;
-            }
-        }
-    } catch  (const xml_schema::exception& e) {
-        std::cout <<  e << std::endl;
-    }
+//     try {
+//         if (!vevent.properties())
+//             return;
+//         const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+//         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+// 
+//         for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+//             if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+//                 std::cout << "Start" << std::endl;
+//                 if (d->date_time()) {
+//                     const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+//                     //datetime.day()
+//     //                 (*(d->date_time()))
+//                 } else if (d->date()) {
+//                     const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+//                     event.date << date;
+//                 }
+// 
+//             } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+//                 std::cout << "Rrule" << std::endl;
+//                 std::cout << d->recur().freq() << std::endl;
+//                 std::cout << d->recur().count() << std::endl;
+//                 //std::cout << d->recur().byhour() << std::endl;
+//             } else {
+//                 std::cout << "other" << std::endl;
+//                 const icalendar_2_0::BasePropertyType &baseProperty = *it;
+//             }
+//         }
+//     } catch  (const xml_schema::exception& e) {
+//         std::cout <<  e << std::endl;
+//     }
 }
 
-KCalCore::Event *readEvent(const std::string& s)
+KCalCore::Event::Ptr readEvent(const std::string& s)
 {
     try {
         //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
         xml_schema::properties props;
-        props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabformat.xsd"); //Force schema
+        props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
         
         std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
-        if (icalendar->vcalendar().size() != 1) {
-            std::cout << "invalid amount vcalendars" << std::endl;
-        }
-        const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
+        const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
         
-        QList <KCalCore::Event*> events;
-        QMap <QString, KTimeZone*> timezones;
-
-        for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
-            if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&*it)) {
-                KCalCore::Event *e = new KCalCore::Event();
-                readEvent(*e, *d);
-                events.append(e);
-            } else if (const icalendar_2_0::VtimezoneType* d = dynamic_cast<const icalendar_2_0::VtimezoneType*> (&*it)) {
-                KTimeZone *tz = new KTimeZone();
-                //readTimezone(event, *d);
-                timezones.insert(tz->name(), tz);
-            } else {
-                kDebug() << "unknown component" << typeid(*it).name();
-            }
+        QList <KCalCore::Event::Ptr> events;
+        
+        
+        for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
+            KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
+            const icalendar_2_0::KolabEvent &event = *it;
+            readEvent(*e, event);
+            events.append(e);
         }
-        //Match timezones by name and apply correctly
+
         //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
-        foreach (KCalCore::Event * event, events) {
-            if (!event->hasRecurrenceId()) {
-                return event;
-            }
-        }
+//         foreach (KCalCore::Event * event, events) {
+//             if (!event->hasRecurrenceId()) {
+//                 return event;
+//             }
+//         }
+        return events.first();
     } catch  (const xml_schema::exception& e) {
         std::cout <<  e << std::endl;
     }
-    return 0;
+    return KCalCore::Event::Ptr();
 }
 
-void readEvent(KCalCore::Event &event ,const icalendar_2_0::VeventType &vevent)
+void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
 {
-    if (!vevent.properties())
-        return;
-    const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
-    const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
-    for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
-        if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&*it)) {
-            KDateTime date;
-            event.setDtStart(date << *d);
-//             kDebug() << "dtstart" << date;
-        } if (const icalendar_2_0::DtendPropType* d = dynamic_cast<const icalendar_2_0::DtendPropType*> (&*it)) {
-            KDateTime date;
-            event.setDtEnd(date << *d);
-//             kDebug() << "dtstart" << date;
-        } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
-            std::cout << "Rrule" << std::endl;
-            std::cout << d->recur().freq() << std::endl;
-            std::cout << d->recur().count() << std::endl;
-            //std::cout << d->recur().byhour() << std::endl;
+
+    const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+    {
+        QString string;
+        event.setUid(string << prop.uid());
+    }
+    {
+        KDateTime date;
+        event.setCreated(date << prop.created());
+    }
+    kDebug() << "last mod";
+    {
+        KDateTime date;
+        event.setLastModified(date << prop.dtstamp());
+    }
+    if (prop.sequence()) {
+        int i;
+        event.setRevision(i << *prop.sequence());
+    }
+    
+    if (prop.dtstart()) {
+        KDateTime date;
+        kDebug() << "dtstart";
+        event.setDtStart(date << *prop.dtstart());
+        event.setAllDay(date.isDateOnly()); //TODO add to specification that allday depends on start date format
+    }
+    
+    if (prop.dtend()) {
+        KDateTime date;
+        kDebug() << "dtend";
+        event.setDtEnd(date << *prop.dtend());
+        if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+            kWarning() << "dtEnd has wrong timespec";
+        }
+    } else if (prop.duration()) {
+//          KCalCore::Duration duration.;
+//          event.setDuration(duration << prop.duration());
+    }
+    //TODO check for equality of timespecs
+    
+    if (prop.categories()) {
+        QStringList list;
+        event.setCategories(list << *prop.categories());
+    }
+    if (prop.class_()) {
+        QString string;
+        string << *prop.class_();
+        KCalCore::Incidence::Secrecy sec;
+        if (string == "PRIVATE") {
+            sec = KCalCore::Incidence::SecrecyPrivate;
+        } else if (string == "CONFIDENTIAL") {
+            sec = KCalCore::Incidence::SecrecyConfidential;
         } else {
-            std::cout << "other" << std::endl;
-            const icalendar_2_0::BasePropertyType &baseProperty = *it;
+            sec = KCalCore::Incidence::SecrecyPublic;
         }
+        event.setSecrecy(sec);
+    }
+
+    KCalCore::Recurrence *recurrence = event.recurrence();
+    if (prop.rrule()) {
+       KCalCore::RecurrenceRule* rrule = new KCalCore::RecurrenceRule();
+       rrule->setStartDt(recurrence->startDateTime()); //TODO shouldn't this happen as part of addRRule?
+       *rrule << *prop.rrule();
+       recurrence->addRRule(rrule);
+    }
+
+    if (prop.summary()) {
+        QString string;
+        string << *prop.summary();
+        event.setSummary(string); //TODO detect richtext and set flag accordingly
+    }
+    
+    if (prop.description()) {
+        QString string;
+        string << *prop.description();
+        event.setDescription(string); //TODO detect richtext and set flag accordingly
     }
-//     const icalendar_2_0::
 }
 
 
@@ -241,22 +415,6 @@ void Test::test()
 }
 
 
-// QString Kolab::serializeEvent(const KCalCore::Event& event)
-// {
-//     return event.summary();
-// }
-
-/*
-Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
-{
-
-}
-*/
-
-// void Kolab::readEvent(const QString &string, KCalCore::Event &event)
-// {
-//     event.setSummary(string);
-// }
 
 }
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 24829f7..fa940f2 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -4,6 +4,7 @@
 //#include <QString>
 #include <string>
 #include <xsd/cxx/tree/date-time.hxx>
+#include <KDE/KCalCore/Event>
 
 namespace KCalCore {
     class Event;
@@ -11,6 +12,7 @@ namespace KCalCore {
 
 namespace icalendar_2_0 {
     class VeventType;
+    class KolabEvent;
 }
 
 namespace Kolab {
@@ -45,10 +47,10 @@ struct Event {
 
 
 std::string serializeEvent();
-void readEvent(const icalendar_2_0::VeventType &vevent);
-void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
-void readEvent(KCalCore::Event &,const icalendar_2_0::VeventType &vevent);
-KCalCore::Event *readEvent(const std::string& s);
+// void readEvent(const icalendar_2_0::VeventType &vevent);
+// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
+void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
+KCalCore::Event::Ptr readEvent(const std::string& s);
 void readICalendar(const std::string &s);
 
 //QString serializeEvent(const KCalCore::Event &note);
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 01602ad..7701cf9 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -335,13 +335,49 @@ void BindingsTest::readContact()
 void BindingsTest::readEvent()
 {
     
-    KCalCore::Event *event = Kolab::readEvent("testfiles/icalEvent.xml");
+    KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
     QVERIFY(event);
-    kDebug() << event->dtStart().date() << event->dtStart().time();
-    QCOMPARE(event->dtStart().date(), QDate(2006, 1, 2));
-    QCOMPARE(event->dtStart().time(), QTime(12, 0, 0));
-    QCOMPARE(event->dtStart().timeZone().name(), QString::fromLatin1("US/Eastern"));
-    delete event;
+    
+    //Check basics
+    QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
+    QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
+    QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+    QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
+
+    //Check recurrence
+    //TODO do some "heavy" testing for recurrences, including possible edge cases.
+
+    //Check recurrence rule
+    foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
+        QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
+    }
+    QCOMPARE(event->recurrence()->rRules().size(), 1);
+    KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
+    QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
+    QCOMPARE(rule->duration(), 5);
+    KDateTime start(event->dtStart());
+    KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
+    QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
+    QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
+    const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
+    foreach (const KDateTime &d, ruleList) {
+        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+//         kDebug() << d << d.timeZone().name();
+    }
+    QCOMPARE(ruleList.first(), event->dtStart());
+    QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+    //Check complete recurrence
+    const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);  
+    foreach (const KDateTime &d, list) {
+        QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+//         kDebug() << d << d.timeZone().name();
+    }
+    
+    QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
+    kDebug() << event->summary();
+//     QCOMPARE(event->summary(), QString::fromUtf8("Test.&#x0a;Test.Test.")); //FIXME fix control character &#x0a; (linefeed)
+    kDebug() << event->description();
 }
 
 
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index ee2931e..7cb8685 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -9,76 +9,25 @@
          <version>
            <text>2.0</text>
          </version>
-         <x-kolab-version xmlns="http://kolab.org">
+         <x-kolab-version > <!--xmlns="http://kolab.org"-->
              <version>3.0dev1</version>
          </x-kolab-version>
        </properties>
        <components>
-         <vtimezone>
-           <!--This doesn't work right now because the tzid is commented in the schema (nameconflict with tzid component)-->
-           <!--<properties>
-             <last-modified>
-               <date-time>2004-01-10T03:28:45Z</date-time>
-             </last-modified>
-             <tzid>US/Eastern</tzid>
-           </properties>-->
-           <components>
-             <daylight>
-               <properties>
-                 <dtstart>
-                   <date-time>2000-04-04T02:00:00</date-time>
-                 </dtstart>
-                 <rrule>
-                   <recur>
-                     <freq>YEARLY</freq>
-                     <byday>1SU</byday>
-                     <bymonth>4</bymonth>
-                   </recur>
-                 </rrule>
-                 <tzname>
-                   <text>EDT</text>
-                 </tzname>
-                 <tzoffsetfrom>
-                   <utc-offset>-05:00</utc-offset>
-                 </tzoffsetfrom>
-                 <tzoffsetto>
-                   <utc-offset>-04:00</utc-offset>
-                 </tzoffsetto>
-               </properties>
-             </daylight>
-             <standard>
-               <properties>
-                 <dtstart>
-                   <date-time>2000-10-26T02:00:00</date-time>
-                 </dtstart>
-                 <rrule>
-                   <recur>
-                     <freq>YEARLY</freq>
-                     <byday>-1SU</byday>
-                     <bymonth>10</bymonth>
-                   </recur>
-                 </rrule>
-                 <tzname>
-                   <text>EST</text>
-                 </tzname>
-                 <tzoffsetfrom>
-                   <utc-offset>-04:00</utc-offset>
-                 </tzoffsetfrom>
-                 <tzoffsetto>
-                   <utc-offset>-05:00</utc-offset>
-                 </tzoffsetto>
-               </properties>
-             </standard>
-           </components>
-         </vtimezone>
          <vevent>
            <properties>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+             <created>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </created>
              <dtstamp>
                <date-time>2006-02-06T00:11:21Z</date-time>
              </dtstamp>
              <dtstart>
                <parameters>
-                 <tzid><text>US/Eastern</text></tzid>
+                 <tzid><text>/kolab.org/US/Eastern</text></tzid>
                </parameters>
                <date-time>2006-01-02T12:00:00</date-time>
              </dtstart>
@@ -91,7 +40,7 @@
                  <count>5</count>
                </recur>
              </rrule>
-             <rdate>
+<!--             <rdate>
                <parameters>
                  <tzid><text>US/Eastern</text></tzid>
                </parameters>
@@ -99,23 +48,19 @@
                  <start>2006-01-02T15:00:00</start>
                  <duration>PT2H</duration>
                </period>
-             </rdate>
+             </rdate>-->
              <summary>
                <text>Event #2</text>
              </summary>
              <description>
-               <text>We are having a meeting all this week at 12
-   pm for one hour, with an additional meeting on the first day
-   2 hours long.&#x0a;Please bring your own lunch for the 12 pm
-   meetings.</text>
+               <text>Test.&#x0a;Test.
+Test.</text>
              </description>
-             <uid>
-               <text>00959BC664CA650E933C892C at example.com</text>
-             </uid>
+
            </properties>
            <components/>
          </vevent>
-         <vevent>
+<!--         <vevent>
            <properties>
              <dtstamp>
                <date-time>2006-02-06T00:11:21Z</date-time>
@@ -138,12 +83,10 @@
              <summary>
                <text>Event #2 bis</text>
              </summary>
-             <uid>
-               <text>00959BC664CA650E933C892C at example.com</text>
-             </uid>
+
            </properties>
            <components/>
-         </vevent>
+         </vevent>-->
        </components>
      </vcalendar>
 </icalendar>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 1d91f90..519a279 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -4,7 +4,7 @@
     xmlns="urn:ietf:params:xml:ns:icalendar-2.0"
     elementFormDefault="qualified">
 
-    <xs:include schemaLocation="iCalendar.xsd" />
+    <xs:include schemaLocation="iCalendar-props.xsd" />
 
     <xs:complexType name="KolabVersion" >
         <xs:complexContent mixed="false">
@@ -16,7 +16,7 @@
         </xs:complexContent>
     </xs:complexType>
 
-    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
+<!--    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
 
     <xs:complexType name="CustomType" >
         <xs:complexContent mixed="false">
@@ -29,25 +29,89 @@
         </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:element name="vevent" type="xcal:KolabEventType" substitutionGroup="xcal:vcalendarContainedComponent"/>
-    <xs:complexType name="KolabEventType" mixed="false">
-        <xs:complexContent>
-            <xs:element name="components" />
-            
-            
+    <xs:complexType name="KolabEvent" >
+        <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="dtstart" type="DtstartPropType" minOccurs="0"/>
+                        <xs:element name="dtend" type="DtendPropType" minOccurs="0"/>
+                        <xs:element name="duration" type="DurationPropType" minOccurs="0"/>
+                        <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+                        <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
+                        <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+                    </xs:sequence>
+                </xs:complexType>
             </xs:element>
-            <xs:extension base="xcal:VcalendarContainedComponentType">
-            <xs:sequence>
-<!--                 <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
-                <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
-            </xs:sequence>
-        </xs:extension>
-        </xs:complexContent>
+            <xs:element name="components">
+                <xs:complexType>
+                <!--TODO valarm-->
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
     </xs:complexType>
 
+    <xs:complexType name="KolabTodo" >
+        <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="dtstart" type="DtstartPropType" minOccurs="0"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="components">
+                <xs:complexType>
+                <!--TODO valarm-->
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType> 
+
+    <xs:complexType name="VcalendarType" mixed="false">
+        <xs:sequence>
+            <xs:element name="properties">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="prodid" type="ProdidPropType"/>
+                        <xs:element name="version" type="VersionPropType"/>
+                        <xs:element name="x-kolab-version" type="KolabVersion"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="components">
+                 <xs:complexType>
+                    <xs:choice>
+                        <xs:element name="vevent" type="KolabEvent" maxOccurs="unbounded"/>
+                        <xs:element name="vtodo" type="KolabTodo" maxOccurs="unbounded"/>
+                    </xs:choice>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="IcalendarType">
+        <xs:sequence>
+            <xs:element name="vcalendar" type="VcalendarType"/>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:element name="icalendar" type="IcalendarType"/>
+    
+    
     
 </xs:schema>
\ No newline at end of file


commit 2eb5d601daaa30ce7b1193a2fb3c49a0a1ff424b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 12 17:59:19 2011 +0100

    iCalendar-props fix

diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
index c4dfc92..c31f344 100644
--- a/schemas/ical/iCalendar-props.xsd
+++ b/schemas/ical/iCalendar-props.xsd
@@ -280,7 +280,10 @@
     <xs:complexContent mixed="false">
       <xs:extension base="xcal:BasePropertyType">
         <xs:sequence>
-          <xs:element ref="xcal:utc-date-time"/>
+            <xs:choice>
+                <xs:element ref="xcal:utc-date-time"/>
+                <xs:element ref="xcal:date-time"/>
+            </xs:choice>
         </xs:sequence>
       </xs:extension>
     </xs:complexContent>
@@ -662,7 +665,15 @@
   <!-- 3.8.5.2 Recurrence Date/Times -->
   <xs:complexType name="RdatePropType">
     <xs:complexContent mixed="false">
-      <xs:extension base="xcal:DateDatetimePropertyType"/>
+        <xs:extension base="xcal:BasePropertyType">
+            <xs:sequence>
+                <xs:choice>
+                    <xs:element ref="xcal:date"/>
+                    <xs:element ref="xcal:date-time"/>
+                    <xs:element ref="xcal:period"/>
+                </xs:choice>
+            </xs:sequence>
+        </xs:extension>
     </xs:complexContent>
   </xs:complexType>
     


commit b8090c03ef8023865fb4c1041e3f3f88f85403b6
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Dec 12 17:59:09 2011 +0100

    temp

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index edfbcb7..313939c 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -31,6 +31,8 @@ file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
 set( XCAL_SCHEMA_SOURCEFILES  
     bindings/xCard.cxx
     bindings/kolabformat.cxx
+    bindings/kolabformat-xcal.cxx
+    bindings/kolabformat-xcard.cxx
     bindings/iCalendar.cxx
     bindings/iCalendar-params.cxx
     bindings/iCalendar-props.cxx
@@ -43,7 +45,7 @@ set( XCAL_SCHEMA_SOURCEFILES
 )
 # --cxx-suffix .cpp --hxx-suffix .h  
 add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --output-dir bindings ${XCAL_SCHEMAS}
+    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
     COMMENT "Generating xCal XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS}
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index e020abf..71d77a4 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -6,6 +6,8 @@
 #include <iostream>
 #include <bindings/kolabformat.hxx>
 //#include "note.h"
+#include <kdebug.h>
+#include "typeinfo"
 
 namespace Kolab {
     
@@ -44,48 +46,181 @@ Date &operator <<(Date &d, const  icalendar_2_0::DateDatetimePropertyType &dtPro
     }
     return d;
 }
-/*
-QString Kolab::serializeNote(const Kolab::Note& note)
+
+
+KDateTime &operator <<(KDateTime &d, const  xml_schema::date &dt)
 {
+    d.setDate(QDate(dt.year(), dt.month(), dt.day()));
+    return d;
+}
 
+KDateTime &operator <<(KDateTime &d, const  xml_schema::date_time &dt)
+{
+    kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+    d.setDate(QDate(dt.year(), dt.month(), dt.day()));
+    d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+    kDebug() << d.date() << d;
+    return d;
 }
-*/
+
+QString &operator <<(QString &d, const  xml_schema::string &s)
+{
+    d.append(QString::fromStdString(s) );
+    return d;
+}
+
+KDateTime &operator <<(KDateTime &d, const  icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    if (dtProperty.date_time()) {
+        d << *dtProperty.date_time();
+        kDebug() << "date_time";
+    } else if (dtProperty.date()) {
+        d << *dtProperty.date();
+        kDebug() << "date";
+    }
+    if (dtProperty.parameters()) {
+        
+        
+        for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+            if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+                QString tzid;
+                tzid << tz->text();
+                KTimeZone timezone(tzid);
+                KDateTime::Spec spec(timezone);
+                d.setTimeSpec(spec);
+//                 kDebug() << tzid;
+            }
+//             kDebug() << "---------------_";
+        }
+    }
+    return d;
+}
+
 std::string serializeEvent()
 {
     std::cout << "ksjdsldfj";
     return "bla";
 }
 
-void readEvent(const std::string &s)
+void readICalendar(const std::string &s)
 {
-    std::auto_ptr<icalendar_2_0::VeventType> vevent(icalendar_2_0::vevent(s, xml_schema::flags::dont_validate));
+    try {
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s, xml_schema::flags::dont_validate));
+        if (icalendar->vcalendar().size() != 1) {
+            std::cout << "invalid amount vcalendars" << std::endl;
+        }
+        const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
         
-    const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent->properties();
-    const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-    
-    KCalCore::Event event;
-    
-    Kolab::Event e;
-    
-    for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
-        if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
-            std::cout << "Start" << std::endl;
-            
-//             KDateTime::TimeZone tz;
-//             KDateTime::Spec spec;
-            if (d->date_time()) {
-                const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
-                //datetime.day()
-//                 (*(d->date_time()))
-            } else if (d->date()) {
-                const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
-//                 e.date = date;
-                e.date << date;
-                const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
-//                 dt.setTimeSpec(spec);
-                event.setDtStart(dt);
+        
+        //TODO extract timezone information first, so we can pass that information to the rest
+        for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
+            if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&(*it))) {
+                KCalCore::Event event;
+                readEvent(event, *d);
+            }
+        }
+    } catch  (const xml_schema::exception& e) {
+        
+        std::cout <<"exceotuib" <<  e << std::endl;
+    }/* catch  (const xsd::cxx::tree::parsing_char<char> & e) {
+        std::cout << e << std::endl;
+    } */
+}
+
+
+void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
+{
+    try {
+        if (!vevent.properties())
+            return;
+        const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+        const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+
+        for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+            if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+                std::cout << "Start" << std::endl;
+                if (d->date_time()) {
+                    const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+                    //datetime.day()
+    //                 (*(d->date_time()))
+                } else if (d->date()) {
+                    const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+                    event.date << date;
+                }
+
+            } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+                std::cout << "Rrule" << std::endl;
+                std::cout << d->recur().freq() << std::endl;
+                std::cout << d->recur().count() << std::endl;
+                //std::cout << d->recur().byhour() << std::endl;
+            } else {
+                std::cout << "other" << std::endl;
+                const icalendar_2_0::BasePropertyType &baseProperty = *it;
             }
+        }
+    } catch  (const xml_schema::exception& e) {
+        std::cout <<  e << std::endl;
+    }
+}
 
+KCalCore::Event *readEvent(const std::string& s)
+{
+    try {
+        //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
+        xml_schema::properties props;
+        props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabformat.xsd"); //Force schema
+        
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
+        if (icalendar->vcalendar().size() != 1) {
+            std::cout << "invalid amount vcalendars" << std::endl;
+        }
+        const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
+        
+        QList <KCalCore::Event*> events;
+        QMap <QString, KTimeZone*> timezones;
+
+        for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
+            if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&*it)) {
+                KCalCore::Event *e = new KCalCore::Event();
+                readEvent(*e, *d);
+                events.append(e);
+            } else if (const icalendar_2_0::VtimezoneType* d = dynamic_cast<const icalendar_2_0::VtimezoneType*> (&*it)) {
+                KTimeZone *tz = new KTimeZone();
+                //readTimezone(event, *d);
+                timezones.insert(tz->name(), tz);
+            } else {
+                kDebug() << "unknown component" << typeid(*it).name();
+            }
+        }
+        //Match timezones by name and apply correctly
+        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+        foreach (KCalCore::Event * event, events) {
+            if (!event->hasRecurrenceId()) {
+                return event;
+            }
+        }
+    } catch  (const xml_schema::exception& e) {
+        std::cout <<  e << std::endl;
+    }
+    return 0;
+}
+
+void readEvent(KCalCore::Event &event ,const icalendar_2_0::VeventType &vevent)
+{
+    if (!vevent.properties())
+        return;
+    const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+    const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+
+    for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+        if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&*it)) {
+            KDateTime date;
+            event.setDtStart(date << *d);
+//             kDebug() << "dtstart" << date;
+        } if (const icalendar_2_0::DtendPropType* d = dynamic_cast<const icalendar_2_0::DtendPropType*> (&*it)) {
+            KDateTime date;
+            event.setDtEnd(date << *d);
+//             kDebug() << "dtstart" << date;
         } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
             std::cout << "Rrule" << std::endl;
             std::cout << d->recur().freq() << std::endl;
@@ -93,7 +228,7 @@ void readEvent(const std::string &s)
             //std::cout << d->recur().byhour() << std::endl;
         } else {
             std::cout << "other" << std::endl;
-            const icalendar_2_0::BasePropertyType &baseProperty = (*it);
+            const icalendar_2_0::BasePropertyType &baseProperty = *it;
         }
     }
 //     const icalendar_2_0::
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 350d38a..24829f7 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -9,6 +9,10 @@ namespace KCalCore {
     class Event;
 }
 
+namespace icalendar_2_0 {
+    class VeventType;
+}
+
 namespace Kolab {
 
 //class Note;
@@ -41,7 +45,11 @@ struct Event {
 
 
 std::string serializeEvent();
-void readEvent(const std::string&);
+void readEvent(const icalendar_2_0::VeventType &vevent);
+void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
+void readEvent(KCalCore::Event &,const icalendar_2_0::VeventType &vevent);
+KCalCore::Event *readEvent(const std::string& s);
+void readICalendar(const std::string &s);
 
 //QString serializeEvent(const KCalCore::Event &note);
 //void readEvent(const QString &string, KCalCore::Event &);
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 0794b7e..ce02581 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -9,4 +9,4 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 #QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
 QT4_AUTOMOC(bindingstest.cpp)
 add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
-target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c)
+target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 5c1157a..01602ad 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -14,6 +14,9 @@
 #include <xercesc/dom/DOMException.hpp>
 #include <xercesc/dom/DOMImplementation.hpp>
 #include <bindings/contact.hxx>
+#include <kcalcore/event.h>
+#include <lib/kolabformat.h>
+#include <kdebug.h>
 
 
 void BindingsTest::writeNoteTest()
@@ -293,28 +296,28 @@ void BindingsTest::xercesException()
 void BindingsTest::writeContact()
 {
     try {
-        KolabXSD::Contact::vcard_type vcard;
-        
-        vcard_4_0::fnPropType fn("Fritz Muster");
-        vcard.baseProperty().push_back(fn);
-        
-        vcard_4_0::nPropType n;
-        n.given().push_back("john");
-        n.surname().push_back("doe");
-        vcard.baseProperty().push_back(n);
-        
-        vcard_4_0::bdayPropType bday;
-        vcard_4_0::bdayPropType::date_type date(1988,12,12);
-        bday.date(date);
-        vcard.baseProperty().push_back(bday);
-        
-        KolabXSD::Contact contact(vcard);
-        xml_schema::namespace_infomap map;
-        map["kolab"].name = "http://kolab.org";
-        map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
-        //map["xcal"].schema = "iCalendar.xsd";
-
-        KolabXSD::contact (std::cout, contact, map);
+//         KolabXSD::Contact::vcard_type vcard;
+//         
+//         vcard_4_0::fnPropType fn("Fritz Muster");
+//         vcard.baseProperty().push_back(fn);
+//         
+//         vcard_4_0::nPropType n;
+//         n.given().push_back("john");
+//         n.surname().push_back("doe");
+//         vcard.baseProperty().push_back(n);
+//         
+//         vcard_4_0::bdayPropType bday;
+//         vcard_4_0::bdayPropType::date_type date(1988,12,12);
+//         bday.date(date);
+//         vcard.baseProperty().push_back(bday);
+//         
+//         KolabXSD::Contact contact(vcard);
+//         xml_schema::namespace_infomap map;
+//         map["kolab"].name = "http://kolab.org";
+//         map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+//         //map["xcal"].schema = "iCalendar.xsd";
+// 
+//         KolabXSD::contact (std::cout, contact, map);
        
     
     } catch  (const xml_schema::exception& e) {
@@ -329,6 +332,20 @@ void BindingsTest::readContact()
 }
 
 
+void BindingsTest::readEvent()
+{
+    
+    KCalCore::Event *event = Kolab::readEvent("testfiles/icalEvent.xml");
+    QVERIFY(event);
+    kDebug() << event->dtStart().date() << event->dtStart().time();
+    QCOMPARE(event->dtStart().date(), QDate(2006, 1, 2));
+    QCOMPARE(event->dtStart().time(), QTime(12, 0, 0));
+    QCOMPARE(event->dtStart().timeZone().name(), QString::fromLatin1("US/Eastern"));
+    delete event;
+}
+
+
+
 
 QTEST_MAIN( BindingsTest )
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index fd93cac..4afef3e 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -21,6 +21,10 @@ class BindingsTest : public QObject
     
     void writeContact();
     void readContact();
+    
+    
+    //Kolabformat
+    void readEvent();
 };
 
 #endif
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
new file mode 100644
index 0000000..1d91f90
--- /dev/null
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0"
+    xmlns="urn:ietf:params:xml:ns:icalendar-2.0"
+    elementFormDefault="qualified">
+
+    <xs:include schemaLocation="iCalendar.xsd" />
+
+    <xs:complexType name="KolabVersion" >
+        <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:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
+
+    <xs:complexType name="CustomType" >
+        <xs:complexContent mixed="false">
+            <xs:extension base="BasePropertyType">
+                <xs:sequence>
+                    <xs:element name="identifier" type="xs:string"/>
+                    <xs:element name="value" type="xs:string"/>
+                </xs:sequence>
+           </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
+
+    
+    
+    <xs:element name="vevent" type="xcal:KolabEventType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+    <xs:complexType name="KolabEventType" mixed="false">
+        <xs:complexContent>
+            <xs:element name="components" />
+            
+            
+            </xs:element>
+            <xs:extension base="xcal:VcalendarContainedComponentType">
+            <xs:sequence>
+<!--                 <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
+                <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
+            </xs:sequence>
+        </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcard.xsd b/schemas/ical/kolabformat-xcard.xsd
new file mode 100644
index 0000000..e0abc67
--- /dev/null
+++ b/schemas/ical/kolabformat-xcard.xsd
@@ -0,0 +1,35 @@
+<?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">
+
+    <xs:include schemaLocation="xCard.xsd" />
+
+    <xs:complexType name="KolabVersion" >
+        <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:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" /> 
+    
+    <xs:complexType name="CustomType" >
+        <xs:complexContent mixed="false">
+            <xs:extension base="BasePropertyType">
+                <xs:sequence>
+                    <xs:element name="identifier" type="xs:string"/>
+                    <xs:element name="value" type="xs:string"/>
+                </xs:sequence>
+           </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />  
+    
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
index aa27828..f780c2a 100644
--- a/schemas/ical/kolabformat.xsd
+++ b/schemas/ical/kolabformat.xsd
@@ -16,7 +16,7 @@
 
 <!--     <xs:element ref="xcal:vevent"/> -->
     
-    <xs:complexType name="Event">
+<!--    <xs:complexType name="Event">
         <xs:complexContent mixed="false">
             <xs:extension base="KolabBase">
                 <xs:sequence>
@@ -24,9 +24,9 @@
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
-    </xs:complexType>
+    </xs:complexType>-->
 
-    <xs:element name="todo" type="Todo"/>
+<!--    <xs:element name="todo" type="Todo"/>
     <xs:complexType name="Todo">
         <xs:complexContent mixed="false">
             <xs:extension base="KolabBase">
@@ -35,7 +35,7 @@
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
-    </xs:complexType>
+    </xs:complexType>-->
     
     <xs:element name="note" type="Note"/>
     <xs:complexType name="Note">
@@ -48,7 +48,7 @@
         </xs:complexContent>
     </xs:complexType>
     
-    <xs:element name="contact" type="Contact"/>
+<!--    <xs:element name="contact" type="Contact"/>
     <xs:complexType name="Contact">
         <xs:complexContent mixed="false">
             <xs:extension base="KolabBase">
@@ -57,7 +57,7 @@
                 </xs:sequence>
             </xs:extension>
         </xs:complexContent>
-    </xs:complexType>
+    </xs:complexType>-->
     
 <!--    <xs:element name="distlist" type="DistributionList"/>
 
@@ -66,19 +66,14 @@
             <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
         </xs:sequence>
     </xs:complexType>-->
-
+    
     <xs:complexType name="CustomType" >
-        <xs:complexContent mixed="false">
-            <xs:extension base="xcal:BasePropertyType">
-                <xs:sequence>
-                    <xs:element name="identifier" type="xs:string"/>
-                    <xs:element name="value" type="xs:string"/>
-                </xs:sequence>
-            </xs:extension>
-        </xs:complexContent>
+        <xs:sequence>
+            <xs:element name="identifier" type="xs:string"/>
+            <xs:element name="value" type="xs:string"/>
+        </xs:sequence>
     </xs:complexType>
 
-    <xs:element name="x-kolab-customproperty" type="CustomType" substitutionGroup="xcal:baseProperty" /> 
-<!--     <xs:element name="x-kolab-customproperty" type="xcardCustomType" substitutionGroup="xcard:baseProperty" />  -->
+    <xs:element name="x-kolab-custom" type="CustomType" />  
 
 </xs:schema>
\ No newline at end of file
diff --git a/testfiles/xcalCalendar.xml b/testfiles/xcalCalendar.xml
new file mode 100644
index 0000000..0ae17ef
--- /dev/null
+++ b/testfiles/xcalCalendar.xml
@@ -0,0 +1,142 @@
+ <?xml version="1.0" encoding="utf-8" ?>
+   <icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+     <vcalendar>
+       <properties>
+         <prodid>
+           <text>-//Example Inc.//Example Client//EN</text>
+         </prodid>
+         <version>
+           <text>2.0</text>
+         </version>
+       </properties>
+       <components>
+         <vtimezone>
+           <properties>
+             <last-modified>
+               <date-time>2004-01-10T03:28:45Z</date-time>
+             </last-modified>
+             <tzid>US/Eastern</tzid>
+           </properties>
+           <components>
+             <daylight>
+               <properties>
+                 <dtstart>
+                   <date-time>2000-04-04T02:00:00</date-time>
+                 </dtstart>
+                 <rrule>
+                   <recur>
+                     <freq>YEARLY</freq>
+                     <byday>1SU</byday>
+                     <bymonth>4</bymonth>
+                   </recur>
+                 </rrule>
+                 <tzname>
+                   <text>EDT</text>
+                 </tzname>
+                 <tzoffsetfrom>
+                   <utc-offset>-05:00</utc-offset>
+                 </tzoffsetfrom>
+                 <tzoffsetto>
+                   <utc-offset>-04:00</utc-offset>
+                 </tzoffsetto>
+               </properties>
+             </daylight>
+             <standard>
+               <properties>
+                 <dtstart>
+                   <date-time>2000-10-26T02:00:00</date-time>
+                 </dtstart>
+                 <rrule>
+                   <recur>
+                     <freq>YEARLY</freq>
+                     <byday>-1SU</byday>
+                     <bymonth>10</bymonth>
+                   </recur>
+                 </rrule>
+                 <tzname>
+                   <text>EST</text>
+                 </tzname>
+                 <tzoffsetfrom>
+                   <utc-offset>-04:00</utc-offset>
+                 </tzoffsetfrom>
+                 <tzoffsetto>
+                   <utc-offset>-05:00</utc-offset>
+                 </tzoffsetto>
+               </properties>
+             </standard>
+           </components>
+         </vtimezone>
+         <vevent>
+           <properties>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-02T12:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <rrule>
+               <recur>
+                 <freq>DAILY</freq>
+                 <count>5</count>
+               </recur>
+             </rrule>
+             <rdate>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <period>
+                 <start>2006-01-02T15:00:00</start>
+                 <duration>PT2H</duration>
+               </period>
+             </rdate>
+             <summary>
+               <text>Event #2</text>
+             </summary>
+             <description>
+               <text>We are having a meeting all this week at 12
+   pm for one hour, with an additional meeting on the first day
+   2 hours long.&#x0a;Please bring your own lunch for the 12 pm
+   meetings.</text>
+             </description>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+           </properties>
+         </vevent>
+         <vevent>
+           <properties>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T14:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <recurrence-id>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T12:00:00</date-time>
+             </recurrence-id>
+             <summary>
+               <text>Event #2 bis</text>
+             </summary>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+           </properties>
+         </vevent>
+       </components>
+     </vcalendar>
+   </icalendar>
\ No newline at end of file
diff --git a/testfiles/xcalEvent.xml b/testfiles/xcalEvent.xml
new file mode 100644
index 0000000..16c78c6
--- /dev/null
+++ b/testfiles/xcalEvent.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+    <vcalendar>
+    <properties>
+    <calscale>
+        <text>GREGORIAN</text>
+    </calscale>
+    <prodid>
+    <text>-//Example Inc.//Example Calendar//EN</text>
+    </prodid>
+    <version>
+        <text>2.0</text>
+    </version>
+    </properties>
+    <components>
+    <vevent>
+    <properties>
+        <dtstamp>
+        <date-time>2008-02-05T19:12:24Z</date-time>
+        </dtstamp>
+        <dtstart>
+        <date>2008-10-06</date>
+        </dtstart>
+        <summary>
+        <text>Planning meeting</text>
+        </summary>
+        <uid>
+        <text>4088E990AD89CB3DBB484909</text>
+        </uid>
+    </properties>
+    </vevent>
+    </components>
+    </vcalendar>
+</icalendar>
\ No newline at end of file


commit 89ee425f65f04003b3cc605a29084c18136c65bf
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Nov 24 17:00:14 2011 +0100

    comment part of document which cannot be validated yet

diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 2c70272..ee2931e 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <!--Copy of an example event from the xCal RFC-->
-<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0" >
      <vcalendar>
        <properties>
          <prodid>
@@ -9,16 +9,19 @@
          <version>
            <text>2.0</text>
          </version>
-         <x-kolab-version><string>3.0dev1</string></x-kolab-version>
+         <x-kolab-version xmlns="http://kolab.org">
+             <version>3.0dev1</version>
+         </x-kolab-version>
        </properties>
        <components>
          <vtimezone>
-           <properties>
+           <!--This doesn't work right now because the tzid is commented in the schema (nameconflict with tzid component)-->
+           <!--<properties>
              <last-modified>
                <date-time>2004-01-10T03:28:45Z</date-time>
              </last-modified>
              <tzid>US/Eastern</tzid>
-           </properties>
+           </properties>-->
            <components>
              <daylight>
                <properties>
@@ -110,6 +113,7 @@
                <text>00959BC664CA650E933C892C at example.com</text>
              </uid>
            </properties>
+           <components/>
          </vevent>
          <vevent>
            <properties>
@@ -138,6 +142,7 @@
                <text>00959BC664CA650E933C892C at example.com</text>
              </uid>
            </properties>
+           <components/>
          </vevent>
        </components>
      </vcalendar>


commit 516fdc55b547832f1805db2872405377c8994051
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Nov 23 21:43:12 2011 +0100

    Copy of an example event from the xCal RFC

diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
new file mode 100644
index 0000000..2c70272
--- /dev/null
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--Copy of an example event from the xCal RFC-->
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+     <vcalendar>
+       <properties>
+         <prodid>
+           <text>-//Example Inc.//Example Client//EN</text>
+         </prodid>
+         <version>
+           <text>2.0</text>
+         </version>
+         <x-kolab-version><string>3.0dev1</string></x-kolab-version>
+       </properties>
+       <components>
+         <vtimezone>
+           <properties>
+             <last-modified>
+               <date-time>2004-01-10T03:28:45Z</date-time>
+             </last-modified>
+             <tzid>US/Eastern</tzid>
+           </properties>
+           <components>
+             <daylight>
+               <properties>
+                 <dtstart>
+                   <date-time>2000-04-04T02:00:00</date-time>
+                 </dtstart>
+                 <rrule>
+                   <recur>
+                     <freq>YEARLY</freq>
+                     <byday>1SU</byday>
+                     <bymonth>4</bymonth>
+                   </recur>
+                 </rrule>
+                 <tzname>
+                   <text>EDT</text>
+                 </tzname>
+                 <tzoffsetfrom>
+                   <utc-offset>-05:00</utc-offset>
+                 </tzoffsetfrom>
+                 <tzoffsetto>
+                   <utc-offset>-04:00</utc-offset>
+                 </tzoffsetto>
+               </properties>
+             </daylight>
+             <standard>
+               <properties>
+                 <dtstart>
+                   <date-time>2000-10-26T02:00:00</date-time>
+                 </dtstart>
+                 <rrule>
+                   <recur>
+                     <freq>YEARLY</freq>
+                     <byday>-1SU</byday>
+                     <bymonth>10</bymonth>
+                   </recur>
+                 </rrule>
+                 <tzname>
+                   <text>EST</text>
+                 </tzname>
+                 <tzoffsetfrom>
+                   <utc-offset>-04:00</utc-offset>
+                 </tzoffsetfrom>
+                 <tzoffsetto>
+                   <utc-offset>-05:00</utc-offset>
+                 </tzoffsetto>
+               </properties>
+             </standard>
+           </components>
+         </vtimezone>
+         <vevent>
+           <properties>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-02T12:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <rrule>
+               <recur>
+                 <freq>DAILY</freq>
+                 <count>5</count>
+               </recur>
+             </rrule>
+             <rdate>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <period>
+                 <start>2006-01-02T15:00:00</start>
+                 <duration>PT2H</duration>
+               </period>
+             </rdate>
+             <summary>
+               <text>Event #2</text>
+             </summary>
+             <description>
+               <text>We are having a meeting all this week at 12
+   pm for one hour, with an additional meeting on the first day
+   2 hours long.&#x0a;Please bring your own lunch for the 12 pm
+   meetings.</text>
+             </description>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+           </properties>
+         </vevent>
+         <vevent>
+           <properties>
+             <dtstamp>
+               <date-time>2006-02-06T00:11:21Z</date-time>
+             </dtstamp>
+             <dtstart>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T14:00:00</date-time>
+             </dtstart>
+             <duration>
+               <duration>PT1H</duration>
+             </duration>
+             <recurrence-id>
+               <parameters>
+                 <tzid><text>US/Eastern</text></tzid>
+               </parameters>
+               <date-time>2006-01-04T12:00:00</date-time>
+             </recurrence-id>
+             <summary>
+               <text>Event #2 bis</text>
+             </summary>
+             <uid>
+               <text>00959BC664CA650E933C892C at example.com</text>
+             </uid>
+           </properties>
+         </vevent>
+       </components>
+     </vcalendar>
+</icalendar>
\ No newline at end of file


commit f5271da7096fe5b759de54331dab437a66a55096
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Nov 23 15:37:51 2011 +0100

    A copy paste minimal xCard schema version

diff --git a/schemas/ical/xCard.xsd b/schemas/ical/xCard.xsd
new file mode 100644
index 0000000..e7f4603
--- /dev/null
+++ b/schemas/ical/xCard.xsd
@@ -0,0 +1,126 @@
+<?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"/>
+  
+    <!-- 3.3.5 DATE-TIME -->
+  <!-- 
+  <xs:element name="date-time" type="xs:string"/>
+ -->  
+   <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>
+  </xs:simpleType>
+  
+  <xs:element name="date-time" type="xcard:DateTimeType"/>
+
+<!-- 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>
+
+<!-- Properties -->
+  <xs:complexType name="BasePropertyType" abstract="true" >
+    <xs:sequence>
+      <xs:element ref="xcard:parameters" 
+                  minOccurs="0" />
+    </xs:sequence>
+  </xs:complexType>
+  
+  <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
+
+  <xs:element name="baseProperty" type="xcard:BasePropertyType" />
+
+  <xs:element name="fn" type="xcard:fnPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  <xs:element name="n" type="xcard:nPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  <xs:element name="bday" type="xcard:bdayPropType"
+              substitutionGroup="xcard:baseProperty" />
+              
+  
+              
+  <!-- Properties that take a simple text value -->
+  <xs:complexType name="TextPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:text" />
+        </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">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence>
+          <xs:choice>
+            <xs:element ref="xcard:date-time"/>
+            <xs:element ref="xcard:date"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  
+  
+  <xs:complexType name="fnPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="nPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+            <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>   
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:complexType name="bdayPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:DateDatetimePropertyType"/>
+    </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 73d8c72919b5a9f80e3fd7ffc365a4dd0511d61b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Nov 23 15:37:16 2011 +0100

    temp commit with SWIG bindings,
    
    format vevent nested in kolab event

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 350994d..edfbcb7 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -20,14 +20,16 @@ set( KOLAB_SCHEMA_SOURCEFILES
     bindings/note.cxx )
 
 add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD --output-dir bindings ${KOLAB_SCHEMAS}
+    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD_test --output-dir bindings ${KOLAB_SCHEMAS}
     COMMENT "Generating Kolab XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    DEPENDS ${KOLAB_SCHEMAS}
     VERBATIM
     )
 
 file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
 set( XCAL_SCHEMA_SOURCEFILES  
+    bindings/xCard.cxx
     bindings/kolabformat.cxx
     bindings/iCalendar.cxx
     bindings/iCalendar-params.cxx
@@ -36,14 +38,15 @@ set( XCAL_SCHEMA_SOURCEFILES
     bindings/iCalendar-link-extension.cxx
     bindings/iCalendar-bw-extensions.cxx
     bindings/iCalendar-ms-extensions.cxx
-    bindings/iCalendar-availability-extension.cxx
+#     bindings/iCalendar-availability-extension.cxx
 #     bindings/iCalendar-wscal-extensions.cxx
 )
 # --cxx-suffix .cpp --hxx-suffix .h  
 add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element event --root-element todo --output-dir bindings ${XCAL_SCHEMAS}
+    COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --output-dir bindings ${XCAL_SCHEMAS}
     COMMENT "Generating xCal XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    DEPENDS ${XCAL_SCHEMAS}
     VERBATIM
     )
 
@@ -54,7 +57,7 @@ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
 
 include_directories( ./ )
-add_library(kolabxml lib/kolabkcalconversion.cpp ${SCHEMA_SOURCEFILES})
+add_library(kolabxml lib/kolabformat.cpp ${SCHEMA_SOURCEFILES})
 target_link_libraries(${kolabxml} xerces-c)
 add_subdirectory(tests)
 add_subdirectory(lib)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 342e65a..1049024 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,25 +7,50 @@
 #     VERBATIM
 #     )
 
-set(KOLAB_SWIG_SOURCE_FILES kolabformat_wrap.cxx) 
-add_custom_command(OUTPUT ${KOLAB_SWIG_SOURCE_FILES}
-    COMMAND swig -v -c++ -python kolabformat.i
+set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp) 
+
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
+add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
+    COMMAND swig -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
     COMMENT "Generating python bindings"
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     DEPENDS kolabformat.i
     VERBATIM
     )
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
 
-SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_SOURCE_FILES} PROPERTIES GENERATED 1)
 
-ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_SOURCE_FILES})
+set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) 
+add_custom_command(OUTPUT ${KOLAB_SWIG_PHP_SOURCE_FILE}
+    COMMAND swig -v -c++ -php -o ${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
+    COMMENT "Generating php bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS kolabformat.i
+    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( ./ )
-include_directories(/usr/include/python2.7)
 
-add_library(bindings SHARED ${KOLAB_SWIG_SOURCE_FILES} kolabformat.cpp)
-ADD_DEPENDENCIES(bindings generate_python_bindings)
-SET_TARGET_PROPERTIES(bindings PROPERTIES OUTPUT_NAME "_kolabformat")
-SET_TARGET_PROPERTIES(bindings PROPERTIES PREFIX "")
+#PYTHON
+find_package(PythonLibs)
+include_directories(${PYTHON_INCLUDE_DIRS})
+add_library(pythonbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+# ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
+
+
+
+#PHP
+#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
+find_package(PHP4)
+include_directories(${PHP4_INCLUDE_PATH})
+add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
+# ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 6c45778..e020abf 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,8 +4,46 @@
 
 #include <kcalcore/event.h>
 #include <iostream>
+#include <bindings/kolabformat.hxx>
 //#include "note.h"
 
+namespace Kolab {
+    
+// xml_schema::date::operator Date(Date &d, const  xml_schema::date &dt) { 
+//     Date d;
+//     d.year = year();
+//     return d;
+// }; //conversion operator
+    
+Date &operator <<(Date &d, const  xml_schema::date &dt)
+{
+    d.year = dt.year();
+    return d;
+}
+
+// Date &operator =(Date &d, const  xml_schema::date &dt)
+// {
+//     d.year = dt.year();
+//     return d;
+// }
+    
+//Event & operator<<(const MyClass &rhs);
+Date &operator <<(Date &d, const  icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    if (dtProperty.date_time()) {
+        const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(dtProperty.date_time());
+        //datetime.day()
+//                 (*(d->date_time()))
+    } else if (dtProperty.date()) {
+        const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(dtProperty.date());
+//                 e.date = date;
+        d.year = date.year();
+//         const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
+// //                 dt.setTimeSpec(spec);
+//         event.setDtStart(dt);
+    }
+    return d;
+}
 /*
 QString Kolab::serializeNote(const Kolab::Note& note)
 {
@@ -18,6 +56,50 @@ std::string serializeEvent()
     return "bla";
 }
 
+void readEvent(const std::string &s)
+{
+    std::auto_ptr<icalendar_2_0::VeventType> vevent(icalendar_2_0::vevent(s, xml_schema::flags::dont_validate));
+        
+    const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent->properties();
+    const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+    
+    KCalCore::Event event;
+    
+    Kolab::Event e;
+    
+    for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+        if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+            std::cout << "Start" << std::endl;
+            
+//             KDateTime::TimeZone tz;
+//             KDateTime::Spec spec;
+            if (d->date_time()) {
+                const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+                //datetime.day()
+//                 (*(d->date_time()))
+            } else if (d->date()) {
+                const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+//                 e.date = date;
+                e.date << date;
+                const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
+//                 dt.setTimeSpec(spec);
+                event.setDtStart(dt);
+            }
+
+        } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+            std::cout << "Rrule" << std::endl;
+            std::cout << d->recur().freq() << std::endl;
+            std::cout << d->recur().count() << std::endl;
+            //std::cout << d->recur().byhour() << std::endl;
+        } else {
+            std::cout << "other" << std::endl;
+            const icalendar_2_0::BasePropertyType &baseProperty = (*it);
+        }
+    }
+//     const icalendar_2_0::
+}
+
+
 void Test::test()
 {
     std::cout << "test";
@@ -40,3 +122,6 @@ Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
 // {
 //     event.setSummary(string);
 // }
+
+}
+
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index fa27675..350d38a 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -3,12 +3,13 @@
 #define KOLABFORMAT_H
 //#include <QString>
 #include <string>
+#include <xsd/cxx/tree/date-time.hxx>
 
 namespace KCalCore {
     class Event;
 }
 
-// namespace Kolab {
+namespace Kolab {
 
 //class Note;
 
@@ -29,11 +30,22 @@ public:
     void test();
 };
 
+
+struct Date {
+    int year;
+};
+
+struct Event {
+     Date date;
+};
+
+
 std::string serializeEvent();
+void readEvent(const std::string&);
 
 //QString serializeEvent(const KCalCore::Event &note);
 //void readEvent(const QString &string, KCalCore::Event &);
 
-// }
+}
 
 #endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index cf7ae03..d14ae8f 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -7,6 +7,7 @@
 %include "std_string.i"
 
 /*%apply const std::string& {std::string* foo};*/
+namespace Kolab {
 
 std::string serializeEvent();
 
@@ -14,5 +15,13 @@ class Test {
 public:
     void test();
 };
+struct Date {
+    int year;
+};
+
+struct Event {
+    Date date;
+};
+}
 
 /*extern void readEvent(const QString &string, KCalCore::Event &); */
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index d59dc7c..0794b7e 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,10 +1,10 @@
 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 
 
-QT4_WRAP_CPP(kcalconversiontest_MOC kcalconversiontest.h)
+# 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)
+# add_executable(kcalconversiontest kcalconversiontest.cpp ${kcalconversiontest_MOC})
+# target_link_libraries(kcalconversiontest ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_KCALCORE_LIBS} kolabxml)
 
 #QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
 QT4_AUTOMOC(bindingstest.cpp)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 1e741ea..5c1157a 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -13,23 +13,23 @@
 
 #include <xercesc/dom/DOMException.hpp>
 #include <xercesc/dom/DOMImplementation.hpp>
+#include <bindings/contact.hxx>
 
 
 void BindingsTest::writeNoteTest()
 {
     xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
-    KolabXSD::XMLBase::sensitivity_type sensitivity = KolabXSD::Sensitivity::public_;
-    KolabXSD::Note::background_color_type bg = KolabXSD::Note::background_color_default_value();
-    KolabXSD::Note::foreground_color_type fg = KolabXSD::Note::foreground_color_default_value();
-    KolabXSD::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-    
+    KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
+    KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
+    KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
+    KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
+
     xml_schema::namespace_infomap map;
     map[""].name = "http://kolab.org";
     map[""].schema = "note.xsd";
 
-    KolabXSD::note (std::cout, note, map);
-    
-    
+    KolabXSD_test::note (std::cout, note, map);
+
   /*  QFETCH(KCalCore::Recurrence, kcalrecurrence);
     
     KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
@@ -43,13 +43,13 @@ void BindingsTest::readNoteTest()
         xml_schema::properties props;
 //         props.no_namespace_schema_location ("../../schemas/note.xsd");
 //         props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
-        std::auto_ptr<KolabXSD::Note> note(KolabXSD::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
+        std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
         
         xml_schema::namespace_infomap map;
         map[""].name = "http://kolab.org";
         map[""].schema = "note.xsd";
 
-        KolabXSD::note (std::cout, *note, map);
+        KolabXSD_test::note (std::cout, *note, map);
     } catch  (const xml_schema::exception& e) {
         std::cout << e << endl;
         QVERIFY(false);
@@ -63,103 +63,107 @@ void BindingsTest::writeReadNoteTest()
 
 void BindingsTest::writeKolabXCalEvent()
 {
-    try {
-    //Components
-    icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-
-    icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-    component.valarm().push_back(alarm);
-
-    //Properties
-
-    //Recurrence
-    icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-    recur.count(2);
-    recur.byhour().push_back("3");
-    icalendar_2_0::RrulePropType rrule(recur);
-
-    //Startdate
-    xml_schema::date_time dt(2011,8,12,2,12,15);
-    icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
-    icalendar_2_0::DtstartPropType startdate;
-    startdate.date_time(datetime);
-    //Startdate timezone
-    ::icalendar_2_0::ArrayOfParameters parameters;
-    ::icalendar_2_0::TzidParamType tzid("US/Eastern");
-    parameters.baseParameter().push_back(tzid);
-    startdate.parameters(parameters);
-    
-    
-    //Custom value
-    KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-
-    //Assembling event properties
-    ::icalendar_2_0::ArrayOfProperties properties;
-    properties.baseProperty().push_back(startdate);
-    properties.baseProperty().push_back(rrule);
-    properties.baseProperty().push_back(custom);
-
-    //Assembling the complete event
-    icalendar_2_0::VeventType event(component);
-    event.properties(properties);
-    
-    KolabXSD::Event kolabEvent(event);
-    xml_schema::namespace_infomap map;
-    map["kolab"].name = "http://kolab.org";
-    map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-    //map["xcal"].schema = "iCalendar.xsd";
-
-    KolabXSD::event (std::cout, kolabEvent, map);
-    
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << endl;
-        QVERIFY(false);
-    } 
+//     try {
+//     //Components
+//     icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
+// 
+//     icalendar_2_0::ArrayOfEventTodoContainedComponents component;
+//     component.valarm().push_back(alarm);
+// 
+//     //Properties
+// 
+//     //Recurrence
+//     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+//     recur.count(2);
+//     recur.byhour().push_back("3");
+//     icalendar_2_0::RrulePropType rrule(recur);
+// 
+//     //Startdate
+//     xml_schema::date_time dt(2011,8,12,2,12,15);
+//     icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+//     icalendar_2_0::DtstartPropType startdate;
+//     startdate.date_time(datetime);
+//     //Startdate timezone
+//     ::icalendar_2_0::ArrayOfParameters parameters;
+//     ::icalendar_2_0::TzidParamType tzid("US/Eastern");
+//     parameters.baseParameter().push_back(tzid);
+//     startdate.parameters(parameters);
+//     
+//     
+//     //Custom value
+//     KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
+// 
+//     //Assembling event properties
+//     ::icalendar_2_0::ArrayOfProperties properties;
+//     properties.baseProperty().push_back(startdate);
+//     properties.baseProperty().push_back(rrule);
+//     properties.baseProperty().push_back(custom);
+// 
+//     //Assembling the complete event
+//     icalendar_2_0::VeventType event(component);
+//     event.properties(properties);
+//     
+//     KolabXSD::Event kolabEvent(event);
+//     xml_schema::namespace_infomap map;
+//     map["kolab"].name = "http://kolab.org";
+//     map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+//     //map["xcal"].schema = "iCalendar.xsd";
+// 
+//     KolabXSD::event (std::cout, kolabEvent, map);
+//     
+//             
+// //     icalendar_2_0::VstrictTodoType todo;
+// //     icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// //     todo.rrule().;
+//     
+//     } catch  (const xml_schema::exception& e) {
+//         std::cout << e << endl;
+//         QVERIFY(false);
+//     } 
 }
 
 
 void BindingsTest::readKolabXCalEvent()
 {
-    try {
-//         xml_schema::properties props;
-//         props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-//         props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-//         std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
-
-        std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-        
-        const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
-        const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-        
-        /*for(int i = 0; i < propertyList.size(); i++) {
-            const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-            
-        }*/
-        std::cout << propertyList.size() << std::endl;
-        for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
-            if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
-                std::cout << "Rrule" << std::endl;
-                std::cout << d->recur().freq() << std::endl;
-                std::cout << d->recur().count() << std::endl;
-                //std::cout << d->recur().byhour() << std::endl;
-            } else {
-                std::cout << "other" << std::endl;
-                const icalendar_2_0::BasePropertyType &baseProperty = (*i);
-            }
-        }
-        
-        xml_schema::namespace_infomap map;
-        map[""].name = "http://kolab.org";
-//         map[""].schema = "kolabevent.xsd";
-        map["xcal"].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-//         map["xcal"].schema = "iCalendar.xsd";
-
-        KolabXSD::event (std::cout, *event, map);
-
-    } catch  (const xml_schema::exception& e) {
-        std::cout << e << std::endl;
-        QVERIFY(false);
-    } 
+//     try {
+// //         xml_schema::properties props;
+// //         props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
+// //         props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
+// //         std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+// 
+//         std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
+//         
+//         const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
+//         const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+// 
+//         /*for(int i = 0; i < propertyList.size(); i++) {
+//             const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
+//         }*/
+//         std::cout << propertyList.size() << std::endl;
+//         for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
+//             if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
+//                 std::cout << "Rrule" << std::endl;
+//                 std::cout << d->recur().freq() << std::endl;
+//                 std::cout << d->recur().count() << std::endl;
+//                 //std::cout << d->recur().byhour() << std::endl;
+//             } else {
+//                 std::cout << "other" << std::endl;
+//                 const icalendar_2_0::BasePropertyType &baseProperty = (*i);
+//             }
+//         }
+//         
+//         xml_schema::namespace_infomap map;
+//         map["kolab"].name = "http://kolab.org";
+// //         map[""].schema = "kolabevent.xsd";
+//         map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// //         map["xcal"].schema = "iCalendar.xsd";
+// 
+//         KolabXSD::event (std::cout, *event, map);
+// 
+//     } catch  (const xml_schema::exception& e) {
+//         std::cout << e << std::endl;
+//         QVERIFY(false);
+//     } 
 }
 
 #if 0
@@ -286,6 +290,44 @@ void BindingsTest::xercesException()
     doc->release();
 }
 
+void BindingsTest::writeContact()
+{
+    try {
+        KolabXSD::Contact::vcard_type vcard;
+        
+        vcard_4_0::fnPropType fn("Fritz Muster");
+        vcard.baseProperty().push_back(fn);
+        
+        vcard_4_0::nPropType n;
+        n.given().push_back("john");
+        n.surname().push_back("doe");
+        vcard.baseProperty().push_back(n);
+        
+        vcard_4_0::bdayPropType bday;
+        vcard_4_0::bdayPropType::date_type date(1988,12,12);
+        bday.date(date);
+        vcard.baseProperty().push_back(bday);
+        
+        KolabXSD::Contact contact(vcard);
+        xml_schema::namespace_infomap map;
+        map["kolab"].name = "http://kolab.org";
+        map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+        //map["xcal"].schema = "iCalendar.xsd";
+
+        KolabXSD::contact (std::cout, contact, map);
+       
+    
+    } catch  (const xml_schema::exception& e) {
+        std::cout << e << endl;
+        QVERIFY(false);
+    } 
+}
+
+void BindingsTest::readContact()
+{
+
+}
+
 
 
 QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4122321..fd93cac 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -18,6 +18,9 @@ class BindingsTest : public QObject
     void readNoteTest();
     void writeReadNoteTest();
     void xercesException();
+    
+    void writeContact();
+    void readContact();
 };
 
 #endif
\ No newline at end of file
diff --git a/c++/tests/testfiles/testkolabevent.xml b/c++/tests/testfiles/testkolabevent.xml
index 021f289..e991846 100644
--- a/c++/tests/testfiles/testkolabevent.xml
+++ b/c++/tests/testfiles/testkolabevent.xml
@@ -1,29 +1,29 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<event xmlns="http://kolab.org" xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0">
+<kolab:event xmlns:kolab="http://kolab.org" xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
 
-  <xcal:vevent>
-    <xcal:properties>
-      <xcal:dtstart>
-        <xcal:date>2011-11-10+10:10</xcal:date>
-      </xcal:dtstart>
-      <xcal:rrule>
-        <xcal:recur>
-           <xcal:count>2</xcal:count>
-          <xcal:byhour>3</xcal:byhour>
-          <xcal:freq>DAILY</xcal:freq>
+  <vevent>
+    <properties>
+      <dtstart>
+        <date>2011-11-10+10:10</date>
+      </dtstart>
+      <rrule>
+        <recur>
+           <count>2</count>
+          <byhour>3</byhour>
+          <freq>DAILY</freq>
           
-        </xcal:recur>
-      </xcal:rrule>
+        </recur>
+      </rrule>
       <x-custom-property>
          <unknown>blabla</unknown>
       </x-custom-property>       
       <x-unknown-property>
          <unknown>blibla</unknown>
       </x-unknown-property>       
-    </xcal:properties>
-    <xcal:components>
-      <xcal:valarm/>
-    </xcal:components>
-  </xcal:vevent>
+    </properties>
+    <components>
+      <valarm/>
+    </components>
+  </vevent>
 
-</event>
+</kolab:event>
diff --git a/schemas/ical/iCalendar.xsd b/schemas/ical/iCalendar.xsd
index bd937d7..89f9b00 100644
--- a/schemas/ical/iCalendar.xsd
+++ b/schemas/ical/iCalendar.xsd
@@ -48,6 +48,23 @@
 	<xs:element name="standard" type="xcal:StandardType" substitutionGroup="xcal:baseComponent"/>
 	<xs:element name="daylight" type="xcal:DaylightType" substitutionGroup="xcal:baseComponent"/>
 	<xs:element name="valarm" type="xcal:ValarmType"/>
+    
+    
+    
+    
+    <xs:element name="vstricttodo" type="xcal:VstrictTodoType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+    <xs:complexType name="VstrictTodoType" mixed="false">
+        <xs:complexContent>
+            <xs:extension base="xcal:VcalendarContainedComponentType">
+            <xs:sequence>
+<!--                 <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
+                <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
+            </xs:sequence>
+        </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    
 	<!-- 3.4 iCalendar Stream -->
 	<xs:complexType name="IcalendarType">
 		<xs:sequence>
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
index fff27e1..aa27828 100644
--- a/schemas/ical/kolabformat.xsd
+++ b/schemas/ical/kolabformat.xsd
@@ -1,27 +1,71 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
+    xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
     targetNamespace="http://kolab.org"
     xmlns="http://kolab.org"
     elementFormDefault="qualified">
 
     <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+    <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+    
+    
+    <xs:complexType name="KolabBase">
+        <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
+    </xs:complexType>
 
-    <xs:element name="event" type="Event"/>
-
+<!--     <xs:element ref="xcal:vevent"/> -->
+    
     <xs:complexType name="Event">
-        <xs:sequence>
-            <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
-        </xs:sequence>
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
     </xs:complexType>
 
     <xs:element name="todo" type="Todo"/>
-
     <xs:complexType name="Todo">
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="note" type="Note"/>
+    <xs:complexType name="Note">
+        <xs:complexContent mixed="false">
+            <xs:extension base="KolabBase">
+                <xs:sequence>
+                    <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </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="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+            <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
         </xs:sequence>
-    </xs:complexType>
+    </xs:complexType>-->
 
     <xs:complexType name="CustomType" >
         <xs:complexContent mixed="false">
@@ -35,5 +79,6 @@
     </xs:complexType>
 
     <xs:element name="x-kolab-customproperty" type="CustomType" substitutionGroup="xcal:baseProperty" /> 
+<!--     <xs:element name="x-kolab-customproperty" type="xcardCustomType" substitutionGroup="xcard:baseProperty" />  -->
 
 </xs:schema>
\ No newline at end of file


commit 06f064f656b17234b534d4212d6863078a32c6a7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Nov 17 12:22:46 2011 +0100

    disable wscal extensions and availability-extension so xsdcxx produces compiling code (workaround)

diff --git a/schemas/ical/iCalendar-wscal-extensions.xsd b/schemas/ical/iCalendar-wscal-extensions.xsd
index 4f3c7fe..8f3dcb3 100644
--- a/schemas/ical/iCalendar-wscal-extensions.xsd
+++ b/schemas/ical/iCalendar-wscal-extensions.xsd
@@ -16,6 +16,7 @@
 <!--OASIS WS-Calendar extensions to icalendar -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0" targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0" elementFormDefault="qualified">
 	<xs:include schemaLocation="iCalendar-valtypes.xsd"/>
+    <xs:include schemaLocation="iCalendar-availability-extension.xsd"/>
 	<!-- ===================== Properties =================================  -->
 	<xs:include schemaLocation="iCalendar-props.xsd"/>
 	<!-- ===================== Components =================================  -->
diff --git a/schemas/ical/iCalendar.xsd b/schemas/ical/iCalendar.xsd
index def79cb..bd937d7 100644
--- a/schemas/ical/iCalendar.xsd
+++ b/schemas/ical/iCalendar.xsd
@@ -20,8 +20,8 @@
 	<!-- ===================== Proprietary Extensions =======================  -->
 	<xs:include schemaLocation="iCalendar-bw-extensions.xsd"/>
 	<xs:include schemaLocation="iCalendar-ms-extensions.xsd"/>
-	<xs:include schemaLocation="iCalendar-availability-extension.xsd"/>
-	<xs:include schemaLocation="iCalendar-wscal-extensions.xsd"/>
+<!-- 	<xs:include schemaLocation="iCalendar-availability-extension.xsd"/> -->
+<!-- 	<xs:include schemaLocation="iCalendar-wscal-extensions.xsd"/> -->
 	<!-- =====================================================================
        3.4 Calendar Components
        ===================================================================== -->


commit 8bd9bd3ca300b8db3971beded2453d2d50e73a7a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Nov 14 23:18:32 2011 +0100

    first working SWIG tests

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index dc1b2a3..350994d 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -57,3 +57,4 @@ include_directories( ./ )
 add_library(kolabxml lib/kolabkcalconversion.cpp ${SCHEMA_SOURCEFILES})
 target_link_libraries(${kolabxml} xerces-c)
 add_subdirectory(tests)
+add_subdirectory(lib)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
new file mode 100644
index 0000000..342e65a
--- /dev/null
+++ b/c++/lib/CMakeLists.txt
@@ -0,0 +1,31 @@
+
+# add_custom_command(OUTPUT qt_wrap.c
+#     COMMAND swig -c++ -python -I$QTPATH/include  qt.i
+#     COMMENT "Generating qt python bindings"
+#     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+#     DEPENDS qt.i
+#     VERBATIM
+#     )
+
+set(KOLAB_SWIG_SOURCE_FILES kolabformat_wrap.cxx) 
+add_custom_command(OUTPUT ${KOLAB_SWIG_SOURCE_FILES}
+    COMMAND swig -v -c++ -python kolabformat.i
+    COMMENT "Generating python bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS kolabformat.i
+    VERBATIM
+    )
+
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_SOURCE_FILES} PROPERTIES GENERATED 1)
+
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_SOURCE_FILES})
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
+
+include_directories( ./ )
+include_directories(/usr/include/python2.7)
+
+add_library(bindings SHARED ${KOLAB_SWIG_SOURCE_FILES} kolabformat.cpp)
+ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(bindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(bindings PROPERTIES PREFIX "")
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
new file mode 100644
index 0000000..6c45778
--- /dev/null
+++ b/c++/lib/kolabformat.cpp
@@ -0,0 +1,42 @@
+
+
+#include "kolabformat.h"
+
+#include <kcalcore/event.h>
+#include <iostream>
+//#include "note.h"
+
+/*
+QString Kolab::serializeNote(const Kolab::Note& note)
+{
+
+}
+*/
+std::string serializeEvent()
+{
+    std::cout << "ksjdsldfj";
+    return "bla";
+}
+
+void Test::test()
+{
+    std::cout << "test";
+}
+
+
+// QString Kolab::serializeEvent(const KCalCore::Event& event)
+// {
+//     return event.summary();
+// }
+
+/*
+Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
+{
+
+}
+*/
+
+// void Kolab::readEvent(const QString &string, KCalCore::Event &event)
+// {
+//     event.setSummary(string);
+// }
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
new file mode 100644
index 0000000..fa27675
--- /dev/null
+++ b/c++/lib/kolabformat.h
@@ -0,0 +1,39 @@
+
+#ifndef KOLABFORMAT_H
+#define KOLABFORMAT_H
+//#include <QString>
+#include <string>
+
+namespace KCalCore {
+    class Event;
+}
+
+// namespace Kolab {
+
+//class Note;
+
+/*
+enum TYPE {
+    NoteType,
+    TodoType,
+    EventType,
+    ContactType
+};*/
+
+
+//QString serializeNote(const Note &note);
+
+class Test
+{
+public:
+    void test();
+};
+
+std::string serializeEvent();
+
+//QString serializeEvent(const KCalCore::Event &note);
+//void readEvent(const QString &string, KCalCore::Event &);
+
+// }
+
+#endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
new file mode 100644
index 0000000..cf7ae03
--- /dev/null
+++ b/c++/lib/kolabformat.i
@@ -0,0 +1,18 @@
+/* kolabformat.i */
+ %module kolabformat
+ %{
+ /* Put header files here or function declarations like below */
+ #include "kolabformat.h"
+ %}
+%include "std_string.i"
+
+/*%apply const std::string& {std::string* foo};*/
+
+std::string serializeEvent();
+
+class Test {
+public:
+    void test();
+};
+
+/*extern void readEvent(const QString &string, KCalCore::Event &); */





More information about the commits mailing list