115 commits - c++/autogen.sh c++/CMakeLists.txt c++/compiled c++/.gitignore c++/lib c++/README 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
Sun Feb 12 23:26:28 CET 2012


 c++/.gitignore                                    |    1 
 c++/CMakeLists.txt                                |  109 +
 c++/README                                        |   18 
 c++/autogen.sh                                    |    9 
 c++/compiled/README                               |   20 
 c++/compiled/XMLParserWrapper.cpp                 |  281 +++
 c++/compiled/XMLParserWrapper.h                   |   93 +
 c++/compiled/grammar-input-stream.cxx             |  115 +
 c++/compiled/grammar-input-stream.hxx             |   53 
 c++/compiled/xsdbin.cxx                           |  505 ++++++
 c++/lib/CMakeLists.txt                            |   68 
 c++/lib/DEVELOPMENT                               |  102 +
 c++/lib/base64.cpp                                |  123 +
 c++/lib/base64.h                                  |    4 
 c++/lib/global_definitions.h                      |   37 
 c++/lib/incidence_p.h                             |   66 
 c++/lib/kcalkolabformat.cpp                       |   55 
 c++/lib/kcalkolabformat.h                         |   35 
 c++/lib/kolabcontact.cpp                          |  393 +++++
 c++/lib/kolabcontact.h                            |  280 +++
 c++/lib/kolabcontainers.cpp                       |  722 +++++++++
 c++/lib/kolabcontainers.h                         |  365 ++++
 c++/lib/kolabcontainers.i                         |   15 
 c++/lib/kolabevent.cpp                            |  344 ++++
 c++/lib/kolabevent.h                              |  124 +
 c++/lib/kolabformat.cpp                           |  163 ++
 c++/lib/kolabformat.h                             |   75 
 c++/lib/kolabformat.i                             |   31 
 c++/lib/kolabkcalconversion.cpp                   |   68 
 c++/lib/kolabkcalconversion.h                     |   38 
 c++/lib/kolabtodo.cpp                             |  328 ++++
 c++/lib/kolabtodo.h                               |  120 +
 c++/lib/php/CMakeLists.txt                        |   32 
 c++/lib/php/test.php                              |   31 
 c++/lib/python/CMakeLists.txt                     |   34 
 c++/lib/python/test.py                            |   16 
 c++/lib/utils.cpp                                 |  135 +
 c++/lib/utils.h                                   |   90 +
 c++/lib/xcalconversions.h                         | 1670 ++++++++++++++++++++++
 c++/lib/xcardconversions.h                        |  777 ++++++++++
 c++/tests/CMakeLists.txt                          |   21 
 c++/tests/bindingstest.cpp                        |  406 +++++
 c++/tests/bindingstest.h                          |   41 
 c++/tests/conversiontest.cpp                      |  138 +
 c++/tests/conversiontest.h                        |   31 
 c++/tests/kcalconversiontest.cpp                  |  373 ++++
 c++/tests/kcalconversiontest.h                    |   27 
 c++/tests/serializers.h                           |  171 ++
 c++/tests/testfiles/icalEvent.xml                 |   92 +
 c++/tests/testfiles/testevent.xml                 |   26 
 c++/tests/testfiles/testkolabevent.xml            |   29 
 schemas/base.xsd                                  |   92 -
 schemas/contact.xsd                               |   82 -
 schemas/event.xsd                                 |   25 
 schemas/ical/iCalendar-availability-extension.xsd |   85 +
 schemas/ical/iCalendar-bw-extensions.xsd          |   59 
 schemas/ical/iCalendar-link-extension.xsd         |   50 
 schemas/ical/iCalendar-ms-extensions.xsd          |   48 
 schemas/ical/iCalendar-params.xsd                 |  376 ++++
 schemas/ical/iCalendar-props.xsd                  |  791 ++++++++++
 schemas/ical/iCalendar-valtypes.xsd               |  285 +++
 schemas/ical/iCalendar-wscal-extensions.xsd       |  162 ++
 schemas/ical/iCalendar.rng                        | 1184 +++++++++++++++
 schemas/ical/iCalendar.xsd                        |  223 ++
 schemas/ical/kolabformat-xcal.xsd                 |  217 ++
 schemas/incidence.xsd                             |   95 -
 schemas/kolabformat-xcard.xsd                     |   74 
 schemas/kolabformat.xsd                           |   62 
 schemas/note.xsd                                  |   33 
 schemas/task.xsd                                  |   29 
 schemas/xCard.xsd                                 |  390 +++++
 testfiles/xcalCalendar.xml                        |  142 +
 testfiles/xcalEvent.xml                           |   34 
 73 files changed, 13082 insertions(+), 356 deletions(-)

New commits:
commit 003f6c65819f8f31284af00316ce99c029b0f782
Merge: 7f0a2ab 16daa73
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 12 23:23:13 2012 +0100

    Merge remote-tracking branch 'origin/c++/master' into c++/master
    
    Conflicts:
    	c++/lib/global_definitions.h

diff --cc c++/lib/global_definitions.h
index 21aac74,326678c..2aa36e8
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@@ -22,8 -22,8 +22,8 @@@
  namespace Kolab {
  
  const char* const KOLAB_LIBNAME = "libkolabxml";
 -const char* const KOLAB_LIB_VERSION = "0.9";
 +const char* const KOLAB_LIB_VERSION = "0.1";
- const char* const KOLAB_FORMAT_VERSION = "2.9.0";
+ const char* const KOLAB_FORMAT_VERSION = "3.0dev1";
  
  enum ErrorSeverity {
      NoError,


commit 7f0a2ab8882808ae2a542fe4ede54824f1502d77
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 12 21:33:39 2012 +0100

    version 0.1

diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
index 1146e9c..21aac74 100644
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@ -22,7 +22,7 @@
 namespace Kolab {
 
 const char* const KOLAB_LIBNAME = "libkolabxml";
-const char* const KOLAB_LIB_VERSION = "0.9";
+const char* const KOLAB_LIB_VERSION = "0.1";
 const char* const KOLAB_FORMAT_VERSION = "2.9.0";
 
 enum ErrorSeverity {


commit a996fc636886d3f86b9ff97f006c5c929007273f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 12 21:33:26 2012 +0100

    Tests and a couple of fixes

diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index 938fdca..fb1871f 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -457,14 +457,26 @@ std::string serializeCard(const T &card, const std::string prod = std::string())
 
     try {
         vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
-        setCreatedUid(uid.uri());
+        setCreatedUid(uid.text());
         vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
         vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
         vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
         vcard_4_0::vcard::kind_type kind(getType<T>());
         vcard_4_0::vcard::fn_type fn(card.name());
+        
+        
 
         vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+        if (!card.categories().empty()) {
+            vcard_4_0::vcard::categories_type cat;
+            vcard_4_0::vcard::categories_type::text_sequence seq;
+            BOOST_FOREACH(const std::string &s, card.categories()) {
+                seq.push_back(s);
+            }
+            cat.text(seq);
+            vcard.categories(cat);
+        }
+        
         //TODO custom properties
         writeCard<T>(vcard, card);
         
@@ -739,6 +751,10 @@ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
         
         boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
         card->setName(vcards->vcard().fn().text());
+
+        if (vcards->vcard().categories()) {
+            card->setCategories(toStringList((*vcards->vcard().categories()).text()));
+        }
         
         setProductId( vcards->vcard().prodid().text() );
 //         setFormatVersion( vcards->vcard().version().text() );
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index ed7d906..1d1433f 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -235,6 +235,7 @@ void BindingsTest::contactCompletness()
     stringlist.push_back("sdf");
 
     Kolab::Contact c;
+    c.setCategories(stringlist);
     c.setName("name");
     Kolab::NameComponents nc;
     nc.setSurnames(stringlist);
@@ -305,26 +306,37 @@ void BindingsTest::contactCompletness()
     std::cout << result << endl;
     Kolab::Contact e = Kolab::readContact(result, false);
     QVERIFY(Kolab::error() == Kolab::NoError);
+    QCOMPARE(e.uid(), c.uid());
+    QCOMPARE(e.created(), c.created());
+    QCOMPARE(e.categories(), c.categories());
     QCOMPARE(e.name(), c.name());
     QCOMPARE(e.nameComponents(), c.nameComponents());
     QCOMPARE(e.note(), c.note());
     QCOMPARE(e.freeBusyUrl(), c.freeBusyUrl());
+    QCOMPARE(e.affiliations(), c.affiliations());
     QCOMPARE(e.urls(), c.urls());
+    QCOMPARE(e.addresses(), c.addresses());
+    QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex());
     QCOMPARE(e.nickNames(), c.nickNames());
+//     QCOMPARE(e.relateds(), c.relateds());
     QCOMPARE(e.bDay(), c.bDay());
     QCOMPARE(e.anniversary(), c.anniversary());
-    QCOMPARE(e.languages(), c.languages());
-    QCOMPARE(e.gender(), c.gender());
-    QCOMPARE(e.affiliations(), c.affiliations());
     QCOMPARE(e.photo(), c.photo());
-//     QCOMPARE(e.photoMimetype(), c.photoMimetype());
-    QCOMPARE(e.addresses(), c.addresses());
-    QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex());
-
+    //     QCOMPARE(e.photoMimetype(), c.photoMimetype());
+    QCOMPARE(e.gender(), c.gender());
+    QCOMPARE(e.languages(), c.languages());
     QCOMPARE(e.telephones(), c.telephones());
     QCOMPARE(e.telephonesPreferredIndex(), c.telephonesPreferredIndex());
+    QCOMPARE(e.imAddresses(), c.imAddresses());
+    QCOMPARE(e.imAddressPreferredIndex(), c.imAddressPreferredIndex());
     QCOMPARE(e.emailAddresses(), c.emailAddresses());
     QCOMPARE(e.emailAddressPreferredIndex(), c.emailAddressPreferredIndex());
+//     QCOMPARE(e.gpsPos(), c.gpsPos());
+//     QCOMPARE(e.crypto(), c.crypto());
+//     QCOMPARE(e.customProperties(), c.customProperties());
+
+
+    
 
 
 }
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
index a9ae046..407234c 100644
--- a/schemas/kolabformat-xcard.xsd
+++ b/schemas/kolabformat-xcard.xsd
@@ -40,6 +40,7 @@
                         <xs:element name="x-kolab-version" type="KolabVersion"/>
                         <xs:element name="prodid" type="prodidPropType"/>
                         <xs:element name="rev" type="revPropType"/>
+                        <xs:element name="categories" type="categoriesPropType" minOccurs="0" />
                         <xs:element name="kind" type="kindPropType"/>
                         <xs:element name="fn" type="fnPropType"/>
                         <xs:element name="n" type="nPropType" minOccurs="0"/>
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index 29d8f56..c523a80 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -211,6 +211,12 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <xs:complexType name="categoriesPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextListPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
   <xs:complexType name="fnPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:TextPropertyType"/>
@@ -219,7 +225,7 @@
   
   <xs:complexType name="uidPropType">
     <xs:complexContent mixed="false">
-      <xs:extension base="xcard:UriPropertyType"/> <!--TODO not text?-->
+      <xs:extension base="xcard:TextPropertyType"/>
     </xs:complexContent>
   </xs:complexType>
   
@@ -327,11 +333,9 @@
     </xs:simpleType>
   
   <xs:complexType name="genderPropType">
-<!--    <xs:complexContent mixed="false">-->
   <xs:sequence>
       <xs:element name="sex" type="xcard:SexType" />
     </xs:sequence>
-<!--    </xs:complexContent>-->
   </xs:complexType>
   
   <xs:complexType name="langPropType">


commit 70cd843b8fcb9088a7a2bf381a64961a1fdf8112
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 12 19:25:19 2012 +0100

    xCard Contacts implementation (not yet complete), cleanup, comments.

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 2e4dd72..83ceb27 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -85,7 +85,7 @@ add_executable(xsdbin compiled/xsdbin.cxx)
 target_link_libraries(xsdbin ${XERCES_C})
 
 add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
-    COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR}   ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+    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 ${SCHEMA_DIR}/xCard.xsd ${SCHEMA_DIR}/kolabformat-xcard.xsd
     COMMENT "Compiling Kolab XSD schema"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS ${XCAL_SCHEMAS} xsdbin
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index b48e630..e98acdc 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -9,7 +9,7 @@ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC " ) #always generate shared libraries with -fPIC
 
 #Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml ${XERCES_C})
 
 #For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index 466c494..08cab4d 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -54,7 +54,7 @@ They were also designed to be easily copieable and make therefore minimal use of
 
 The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
 
-The validity of the containers can be checked using the isValid() function.
+The validity of the containers can be checked using the isValid() function. This function is used to check if a value has been set, and does not really verifiy the validity of the values in terms of what ranges/combinations are allowed.
 
 === Why KCalCore containers were not directly used ===
 
@@ -91,4 +91,12 @@ For further performance improvements read this: http://xerces.apache.org/xerces2
 All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that.
 If an error occurs a message is printed to the standard error output and a default constructed value is returned.
 
-Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
\ No newline at end of file
+Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
+
+
+
+=== The XSD based development checklist ===
+-Don't forget to add an element for each attribute in the style off: <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
+ Otherwise you won't get the serialization/deserialization code (or respectively just wrong code), which still compiles though and looks correct from the outside.
+
+-If you have modified the xsd's make sure to run "make clean && make" in the toplevel make directory, otherwise the schema is not recompiles => parsing errors
\ No newline at end of file
diff --git a/c++/lib/kolabcontact.cpp b/c++/lib/kolabcontact.cpp
new file mode 100644
index 0000000..7bc50ac
--- /dev/null
+++ b/c++/lib/kolabcontact.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabcontact.h"
+
+namespace Kolab {
+    
+struct Contact::Private
+{
+    Private()
+    :  addressPreferredIndex(-1),
+    gender(NotSet),
+    telephonesPreferredIndex(-1),
+    imAddressPreferredIndex(-1),
+    emailAddressPreferredIndex(-1)
+    {}
+    
+    std::string uid;
+    DateTime created;
+    DateTime lastModified;
+    std::vector< std::string > categories;
+    
+    std::string name;
+    NameComponents nameComponents;
+    std::string note;
+    std::string freeBusyUrl;
+    std::vector<Affiliation> affiliations;
+    std::vector<std::string> urls;
+    std::vector<Address> addresses;
+    int addressPreferredIndex;
+    std::vector<std::string> nickNames;
+    std::vector<Related> relateds;
+    DateTime bDay;
+    DateTime anniversary;
+    std::string photo;
+    std::string photoMimetype;
+    Gender gender;
+    std::vector<std::string> languages;
+    std::vector<Telephone> telephones;
+    int telephonesPreferredIndex;
+    std::vector<std::string> imAddresses;
+    int imAddressPreferredIndex;
+    std::vector<std::string> emailAddresses;
+    int emailAddressPreferredIndex;
+    std::vector<std::string> gpsPos;
+    Crypto crypto;
+    std::vector<CustomProperty> customProperties;
+};
+
+Contact::Contact()
+: d(new Contact::Private())
+{
+    
+}
+
+Contact::Contact(const Contact &other)
+: d(new Contact::Private())
+{
+    *d = *other.d;
+}
+
+Contact::~Contact()
+{
+    
+}
+
+void Contact::operator=(const Kolab::Contact &other)
+{
+    *d = *other.d;
+}
+
+void Contact::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Contact::uid() const
+{
+    return d->uid;
+}
+
+void Contact::setCreated(const Kolab::DateTime &created)
+{
+    d->created = created;
+}
+
+DateTime Contact::created() const
+{
+    return d->created;
+}
+
+void Contact::setLastModified(const Kolab::DateTime &dt)
+{
+    d->lastModified = dt;
+}
+
+DateTime Contact::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Contact::setCategories(const std::vector< std::string > &cat)
+{
+ d->categories = cat;
+}
+
+void Contact::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Contact::categories() const
+{
+    return d->categories;
+}
+
+void Contact::setName(const std::string &name)
+{
+    d->name = name;
+}
+
+std::string Contact::name() const
+{
+    return d->name;
+}
+
+void Contact::setNameComponents(const Kolab::NameComponents &nc)
+{
+    d->nameComponents = nc;
+}
+
+NameComponents Contact::nameComponents() const
+{
+    return d->nameComponents;
+}
+
+void Contact::setNote(const std::string &note)
+{
+    d->note = note;
+}
+
+std::string Contact::note() const
+{
+    return d->note;
+}
+
+void Contact::setFreeBusyUrl(const std::string &url)
+{
+    d->freeBusyUrl = url;
+}
+
+std::string Contact::freeBusyUrl() const
+{
+    return d->freeBusyUrl;
+}
+
+void Contact::setAffiliations(const std::vector< Affiliation > &a)
+{
+    d->affiliations = a;
+}
+
+std::vector< Affiliation > Contact::affiliations() const
+{
+    return d->affiliations;
+}
+
+void Contact::setUrls(const std::vector< std::string > &urls)
+{
+    d->urls = urls;
+}
+
+std::vector< std::string > Contact::urls() const
+{
+    return d->urls;
+}
+
+void Contact::setAddresses(const std::vector< Address > &ad, int preferred)
+{
+    d->addresses = ad;
+    d->addressPreferredIndex = preferred;
+}
+
+std::vector< Address > Contact::addresses() const
+{
+    return d->addresses;
+}
+
+int Contact::addressPreferredIndex() const
+{
+    return d->addressPreferredIndex;
+}
+
+
+void Contact::setNickNames(const std::vector< std::string > &n)
+{
+    d->nickNames = n;
+}
+
+std::vector< std::string > Contact::nickNames() const
+{
+    return d->nickNames;
+}
+
+void Contact::setRelateds(const std::vector< Related > &relateds)
+{
+    d->relateds = relateds;
+}
+
+std::vector< Related > Contact::relateds() const
+{
+    return d->relateds;
+}
+
+void Contact::setBDay(const Kolab::DateTime &bday)
+{
+    d->bDay = bday;
+}
+
+DateTime Contact::bDay() const
+{
+    return d->bDay;
+}
+
+void Contact::setAnniversary(const Kolab::DateTime& dt)
+{
+    d->anniversary = dt;
+}
+
+DateTime Contact::anniversary() const
+{
+    return d->anniversary;
+}
+
+void Contact::setPhoto(const std::string& data, const std::string& mimetype)
+{
+    d->photo = data;
+    d->photoMimetype = mimetype;
+}
+
+std::string Contact::photo() const
+{
+    return d->photo;
+}
+
+std::string Contact::photoMimetype() const
+{
+    return d->photoMimetype;
+}
+
+void Contact::setGender(Contact::Gender g)
+{
+    d->gender = g;
+}
+
+Contact::Gender Contact::gender() const
+{
+    return d->gender;
+}
+
+void Contact::setLanguages(const std::vector< std::string >& l)
+{
+    d->languages = l;
+}
+
+std::vector< std::string > Contact::languages() const
+{
+    return d->languages;
+}
+
+void Contact::setTelephones(const std::vector< Telephone >& tel, int preferredIndex)
+{
+    d->telephonesPreferredIndex = preferredIndex;
+    d->telephones = tel;
+}
+
+std::vector< Telephone > Contact::telephones() const
+{
+    return d->telephones;
+}
+
+int Contact::telephonesPreferredIndex() const
+{
+    return d->telephonesPreferredIndex;
+}
+
+void Contact::setIMaddresses(const std::vector< std::string > &adr, int preferredIndex)
+{
+    d->imAddresses = adr;
+    d->imAddressPreferredIndex = preferredIndex;
+}
+
+std::vector< std::string > Contact::imAddresses() const
+{
+    return d->imAddresses;
+}
+
+int Contact::imAddressPreferredIndex() const
+{
+    return d->imAddressPreferredIndex;
+}
+
+void Contact::setEmailAddresses(const std::vector< std::string >& email, int preferredIndex)
+{
+    d->emailAddresses = email;
+    d->emailAddressPreferredIndex = preferredIndex;
+}
+
+std::vector< std::string > Contact::emailAddresses() const
+{
+    return d->emailAddresses;
+}
+
+int Contact::emailAddressPreferredIndex() const
+{
+    return d->emailAddressPreferredIndex;
+}
+
+void Contact::setGPSpos(const std::vector< std::string >& pos)
+{
+    d->gpsPos = pos;
+}
+
+std::vector< std::string > Contact::gpsPos() const
+{
+    return d->gpsPos;
+}
+
+void Contact::setCrypto(const Kolab::Crypto& c)
+{
+    d->crypto = c;
+}
+
+Crypto Contact::crypto() const
+{
+    return d->crypto;
+}
+
+void Contact::setCustomProperties(const std::vector< CustomProperty >& c)
+{
+    d->customProperties = c;
+}
+
+std::vector< CustomProperty > Contact::customProperties() const
+{
+    return d->customProperties;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+} //Namespace
+
diff --git a/c++/lib/kolabcontact.h b/c++/lib/kolabcontact.h
new file mode 100644
index 0000000..c4a3456
--- /dev/null
+++ b/c++/lib/kolabcontact.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABCONTACT_H
+#define KOLABCONTACT_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+
+namespace Kolab {
+    
+struct NameComponents {
+    bool operator==(const NameComponents &other) const { return mSurnames == other.mSurnames &&
+                                                        mGiven == other.mGiven &&
+                                                        mAdditional == other.mAdditional &&
+                                                        mPrefixes == other.mPrefixes &&
+                                                        mSuffixes == other.mSuffixes;
+                                                        };
+    void setSurnames(const std::vector<std::string> &s) { mSurnames = s; };
+    std::vector<std::string> surnames() const { return mSurnames; };
+    void setGiven(const std::vector<std::string> &s) { mGiven = s; };
+    std::vector<std::string> given() const { return mGiven; };
+    void setAdditional(const std::vector<std::string> &s) { mAdditional = s; };
+    std::vector<std::string> additional() const { return mAdditional; };
+    void setPrefixes(const std::vector<std::string> &s) { mPrefixes = s; };
+    std::vector<std::string> prefixes() const { return mPrefixes; };
+    void setSuffixes(const std::vector<std::string> &s) { mSuffixes = s; };
+    std::vector<std::string> suffixes() const { return mSuffixes; };
+    bool isValid() const { return !(mSurnames.empty() && mGiven.empty() && mAdditional.empty() && mPrefixes.empty() && mSuffixes.empty()); };
+private:
+    std::vector<std::string> mSurnames;
+    std::vector<std::string> mGiven;
+    std::vector<std::string> mAdditional;
+    std::vector<std::string> mPrefixes;
+    std::vector<std::string> mSuffixes;
+};
+
+struct Affiliation {
+    bool operator==(const Affiliation &other) const { return mOrg == other.mOrg &&
+                                                    mLogo == other.mLogo &&
+                                                    mTitles == other.mTitles &&
+                                                    mRoles == other.mRoles &&
+                                                    mManagers == other.mManagers &&
+                                                    mAssistants == other.mAssistants &&
+                                                    mOffices == other.mOffices;
+                                                    };
+    void setOrganisation(const std::string &org) { mOrg = org; };
+    std::string organisation() const { return mOrg; };
+//     void setOrganisationalUnits(const std::vector<std::string> &units);
+    void setLogo(const std::string &l) { mLogo = l; };
+    std::string logo() const { return mLogo; };
+    void setTitles(const std::vector<std::string> &titles) { mTitles = titles; };
+    std::vector<std::string> titles() const { return mTitles; };
+    void setRoles(const std::vector<std::string> &roles) { mRoles = roles; };
+    std::vector<std::string> roles() const { return mRoles; };
+    void setManagers(const std::vector<std::string> &managers) { mManagers = managers; };
+    std::vector<std::string> managers() const { return mManagers; };
+    void setAssistants(const std::vector<std::string> &assistants) { mAssistants = assistants; };
+    std::vector<std::string> assistants() const { return mAssistants; };
+    void setOffices(const std::vector<std::string> &offices) { mOffices = offices; };
+    std::vector<std::string> offices() const { return mOffices; };
+private:
+    std::string mOrg;
+    std::vector<std::string> mOrgUnits;
+    std::string mLogo;
+    std::vector<std::string> mTitles;
+    std::vector<std::string> mRoles;
+    std::vector<std::string> mManagers;
+    std::vector<std::string> mAssistants;
+    std::vector<std::string> mOffices;
+};
+
+struct Address {
+
+    Address(): mTypes(0) {};
+    enum Type {
+        Work = 0x01,
+        Home = 0x02
+    };
+    bool operator==(const Address &other) const { return mTypes == other.mTypes &&
+                                                    mLabel == other.mLabel &&
+                                                    mStreet == other.mStreet &&
+                                                    mLocality == other.mLocality &&
+                                                    mRegion == other.mRegion &&
+                                                    mCode == other.mCode &&
+                                                    mCountry == other.mCountry;
+                                                    };
+    void setTypes(int t) { mTypes = t; };
+    int types() const { return mTypes; };
+
+    void setLabel(const std::string &s) { mLabel = s; };
+    std::string label() const { return mLabel; }
+
+    void setStreet(const std::string &s) { mStreet = s; };
+    std::string street() const { return mStreet; };
+    
+    void setLocality(const std::string &s) { mLocality = s; };
+    std::string locality() const { return mLocality; };
+    
+    void setRegion(const std::string &s) { mRegion = s; };
+    std::string region() const { return mRegion; };
+    
+    void setCode(const std::string &s) { mCode = s; };
+    std::string code() const { return mCode; };
+    
+    void setCountry(const std::string &s) { mCountry = s; };
+    std::string country() const { return mCountry; };
+private:
+    int mTypes;
+    std::string mLabel;
+    std::string mStreet;
+    std::string mLocality;
+    std::string mRegion;
+    std::string mCode;
+    std::string mCountry;
+};
+
+struct Related {
+//     void setUri(const std::string &);
+//     std::string uri() const;
+//     void setText(const std::string &);
+//     std::string text() const;
+//     enum Type {
+//         Child,
+//         Spouse
+//     };
+//     void setType(Type t) { type = t; };
+//     Type type() const { return type; };
+// private:
+//     std::string uri;
+//     std::string text;
+//     Type type;
+};
+
+struct Telephone {
+    enum Type {
+        Work = 0x01,
+        Home = 0x02,
+        Text = 0x04,
+        Voice = 0x08,
+        Fax = 0x10,
+        Cell = 0x20,
+        Video = 0x40,
+        Pager = 0x80,
+        Textphone = 0x100,
+        Car = 0x200
+    };
+    Telephone(): mType(0){};
+    bool operator==(const Telephone &other) const { return mNumber == other.mNumber &&
+                                                    mType == other.mType;
+                                                    };
+    void setTypes(int t) { mType = t; };
+    int types() const { return mType; };
+    void setNumber(const std::string &n) { mNumber = n; };
+    std::string number() const { return mNumber; };
+private:
+    std::string mNumber;
+    int mType;
+};
+
+struct Crypto {
+    
+};
+
+class Contact {
+public:
+    Contact();
+    ~Contact();
+    Contact(const Contact &);
+    void operator=(const Contact &);
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const DateTime &);
+    DateTime created() const;
+    
+    void setLastModified(const DateTime &);
+    DateTime lastModified() const;
+    
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setName(const std::string &);
+    std::string name() const;
+    
+    void setNameComponents(const NameComponents &);
+    NameComponents nameComponents() const;
+    
+    void setNote(const std::string &);
+    std::string note() const;
+    
+    void setFreeBusyUrl(const std::string &);
+    std::string freeBusyUrl() const;
+    
+    void setAffiliations(const std::vector<Affiliation> &);
+    std::vector<Affiliation> affiliations() const;
+    
+    void setUrls(const std::vector<std::string> &);
+    std::vector<std::string> urls() const;
+    
+    void setAddresses(const std::vector<Address> &, int preferred = -1);
+    std::vector<Address> addresses() const;
+    int addressPreferredIndex() const;
+    
+    void setNickNames(const std::vector< std::string > &);
+    std::vector< std::string > nickNames() const;
+    
+    void setRelateds(const std::vector<Related> &);
+    std::vector<Related> relateds() const;
+     
+    void setBDay(const DateTime &);
+    DateTime bDay() const;
+    
+    void setAnniversary(const DateTime &);
+    DateTime anniversary() const;
+    
+    void setPhoto(const std::string &data, const std::string &mimetype);
+    std::string photo() const;
+    std::string photoMimetype() const;
+    
+    enum Gender {
+        NotSet,
+        NotSpecified,
+        Male,
+        Female
+    };
+    
+    void setGender(Gender);
+    Gender gender() const;
+    
+    void setLanguages(const std::vector<std::string> &);
+    std::vector<std::string> languages() const;
+    
+    void setTelephones(const std::vector<Telephone> &, int preferredIndex = -1);
+    std::vector<Telephone> telephones() const;
+    int telephonesPreferredIndex() const;
+    
+    void setIMaddresses(const std::vector<std::string> &, int preferredIndex = -1);
+    std::vector<std::string> imAddresses() const;
+    int imAddressPreferredIndex() const;
+    
+    void setEmailAddresses(const std::vector<std::string> &, int preferredIndex = -1);
+    std::vector<std::string> emailAddresses() const;
+    int emailAddressPreferredIndex() const;
+    
+    void setGPSpos(const std::vector<std::string> &);
+    std::vector<std::string> gpsPos() const;
+    
+    void setCrypto(const Crypto &);
+    Crypto crypto() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+} //Namespace
+
+#endif // KOLABCONTACT_H
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 6f43ac8..a05dafe 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -345,12 +345,6 @@ class Journal {
     //TODO
 };
 
-class Contact {
-public:
-    std::string uid() const{return std::string();}
-    std::string fn() const{return std::string();}
-    //TODO
-};
 
 class DistList {
     //TODO
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
index 668e254..6cb1587 100644
--- a/c++/lib/kolabevent.h
+++ b/c++/lib/kolabevent.h
@@ -106,7 +106,7 @@ public:
     
     void setCustomProperties(const std::vector<CustomProperty> &);
     std::vector<CustomProperty> customProperties() const;
-/*    TODO what is this?
+/*    TODO what is this? Exceptions it is
     void setExceptions(const std::vector<Event> &);
     std::vector<Event> exceptions() const;*/
     
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 1538fad..3e72998 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -27,17 +27,17 @@ namespace Kolab {
     
 ErrorSeverity error()
 {
-    return getError();
+    return Utils::getError();
 }
 
 std::string errorMessage()
 {
-    return getErrorMessage();
+    return Utils::getErrorMessage();
 }
 
 std::string productId()
 {
-    return XCAL::global_productId;
+    return Utils::productId();
 }
 
 std::string xCalVersion()
@@ -47,7 +47,7 @@ std::string xCalVersion()
 
 std::string xKolabVersion()
 {
-    return XCAL::global_xKolabVersion;
+    return Utils::kolabVersion();
 }
 
 
@@ -112,11 +112,12 @@ std::string writeContact(const Contact &contact)
 
 DistList readDistlist(const std::string& s, bool isUrl)
 {
-    boost::shared_ptr <Kolab::DistList> ptr = XCARD::deserializeCard<Kolab::DistList>(s, isUrl);
-    if (!ptr.get()) {
-        return Kolab::DistList();
-    }
-    return *ptr;
+//     boost::shared_ptr <Kolab::DistList> ptr = XCARD::deserializeCard<Kolab::DistList>(s, isUrl);
+//     if (!ptr.get()) {
+//         return Kolab::DistList();
+//     }
+//     return *ptr;
+    return DistList();
 }
 
 std::string writeDistlist(const DistList &list)
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 5af254a..0a46be7 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -22,15 +22,31 @@
 #include "kolabcontainers.h"
 #include "kolabtodo.h"
 #include "kolabevent.h"
+#include "kolabcontact.h"
 #include "global_definitions.h"
 
 namespace Kolab {
-    
+
+/**
+ * Check to see if serialization/deserialization was successful.
+ */
 Kolab::ErrorSeverity error();
 std::string errorMessage();
 
+/**
+ * Returns productId string of the last deserialized object.
+ * Updated during deserialization of object.
+ */
 std::string productId();
+/**
+ * Returns KolabFormat version of the last deserialized object.
+ * Updated during deserialization of object.
+ */
 std::string xKolabVersion();
+/**
+ * Returns KolabFormat version of the last deserialized xCal object.
+ * Updated during deserialization of object.
+ */
 std::string xCalVersion();
 
 Kolab::Event readEvent(const std::string& s, bool isUrl);
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index 2b9d54a..ce578ab 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -19,26 +19,58 @@
 #include <string>
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_io.hpp>
-#include <time.h>
 #include <boost/lexical_cast.hpp>
+#include <time.h>
 
 namespace Kolab {
+    
+namespace Utils {
+    
+std::string global_createdUID;
+std::string global_productId;
+std::string global_xKolabVersion;
+
+void setKolabVersion(const std::string &s)
+{
+    global_xKolabVersion = s;
+}
+
+std::string kolabVersion()
+{
+    return global_xKolabVersion;
+}
+
+void setProductId(const std::string &s)
+{
+    global_productId = s;
+}
 
-std::string getUID()
+std::string productId()
 {
-    boost::uuids::uuid u; // initialize uuid
-    return boost::uuids::to_string(u);
+    return global_productId;
 }
 
+
+void setCreatedUid(const std::string &s)
+{
+    global_createdUID = s;
+}
+
+std::string createdUid()
+{
+    return global_createdUID;
+}
+
+
 std::string getUID(const std::string &s)
 {
     if (s.empty()) {
-        return getUID();
+        boost::uuids::uuid u; // initialize uuid
+        return boost::uuids::to_string(u);
     }
     return s;
 }
 
-
 DateTime getCurrentTime()
 {
     time_t rawtime;
@@ -74,7 +106,6 @@ void logMessage(const std::string &m, ErrorSeverity s)
                 global_errorBit = Critical;
                 global_errorMessage = m;
             }
-            
     }
 }
 
@@ -99,5 +130,6 @@ std::string getErrorMessage()
     return global_errorMessage;
 }
 
+}
 
 }
\ No newline at end of file
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
index 886d181..29cacb7 100644
--- a/c++/lib/utils.h
+++ b/c++/lib/utils.h
@@ -21,11 +21,15 @@
 #include <string>
 #include "kolabcontainers.h"
 #include "global_definitions.h"
+#include <boost/numeric/conversion/cast.hpp>
 
 namespace Kolab {
 
-std::string getUID();
-std::string getUID(const std::string &);
+    namespace Utils {
+/**
+ * Returns a new globally unique UID if the parameter is empty
+ */
+std::string getUID(const std::string & = std::string());
 
 DateTime getCurrentTime();
 
@@ -42,6 +46,45 @@ void clearErrors();
 ErrorSeverity getError();
 std::string getErrorMessage();
 
+void setCreatedUid(const std::string &);
+std::string createdUid();
+void setProductId(const std::string &);
+std::string productId();
+void setKolabVersion(const std::string &);
+std::string kolabVersion();
+
+template <typename T>
+int convertToInt(T integer)
+{
+    try {
+        return boost::numeric_cast<int>(integer);
+    } catch(boost::numeric::negative_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::positive_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        ERROR(e.what());
+    }
+    return 0;
+}
+
+template <typename T> 
+T fromInt(int integer)
+{
+    try {
+        return boost::numeric_cast<T>(integer);
+    } catch(boost::numeric::negative_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::positive_overflow& e) {
+        ERROR(e.what());
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        ERROR(e.what());
+    }
+    return 0;
+}
+
+    }
+
 }
 
 #endif
\ No newline at end of file
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 74df6e3..d308c6a 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -43,8 +43,6 @@
 namespace Kolab {
     namespace XCAL {
         
-std::string global_productId;
-std::string global_xKolabVersion;
 std::string global_xCalVersion;
 
 const char* const XCAL_VERSION = "2.0";
@@ -99,37 +97,10 @@ const char* const SU = "SU";
 const char* const START = "START";
 const char* const END = "END";
 
+using namespace Kolab::Utils;
+
 //=== Generic Conversions ===
     
-template <typename T>
-int convertToInt(T integer)
-{
-    try {
-        return boost::numeric_cast<int>(integer);
-    } catch(boost::numeric::negative_overflow& e) {
-        logMessage(e.what(), Error);
-    } catch(boost::numeric::positive_overflow& e) {
-        logMessage(e.what(), Error);
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        logMessage(e.what(), Error);
-    }
-    return 0;
-}
-
-template <typename T> 
-T fromInt(int integer)
-{
-    try {
-        return boost::numeric_cast<T>(integer);
-    } catch(boost::numeric::negative_overflow& e) {
-        logMessage(e.what(), Error);
-    } catch(boost::numeric::positive_overflow& e) {
-        logMessage(e.what(), Error);
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        logMessage(e.what(), Error);
-    }
-    return 0;
-}
 
 int toInt(const icalendar_2_0::IntegerPropertyType &prop)
 {
@@ -218,7 +189,7 @@ Kolab::DayPos toDayPos(const std::string &s)
                     try {
                         occurrence = boost::lexical_cast<int>(number);
                     } catch(boost::bad_lexical_cast &) {
-                        logMessage("failed to convert: " + number, Error);
+                        ERROR("failed to convert: " + number);
                         return DayPos();
                     }
                     number.clear();
@@ -1589,6 +1560,7 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
         T::setComponents(eventComponents, incidence);
 
         typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
+        setCreatedUid(uid.text());
         typename KolabType::properties_type::dtstamp_type dtstamp;
         dtstamp.date_time(IC::dtstamp());
         typename KolabType::properties_type::created_type created;
@@ -1668,9 +1640,9 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
             incidences.push_back(e);
         }
         
-        global_productId = vcalendar.properties().prodid().text();
+        setProductId( vcalendar.properties().prodid().text() );
         global_xCalVersion = vcalendar.properties().version().text();
-        global_xKolabVersion = vcalendar.properties().x_kolab_version().text();
+        setKolabVersion( vcalendar.properties().x_kolab_version().text() );
 
 
         //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index d9443ed..938fdca 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -22,8 +22,11 @@
 #include "kolabcontainers.h"
 #include <XMLParserWrapper.h>
 #include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
 #include "global_definitions.h"
 #include "utils.h"
+#include "kolabcontact.h"
 
 namespace Kolab {
     namespace XCARD {
@@ -32,6 +35,8 @@ namespace Kolab {
     const char* const INDIVIDUAL = "individual";
     const char* const GROUP = "group";
     
+using namespace Kolab::Utils;
+    
 template <typename T> 
 std::string getType();
 
@@ -47,49 +52,420 @@ std::string getType<Kolab::DistList>()
     return GROUP;
 }
 
-template <typename T> 
-void writeCard(vcard_4_0::vcard vcard, const T &);
+template <typename T>
+xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input)
+{
+    xsd::cxx::tree::sequence<T> list;
+    BOOST_FOREACH(const std::string &s, input) {
+        list.push_back(T(s));
+    }
+    return list;
+}
 
-template <> 
-void writeCard<Kolab::Contact>(vcard_4_0::vcard vcard, const Kolab::Contact &contact)
+template <typename T>
+xsd::cxx::tree::sequence<T> fromList(const std::vector<std::string> &input, int preferredIndex)
 {
-    //TODO
+    xsd::cxx::tree::sequence<T> list;
+    int index = 0;
+    BOOST_FOREACH(const std::string &s, input) {
+        T im(s);
+        if(preferredIndex == index) {
+            typename T::parameters_type parameters;
+            parameters.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+            im.parameters(parameters);
+        }
+        index++;
+        list.push_back(im);
+    }
+    return list;
 }
 
-template <> 
-void writeCard<Kolab::DistList>(vcard_4_0::vcard vcard, const Kolab::DistList &distlist)
+template <typename T>
+std::vector<std::string> toUriList(const xsd::cxx::tree::sequence<T> &input)
 {
-    //TODO
+    std::vector<std::string> list;
+    BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, input) {
+        list.push_back(s.uri());
+    }
+    return list;
+}
+
+template <typename T>
+std::vector<std::string> toTextList(const xsd::cxx::tree::sequence<T> &input)
+{
+    std::vector<std::string> list;
+    BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, input) {
+        list.push_back(s.text());
+    }
+    return list;
+}
+
+std::vector<std::string> toStringList(const ::xsd::cxx::tree::sequence< ::xml_schema::string > &s)
+{
+    std::vector<std::string> d;
+    std::copy(s.begin(), s.end(), std::back_inserter(d));
+    return d;
 }
 
+::xsd::cxx::tree::sequence< ::xml_schema::string > fromStringList(const std::vector<std::string> &s)
+{
+    ::xsd::cxx::tree::sequence< ::xml_schema::string > d;
+    std::copy(s.begin(), s.end(), std::back_inserter(d));
+    return d;
+}
+
+std::string fromDate(const DateTime &dt)
+{
+    if (!dt.isDateOnly()) {
+        WARNING("fromDate called on date time value");
+    }
+    std::stringstream s;
+    s << dt.year() << dt.month() << dt.day();
+    return s.str();
+}
 
 std::string fromDateTime(const DateTime &dt)
 {
     std::stringstream s;
-    s << dt.year() << dt.month() << dt.day() << "T" << dt.hour() << dt.minute() << dt.second();
-    if (!dt.isUTC()) { //always UTC
-        std::cout << "Date is not UTC but it should be, UTC assumed." << std::endl;
+    s.fill('0');
+    s << std::right; 
+    s.width(4);
+    s << dt.year();
+    s.width(2);
+    s << dt.month();
+    s.width(2);
+    s << dt.day();
+    s.width(1);
+    if (dt.isDateOnly()) {
+        return s.str();
+    }
+    s << "T";
+    s.width(2);
+    s << dt.hour();
+    s.width(2);
+    s << dt.minute();
+    s.width(2);
+    s << dt.second();
+    if (dt.isUTC()) {
+        s << "Z";
     }
-    s << "Z";
     return s.str();
 }
 
+DateTime toDateTime(const std::string &input)
+{
+    int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
+    bool isUtc = false;
+    try {
+        year = boost::lexical_cast<int>(input.substr(0, 4));
+        month = boost::lexical_cast<int>(input.substr(4, 2));
+        day = boost::lexical_cast<int>(input.substr(6, 2));
+        if (input.size() >= 15) { //Minimum for time
+            if (input.at(8) != 'T') {
+                ERROR("Wrong demiliter");
+                return DateTime();
+            }
+            hour = boost::lexical_cast<int>(input.substr(9, 2));
+            minute = boost::lexical_cast<int>(input.substr(11, 2));
+            second = boost::lexical_cast<int>(input.substr(13, 2));
+        } else {
+            if (input.size() >= 9) {
+                ERROR("Invalid dt " + input);
+                return DateTime();
+            }
+            return DateTime(year, month, day);
+        }
+        if (input.size() >= 16) {
+            if (input.at(15) == 'Z') {
+                isUtc = true;
+            } else {
+                ERROR("wrong utc char? " + input.at(15));
+                return DateTime();
+            }
+        }
+    } catch (boost::bad_lexical_cast &c) {
+        ERROR("failed to convert: "+std::string(c.what()));
+        return DateTime();
+    } catch (...) {
+        ERROR("failed to convert: unkown exception");
+        return DateTime();
+    }
+    return DateTime(year, month, day, hour, minute, second, isUtc);
+}
+
+DateTime toDateTime(const vcard_4_0::DateDatetimePropertyType &prop)
+{
+    if (prop.date_time()) {
+        return toDateTime(*prop.date_time());
+    } else if (prop.date()) {
+        return toDateTime(*prop.date());
+    }
+    ERROR("no date and no datetime");
+    return DateTime();
+}
+
+template <typename T>
+T fromDateTime(const Kolab::DateTime &dt)
+{
+    T prop;
+
+    if (dt.isDateOnly()) {
+        prop.date(fromDate(dt));
+    } else {
+        prop.date_time(fromDateTime(dt));
+    }
+    return prop;
+}
+
+template <typename T> 
+void writeCard(vcard_4_0::vcard &vcard, const T &);
+
+template <> 
+void writeCard<Kolab::Contact>(vcard_4_0::vcard &vcard, const Kolab::Contact &contact)
+{
+    using namespace vcard_4_0;
+    
+    if (contact.nameComponents().isValid()) {
+        const NameComponents &nc = contact.nameComponents();
+        vcard::n_type n;
+        n.surname(fromStringList(nc.surnames()));
+        n.given(fromStringList(nc.given()));
+        n.additional(fromStringList(nc.additional()));
+        n.prefix(fromStringList(nc.prefixes()));
+        n.suffix(fromStringList(nc.suffixes()));
+        vcard.n(n);
+    }
+    
+    if (!contact.note().empty()) {
+        vcard.note(vcard::note_type(contact.note()));
+    }
+    
+    if (!contact.freeBusyUrl().empty()) {
+        vcard.fburl(vcard::fburl_type(contact.freeBusyUrl()));
+    }
+    
+    if (!contact.affiliations().empty()) {
+        vcard::group_sequence affiliations;
+        BOOST_FOREACH(const Affiliation &a, contact.affiliations()) {
+            std::string encodedLogo = a.logo();//TODO encode logo
+            affiliationPropType::org_type org;
+            org.text().push_back(a.organisation());
+            vcard::group_type group(org, affiliationPropType::logo_type(encodedLogo));
+            group.title(fromList<affiliationPropType::title_type >(a.titles()));
+            group.role(fromList<affiliationPropType::role_type>(a.roles()));
+            group.x_manager(fromList<affiliationPropType::x_manager_type>(a.managers()));
+            group.x_assistant(fromList<affiliationPropType::x_assistant_type >(a.assistants()));
+            group.x_office(fromList<affiliationPropType::x_office_type>(a.offices()));
+            affiliations.push_back(group);
+        }
+        vcard.group(affiliations);
+    }
+    
+    if (!contact.urls().empty()) {
+        vcard.url(fromList<vcard::url_type>(contact.urls()));
+    }
+    
+    if (!contact.addresses().empty()) {
+        vcard::adr_sequence adrs;
+        int index = 0;
+        BOOST_FOREACH(const Kolab::Address &address, contact.addresses()) {
+            index++;
+            vcard::adr_type a(vcard::adr_type::pobox_type(std::string()/*address.pobox()*/), 
+                            vcard::adr_type::ext_type(std::string()/*address.ext()*/),
+                            vcard::adr_type::street_type(address.street()),
+                            vcard::adr_type::locality_type(address.locality()),
+                            vcard::adr_type::region_type(address.region()),
+                            address.code(),
+                            vcard::adr_type::country_type(address.country())
+            );
+            vcard::adr_type::parameters_type::baseParameter_sequence base;
+            vcard::adr_type::parameters_type b;
+            if (address.types()) {
+                vcard_4_0::typeParamType::text_sequence seq;
+                if (address.types() & Kolab::Address::Home) {
+                    seq.push_back(TypeValueType::home);
+                }
+                if (address.types() & Kolab::Address::Work) {
+                    seq.push_back(TypeValueType::work);
+                }
+                if (!seq.empty()) {
+                    vcard_4_0::typeParamType type;
+                    type.text(seq);
+                    b.baseParameter().push_back(type);
+                }
+            }
+            if (!address.label().empty()) {
+                b.baseParameter().push_back(vcard_4_0::labelParamType(address.label()));
+            }
+            if(contact.addressPreferredIndex() == index) {
+                b.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+            }
+            index++;
+            a.parameters(b);
+            adrs.push_back(a);
+        }
+        vcard.adr(adrs);
+    }
+    
+    if (!contact.nickNames().empty()) {
+        vcard::nickname_type::text_sequence textsequence;
+        BOOST_FOREACH(const std::string &s, contact.nickNames()) {
+            textsequence.push_back(s);
+        }
+        vcard::nickname_type nickName;
+        nickName.text(textsequence);
+        vcard.nickname(nickName);
+    }
+    
+    if (!contact.relateds().empty()) {
+        vcard::related_sequence seq;
+//         BOOST_FOREACH(const std::string &s, contact.urls()) {
+//             urls.push_back(vcard::url_type(s));
+//         }
+        //TODO
+        vcard.related(seq);
+    }
+    
+    if (contact.bDay().isValid()) {
+        Kolab::DateTime dt = contact.bDay();
+        if (dt.isUTC() || !dt.timezone().empty()) {
+            WARNING("Must be local time, local time assumed");
+            dt.setUTC(false);
+        }
+        vcard.bday(fromDateTime<vcard::bday_type>(dt));
+    }
+    
+    if (contact.anniversary().isValid()) {
+        Kolab::DateTime dt = contact.anniversary();
+        if (dt.isUTC() || !dt.timezone().empty()) {
+            WARNING("Must be local time, local time assumed");
+            dt.setUTC(false);
+        }
+        vcard.anniversary(fromDateTime<vcard::anniversary_type>(dt));
+    }
+    
+    if (!contact.photo().empty()) {
+        vcard::photo_type photo(vcard_4_0::UriPropertyType::uri_type(contact.photo()));
+        //TODO photo inline encoding
+        vcard.photo(photo);
+    }
+    
+    if (contact.gender() != Contact::NotSet) {
+        switch (contact.gender()) {
+            case Contact::NotSpecified:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::empty));
+                break;
+            case Contact::Male:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::M));
+                break;
+            case Contact::Female:
+                vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::F));
+                break;
+            default:
+                ERROR("Unhandled gender");
+        }
+    }
+    
+    if (!contact.languages().empty()) {
+        vcard.lang(fromList<vcard::lang_type>(contact.languages()));
+    }
+    
+    if (!contact.telephones().empty()) {
+        vcard::tel_sequence seq;
+        int index = 0;
+        BOOST_FOREACH(const Kolab::Telephone &t, contact.telephones()) {
+            vcard::tel_type tel(t.number());
+            vcard_4_0::typeParamType telTypeParam;
+            if (t.types() & Kolab::Telephone::Car) {
+                telTypeParam.text().push_back(TypeValueType::x_car);
+            } 
+            if (t.types() & Kolab::Telephone::Cell) {
+                telTypeParam.text().push_back(TypeValueType::cell);
+            } 
+            if (t.types() & Kolab::Telephone::Fax) {
+                telTypeParam.text().push_back(TypeValueType::fax);
+            } 
+            if (t.types() & Kolab::Telephone::Home) {
+                telTypeParam.text().push_back(TypeValueType::home);
+            } 
+            if (t.types() & Kolab::Telephone::Work) {
+                telTypeParam.text().push_back(TypeValueType::work);
+            } 
+            if (t.types() & Kolab::Telephone::Text) {
+                telTypeParam.text().push_back(TypeValueType::text);
+            } 
+            if (t.types() & Kolab::Telephone::Voice) {
+                telTypeParam.text().push_back(TypeValueType::voice);
+            } 
+            if (t.types() & Kolab::Telephone::Video) {
+                telTypeParam.text().push_back(TypeValueType::video);
+            } 
+            if (t.types() & Kolab::Telephone::Textphone) {
+                telTypeParam.text().push_back(TypeValueType::textphone);
+            } 
+            if (t.types() & Kolab::Telephone::Pager) {
+                telTypeParam.text().push_back(TypeValueType::pager);
+            }
+            vcard::tel_type::parameters_type params;
+            if(contact.telephonesPreferredIndex() == index) {
+                params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value()));
+            }
+            index++;
+
+            if (!telTypeParam.text().empty()) {
+                params.baseParameter().push_back(telTypeParam);
+                tel.parameters(params);
+            }
+            seq.push_back(tel);
+        }
+        vcard.tel(seq);
+    }
+    
+    if (!contact.imAddresses().empty()) {
+        vcard.impp(fromList<vcard::impp_type>(contact.imAddresses(), contact.imAddressPreferredIndex()));
+    }
+    
+    if (!contact.emailAddresses().empty()) {
+        vcard.email(fromList<vcard::email_type>(contact.emailAddresses(), contact.emailAddressPreferredIndex()));
+    }
+    
+    if (!contact.gpsPos().empty()) {
+        //TODO
+    }
+    
+//     if (!contact.crypto().isValid()) {
+//         //TODO
+//     }
+
+
+}
+
+template <> 
+void writeCard<Kolab::DistList>(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist)
+{
+    //TODO
+}
+
+
 
 template <typename T>
 std::string serializeCard(const T &card, const std::string prod = std::string()) {
 
     using namespace vcard_4_0;
+    
+    clearErrors();
 
     try {
         vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
+        setCreatedUid(uid.uri());
         vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
-        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME);
+        vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
         vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
         vcard_4_0::vcard::kind_type kind(getType<T>());
-        vcard_4_0::vcard::fn_type fn(card.fn());
-        
-        
+        vcard_4_0::vcard::fn_type fn(card.name());
+
         vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn);
+        //TODO custom properties
         writeCard<T>(vcard, card);
         
         VcardsType vcards(vcard);
@@ -101,9 +477,9 @@ std::string serializeCard(const T &card, const std::string prod = std::string())
         vcard_4_0::vcards(ostringstream, vcards, map);
         return ostringstream.str();
     } catch  (const xml_schema::exception& e) {
-        std::cerr << "failed to write Contact";
-        return std::string();
-    } 
+        CRITICAL("Unknown Exception: failed to write Contact");
+    }
+    return std::string();
 }
 
 template <typename T>
@@ -112,20 +488,236 @@ boost::shared_ptr<T> readCard(const vcard_4_0::VcardsType::vcard_type &vcard);
 template <>
 boost::shared_ptr<Kolab::Contact> readCard <Kolab::Contact> (const vcard_4_0::VcardsType::vcard_type &vcard)
 {
-    //TODO
-    return boost::shared_ptr<Kolab::Contact>();
+    using namespace vcard_4_0;
+    boost::shared_ptr<Kolab::Contact> contact(new Kolab::Contact);
+    if (vcard.n()) {
+        NameComponents nc;
+        nc.setSurnames(toStringList((*vcard.n()).surname()));
+        nc.setGiven(toStringList((*vcard.n()).given()));
+        nc.setPrefixes(toStringList((*vcard.n()).prefix()));
+        nc.setSuffixes(toStringList((*vcard.n()).suffix()));
+        nc.setAdditional(toStringList((*vcard.n()).additional()));
+        contact->setNameComponents(nc);
+    }
+    if (vcard.note()) {
+        contact->setNote((*vcard.note()).text());
+    }
+    if (vcard.fburl()) {
+        contact->setFreeBusyUrl((*vcard.fburl()).uri());
+    }
+    if (!vcard.group().empty()) {
+        std::vector<Kolab::Affiliation> list;
+        BOOST_FOREACH (const vcard::group_type &group, vcard.group()) {
+            Kolab::Affiliation aff;
+            std::string org;
+            if (!group.org().text().empty()) {
+                org = *group.org().text().begin();
+            } else {
+                WARNING("No org present");
+            }
+            aff.setOrganisation(org);
+            aff.setLogo(group.logo().uri());
+            aff.setTitles(toTextList<vcard::group_type::title_type>(group.title()));
+            aff.setRoles(toTextList<vcard::group_type::role_type>(group.role()));
+            aff.setManagers(toTextList<vcard::group_type::x_manager_type>(group.x_manager()));
+            aff.setAssistants(toTextList<vcard::group_type::x_assistant_type>(group.x_assistant()));
+            aff.setOffices(toTextList<vcard::group_type::x_office_type>(group.x_office()));
+            list.push_back(aff);
+        }
+        contact->setAffiliations(list);
+    }
+    if (!vcard.url().empty()) {
+        contact->setUrls(toUriList<vcard::url_type >(vcard.url()));
+    }
+    if (!vcard.adr().empty()) {
+        std::vector<Kolab::Address> list;
+        int preferredIndex = -1;
+        int index = 0;
+        BOOST_FOREACH(const vcard::adr_type &adr, vcard.adr()) {
+            Kolab::Address address;
+            if (adr.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*adr.parameters()).baseParameter()) {
+                    if (const vcard_4_0::labelParamType *rel = dynamic_cast<const vcard_4_0::labelParamType*> (&param)) {
+                        address.setLabel(rel->text());
+                    } else if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = index;
+                    } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                        int types = 0;
+                        BOOST_FOREACH(const std::string &s, rel->text()) {
+                            if (s == TypeValueType(TypeValueType::work)) {
+                                types |= Kolab::Telephone::Work;
+                            }
+                            if (s == TypeValueType(TypeValueType::home)) {
+                                types |= Kolab::Telephone::Home;
+                            }
+                        }
+                        address.setTypes(types);
+                    } 
+                }
+            }
+            index++;
+
+            address.setCode(adr.code());
+            address.setCountry(adr.country());
+            address.setLocality(adr.locality());
+            address.setRegion(adr.region());
+            address.setStreet(adr.street());
+            list.push_back(address);
+        }
+        contact->setAddresses(list, preferredIndex);
+    }
+    if (vcard.nickname()) {
+        contact->setNickNames(toTextList<TextListPropertyType::text_type>((*vcard.nickname()).text()));
+    }
+    if (!vcard.related().empty()) {
+//         std::vector<Related> list;
+//         BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) {
+//             list.push_back(l.language_tag());
+//         }
+//         contact->setRelateds();
+        //TODO
+    }
+    if (vcard.bday()) {
+        contact->setBDay(toDateTime(*vcard.bday()));
+    }
+    if (vcard.anniversary()) {
+        contact->setAnniversary(toDateTime(*vcard.anniversary()));
+    }
+    if (vcard.photo()) {
+        const std::string decodedPhoto =  (*vcard.photo()).uri(); //TODO decode photo
+        const std::string mimetype;
+        contact->setPhoto(decodedPhoto, mimetype);
+    }
+    if (vcard.gender()) {
+        if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::empty) {
+            contact->setGender(Kolab::Contact::NotSpecified);
+        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::M) {
+            contact->setGender(Kolab::Contact::Male);
+        } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::F) {
+            contact->setGender(Kolab::Contact::Female);
+        }
+    }
+    if (!vcard.lang().empty()) {
+        std::vector<std::string> list;
+        BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) {
+            list.push_back(l.language_tag());
+        }
+        contact->setLanguages(list);
+    }
+    if (!vcard.tel().empty()) {
+        std::vector<Kolab::Telephone> list;
+        int preferredIndex = -1;
+        int index = 0;
+        BOOST_FOREACH(const vcard::tel_type &tel, vcard.tel()) {
+            Kolab::Telephone telephone;
+            if (tel.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*tel.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = index;
+                    } else if (const vcard_4_0::typeParamType *rel = dynamic_cast<const vcard_4_0::typeParamType*> (&param)) {
+                        int types = 0;
+                        BOOST_FOREACH(const std::string &s, rel->text()) {
+                            if (s == TypeValueType(TypeValueType::work)) {
+                                types |= Kolab::Telephone::Work;
+                            }
+                            if (s == TypeValueType(TypeValueType::home)) {
+                                types |= Kolab::Telephone::Home;
+                            }
+                            if (s == TypeValueType(TypeValueType::text)) {
+                                types |= Kolab::Telephone::Text;
+                            }
+                            if (s == TypeValueType(TypeValueType::voice)) {
+                                types |= Kolab::Telephone::Voice;
+                            }
+                            if (s == TypeValueType(TypeValueType::fax)) {
+                                types |= Kolab::Telephone::Fax;
+                            }
+                            if (s == TypeValueType(TypeValueType::cell)) {
+                                types |= Kolab::Telephone::Cell;
+                            }
+                            if (s == TypeValueType(TypeValueType::video)) {
+                                types |= Kolab::Telephone::Video;
+                            }
+                            if (s == TypeValueType(TypeValueType::pager)) {
+                                types |= Kolab::Telephone::Pager;
+                            }
+                            if (s == TypeValueType(TypeValueType::textphone)) {
+                                types |= Kolab::Telephone::Textphone;
+                            }
+                            if (s == TypeValueType(TypeValueType::x_car)) {
+                                types |= Kolab::Telephone::Car;
+                            }
+                        }
+                        telephone.setTypes(types);
+                    } 
+                }
+            }
+            index++;
+
+            telephone.setNumber(tel.text());
+            list.push_back(telephone);
+        }
+        contact->setTelephones(list, preferredIndex);
+    }
+    
+    if (!vcard.impp().empty()) {
+        int preferredIndex = -1;
+        
+        std::vector<std::string> list;
+        int i = 0;
+        BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, vcard.impp()) {
+            if (s.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = i;
+                    } 
+                }
+            }
+            i++;
+            list.push_back(s.uri());
+        }
+        
+        contact->setIMaddresses(list, preferredIndex);
+    }
+    if (!vcard.email().empty()) {
+        int preferredIndex = -1;
+        
+        std::vector<std::string> list;
+        int i = 0;
+        BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, vcard.email()) {
+            if (s.parameters()) {
+                BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type &param, (*s.parameters()).baseParameter()) {
+                    if (dynamic_cast<const vcard_4_0::prefParamType*> (&param)) {
+                        preferredIndex = i;
+                    } 
+                }
+            }
+            i++;
+            list.push_back(s.text());
+        }
+        
+        contact->setEmailAddresses(list, preferredIndex);
+    }
+    if (!vcard.geo().empty()) {
+        //TODO Geo
+    }
+    if (!vcard.x_crypto().empty()) {
+        //TODO Crypto
+    }
+    return contact;
 }
 
 template <>
 boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::VcardsType::vcard_type &vcard)
 {
-    //TODO
+    //TODO DistList
     return boost::shared_ptr<Kolab::DistList>();
 }
 
 template <typename T>
 boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
 {
+    clearErrors();
     try {
         std::auto_ptr<vcard_4_0::VcardsType> vcards;
         if (isUrl) {
@@ -139,15 +731,24 @@ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
                 vcards = vcard_4_0::vcards(doc);
             }
         }
-        
+
         if (!vcards.get()) {
-            std::cerr << "failed to parse card!" << std::endl;
+            CRITICAL("failed to parse card!");
             return boost::shared_ptr<T>();
         }
-        return readCard<T>(vcards->vcard());
+        
+        boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
+        card->setName(vcards->vcard().fn().text());
+        
+        setProductId( vcards->vcard().prodid().text() );
+//         setFormatVersion( vcards->vcard().version().text() );
+//         global_xCarVersion = vcalendar.properties().version().text();
+        setKolabVersion( vcards->vcard().x_kolab_version().text() );
+        
+        return card;
     } catch  (const xml_schema::exception& e) {
         std::cerr <<  e << std::endl;
-        std::cerr <<  "Failed to read card!" << std::endl;
+        CRITICAL("Failed to read card!");
     }
 
     return boost::shared_ptr<T>();
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 3fa7703..ed7d906 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -150,7 +150,6 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(r1.bysecond(), r2.bysecond());
     QCOMPARE(r1.byminute(), r2.byminute());
     QCOMPARE(r1.byhour(), r2.byhour());
-//     QEXPECT_FAIL("", "Implement Day parser", Continue);
     QCOMPARE(r1.byday(), r2.byday());
     QCOMPARE(r1.bymonthday(), r2.bymonthday());
     QCOMPARE(r1.byyearday(), r2.byyearday());
@@ -185,13 +184,12 @@ void BindingsTest::eventCompletness()
     ev.setTransparency(true);
     
     std::string result = Kolab::writeEvent(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
 //     std::cout << result << endl;
     Kolab::Event e = Kolab::readEvent(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
     checkIncidence(ev, e);
     QCOMPARE(ev.end(), e.end());
-//     QEXPECT_FAIL("", "Will fix in the next release", Continue);
-//     QVERIFY(ev.duration().isValid());
-//     QCOMPARE(ev.duration(), re.duration());
     QCOMPARE(ev.transparency(), e.transparency());
     
 }
@@ -202,8 +200,10 @@ void BindingsTest::eventDuration()
     ev.setDuration(Kolab::Duration(11,22,33,44, true));
 
     const std::string result = Kolab::writeEvent(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
 //     std::cout << result << endl;
     const Kolab::Event e = Kolab::readEvent(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
     QVERIFY(ev.duration().isValid());
     QCOMPARE(ev.duration(), e.duration());
 }
@@ -218,14 +218,117 @@ void BindingsTest::todoCompletness()
     ev.setPercentComplete(50);
     
     std::string result = Kolab::writeTodo(ev);
-//     std::cout << result << endl;
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    std::cout << result << endl;
     Kolab::Todo e = Kolab::readTodo(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
     checkIncidence(ev, e);
     QCOMPARE(ev.due(), e.due());
     QCOMPARE(ev.relatedTo(), e.relatedTo());
     QCOMPARE(ev.percentComplete(), e.percentComplete());
 }
 
+void BindingsTest::contactCompletness()
+{
+    std::vector<std::string> stringlist;
+    stringlist.push_back("lbksdfbklsd");
+    stringlist.push_back("sdf");
+
+    Kolab::Contact c;
+    c.setName("name");
+    Kolab::NameComponents nc;
+    nc.setSurnames(stringlist);
+    nc.setGiven(stringlist);
+    nc.setAdditional(stringlist);
+    nc.setPrefixes(stringlist);
+    nc.setSuffixes(stringlist);
+    c.setNameComponents(nc);
+    c.setNote("note");
+    c.setFreeBusyUrl("freebusy");
+    c.setUrls(stringlist);
+    c.setNickNames(stringlist);
+    c.setBDay(Kolab::DateTime(2001,12,10,12,12,12,false));
+    c.setAnniversary(Kolab::DateTime(2001,3,2,1,1,1,false));
+    c.setPhoto("photo", "mimetype");
+    c.setGender(Kolab::Contact::Male);
+    c.setLanguages(stringlist);
+    c.setIMaddresses(stringlist,1);
+    c.setEmailAddresses(stringlist,1);
+    std::vector<Kolab::Affiliation> list;
+    Kolab::Affiliation aff;
+    aff.setOrganisation("org");
+    aff.setLogo("logo");
+    aff.setTitles(stringlist);
+    aff.setRoles(stringlist);
+    aff.setManagers(stringlist);
+    aff.setAssistants(stringlist);
+    aff.setOffices(stringlist);
+    list.push_back(aff);
+    list.push_back(aff);
+    c.setAffiliations(list);
+    Kolab::Address address;
+    address.setCode("oiuoiu");
+    address.setCountry("werwer");
+    address.setLabel("lkjlkj");
+    address.setLocality("alla");
+    address.setRegion("skjdfkd");
+    address.setStreet("sldkflsdfj");
+    address.setTypes( Kolab::Address::Work | Kolab::Address::Home );
+    std::vector<Kolab::Address> addresses;
+    addresses.push_back(address);
+    addresses.push_back(address);
+    c.setAddresses(addresses);
+    Kolab::Telephone phone;
+    phone.setNumber("lkjsdflkjfds");
+    phone.setTypes(Kolab::Telephone::Work|
+                    Kolab::Telephone::Home|
+                    Kolab::Telephone::Text|
+                    Kolab::Telephone::Voice|
+                    Kolab::Telephone::Fax|
+                    Kolab::Telephone::Cell|
+                    Kolab::Telephone::Video|
+                    Kolab::Telephone::Pager|
+                    Kolab::Telephone::Textphone|
+                    Kolab::Telephone::Car
+    );
+
+    std::vector<Kolab::Telephone> telephones;
+    telephones.push_back(phone);
+    telephones.push_back(phone);
+    c.setTelephones(telephones, 1);
+    c.setPhoto("photo", "mimetype");
+    
+//     c.setGPSpos(stringlist,1);
+    
+    const std::string result = Kolab::writeContact(c);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    std::cout << result << endl;
+    Kolab::Contact e = Kolab::readContact(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    QCOMPARE(e.name(), c.name());
+    QCOMPARE(e.nameComponents(), c.nameComponents());
+    QCOMPARE(e.note(), c.note());
+    QCOMPARE(e.freeBusyUrl(), c.freeBusyUrl());
+    QCOMPARE(e.urls(), c.urls());
+    QCOMPARE(e.nickNames(), c.nickNames());
+    QCOMPARE(e.bDay(), c.bDay());
+    QCOMPARE(e.anniversary(), c.anniversary());
+    QCOMPARE(e.languages(), c.languages());
+    QCOMPARE(e.gender(), c.gender());
+    QCOMPARE(e.affiliations(), c.affiliations());
+    QCOMPARE(e.photo(), c.photo());
+//     QCOMPARE(e.photoMimetype(), c.photoMimetype());
+    QCOMPARE(e.addresses(), c.addresses());
+    QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex());
+
+    QCOMPARE(e.telephones(), c.telephones());
+    QCOMPARE(e.telephonesPreferredIndex(), c.telephonesPreferredIndex());
+    QCOMPARE(e.emailAddresses(), c.emailAddresses());
+    QCOMPARE(e.emailAddressPreferredIndex(), c.emailAddressPreferredIndex());
+
+
+}
+
 void BindingsTest::versionTest()
 {
     Kolab::Todo ev;
@@ -242,7 +345,7 @@ void BindingsTest::errorTest()
 {
     Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
     QCOMPARE(Kolab::error(), Kolab::Critical);
-    QCOMPARE(Kolab::errorMessage(), std::string("/home/chrigi/work/kolab/xmlformat/libkolabxml/c++/lib/xcalconversions.h 1657:   Failed to parse calendar!"));
+    QVERIFY(!Kolab::errorMessage().empty());
 }
 
 //Don't break due to an error
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 674d201..3abaac5 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -25,6 +25,8 @@ class BindingsTest : public QObject
     void eventCompletness();
     void eventDuration();
     void todoCompletness();
+    
+    void contactCompletness();
 
     void versionTest();
     void errorTest();
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
index 5fe8f5e..ef3998c 100644
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@ -2,11 +2,13 @@
 
 #include <QtTest/QtTest>
 #include <lib/xcalconversions.h>
+#include <lib/xcardconversions.h>
 
 #include "serializers.h"
 
 Q_DECLARE_METATYPE(Kolab::Duration);
 Q_DECLARE_METATYPE(Kolab::DayPos);
+Q_DECLARE_METATYPE(Kolab::DateTime);
 
 using namespace Kolab::XCAL;
  
@@ -36,8 +38,8 @@ void ConversionTest::durationSerializerTest_data()
 
     QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false);
     QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false);
-    QTest::newRow("Week") << "P1W" << Kolab::Duration(1, false);
-    QTest::newRow("Week") << "-P3W" << Kolab::Duration(3, false);
+    QTest::newRow("Week positive") << "P1W" << Kolab::Duration(1, false);
+    QTest::newRow("Week negative") << "-P3W" << Kolab::Duration(3, true);
     QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true);
 }
 
@@ -59,7 +61,6 @@ void ConversionTest::dayPosParserTest_data()
     QTest::newRow("positive with +") << Kolab::DayPos(15, Kolab::Wednesday) << "+15WE";
     QTest::newRow("negative") << Kolab::DayPos(-15, Kolab::Wednesday) << "-15WE";
     QTest::newRow("all occurrences") << Kolab::DayPos(0, Kolab::Wednesday) << "WE";
-
 }
 
 void ConversionTest::dayPosParserTest()
@@ -89,6 +90,46 @@ void ConversionTest::dayPosSerializerTest()
     QCOMPARE(QString::fromStdString(result), expected);
 }
 
+void ConversionTest::xcardDateParserTest_data()
+{
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<Kolab::DateTime>("expected");
+
+    QTest::newRow("datetime local") << "20010102T030405" << Kolab::DateTime(2001, 01, 02, 03, 04 ,05, false);
+    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::DateTime(2001, 01, 02, 03, 04 ,05, true);
+    QTest::newRow("date only") << "20010102" << Kolab::DateTime(2001, 01, 02);
+    QTest::newRow("fail 1 short") << "20010102T03040" << Kolab::DateTime();
+    QTest::newRow("fail non utc") << "20010102T030401s" << Kolab::DateTime();
+    QTest::newRow("fail no time") << "20010102T" << Kolab::DateTime();
+}
+
+
+void ConversionTest::xcardDateParserTest()
+{
+    QFETCH(QString, input);
+    QFETCH(Kolab::DateTime, expected);
+    const Kolab::DateTime &dt = Kolab::XCARD::toDateTime(input.toStdString());
+    QCOMPARE(dt, expected);
+}
+
+void ConversionTest::xCardSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::DateTime>("dt");
+
+    QTest::newRow("datetime local") << "20010102T030405" << Kolab::DateTime(2001, 01, 02, 03, 04 ,05, false);
+    QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::DateTime(2001, 01, 02, 03, 04 ,05, true);
+    QTest::newRow("dateonly") << "20010102" << Kolab::DateTime(2001, 01, 02);
+}
+
+void ConversionTest::xCardSerializerTest()
+{
+    QFETCH(QString, expected);
+    QFETCH(Kolab::DateTime, dt);
+    const std::string &s = Kolab::XCARD::fromDateTime(dt);
+    QCOMPARE(QString::fromStdString(s), expected);
+}
+
 
 QTEST_MAIN( ConversionTest )
 
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
index 8672b99..91fe618 100644
--- a/c++/tests/conversiontest.h
+++ b/c++/tests/conversiontest.h
@@ -20,6 +20,12 @@ class ConversionTest : public QObject
     
     void dayPosSerializerTest_data();
     void dayPosSerializerTest();
+    
+    void xcardDateParserTest_data();
+    void xcardDateParserTest();
+    
+    void xCardSerializerTest_data();
+    void xCardSerializerTest();
 };
 
 #endif // CONVERSIONTEST_H
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
index 8548b62..c7f67d7 100644
--- a/c++/tests/serializers.h
+++ b/c++/tests/serializers.h
@@ -142,6 +142,28 @@ namespace QTest {
         ba += ")";
         return qstrdup(ba.data());
     }
+    
+    template<>
+    char *toString(const Kolab::Affiliation &a)
+    {
+        QByteArray ba = "Kolab::Affiliation(";
+        ba += QString::fromStdString(a.organisation()).toAscii()+ ", " + 
+        QString::fromStdString(a.logo()).toAscii()+", " +toString(a.titles()) + ", " + toString(a.roles())+  ", " + toString(a.managers()) +
+        + toString(a.assistants())  + ", " + toString(a.offices());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+        template<>
+    char *toString(const std::vector<Kolab::Affiliation> &v)
+    {
+        QByteArray ba = "vector<Kolab::Affiliation>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
 
  }
  
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
index a7c4e9a..a9ae046 100644
--- a/schemas/kolabformat-xcard.xsd
+++ b/schemas/kolabformat-xcard.xsd
@@ -43,8 +43,25 @@
                         <xs:element name="kind" type="kindPropType"/>
                         <xs:element name="fn" type="fnPropType"/>
                         <xs:element name="n" type="nPropType" minOccurs="0"/>
-                        <xs:element name="member" type="memberPropType" minOccurs="0"/>
-                        <xs:element name="x-custom" type="uidPropType" minOccurs="0"/>
+                        <xs:element name="note" type="notePropType" minOccurs="0"/>
+                        <xs:element name="fburl" type="fburlPropType" minOccurs="0"/>
+                        <xs:element name="group" type="affiliationPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="url" type="urlPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="adr" type="adrPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="nickname" type="nicknamePropType" minOccurs="0"/>
+                        <xs:element name="related" type="relatedPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="bday" type="bdayPropType" minOccurs="0"/>
+                        <xs:element name="anniversary" type="anniversaryPropType" minOccurs="0"/>
+                        <xs:element name="photo" type="photoPropType" minOccurs="0"/>
+                        <xs:element name="gender" type="genderPropType" minOccurs="0"/>
+                        <xs:element name="lang" type="langPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="tel" type="telPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="impp" type="imppPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="email" type="emailPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="geo" type="geoPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="x-crypto" type="cryptoPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="member" type="memberPropType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="x-custom" type="CustomType" minOccurs="0" maxOccurs="unbounded"/>
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index ad6d723..29d8f56 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -29,25 +29,78 @@
       <xs:pattern value="\d{8}T\d{6}(Z|[+\-]\d\d(\d\d)?)?"/>
     </xs:restriction>
   </xs:simpleType>
-  <xs:element name="timestamp" type="xcard:DateTimeType"/>
+  <xs:element name="timestamp" type="xcard:TimeStampType"/>
 
 <!-- Parameters -->
 
   <xs:complexType name="BaseParameterType" abstract="true"/>
-  
   <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
-  
   <xs:complexType name="ArrayOfParameters">
       <xs:sequence>
           <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
   </xs:complexType>
+  
+  <xs:complexType name="TextParameterType" mixed="false">
+      <xs:complexContent>
+          <xs:extension base="xcard:BaseParameterType">
+              <xs:sequence>
+                 <xs:element ref="xcard:text"/>
+              </xs:sequence>
+          </xs:extension>
+      </xs:complexContent>
+  </xs:complexType>
+  
+    <!-- WARNING: don't forget to add those, otherwise the serialization code will not be built and you're up for a long debugging session       -->
+    <xs:element name="type" type="xcard:typeParamType" substitutionGroup="xcard:baseParameter"/>
+    <xs:element name="label" type="xcard:labelParamType" substitutionGroup="xcard:baseParameter"/>
+    <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
+  
+    <xs:simpleType name="TypeValueType">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="work"/>
+            <xs:enumeration value="home"/>
+            <xs:enumeration value="text"/>
+            <xs:enumeration value="voice"/>
+            <xs:enumeration value="fax"/>
+            <xs:enumeration value="cell"/>
+            <xs:enumeration value="video"/>
+            <xs:enumeration value="pager"/>
+            <xs:enumeration value="textphone"/>
+            <xs:enumeration value="x-car"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:complexType name="typeParamType" mixed="false">
+        <xs:complexContent>
+            <xs:extension base="xcard:BaseParameterType">
+                <xs:sequence>
+                    <xs:element name="text" type="xcard:TypeValueType" minOccurs="1" maxOccurs="unbounded" />
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:complexType name="labelParamType" mixed="false">
+        <xs:complexContent>
+            <xs:extension base="xcard:TextParameterType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:complexType name="prefParamType" mixed="false">
+      <xs:complexContent>
+        <xs:extension base="xcard:BaseParameterType">            
+          <xs:sequence>
+            <xs:element name="integer" type="xs:string" fixed="1" />
+          </xs:sequence>
+        </xs:extension>
+      </xs:complexContent>    
+    </xs:complexType>
 
 <!-- Properties -->
   <xs:complexType name="BasePropertyType" abstract="true" >
     <xs:sequence>
-      <xs:element ref="xcard:parameters" 
-                  minOccurs="0" />
+      <xs:element ref="xcard:parameters" minOccurs="0" />
     </xs:sequence>
   </xs:complexType>
   
@@ -77,6 +130,26 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <xs:complexType name="TextListPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:text" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="NonEmptyTextListPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcard:text" minOccurs="1" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
   <xs:complexType name="UriPropertyType" >
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:BasePropertyType">
@@ -87,6 +160,19 @@
     </xs:complexContent>
   </xs:complexType>
   
+  <xs:complexType name="TextOrUriPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:choice>
+            <xs:element ref="xcard:text"/>
+            <xs:element ref="xcard:uri"/>
+          </xs:choice>
+        </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">
@@ -103,19 +189,12 @@
   
   <!-- Properties -->
   
-  <xs:complexType name="memberPropType">
-    <xs:complexContent mixed="false">
-      <xs:extension base="xcard:TextPropertyType"/>
-    </xs:complexContent>
-  </xs:complexType>
-  
   <xs:complexType name="kindPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:TextPropertyType"/>
     </xs:complexContent>
   </xs:complexType>
   
-  
   <xs:complexType name="revPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:BasePropertyType">
@@ -140,7 +219,7 @@
   
   <xs:complexType name="uidPropType">
     <xs:complexContent mixed="false">
-      <xs:extension base="xcard:UriPropertyType"/>
+      <xs:extension base="xcard:UriPropertyType"/> <!--TODO not text?-->
     </xs:complexContent>
   </xs:complexType>
   
@@ -157,12 +236,151 @@
       </xs:extension>   
     </xs:complexContent>
   </xs:complexType>
+  
+  <xs:complexType name="notePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="fburlPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="affiliationPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element name="org" type="xcard:NonEmptyTextListPropertyType" />
+          <xs:element name="logo" type="xcard:UriPropertyType" />
+          <xs:element name="title" type="xcard:TextPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <xs:element name="role" type="xcard:TextPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <xs:element name="x-manager" type="xcard:TextPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <xs:element name="x-assistant" type="xcard:TextPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <xs:element name="x-office" type="xcard:TextPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:string" fixed="Affiliation" />
+      </xs:extension>   
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="urlPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
 
+  <xs:complexType name="adrPropType">
+    <xs:complexContent mixed="false">
+     <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element name="pobox" type="xs:string" />
+          <xs:element name="ext" type="xs:string" />
+          <xs:element name="street" type="xs:string" />
+          <xs:element name="locality" type="xs:string" />
+          <xs:element name="region" type="xs:string" />
+          <xs:element name="code" type="xs:string" />
+          <xs:element name="country" type="xs:string" />
+        </xs:sequence>
+      </xs:extension>   
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="nicknamePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextListPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="relatedPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextOrUriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
   <xs:complexType name="bdayPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcard:DateDatetimePropertyType"/>
     </xs:complexContent>
   </xs:complexType>
+  
+  <xs:complexType name="anniversaryPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="photoPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:simpleType name="SexType">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value=""/>
+            <xs:enumeration value="M"/>
+            <xs:enumeration value="F"/>
+        </xs:restriction>
+    </xs:simpleType>
+  
+  <xs:complexType name="genderPropType">
+<!--    <xs:complexContent mixed="false">-->
+  <xs:sequence>
+      <xs:element name="sex" type="xcard:SexType" />
+    </xs:sequence>
+<!--    </xs:complexContent>-->
+  </xs:complexType>
+  
+  <xs:complexType name="langPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:BasePropertyType">
+        <xs:sequence> 
+          <xs:element name="language-tag" type="xs:string"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="telPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType" />
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="imppPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType" />
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="emailPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType" />
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="geoPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="cryptoPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:TextPropertyType"/>
+<!-- TODO -->
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="memberPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcard:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
 
     
 </xs:schema>


commit 16daa739f0879666243b15c2177c8f7425c7153f
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sun Feb 12 09:57:33 2012 +0100

    Set the version to the same version used in the XSDs

diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
index 1146e9c..326678c 100644
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@ -23,7 +23,7 @@ namespace Kolab {
 
 const char* const KOLAB_LIBNAME = "libkolabxml";
 const char* const KOLAB_LIB_VERSION = "0.9";
-const char* const KOLAB_FORMAT_VERSION = "2.9.0";
+const char* const KOLAB_FORMAT_VERSION = "3.0dev1";
 
 enum ErrorSeverity {
     NoError,


commit 9983d9df11edaefd68716bc869d4f2c373a0695b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Feb 8 21:10:32 2012 +0100

    Removed some old tests.

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 0b35721..3fa7703 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -19,75 +19,8 @@
 #include "serializers.h"
 #include <lib/utils.h>
 
-//TODO remove
-void BindingsTest::writeContact()
-{
-    Kolab::Contact contact;
-    std::cout << Kolab::writeContact(contact) << std::endl;
-}
-
-//TODO remove
-void BindingsTest::readEvent()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    QCOMPARE(event.created(), Kolab::DateTime(2006,2,6,0,11,21,true));
-    QCOMPARE(event.start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
-    
-    const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
-    QCOMPARE(rrule.frequency(), Kolab::RecurrenceRule::Daily);
-    QCOMPARE(rrule.count(), 5);
-    QCOMPARE(rrule.interval(), 1);
-    
-    QCOMPARE(event.summary(), std::string("Event #2"));
-}
-
-//TODO remove
-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::writeEvent(event) << std::endl;
-}
 
-//TODO remove
-void BindingsTest::roundtripEvent()
-{
-    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::writeEvent(event);
-    std::cout << result << std::endl;
-}
-
-//TODO remove
-void BindingsTest::roundtripReverseEvent()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    kDebug() << "-------------------";
-    std::cout << Kolab::writeEvent(event) << std::endl;
-    kDebug() << "-------------------";
-}
 
-void BindingsTest::BenchmarkRoundtrip()
-{
-    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
-    std::string result;
-    QBENCHMARK {
-        result = Kolab::writeEvent(event);
-        Kolab::readEvent(result, false);
-    }
-}
 
 // void BindingsTest::eventCompletness_data()
 template <typename T>
@@ -343,6 +276,15 @@ void BindingsTest::BenchmarkRoundtripKCAL()
     }
 }
 
+void BindingsTest::BenchmarkRoundtrip()
+{
+    const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
+    std::string result;
+    QBENCHMARK {
+        result = Kolab::writeEvent(event);
+        Kolab::readEvent(result, false);
+    }
+}
 
 QTEST_MAIN( BindingsTest )
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index ab34319..674d201 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -21,14 +21,7 @@ class BindingsTest : public QObject
   Q_OBJECT
   private slots:
 
-    void writeContact();
-      
     //Kolabformat
-    void readEvent();
-    void writeEvent();
-    void roundtripEvent();
-    void roundtripReverseEvent();
-    void BenchmarkRoundtrip();
     void eventCompletness();
     void eventDuration();
     void todoCompletness();
@@ -39,6 +32,8 @@ class BindingsTest : public QObject
 
     void BenchmarkRoundtripKolab();
     void BenchmarkRoundtripKCAL();
+    void BenchmarkRoundtrip();
+
 };
 
 #endif
\ No newline at end of file


commit e75e0dbed221f15d297e860cb1c90cc5f5901f6d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Feb 8 20:51:42 2012 +0100

    Basic Error handling/reporting/logging facilites. Not yet thread-safe. Make the parser recover from errors.

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 25140bd..ce38d2c 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -272,6 +272,10 @@ xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::ist
     {
         cerr << ": unable to open or read failure" << endl;
     }
-
+    catch (...)
+    {
+        cerr << ": unknown exception thrown" << endl;
+    }
+    eh.reset();
     return xml_schema::dom::auto_ptr<xercesc::DOMDocument>();
 }
\ No newline at end of file
diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
index 38d31dd..1146e9c 100644
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@ -17,9 +17,21 @@
 
 #ifndef GLOBAL_DEFINITIONS_H
 #define GLOBAL_DEFINITIONS_H
+#include <string>
+
+namespace Kolab {
 
 const char* const KOLAB_LIBNAME = "libkolabxml";
 const char* const KOLAB_LIB_VERSION = "0.9";
 const char* const KOLAB_FORMAT_VERSION = "2.9.0";
 
+enum ErrorSeverity {
+    NoError,
+    Warning, //Warning, error could be corrected, object can be used without dataloss
+    Error, //Potentially corrupt object, writing the object back could result in dataloss. (Object could still be used to display the data readonly).
+    Critical //Ciritcal error, produced object cannot be used and should be thrown away (writing back will result in dataloss).
+};
+
+}
+
 #endif
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index f199be9..1538fad 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -21,8 +21,35 @@
 #include "xcalconversions.h"
 
 #include "xcardconversions.h"
+#include "utils.h"
 
 namespace Kolab {
+    
+ErrorSeverity error()
+{
+    return getError();
+}
+
+std::string errorMessage()
+{
+    return getErrorMessage();
+}
+
+std::string productId()
+{
+    return XCAL::global_productId;
+}
+
+std::string xCalVersion()
+{
+    return XCAL::global_xCalVersion;
+}
+
+std::string xKolabVersion()
+{
+    return XCAL::global_xKolabVersion;
+}
+
 
 Kolab::Event readEvent(const std::string& s, bool isUrl)
 {
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index d0a8b62..5af254a 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -22,8 +22,16 @@
 #include "kolabcontainers.h"
 #include "kolabtodo.h"
 #include "kolabevent.h"
+#include "global_definitions.h"
 
 namespace Kolab {
+    
+Kolab::ErrorSeverity error();
+std::string errorMessage();
+
+std::string productId();
+std::string xKolabVersion();
+std::string xCalVersion();
 
 Kolab::Event readEvent(const std::string& s, bool isUrl);
 std::string writeEvent(const Kolab::Event &);
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index d151556..9fb87c0 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -5,11 +5,11 @@
     /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
     #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
 
+    #include "global_definitions.h"
     #include "kolabformat.h"
     #include "kolabcontainers.h"
     #include "kolabevent.h"
     #include "kolabtodo.h"
-
 %}
 
 %include "std_string.i"
@@ -24,6 +24,7 @@ namespace std {
 
 /*%apply const std::string& {std::string* foo};*/
 
+%include "global_definitions.h"
 %include "kolabcontainers.h"
 %include "kolabevent.h"
 %include "kolabtodo.h"
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index e428c5e..2b9d54a 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -20,6 +20,7 @@
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_io.hpp>
 #include <time.h>
+#include <boost/lexical_cast.hpp>
 
 namespace Kolab {
 
@@ -47,4 +48,56 @@ DateTime getCurrentTime()
     return DateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true);
 }
 
+ErrorSeverity global_errorBit;
+std::string global_errorMessage;
+
+void logMessage(const std::string &m, ErrorSeverity s)
+{
+    switch (s) {
+        case NoError:
+            std::cout << "Debug: " << m << std::endl;
+            break;
+        case Warning:
+            std::cerr << "Warning: " << m << std::endl;
+            break;
+        case Error:
+            std::cerr << "Error: " << m << std::endl;
+            if (global_errorBit < Error) {
+                global_errorBit = Error;
+                global_errorMessage = m;
+            }
+            break;
+        case Critical:
+        default:
+            std::cerr << "Critical: " << m << std::endl;
+            if (global_errorBit < Critical) {
+                global_errorBit = Critical;
+                global_errorMessage = m;
+            }
+            
+    }
+}
+
+void logMessage(const std::string &message, const std::string &file, int line, ErrorSeverity s)
+{
+   logMessage(file+" "+boost::lexical_cast<std::string>(line)+": " + "  " + message, s);
+}
+
+void clearErrors()
+{
+    global_errorBit = NoError;
+    global_errorMessage.clear();
+}
+
+ErrorSeverity getError()
+{
+    return global_errorBit;
+}
+
+std::string getErrorMessage()
+{
+    return global_errorMessage;
+}
+
+
 }
\ No newline at end of file
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
index d0cf739..886d181 100644
--- a/c++/lib/utils.h
+++ b/c++/lib/utils.h
@@ -20,6 +20,7 @@
 
 #include <string>
 #include "kolabcontainers.h"
+#include "global_definitions.h"
 
 namespace Kolab {
 
@@ -28,6 +29,19 @@ std::string getUID(const std::string &);
 
 DateTime getCurrentTime();
 
+void logMessage(const std::string &,const std::string &, int, ErrorSeverity s);
+     
+#define LOG(message) logMessage(message,__FILE__, __LINE__, NoError);
+#define WARNING(message) logMessage(message,__FILE__, __LINE__, Warning);
+#define ERROR(message) logMessage(message,__FILE__, __LINE__, Error);
+#define CRITICAL(message) logMessage(message,__FILE__, __LINE__, Critical);
+
+void logMessage(const std::string &, ErrorSeverity s = Warning);
+
+void clearErrors();
+ErrorSeverity getError();
+std::string getErrorMessage();
+
 }
 
 #endif
\ No newline at end of file
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index b0bfd8d..74df6e3 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -42,7 +42,10 @@
 
 namespace Kolab {
     namespace XCAL {
-
+        
+std::string global_productId;
+std::string global_xKolabVersion;
+std::string global_xCalVersion;
 
 const char* const XCAL_VERSION = "2.0";
 const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
@@ -102,14 +105,13 @@ template <typename T>
 int convertToInt(T integer)
 {
     try {
-        int i = boost::numeric_cast<int>(integer);
-        return i;
+        return boost::numeric_cast<int>(integer);
     } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     }
     return 0;
 }
@@ -118,14 +120,13 @@ template <typename T>
 T fromInt(int integer)
 {
     try {
-        T i = boost::numeric_cast<T>(integer);
-        return i;
+        return boost::numeric_cast<T>(integer);
     } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
+        logMessage(e.what(), Error);
     }
     return 0;
 }
@@ -217,7 +218,7 @@ Kolab::DayPos toDayPos(const std::string &s)
                     try {
                         occurrence = boost::lexical_cast<int>(number);
                     } catch(boost::bad_lexical_cast &) {
-                        std::cerr << "failed to convert: " <<  number <<  std::endl;
+                        logMessage("failed to convert: " + number, Error);
                         return DayPos();
                     }
                     number.clear();
@@ -282,7 +283,7 @@ std::string fromDuration(const Kolab::Duration &d)
         }
         
     } catch(boost::bad_lexical_cast &) { 
-        std::cerr << "failed to convert duration"<<  std::endl;
+        ERROR("failed to convert duration");
         return std::string();
     }
     return s;
@@ -317,7 +318,7 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
                 try {
                     hours = boost::lexical_cast<int>(number);
                 } catch(boost::bad_lexical_cast &) {
-                    std::cerr << "failed to convert: " <<  number <<  std::endl;
+                    ERROR("failed to convert: " +  number);
                     return Duration();
                 }
                 number.clear();
@@ -326,7 +327,7 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
                 try {
                     minutes = boost::lexical_cast<int>(number);
                 } catch(boost::bad_lexical_cast &) {
-                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    ERROR("failed to convert: " + number);
                     return Duration();
                 }
                 number.clear();
@@ -335,7 +336,7 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
                 try {
                     seconds = boost::lexical_cast<int>(number);
                 } catch(boost::bad_lexical_cast &) { 
-                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    ERROR("failed to convert: " + number);
                     return Duration();
                 }
                 number.clear();
@@ -346,7 +347,7 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
                 try {
                     weeks = boost::lexical_cast<int>(number);
                 } catch(boost::bad_lexical_cast &) { 
-                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    ERROR("failed to convert: " + number);
                     return Duration();
                 }
                 return Duration(weeks, negative);
@@ -354,7 +355,7 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
                 try {
                     days = boost::lexical_cast<int>(number);
                 } catch(boost::bad_lexical_cast &) { 
-                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    ERROR("failed to convert: " + number);
                     return Duration();
                 }
                 number.clear();
@@ -367,7 +368,8 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
             case 'P':
                 break;
             default:
-                std::cerr << "error: " << *it << std::endl;
+                ERROR("failed to convert duration: " + *it);
+                return Duration();
         }
     }
     return Duration(days, hours, minutes, seconds, negative);
@@ -401,7 +403,7 @@ Kolab::Attachment toAttachment(T aProp)
             }
             if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
                 if (p->text() != BASE64) {
-                    std::cerr << "wrong encoding";
+                    ERROR("wrong encoding");
                     return Kolab::Attachment();
                 }
             }
@@ -411,7 +413,7 @@ Kolab::Attachment toAttachment(T aProp)
         }
     }
     if (mimetype.empty()) {
-        std::cerr << "no mimetype" << std::endl;
+        ERROR("no mimetype");
     }
 
     if (aProp.uri()) {
@@ -419,7 +421,7 @@ Kolab::Attachment toAttachment(T aProp)
     } else if (aProp.binary()) {
         a.setData(base64_decode(*aProp.binary()), mimetype);
     } else {
-        std::cerr << "not uri and no data available" << std::endl;
+        ERROR("not uri and no data available");
     }
     return a;
 }
@@ -439,7 +441,7 @@ icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
         attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
         p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
     } else {
-        std::cerr << "no uri and no data" << std::endl;
+        ERROR("no uri and no data");
     }
     
     attachment.parameters(p);
@@ -492,7 +494,7 @@ typedef boost::shared_ptr<DateTime> DateTimePtr;
             if (tzid.find(TZ_PREFIX) != std::string::npos) {
                 tzid.erase(0, strlen(TZ_PREFIX));
             } else {
-                std::cerr << "/kolab.org/ timezone prefix is missing";
+                WARNING("/kolab.org/ timezone prefix is missing");
             }
             return tzid;
         }
@@ -526,7 +528,7 @@ DateTimePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
         date = toDate(*dtProperty.date_time());
     } else { //The utc-date-time element shouldn't even exist
         date = DateTimePtr(new DateTime());
-        std::cerr << "This element shouldn't even be existing";
+        ERROR("This element shouldn't even be existing");
         //TODO Implement anyways?
         return date;
     }
@@ -636,7 +638,7 @@ std::string mapPartStat(PartStatus status)
         case PartTentative:
             return PARTTENTATIVE;
     }
-    std::cout << "PartStat not handled: " << status;
+    ERROR("PartStat not handled: " + status);
     return std::string();
 }
 
@@ -653,7 +655,7 @@ PartStatus mapPartStat(const std::string &status)
     } else if (status == PARTTENTATIVE) {
         return PartTentative;
     }
-    std::cout << "Unhandled partstatus" << status;
+    ERROR("PartStat not handled: " + status);
     return PartNeedsAction;
 }
 
@@ -669,7 +671,7 @@ std::string mapRole(Role status)
         case Required:
             return REQUIRED;
     }
-    std::cout << "PartStat not handled: " << status;
+    ERROR("PartStat not handled: " + status);
     return std::string();
 }
 
@@ -684,7 +686,7 @@ Role mapRole(const std::string &status)
     } else if (status == REQUIRED) {
         return Required;
     }
-    std::cout << "Unhandled Role" << status;
+    ERROR("Unhandled Role " + status);
     return Required;
 }
 
@@ -719,7 +721,7 @@ Role mapRole(const std::string &status)
             case FreqRecurType::SECONDLY:
                 return RecurrenceRule::Secondly;
             default:
-                std::cout << "invalid unhandled recurrenc type" << freq;
+                ERROR("invalid unhandled recurrenc type" + freq);
         }
         return RecurrenceRule::None;
     }
@@ -744,7 +746,7 @@ Role mapRole(const std::string &status)
             case RecurrenceRule::Secondly:
                 return FreqRecurType::SECONDLY;
             default:
-                std::cout << "invalid unhandled recurrenc type";
+                ERROR("invalid unhandled recurrenc type");
         }
         return 0;
     }
@@ -776,7 +778,7 @@ Role mapRole(const std::string &status)
                 r->setWeekStart(Kolab::Sunday);
                 break;
             default:
-                std::cout << "invalid unhandled weekday" << wkst;
+                ERROR("invalid unhandled weekday" + wkst);
         }
     }
 
@@ -879,7 +881,7 @@ void setIncidenceProperties(I &inc, const T &prop)
     if (prop.rdate()) {
         inc.setRecurrenceDates(toDateTimeList<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;
+            ERROR("the period element must not be used, ignored.");
         }
     }
 
@@ -931,7 +933,7 @@ void setIncidenceProperties(I &inc, const T &prop)
         } else if (status == FINAL) {
             inc.setStatus(Final);
         } else {
-            std::cout << "Unhandled status";
+            ERROR("Unhandled status");
         }
     }
 
@@ -986,7 +988,7 @@ void setIncidenceProperties(I &inc, const T &prop)
         BOOST_FOREACH(typename T::attach_type aProp, prop.attach()) {
             const Kolab::Attachment &a = toAttachment<typename T::attach_type>(aProp);
             if (!a.isValid()) {
-                std::cerr << "invalid attachment" << std::endl;
+                ERROR("invalid attachment");
                 continue;
             }
             attachments.push_back(a);
@@ -1176,7 +1178,7 @@ void getIncidenceProperties(T &prop, const I &inc)
                 prop.status(typename properties::status_type(FINAL));
                 break;
             default:
-                std::cout << "unhandled status " << inc.status() << std::endl;
+                ERROR("unhandled status " + inc.status());
         }
 
     }
@@ -1259,7 +1261,7 @@ void setAlarms(typename KolabType::components_type& components, const IncidenceT
             trigger.date_time(fromDateTime(alarm.start()));
         } else {
             if (!alarm.relativeStart().isValid()) {
-                std::cerr << "no start and no relativeStart" << std::endl;
+                ERROR("no start and no relativeStart");
                 continue;
             }
             trigger.duration(PropType::trigger_type::duration_type(fromDuration(alarm.relativeStart())));
@@ -1292,7 +1294,7 @@ void setAlarms(typename KolabType::components_type& components, const IncidenceT
                 p->attach(fromAttachment(alarm.audioFile()));
                 break;
             default:
-                std::cerr << "invalid alarm" << std::endl;
+                ERROR("invalid alarm");
                 continue;
         }
         if (alarm.duration().isValid()) {
@@ -1317,7 +1319,7 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
         Kolab::Alarm alarm;
         if (prop.action().text() == DISPLAYALARM) {
             if (!prop.description()) {
-                std::cerr << "description is missing" << std::endl;
+                ERROR("description is missing");
                 continue;
             }
             alarm = Kolab::Alarm((*prop.description()).text());
@@ -1327,30 +1329,30 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
                 attendees.push_back((*at).cal_address());
             }
             if (!prop.description() || !prop.summary()) {
-                std::cerr << "description or summary is missing" << std::endl;
+                ERROR("description or summary is missing");
                 continue;
             }
             alarm = Kolab::Alarm((*prop.summary()).text(), (*prop.description()).text(), attendees);
         } else if (prop.action().text() == AUDIOALARM) {
             if (!prop.attach()) {
-                std::cerr << "audio file is missing" << std::endl;
+                ERROR("audio file is missing");
                 continue;
             }
             const Kolab::Attachment &attach = toAttachment<icalendar_2_0::properties::attach_type>(*prop.attach());
             if (!attach.isValid()) {
-                std::cerr << "audio file is invalid" << std::endl;
+                ERROR("audio file is invalid");
                 continue;
             }
             alarm = Kolab::Alarm(attach);
         } else {
-            std::cerr << "unknown alarm type " << prop.action().text() << std::endl;
+            ERROR("unknown alarm type " + prop.action().text());
             continue;
         }
         
         if (prop.trigger().date_time()) {
             alarm.setStart(*toDate(*prop.trigger().date_time()));
             if (!alarm.start().isUTC()) {
-                std::cerr << "The start date time must be in UTC "<< std::endl;
+                ERROR("The start date time must be in UTC ");
                 continue;
             }
         } else if (prop.trigger().duration()) {
@@ -1363,7 +1365,7 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
                         } else if (rel->text() == END) {
                             relativeTo = Kolab::End;
                         } else {
-                            std::cerr << "relativeTo not specified, default to start " << std::endl;
+                            LOG("relativeTo not specified, default to start ");
                         }
                     }
                 }
@@ -1371,7 +1373,7 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
             
             alarm.setRelativeStart(toDuration(*prop.trigger().duration()), relativeTo);
         } else {
-            std::cerr << "no duration and not starttime " << std::endl;
+            ERROR("no duration and not starttime ");
             continue;
         }
         if (prop.duration()) {
@@ -1459,7 +1461,7 @@ template < > struct IncidenceTrait <Kolab::Event>
             if (event.end().isUTC() != event.end().isUTC() && 
                 event.end().timezone() != event.end().timezone() &&
                 event.end().isDateOnly() != event.end().isDateOnly()) {
-                std::cerr << "dtEnd has wrong timespec" << std::endl;;
+                ERROR("dtEnd has wrong timespec");
             }
         } else if (prop.duration()) {
             event.setDuration(toDuration((*prop.duration()).duration()));
@@ -1471,7 +1473,7 @@ template < > struct IncidenceTrait <Kolab::Event>
             } else {
                 event.setTransparency(false);
                 if (toString(*prop.transp()) != OPAQUE) {
-                    std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
+                    ERROR("wrong transparency value " + toString(*prop.transp()));
                 }
             }
         }
@@ -1578,6 +1580,8 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
     using namespace icalendar_2_0;
     typedef IncidenceConverter< Incidence, typename T::IncidenceType > IC;
     typedef typename T::KolabType KolabType;
+    
+    clearErrors();
 
     try {
 
@@ -1618,9 +1622,9 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
         icalendar_2_0::icalendar(ostringstream, icalendar, map);
         return ostringstream.str();
     } catch  (const xml_schema::exception& e) {
-        std::cout << "failed to write Incidence" << std::endl;
+        CRITICAL("failed to write Incidence");
     } catch (...) {
-        std::cerr <<  "Unhandled exception" << std::endl;
+        CRITICAL("Unhandled exception");
     }
     return std::string();
 }
@@ -1629,10 +1633,12 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
 template <typename T>
 typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 {
+    using namespace icalendar_2_0;
     typedef typename T::IncidencePtr IncidencePtr;
     typedef typename T::IncidenceType IncidenceType;
     typedef typename T::KolabType KolabType;
     
+    clearErrors();
     try {
         std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
         if (isUrl) {
@@ -1648,7 +1654,7 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
         }
         
         if (!icalendar.get()) {
-            std::cerr << "failed to parse calendar!" << std::endl;
+            CRITICAL("Failed to parse calendar!");
             return IncidencePtr();
         }
 
@@ -1662,7 +1668,10 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
             incidences.push_back(e);
         }
         
-        //TODO x_kolab_version
+        global_productId = vcalendar.properties().prodid().text();
+        global_xCalVersion = vcalendar.properties().version().text();
+        global_xKolabVersion = vcalendar.properties().x_kolab_version().text();
+
 
         //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
 //         foreach (KCalCore::Event * event, events) {
@@ -1671,14 +1680,14 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 //             }
 //         }
         if (incidences.size() != 1) {
-            std::cerr << "wrong number of incidences: " << incidences.size() << std::endl;
+            WARNING("wrong number of incidences: "+ incidences.size());
         }
         return *incidences.begin();
     } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        std::cerr <<  "Failed to read incidence!" << std::endl;
+        std::cout <<  e << std::endl;
+        CRITICAL("Failed to read incidence!");
     } catch (...) {
-        std::cerr <<  "Unhandled exception" << std::endl;
+        CRITICAL("Unhandled exception");
     }
     return IncidencePtr();
 }
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index b696f9b..0b35721 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,6 +17,7 @@
 #include <iostream>
 #include <fstream>
 #include "serializers.h"
+#include <lib/utils.h>
 
 //TODO remove
 void BindingsTest::writeContact()
@@ -251,15 +252,14 @@ void BindingsTest::eventCompletness()
     ev.setTransparency(true);
     
     std::string result = Kolab::writeEvent(ev);
-    std::cout << result << endl;
+//     std::cout << result << endl;
     Kolab::Event e = Kolab::readEvent(result, false);
-    const Kolab::Event &re = e;
-    checkIncidence(ev, re);
-    QCOMPARE(ev.end(), re.end());
+    checkIncidence(ev, e);
+    QCOMPARE(ev.end(), e.end());
 //     QEXPECT_FAIL("", "Will fix in the next release", Continue);
 //     QVERIFY(ev.duration().isValid());
 //     QCOMPARE(ev.duration(), re.duration());
-    QCOMPARE(ev.transparency(), re.transparency());
+    QCOMPARE(ev.transparency(), e.transparency());
     
 }
 
@@ -285,15 +285,45 @@ void BindingsTest::todoCompletness()
     ev.setPercentComplete(50);
     
     std::string result = Kolab::writeTodo(ev);
-    std::cout << result << endl;
+//     std::cout << result << endl;
+    Kolab::Todo e = Kolab::readTodo(result, false);
+    checkIncidence(ev, e);
+    QCOMPARE(ev.due(), e.due());
+    QCOMPARE(ev.relatedTo(), e.relatedTo());
+    QCOMPARE(ev.percentComplete(), e.percentComplete());
+}
+
+void BindingsTest::versionTest()
+{
+    Kolab::Todo ev;
+    setIncidence(ev);
+    
+    std::string result = Kolab::writeTodo(ev);
     Kolab::Todo e = Kolab::readTodo(result, false);
-    const Kolab::Todo &re = e;
-    checkIncidence(ev, re);
-    QCOMPARE(ev.due(), re.due());
-    QCOMPARE(ev.relatedTo(), re.relatedTo());
-    QCOMPARE(ev.percentComplete(), re.percentComplete());
+    QCOMPARE(Kolab::productId(), std::string(Kolab::KOLAB_LIBNAME) + std::string(Kolab::KOLAB_LIB_VERSION));
+    QCOMPARE(Kolab::xKolabVersion(), std::string(Kolab::KOLAB_FORMAT_VERSION));
+    QCOMPARE(Kolab::xCalVersion(), std::string("2.0"));
+}
+
+void BindingsTest::errorTest()
+{
+    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
+    QCOMPARE(Kolab::error(), Kolab::Critical);
+    QCOMPARE(Kolab::errorMessage(), std::string("/home/chrigi/work/kolab/xmlformat/libkolabxml/c++/lib/xcalconversions.h 1657:   Failed to parse calendar!"));
+}
 
+//Don't break due to an error
+void BindingsTest::errorRecoveryTest()
+{
+    Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false);
+    QCOMPARE(Kolab::error(), Kolab::Critical);
+
+    Kolab::Todo ev;
+    setIncidence(ev);
     
+    const std::string result = Kolab::writeTodo(ev);
+    Kolab::readTodo(result, false);
+    QCOMPARE(Kolab::error(), Kolab::NoError);
 }
 
 void BindingsTest::BenchmarkRoundtripKolab()
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index aa140b1..ab34319 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -32,7 +32,11 @@ class BindingsTest : public QObject
     void eventCompletness();
     void eventDuration();
     void todoCompletness();
-    
+
+    void versionTest();
+    void errorTest();
+    void errorRecoveryTest();
+
     void BenchmarkRoundtripKolab();
     void BenchmarkRoundtripKCAL();
 };


commit cabcfc5d8cec3e04a2f869a098cd3fa166f793e8
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Feb 7 11:27:06 2012 +0100

    Refactoring to get rid of all the unnecessary templates.
    
    All xcal code is now in a single file and the kcalconversion are no longer.
    +some general code cleanups

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
deleted file mode 100644
index 6c879d5..0000000
--- a/c++/lib/genericxcalconverions.h
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLAB_CONVERSIONS_H
-#define KOLAB_CONVERSIONS_H
-
-#include "global_definitions.h"
-
-#include <bindings/kolabformat-xcal.hxx>
-#include <bindings/iCalendar-props.hxx>
-#include <compiled/XMLParserWrapper.h>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/numeric/conversion/converter_policies.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/foreach.hpp>
-
-#include <fstream>
-#include <iostream>
-#include "kolabcontainers.h"
-
-const char* const XCAL_VERSION = "2.0";
-const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
-
-const char* const TZ_PREFIX = "/kolab.org/";
-
-const char* const THISANDFUTURE = "THISANDFUTURE";
-
-const char* const BASE64 = "BASE64";
-
-const char* const NEEDSACTION = "NEEDS-ACTION";
-const char* const COMPLETED = "OPAQUE";
-const char* const INPROCESS = "IN-PROCESS";
-const char* const CANCELLED = "CANCELLED";
-const char* const TENTATIVE = "TENTATIVE";
-const char* const CONFIRMED = "CONFIRMED";
-const char* const DRAFT = "DRAFT";
-const char* const FINAL = "FINAL";
-
-const char* const CONFIDENTIAL = "CONFIDENTIAL";
-const char* const PRIVATE = "PRIVATE";
-const char* const PUBLIC = "PUBLIC";
-
-const char* const PARTACCEPTED = "ACCEPTED";
-const char* const PARTDECLINED = "DECLINED";
-const char* const PARTDELEGATED = "DELEGATED";
-const char* const PARTNEEDSACTION = "NEEDS-ACTION";
-const char* const PARTTENTATIVE = "TENTATIVE";
-
-const char* const CHAIR = "CHAIR";
-const char* const NONPARTICIPANT = "NON-PARTICIPANT";
-const char* const OPTIONAL = "OPT-PARTICIPANT";
-const char* const REQUIRED = "REQ-PARTICIPANT";
-
-
-namespace Kolab {
-
-
-//=== Generic ===
-    
-template <typename T>
-int convertToInt(T integer)
-{
-    try {
-        int i = boost::numeric_cast<int>(integer);
-        return i;
-    } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
-    }
-    return 0;
-}
-
-template <typename T> 
-T fromInt(int integer)
-{
-    try {
-        T i = boost::numeric_cast<T>(integer);
-        return i;
-    } catch(boost::numeric::negative_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::positive_overflow& e) {
-        std::cerr << e.what();
-    } catch(boost::numeric::bad_numeric_cast& e) {
-        std::cerr << e.what();
-    }
-    return 0;
-}
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
-    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
-}
-
-//----------------
-
-//=== Attendee ===
-
-std::string mapPartStat(PartStatus status)
-{
-    switch (status) {
-        case PartAccepted:
-            return PARTACCEPTED;
-        case PartDeclined:
-            return PARTDECLINED;
-        case PartDelegated:
-            return PARTDELEGATED;
-        case PartNeedsAction:
-            return PARTNEEDSACTION;
-        case PartTentative:
-            return PARTTENTATIVE;
-    }
-    std::cout << "PartStat not handled: " << status;
-    return std::string();
-}
-
-PartStatus mapPartStat(const std::string &status)
-{
-    if (status == PARTACCEPTED) {
-        return PartAccepted;
-    } else if (status == PARTDECLINED) {
-        return PartDeclined;
-    } else if (status == PARTDELEGATED) {
-        return PartDelegated;
-    } else if (status == PARTNEEDSACTION) {
-        return PartNeedsAction;
-    } else if (status == PARTTENTATIVE) {
-        return PartTentative;
-    }
-    std::cout << "Unhandled partstatus" << status;
-    return PartNeedsAction;
-}
-
-std::string mapRole(Role status)
-{
-    switch (status) {
-        case Chair:
-            return std::string(CHAIR);
-        case NonParticipant:
-            return NONPARTICIPANT;
-        case Optional:
-            return OPTIONAL;
-        case Required:
-            return REQUIRED;
-    }
-    std::cout << "PartStat not handled: " << status;
-    return std::string();
-}
-
-Role mapRole(const std::string &status)
-{
-    if (status == CHAIR) {
-        return Chair;
-    } else if (status == NONPARTICIPANT) {
-        return NonParticipant;
-    } else if (status == OPTIONAL) {
-        return Optional;
-    } else if (status == REQUIRED) {
-        return Required;
-    }
-    std::cout << "Unhandled Role" << status;
-    return Required;
-}
-
-
-
-
-
-//----------------
-
-///trait to convert date-time values
-template <typename T> 
-struct DateTimeConverter;
-
-std::string getTimezone(const icalendar_2_0::ArrayOfParameters &parameters) {
-    for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-        if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
-            std::string tzid = tz->text();
-            if (tzid.find(TZ_PREFIX) != std::string::npos) {
-                tzid.erase(0, strlen(TZ_PREFIX));
-            } else {
-                std::cout << "/kolab.org/ timezone prefix is missing";
-            }
-            return tzid;
-        }
-    }
-    return std::string();
-}
-
-template <typename T> 
-typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
-    typedef DateTimeConverter<typename T::DateType> DC;
-    typename T::DatePtr date;
-    if (dtProperty.date_time()) {
-        date = DC::toDate(*dtProperty.date_time());
-    } else if (dtProperty.date()) {
-        date = DC::toDate(*dtProperty.date());
-    }
-
-    if (dtProperty.parameters()) {
-        const std::string &tzid = getTimezone(*dtProperty.parameters());
-        if (tzid.size()) {
-            DC::setTimezone(date, tzid);
-        }
-    }
-    return date;
-}
-
-
-// template <typename T, typename I> 
-// typename T::DatePtr toDate(const I &dtProperty)
-// {
-//     typedef DateTimeConverter<typename T::DateType> DC;
-//     typename T::DatePtr date;
-//     if (dtProperty.date_time()) {
-//         date = DC::toDate(*dtProperty.date_time());
-//     } else if (dtProperty.date()) {
-//         date = DC::toDate(*dtProperty.date());
-//     }
-// 
-//     if (dtProperty.parameters()) {
-//         const std::string &tzid = getTimezone(*dtProperty.parameters());
-//         if (tzid.size()) {
-//             DC::setTimezone(date, tzid);
-//         }
-//     }
-//     return date;
-// }
-
-template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    typename T::DatePtr date;
-    if (dtProperty.date_time()) {
-        date = DC::toDate(*dtProperty.date_time());
-    } else { //The utc-date-time element shouldn't even exist
-        date = DatePtr(new DateType());
-        std::cerr << "This element shouldn't even be existing";
-        //TODO Implement anyways?
-        return date;
-    }
-    DC::setUTC(date);
-    return date;
-}
-
-template <typename T, typename I>
-std::auto_ptr<I> fromDate(const typename T::DateType &dt)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::auto_ptr<I> ptr(new I);
-    
-    if (DC::isDateOnly(dt)) {
-        ptr->date(DC::fromDate(dt));
-    } else {
-        ptr->date_time(DC::fromDateTime(dt));
-
-        const std::string &timezone = DC::getTimezone(dt);
-        if (timezone.size() != 0) {
-            std::string tz(TZ_PREFIX);
-            tz.append(timezone);
-            icalendar_2_0::TzidParamType tzidParam(tz);
-            icalendar_2_0::ArrayOfParameters parameters;
-            parameters.baseParameter().push_back(tzidParam);
-            ptr->parameters(parameters);
-        }
-    }
-    return ptr;
-}
-
-template <typename T>
-void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    if (DC::isDateOnly(dt)) {
-        date.date(DC::fromDate(dt));
-    } else {
-        date.date_time(DC::fromDateTime(dt));
-
-        const std::string &timezone = DC::getTimezone(dt);
-        if (timezone.size() != 0) {
-            std::string tz(TZ_PREFIX);
-            tz.append(timezone);
-            icalendar_2_0::TzidParamType tzidParam(tz);
-            icalendar_2_0::ArrayOfParameters parameters;
-            parameters.baseParameter().push_back(tzidParam);
-            date.parameters(parameters);
-        }
-    }
-}
-
-template <typename T, typename I>
-std::vector<typename T::DateType> toDateTimeList(I datelistProperty)
-{
-    typedef typename T::DateType DateType;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::vector<DateType>  list;
-    
-    std::string tzid;
-    if (datelistProperty.parameters()) {
-        tzid = getTimezone(*datelistProperty.parameters());
-    }
-    if (!datelistProperty.date().empty()) {
-        BOOST_FOREACH(const xml_schema::date &d, datelistProperty.date()) {
-            list.push_back(*DC::toDate(d));
-        }
-    } else if (!datelistProperty.date_time().empty()) {
-        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
-            typename DC::Ptr date = DC::toDate(d);
-            if (tzid.size()) {
-                date->setTimezone(tzid);
-            }
-            list.push_back(*date);
-        }
-    }
-    return list;
-}
-
-template <typename T, typename I>
-std::auto_ptr<I> fromDateTimeList(const std::vector<typename T::DateType> &dtlist)
-{
-    typedef typename T::DateType DateType;
-    typedef typename T::DatePtr DatePtr;
-    typedef DateTimeConverter<DateType> DC;
-    
-    std::auto_ptr<I> ptr(new I);
-    BOOST_FOREACH(const DateType &dt, dtlist) {
-        if (DC::isDateOnly(dt)) {
-            ptr->date().push_back(DC::fromDate(dt));
-        } else {
-            ptr->date_time().push_back(DC::fromDateTime(dt));
-        }
-        //TODO handle utc
-        //TODO check for equality of timezones?
-    }
-    
-    if (!dtlist.empty() && !DC::getTimezone(dtlist.at(0)).empty()) {
-        const std::string &timezone = DC::getTimezone(dtlist.at(0));
-        if (timezone.size() != 0) {
-            std::string tz(TZ_PREFIX);
-            tz.append(timezone);
-            icalendar_2_0::TzidParamType tzidParam(tz);
-            icalendar_2_0::ArrayOfParameters parameters;
-            parameters.baseParameter().push_back(tzidParam);
-            ptr->parameters(parameters);
-        }
-    }
-    
-    return ptr;
-}
-
-
-
-///trait to convert recurrence properties
-template <typename T>
-struct RecurrenceConverter;
-
-template <typename T>
-typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-{
-    using namespace icalendar_2_0;
-
-    typedef RecurrenceConverter< typename T::RecurrenceType> RC;
-    typedef DateTimeConverter< typename T::DateType> DC;
-    typedef typename T::DatePtr DatePtr;
-    typedef typename T::RecurrencePtr RecurrencePtr;
-    typedef typename T::RecurrenceType RecurrenceType;
-
-    RecurrencePtr r(new RecurrenceType());
-    RC::setType(r, rrule.freq());
-    if (rrule.until()) {
-        DatePtr date;
-        if ((*rrule.until()).date_time()) {
-            date = DC::toDate(*(*rrule.until()).date_time());
-        } else if ((*rrule.until()).date()) {
-            date = DC::toDate(*(*rrule.until()).date());
-        }
-        RC::setEndDt(r, date);
-    } else if (rrule.count()) {
-        RC::setCount(r, toInt(*rrule.count()));
-    }
-    if (rrule.interval()) {
-        RC::setInterval(r, toInt(*rrule.interval()));
-    } else {
-        RC::setInterval(r, 1); //FIXME should be initialized to 1 in KCalCore::RecurrenceRule class (default value of interval per RFC).
-    }
-    RC::setBysecond(r, rrule.bysecond());
-    RC::setByminute(r, rrule.byminute());
-    RC::setByhour(r, rrule.byhour());
-    RC::setByday(r, rrule.byday());
-    RC::setBymonthday(r, rrule.bymonthday());
-    RC::setByyearday(r, rrule.byyearday());
-    RC::setByweekno(r, rrule.byweekno());
-    RC::setBymonth(r, rrule.bymonth());
-    if (rrule.wkst()) {
-        RC::setWeekStart(r, *rrule.wkst());
-    }
-
-    return r;
-}
-
-///Trait for Incidence object
-template <typename T, typename I> 
-struct IncidenceConverter;
-
-///Trait for incidence properties specialized for Event/Todo/Journal
-template <typename T> struct IncidenceTrait;
-
-
-
-
-template <typename T>
-typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
-{
-    typedef typename T::IncidencePtr IncidencePtr;
-    typedef typename T::IncidenceType IncidenceType;
-    typedef typename T::KolabType KolabType;
-    
-    try {
-//         xml_schema::properties props;
-        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
-        if (isUrl) {
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
-//             icalendar = icalendar_2_0::icalendar(s, 0, props);
-        } else {
-//             props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
-            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
-            if (doc.get()) {
-                icalendar = icalendar_2_0::icalendar(doc);
-            }
-//             icalendar = readCompiledIncidence(is, "string");
-//             icalendar = icalendar_2_0::icalendar(is, 0, props);
-        }
-        
-        if (!icalendar.get()) {
-            std::cerr << "failed to parse calendar!" << std::endl;
-            return IncidencePtr();
-        }
-
-        const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
-
-        std::vector < IncidencePtr > incidences;
-        for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
-            IncidencePtr e = IncidencePtr(new IncidenceType);
-            const KolabType &event = *it;
-            T::readIncidence(*e, event);
-            incidences.push_back(e);
-        }
-        
-        //TODO x_kolab_version
-
-        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
-//         foreach (KCalCore::Event * event, events) {
-//             if (!event->hasRecurrenceId()) {
-//                 return event;
-//             }
-//         }
-
-        return *incidences.begin();
-    } catch  (const xml_schema::exception& e) {
-        std::cerr <<  e << std::endl;
-        std::cerr <<  "Failed to read incidence!" << std::endl;
-    }
-
-    return IncidencePtr();
-    
-}
-
-
-const char* const DISPLAYALARM = "DISPLAY";
-const char* const EMAILALARM = "EMAIL";
-const char* const AUDIOALARM = "AUDIO";
-
-
-template <typename T>
-std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
-    
-    using namespace icalendar_2_0;
-    typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
-    typedef typename T::KolabType KolabType;
-
-    try {
-
-        typename KolabType::components_type eventComponents;
-        T::setComponents(eventComponents, incidence);
-
-        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
-        typename KolabType::properties_type::dtstamp_type dtstamp;
-        dtstamp.date_time(IC::dtstamp());
-        typename KolabType::properties_type::created_type created;
-        created.date_time(IC::created(incidence));
-        typename KolabType::properties_type eventProps(uid, created, dtstamp);
-        
-        KolabType inc(eventProps);
-        if (!eventComponents.valarm().empty()) {
-            inc.components(eventComponents);
-        }
-        T::writeIncidence(inc, incidence);
-
-        
-        VcalendarType::components_type components;
-        T::addIncidence(components, inc);
-        
-        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME+KOLAB_LIB_VERSION); //FIXME own version field for lib version
-        VcalendarType::properties_type::version_type version(XCAL_VERSION);
-        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION);
-        
-        VcalendarType::properties_type properties(prodid, version, x_kolab_version);
-        
-        VcalendarType vcalendar(properties, components);
-        
-        IcalendarType icalendar(vcalendar);
-
-        xml_schema::namespace_infomap map;
-        map[""].name = XCAL_NAMESPACE;
-        
-        std::ostringstream ostringstream;
-        icalendar_2_0::icalendar(ostringstream, icalendar, map);
-        return ostringstream.str();
-    } catch  (const xml_schema::exception& e) {
-        std::cout << "failed to write Incidence";
-        return std::string();
-    } 
-}
-
-
-
-
-
-}
-
-#endif
\ No newline at end of file
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
deleted file mode 100644
index d805194..0000000
--- a/c++/lib/kcalconversions.h
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KOLAB_KCALCONVERSIONS_H
-#define KOLAB_KCALCONVERSIONS_H
-
-#include "genericxcalconverions.h"
-#include <KDE/KDateTime>
-#include <KDE/KDebug>
-#include <kcalcore/recurrencerule.h>
-#include <kcalcore/recurrence.h>
-#include <kcalcore/incidence.h>
-#include <KDE/KCalCore/Event>
-#include <KDE/KCalCore/Todo>
-#include <kcalcore/person.h>
-
-namespace Kolab {
-
-struct KCalCoreTypes
-{
-    typedef KDateTime DateType;
-    typedef boost::shared_ptr<KDateTime> DatePtr;
-    typedef KCalCore::RecurrenceRule RecurrenceType;
-    typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
-    typedef QString StringType;
-    typedef 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());
-}
-
-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 KCalCoreTypes::RecurrencePtr RecurrencePtr;
-
-template <> struct DateTimeConverter<KDateTime>
-{
-    typedef KDateTime Type;
-    typedef 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 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)
-    {
-        KTimeZone timezone(QString::fromStdString(tzid));
-        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) {
-            kWarning() << "utc date wrong formatting, corrected to utc";
-            date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        }
-    }
-
-    static bool isDateOnly(Type date)
-    {
-        return date.isDateOnly();
-    }
-
-};
-
-
-
-template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
-{
-    typedef KCalCoreTypes::RecurrenceType Type;
-    typedef 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)
-    {
-        using namespace icalendar_2_0;
-        using namespace KCalCore;
-        
-        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:
-                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 icalendar_2_0::RecurType::freq_type type(const Type &t)
-    {
-        using namespace icalendar_2_0;
-        using namespace KCalCore;
-        
-        switch (t.recurrenceType()) {
-            case KCalCore::RecurrenceRule::rYearly:
-                return FreqRecurType::YEARLY;
-            case KCalCore::RecurrenceRule::rMonthly:
-                return FreqRecurType::MONTHLY;
-            case KCalCore::RecurrenceRule::rWeekly:
-                return FreqRecurType::WEEKLY;
-            case KCalCore::RecurrenceRule::rDaily:
-                return FreqRecurType::DAILY;
-            case KCalCore::RecurrenceRule::rHourly:
-                return FreqRecurType::HOURLY;
-            case KCalCore::RecurrenceRule::rMinutely:
-                return FreqRecurType::MINUTELY;
-            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)
-    {
-        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);
-    }
-    
-    static void setCount(Ptr r, int count )
-    {
-        r->setDuration(count);
-    }
-    
-    static void setInterval(Ptr r, int interval )
-    {
-        r->setFrequency(interval);
-    }
-    
-    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);
-        }
-    }
-    
-    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> 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 (!by.isEmpty()) {
-            r->setByHours(by);
-        }
-    }
-    
-    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);
-        }
-    }
-    
-    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;
-// }
-
-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)
-{
-    using namespace icalendar_2_0;
-    
-    typedef RecurrenceConverter< 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()));
-    }
-    
-    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;
-}
-
-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()));
-
-    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()) {
-        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()) {
-        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 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()) {
-        
-    }
-    
-    if (prop.attach().size()) {
-        
-    }
-    
-    if (prop.x_custom().size()) {
-        
-    }
-
-}
-
-template <typename T>
-void getIncidenceProperties(T &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_(typename T::class_type("CONFIDENTIAL"));
-            break;
-        case Incidence::SecrecyPrivate:
-            prop.class_(typename T::class_type("PRIVATE"));
-            break;
-        default:
-            prop.class_(typename T::class_type("PUBLIC"));
-            break;
-    }
-
-    if (inc.dtStart().isValid()) {
-        typename T::dtstart_type dtstart;
-        setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
-        prop.dtstart(dtstart);
-    }
-    
-    if (inc.recurs()) {
-        KCalCore::Recurrence *r = inc.recurrence();
-        if (r->rRules().size() >= 1) {
-            if (r->rRules().size() != 1) {
-                kWarning() << "too many recurrences: " << r->rRules().size();
-            }
-            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));
-        }
-    }
-    
-}
-
-template <> struct IncidenceConverter < KCalCore::Incidence, KCalCore::Incidence >
-{
-    typedef DateTimeConverter< KDateTime> DC;
-    static std::string uid(const KCalCore::Incidence &inc) { //FIXME thats possibly the kontact internal uid?
-        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());
-    }
-
-};
-
-template < > struct IncidenceTrait <KCalCore::Event>
-{
-    typedef icalendar_2_0::KolabEvent KolabType;
-    typedef KCalCore::Event IncidenceType;
-    typedef KCalCore::Event::Ptr IncidencePtr;
-    typedef 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::KolabEvent::properties_type::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 icalendar_2_0::KolabTodo KolabType;
-    typedef KCalCore::Todo IncidenceType;
-    typedef 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
index 1922fa4..12eaba2 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -20,7 +20,7 @@
 #include <kcalcore/event.h>
 #include <KDE/KCalCore/Todo>
 
-#include "kcalconversions.h"
+// #include "kcalconversions.h"
 
 namespace Kolab {
     
@@ -28,7 +28,8 @@ namespace KCal {
 
 KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 {
-     return deserializeIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+//      return deserializeIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+    return KCalCore::Event::Ptr();
 }
 
 KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
index 821b819..43caaad 100644
--- a/c++/lib/kolabevent.cpp
+++ b/c++/lib/kolabevent.cpp
@@ -318,15 +318,15 @@ std::vector< CustomProperty > Event::customProperties() const
     return d->customProperties;
 }
 
-void Event::setExceptions(const std::vector< Event > &exceptions)
-{
-    d->exceptions = exceptions;
-}
-
-std::vector< Event > Event::exceptions() const
-{
-    return d->exceptions;
-}
+// void Event::setExceptions(const std::vector< Event > &exceptions)
+// {
+//     d->exceptions = exceptions;
+// }
+// 
+// std::vector< Event > Event::exceptions() const
+// {
+//     return d->exceptions;
+// }
 
 void Event::setAlarms(const std::vector< Alarm > &alarms)
 {
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
index 866bf27..668e254 100644
--- a/c++/lib/kolabevent.h
+++ b/c++/lib/kolabevent.h
@@ -106,9 +106,9 @@ public:
     
     void setCustomProperties(const std::vector<CustomProperty> &);
     std::vector<CustomProperty> customProperties() const;
-    
+/*    TODO what is this?
     void setExceptions(const std::vector<Event> &);
-    std::vector<Event> exceptions() const;
+    std::vector<Event> exceptions() const;*/
     
     void setAlarms(const std::vector<Alarm> &);
     std::vector<Alarm> alarms() const;
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 16eb19e..f199be9 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -26,7 +26,7 @@ namespace Kolab {
 
 Kolab::Event readEvent(const std::string& s, bool isUrl)
 {
-    Kolab::IncidenceTrait <Kolab::Event >::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
+    Kolab::XCAL::IncidenceTrait <Kolab::Event >::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(s, isUrl);
     if (!ptr.get()) {
         return Kolab::Event();
     }
@@ -35,12 +35,12 @@ Kolab::Event readEvent(const std::string& s, bool isUrl)
 
 std::string writeEvent(const Kolab::Event &event)
 {
-    return serializeIncidence< IncidenceTrait<Kolab::Event> >(event);
+    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Event> >(event);
 }
 
 Kolab::Todo readTodo(const std::string& s, bool isUrl)
 {
-    Kolab::IncidenceTrait<Kolab::Todo>::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+    XCAL::IncidenceTrait<Kolab::Todo>::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(s, isUrl);
     if (!ptr.get()) {
         return Kolab::Todo();
     }
@@ -49,7 +49,7 @@ Kolab::Todo readTodo(const std::string& s, bool isUrl)
 
 std::string writeTodo(const Kolab::Todo &event)
 {
-    return serializeIncidence< IncidenceTrait<Kolab::Todo> >(event);
+    return XCAL::serializeIncidence< XCAL::IncidenceTrait<Kolab::Todo> >(event);
 }
 
 Journal readJournal(const std::string& s, bool isUrl)
@@ -71,7 +71,7 @@ std::string writeJournal(const Kolab::Journal &j)
 
 Kolab::Contact readContact(const std::string& s, bool isUrl)
 {
-    boost::shared_ptr <Kolab::Contact > ptr = deserializeCard<Kolab::Contact>(s, isUrl);
+    boost::shared_ptr <Kolab::Contact > ptr = XCARD::deserializeCard<Kolab::Contact>(s, isUrl);
     if (!ptr.get()) {
         return Kolab::Contact();
     }
@@ -80,12 +80,12 @@ Kolab::Contact readContact(const std::string& s, bool isUrl)
 
 std::string writeContact(const Contact &contact)
 {
-    return serializeCard(contact);
+    return XCARD::serializeCard(contact);
 }
 
 DistList readDistlist(const std::string& s, bool isUrl)
 {
-    boost::shared_ptr <Kolab::DistList> ptr = deserializeCard<Kolab::DistList>(s, isUrl);
+    boost::shared_ptr <Kolab::DistList> ptr = XCARD::deserializeCard<Kolab::DistList>(s, isUrl);
     if (!ptr.get()) {
         return Kolab::DistList();
     }
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 752c162..b0bfd8d 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -18,9 +18,20 @@
 #ifndef XCALCONVERSIONS_H
 #define XCALCONVERSIONS_H
 
-#include "genericxcalconverions.h"
+#include "global_definitions.h"
 
+#include <bindings/kolabformat-xcal.hxx>
+#include <bindings/iCalendar-props.hxx>
+#include <compiled/XMLParserWrapper.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/numeric/conversion/converter_policies.hpp>
+#include <boost/numeric/conversion/cast.hpp>
 #include <boost/foreach.hpp>
+
+#include <fstream>
+#include <iostream>
+
 #include <boost/lexical_cast.hpp>
 
 #include "kolabcontainers.h"
@@ -30,20 +41,100 @@
 #include "base64.h"
 
 namespace Kolab {
+    namespace XCAL {
 
-class Incidence;
 
-//TODO we can get rid of this construct (was used for the kcalcore/kolab in parallel masterplan)
-struct KolabTypes
-{
-    typedef DateTime DateType;
-    typedef boost::shared_ptr<DateTime> DatePtr;
-    typedef RecurrenceRule RecurrenceType;
-    typedef std::auto_ptr<RecurrenceRule> RecurrencePtr;
-    typedef std::string StringType;
-    typedef Incidence IncidenceType;
-};
+const char* const XCAL_VERSION = "2.0";
+const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
+
+const char* const TZ_PREFIX = "/kolab.org/";
+
+const char* const THISANDFUTURE = "THISANDFUTURE";
+
+const char* const BASE64 = "BASE64";
+
+const char* const NEEDSACTION = "NEEDS-ACTION";
+const char* const COMPLETED = "OPAQUE";
+const char* const INPROCESS = "IN-PROCESS";
+const char* const CANCELLED = "CANCELLED";
+const char* const TENTATIVE = "TENTATIVE";
+const char* const CONFIRMED = "CONFIRMED";
+const char* const DRAFT = "DRAFT";
+const char* const FINAL = "FINAL";
+
+const char* const CONFIDENTIAL = "CONFIDENTIAL";
+const char* const PRIVATE = "PRIVATE";
+const char* const PUBLIC = "PUBLIC";
+
+const char* const PARTACCEPTED = "ACCEPTED";
+const char* const PARTDECLINED = "DECLINED";
+const char* const PARTDELEGATED = "DELEGATED";
+const char* const PARTNEEDSACTION = "NEEDS-ACTION";
+const char* const PARTTENTATIVE = "TENTATIVE";
+
+const char* const CHAIR = "CHAIR";
+const char* const NONPARTICIPANT = "NON-PARTICIPANT";
+const char* const OPTIONAL = "OPT-PARTICIPANT";
+const char* const REQUIRED = "REQ-PARTICIPANT";
+
+const char* const DISPLAYALARM = "DISPLAY";
+const char* const EMAILALARM = "EMAIL";
+const char* const AUDIOALARM = "AUDIO";
+
+const char* const TRANSPARENT = "TRANSPARENT";
+const char* const OPAQUE = "OPAQUE";
+
+const char* const MO = "MO";
+const char* const TU = "TU";
+const char* const WE = "WE";
+const char* const TH = "TH";
+const char* const FR = "FR";
+const char* const SA = "SA";
+const char* const SU = "SU";
+
+//Alarms
+const char* const START = "START";
+const char* const END = "END";
+
+//=== Generic Conversions ===
     
+template <typename T>
+int convertToInt(T integer)
+{
+    try {
+        int i = boost::numeric_cast<int>(integer);
+        return i;
+    } catch(boost::numeric::negative_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cerr << e.what();
+    }
+    return 0;
+}
+
+template <typename T> 
+T fromInt(int integer)
+{
+    try {
+        T i = boost::numeric_cast<T>(integer);
+        return i;
+    } catch(boost::numeric::negative_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::positive_overflow& e) {
+        std::cerr << e.what();
+    } catch(boost::numeric::bad_numeric_cast& e) {
+        std::cerr << e.what();
+    }
+    return 0;
+}
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+    return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
+}
+
 std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
 {
     std::vector<std::string> d;
@@ -66,13 +157,7 @@ std::string toString(const icalendar_2_0::TextPropertyType &s)
 }
 
 
-const char* const MO = "MO";
-const char* const TU = "TU";
-const char* const WE = "WE";
-const char* const TH = "TH";
-const char* const FR = "FR";
-const char* const SA = "SA";
-const char* const SU = "SU";
+
 
 std::string fromDayPos(const Kolab::DayPos &d)
 {   
@@ -287,29 +372,94 @@ Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
     }
     return Duration(days, hours, minutes, seconds, negative);
 }
-// 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>
+
+
+
+void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string &email, std::string &name)
 {
-    typedef DateTime Type;
-    typedef boost::shared_ptr<DateTime> Ptr;
+    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();
+}
 
-    static Ptr toDate(const  xml_schema::date &dt)
+
+template <typename T>
+Kolab::Attachment toAttachment(T aProp)
+{
+    Kolab::Attachment a;
+    std::string mimetype;
+    if (aProp.parameters()) {
+        const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
+        for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+            if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
+                mimetype = p->text();
+            }
+            if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
+                if (p->text() != BASE64) {
+                    std::cerr << "wrong encoding";
+                    return Kolab::Attachment();
+                }
+            }
+            if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
+                a.setLabel(p->text());
+            }
+        }
+    }
+    if (mimetype.empty()) {
+        std::cerr << "no mimetype" << std::endl;
+    }
+
+    if (aProp.uri()) {
+        a.setUri(*aProp.uri(), mimetype);
+    } else if (aProp.binary()) {
+        a.setData(base64_decode(*aProp.binary()), mimetype);
+    } else {
+        std::cerr << "not uri and no data available" << std::endl;
+    }
+    return a;
+}
+
+icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
+{
+    icalendar_2_0::AttachPropType attachment;
+    icalendar_2_0::AttachPropType::parameters_type p;
+    p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
+    if (!a.label().empty()) {
+        p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
+    }
+    
+    if (!a.uri().empty()) {
+        attachment.uri(a.uri());
+    } else  if (!a.data().empty()) {
+        attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
+        p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
+    } else {
+        std::cerr << "no uri and no data" << std::endl;
+    }
+    
+    attachment.parameters(p);
+    return attachment;
+}
+
+//==== DateTime ====
+
+typedef boost::shared_ptr<DateTime> DateTimePtr;
+
+    static DateTimePtr toDate(const  xml_schema::date &dt)
     {
-        Ptr date(new DateTime());
+        DateTimePtr date(new DateTime());
         date->setDate(dt.year(), dt.month(), dt.day());
         return date;
     }
 
-    static Ptr toDate(const xml_schema::date_time &dt)
+    static DateTimePtr toDate(const xml_schema::date_time &dt)
     {
-        Ptr date(new DateTime());
+        DateTimePtr date(new DateTime());
         date->setDate(dt.year(), dt.month(), dt.day());
         date->setTime(dt.hours(), dt.minutes(), dt.seconds());
         if (dt.zone_present()) {
@@ -335,71 +485,250 @@ template <> struct DateTimeConverter<DateTime>
         return date;
     }
 
-    static void setTimezone(Ptr date, const std::string &tzid)
-    {
-        date->setTimezone(tzid);
+    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::cerr << "/kolab.org/ timezone prefix is missing";
+            }
+            return tzid;
+        }
     }
+    return std::string();
+}
 
-    static std::string getTimezone(const DateTime &dt)
-    {
-        return dt.timezone();
+DateTimePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+    DateTimePtr date;
+    if (dtProperty.date_time()) {
+        date = toDate(*dtProperty.date_time());
+    } else if (dtProperty.date()) {
+        date = toDate(*dtProperty.date());
     }
 
-    static void setUTC(Ptr date)
-    {
-        date->setUTC(true);
+    if (dtProperty.parameters()) {
+        const std::string &tzid = getTimezone(*dtProperty.parameters());
+        if (tzid.size()) {
+            date->setTimezone(tzid);
+        }
     }
+    return date;
+}
 
-    static bool isDateOnly(Type date)
-    {
-        return date.isDateOnly();
+
+DateTimePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+    DateTimePtr date;
+    if (dtProperty.date_time()) {
+        date = toDate(*dtProperty.date_time());
+    } else { //The utc-date-time element shouldn't even exist
+        date = DateTimePtr(new DateTime());
+        std::cerr << "This element shouldn't even be existing";
+        //TODO Implement anyways?
+        return date;
     }
+    date->setUTC(true);
+    return date;
+}
 
-};
+template <typename I>
+std::auto_ptr<I> fromDate(const DateTime &dt)
+{
+    std::auto_ptr<I> ptr(new I);
+    if (dt.isDateOnly()) {
+        ptr->date(fromDate(dt));
+    } else {
+        ptr->date_time(fromDateTime(dt));
 
+        const std::string &timezone = dt.timezone();
+        if (timezone.size() != 0) {
+            std::string tz(TZ_PREFIX);
+            tz.append(timezone);
+            icalendar_2_0::TzidParamType tzidParam(tz);
+            icalendar_2_0::ArrayOfParameters parameters;
+            parameters.baseParameter().push_back(tzidParam);
+            ptr->parameters(parameters);
+        }
+    }
+    return ptr;
+}
+
+
+template <typename I>
+std::vector<DateTime> toDateTimeList(I datelistProperty)
+{
+    std::vector<DateTime>  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(*toDate(d));
+        }
+    } else if (!datelistProperty.date_time().empty()) {
+        BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
+            DateTimePtr date = toDate(d);
+            if (tzid.size()) {
+                date->setTimezone(tzid);
+            }
+            list.push_back(*date);
+        }
+    }
+    return list;
+}
+
+template <typename I>
+std::auto_ptr<I> fromDateTimeList(const std::vector<DateTime> &dtlist)
+{
+    
+    std::auto_ptr<I> ptr(new I);
+    BOOST_FOREACH(const DateTime &dt, dtlist) {
+        if (dt.isDateOnly()) {
+            ptr->date().push_back(fromDate(dt));
+        } else {
+            ptr->date_time().push_back(fromDateTime(dt));
+        }
+        //TODO handle utc
+        //TODO check for equality of timezones?
+    }
+    
+    if (!dtlist.empty() && !dtlist.at(0).timezone().empty()) {
+        const std::string &timezone = dtlist.at(0).timezone();
+        if (timezone.size() != 0) {
+            std::string tz(TZ_PREFIX);
+            tz.append(timezone);
+            icalendar_2_0::TzidParamType tzidParam(tz);
+            icalendar_2_0::ArrayOfParameters parameters;
+            parameters.baseParameter().push_back(tzidParam);
+            ptr->parameters(parameters);
+        }
+    }
+    
+    return ptr;
+}
+
+    
+
+//---- DateTime ----
+
+
+
+//----------------
 
-template <> struct RecurrenceConverter < RecurrenceRule >
+//=== Attendee ===
+
+std::string mapPartStat(PartStatus status)
+{
+    switch (status) {
+        case PartAccepted:
+            return PARTACCEPTED;
+        case PartDeclined:
+            return PARTDECLINED;
+        case PartDelegated:
+            return PARTDELEGATED;
+        case PartNeedsAction:
+            return PARTNEEDSACTION;
+        case PartTentative:
+            return PARTTENTATIVE;
+    }
+    std::cout << "PartStat not handled: " << status;
+    return std::string();
+}
+
+PartStatus mapPartStat(const std::string &status)
 {
+    if (status == PARTACCEPTED) {
+        return PartAccepted;
+    } else if (status == PARTDECLINED) {
+        return PartDeclined;
+    } else if (status == PARTDELEGATED) {
+        return PartDelegated;
+    } else if (status == PARTNEEDSACTION) {
+        return PartNeedsAction;
+    } else if (status == PARTTENTATIVE) {
+        return PartTentative;
+    }
+    std::cout << "Unhandled partstatus" << status;
+    return PartNeedsAction;
+}
+
+std::string mapRole(Role status)
+{
+    switch (status) {
+        case Chair:
+            return std::string(CHAIR);
+        case NonParticipant:
+            return NONPARTICIPANT;
+        case Optional:
+            return OPTIONAL;
+        case Required:
+            return REQUIRED;
+    }
+    std::cout << "PartStat not handled: " << status;
+    return std::string();
+}
+
+Role mapRole(const std::string &status)
+{
+    if (status == CHAIR) {
+        return Chair;
+    } else if (status == NONPARTICIPANT) {
+        return NonParticipant;
+    } else if (status == OPTIONAL) {
+        return Optional;
+    } else if (status == REQUIRED) {
+        return Required;
+    }
+    std::cout << "Unhandled Role" << status;
+    return Required;
+}
 
-    typedef KolabTypes::RecurrenceType Type;
-    typedef 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)
+
+
+
+//----------------
+
+//=== Recurrence Rule ===
+
+    typedef std::auto_ptr<RecurrenceRule> RecurrencePtr;
+
+
+    RecurrenceRule::Frequency mapRecurrenceFrequency(const icalendar_2_0::RecurType::freq_type &freq)
     {
         using namespace icalendar_2_0;
         
         switch (freq) {
             case FreqRecurType::YEARLY:
-                r->setFrequency(RecurrenceRule::Yearly);
-                break;
+                return RecurrenceRule::Yearly;
             case FreqRecurType::MONTHLY:
-                r->setFrequency(RecurrenceRule::Monthly);
-                break;
+                return RecurrenceRule::Monthly;
             case FreqRecurType::WEEKLY:
-                r->setFrequency(RecurrenceRule::Weekly);
-                break;
+                return RecurrenceRule::Weekly;
             case FreqRecurType::DAILY:
-                r->setFrequency(RecurrenceRule::Daily);
-                break;
+                return RecurrenceRule::Daily;
             case FreqRecurType::HOURLY:
-                r->setFrequency(RecurrenceRule::Hourly);
-                break;
+                return RecurrenceRule::Hourly;
             case FreqRecurType::MINUTELY:
-                r->setFrequency(RecurrenceRule::Minutely);
-                break;
+                return RecurrenceRule::Minutely;
             case FreqRecurType::SECONDLY:
-                r->setFrequency(RecurrenceRule::Secondly);
-                break;
+                return RecurrenceRule::Secondly;
             default:
                 std::cout << "invalid unhandled recurrenc type" << freq;
         }
+        return RecurrenceRule::None;
     }
     
-    static icalendar_2_0::RecurType::freq_type type(const Type &t)
+    icalendar_2_0::RecurType::freq_type mapRecurrenceFrequency(RecurrenceRule::Frequency freq)
     {
         using namespace icalendar_2_0;
 
-        switch (t.frequency()) {
+        switch (freq) {
             case RecurrenceRule::Yearly:
                 return FreqRecurType::YEARLY;
             case RecurrenceRule::Monthly:
@@ -420,7 +749,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
         return 0;
     }
     
-    static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
+    static void setWeekStart(RecurrencePtr &r, const icalendar_2_0::RecurType::wkst_type &wkst)
     {
         using namespace icalendar_2_0;
 
@@ -451,49 +780,8 @@ template <> struct RecurrenceConverter < RecurrenceRule >
         }
     }
 
-    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)
+    static void setByday(RecurrencePtr &r, const icalendar_2_0::RecurType::byday_sequence &list)
     {
         std::vector<DayPos> by;
         for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
@@ -501,109 +789,63 @@ template <> struct RecurrenceConverter < RecurrenceRule >
         }
         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)
-    {
+
+    template <typename T, typename I>
+    std::vector<int> bylist(const xsd::cxx::tree::sequence <T> &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));
+        BOOST_FOREACH(const T i, list) {
+            by.push_back(convertToInt<I>(i));
         }
-        r->setByweekno(by);
+        return by;
     }
     
-    static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
-    {
-        std::vector<int> by;
-        for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
-            by.push_back(convertToInt<xml_schema::integer>(*it));
-        }
-        r->setBymonth(by);
-    }
-};
-
-
-void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string &email, std::string &name)
+RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
 {
-    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 T> setProperty(T::parameters_type::baseParameter_const_iterator it, void (*set)(std::string))
-// {
-//     if (const T * p = dynamic_cast<const T*> (&*it)) {
-//         set(p->text());
-//     }
-// }
+    using namespace icalendar_2_0;
 
-template <typename T>
-Kolab::Attachment toAttachment(T aProp)
-{
-    Kolab::Attachment a;
-    std::string mimetype;
-    if (aProp.parameters()) {
-        const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
-        for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-            if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
-                mimetype = p->text();
-            }
-            if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
-                if (p->text() != BASE64) {
-                    std::cerr << "wrong encoding";
-                    return Kolab::Attachment();
-                }
-            }
-            if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
-                a.setLabel(p->text());
-            }
+    RecurrencePtr r(new RecurrenceRule());
+    r->setFrequency(mapRecurrenceFrequency(rrule.freq()));
+    if (rrule.until()) {
+        DateTimePtr date;
+        if ((*rrule.until()).date_time()) {
+            date = toDate(*(*rrule.until()).date_time());
+        } else if ((*rrule.until()).date()) {
+            date = toDate(*(*rrule.until()).date());
         }
+        r->setEnd(*date);
+    } else if (rrule.count()) {
+        r->setCount(toInt(*rrule.count()));
     }
-    if (mimetype.empty()) {
-        std::cerr << "no mimetype" << std::endl;
-    }
-
-    if (aProp.uri()) {
-        a.setUri(*aProp.uri(), mimetype);
-    } else if (aProp.binary()) {
-        a.setData(base64_decode(*aProp.binary()), mimetype);
+    if (rrule.interval()) {
+        r->setInterval(toInt(*rrule.interval()));
     } else {
-        std::cerr << "not uri and no data available" << std::endl;
-    }
-    return a;
+        r->setInterval(1);
+    }
+    r->setBysecond(bylist<RecurType::bysecond_type, xml_schema::non_negative_integer>(rrule.bysecond()));
+    r->setByminute(bylist<RecurType::byminute_type, xml_schema::non_negative_integer>(rrule.byminute()));
+    r->setByhour(bylist<RecurType::byhour_type, xml_schema::non_negative_integer>(rrule.byhour()));
+    setByday(r, rrule.byday());
+    r->setBymonthday(bylist<RecurType::bymonthday_type, xml_schema::integer>(rrule.bymonthday()));
+    r->setByyearday(bylist<RecurType::byyearday_type, xml_schema::integer>(rrule.byyearday()));
+    r->setByweekno(bylist<RecurType::byweekno_type, xml_schema::integer>(rrule.byweekno()));
+    r->setBymonth(bylist<RecurType::bymonth_type, xml_schema::integer>(rrule.bymonth()));
+    if (rrule.wkst()) {
+        setWeekStart(r, *rrule.wkst());
+    }
+    return r;
 }
+    
+//--- Recurrence Rule ---
+
 
 
 template <typename I, typename T>
 void setIncidenceProperties(I &inc, const T &prop)
-{
-    typedef DateTimeConverter<Kolab::DateTime> DC;
-    
+{    
     inc.setUid(toString(prop.uid()));
-    inc.setCreated(*toDate<KolabTypes>(prop.created()));
-    inc.setLastModified(*toDate<KolabTypes>(prop.dtstamp()));
+    inc.setCreated(*toDate(prop.created()));
+    inc.setLastModified(*toDate(prop.dtstamp()));
 
     if (prop.sequence()) {
         inc.setSequence(toInt(*prop.sequence()));
@@ -625,24 +867,24 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     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
+        const DateTimePtr date = toDate(*prop.dtstart());
+        inc.setStart(*date);
     }
 
     if (prop.rrule()) {
-       KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
+       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
        inc.setRecurrenceRule(*rrule);
     }
 
     if (prop.rdate()) {
-        inc.setRecurrenceDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
+        inc.setRecurrenceDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
         if (!prop.rdate()->period().empty()) {
             std::cout << "the period element must not be used, ignored." << std::endl;
         }
     }
 
     if (prop.exdate()) {
-       inc.setExceptionDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
+       inc.setExceptionDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
     }
     
     if (prop.recurrence_id()) {
@@ -655,7 +897,7 @@ void setIncidenceProperties(I &inc, const T &prop)
                 }
             }
         }
-        inc.setRecurrenceID(*toDate<KolabTypes>(*prop.recurrence_id()), thisandfuture);
+        inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture);
     }
     
     if (prop.summary()) {
@@ -774,20 +1016,17 @@ T fromList(const std::vector<int> &input) {
 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)));
+        
+    std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(mapRecurrenceFrequency(r.frequency())));
     
     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));
+            until.date(fromDate(endDate));
         } else {
-            until.date_time(DC::fromDateTime(endDate));
+            until.date_time(fromDateTime(endDate));
         }
         recur.until(until);
     } else if (r.count() > 0) {
@@ -837,27 +1076,7 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
     return rruleProp;
 }
 
-icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
-{
-    icalendar_2_0::AttachPropType attachment;
-    icalendar_2_0::AttachPropType::parameters_type p;
-    p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
-    if (!a.label().empty()) {
-        p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
-    }
-    
-    if (!a.uri().empty()) {
-        attachment.uri(a.uri());
-    } else  if (!a.data().empty()) {
-        attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
-        p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
-    } else {
-        std::cerr << "no uri and no data" << std::endl;
-    }
-    
-    attachment.parameters(p);
-    return attachment;
-}
+
 
 
 template <typename T, typename I>
@@ -866,7 +1085,6 @@ void getIncidenceProperties(T &prop, const I &inc)
     using namespace icalendar_2_0;
     
     typedef T properties; 
-    typedef DateTimeConverter< DateTime> DC;
     
     prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
     
@@ -887,7 +1105,7 @@ void getIncidenceProperties(T &prop, const I &inc)
     }
 
     if (inc.start().isValid()) {
-        prop.dtstart(fromDate<KolabTypes, typename properties::dtstart_type>(inc.start()));
+        prop.dtstart(fromDate<typename properties::dtstart_type>(inc.start()));
     }
     
     if (inc.recurrenceRule().isValid()) {
@@ -898,15 +1116,15 @@ void getIncidenceProperties(T &prop, const I &inc)
     }
     
     if (!inc.recurrenceDates().empty()) {
-        prop.rdate(fromDateTimeList<KolabTypes, typename properties::rdate_type>(inc.recurrenceDates()));
+        prop.rdate(fromDateTimeList<typename properties::rdate_type>(inc.recurrenceDates()));
     }
     
     if (!inc.exceptionDates().empty()) {
-        prop.exdate(fromDateTimeList<KolabTypes, typename properties::exdate_type>(inc.exceptionDates()));
+        prop.exdate(fromDateTimeList<typename properties::exdate_type>(inc.exceptionDates()));
     }
     
     if (inc.recurrenceID().isValid()) {
-        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID());
+        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<typename properties::recurrence_id_type>(inc.recurrenceID());
         if (inc.thisAndFuture()) {
             if (!recurrenceId->parameters()) {
                 recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
@@ -1027,20 +1245,18 @@ void getIncidenceProperties(T &prop, const I &inc)
 
 }
 
-const char* const START = "START";
-const char* const END = "END";
+//=== Alarms ===
 
 template <typename KolabType, typename IncidenceType>
 void setAlarms(typename KolabType::components_type& components, const IncidenceType &incidence)
 {
-    typedef DateTimeConverter< DateTime> DC;
     BOOST_FOREACH(const Kolab::Alarm &alarm, incidence.alarms()) {
         typedef icalendar_2_0::ValarmType::properties_type PropType;
         
         PropType::trigger_type trigger;
         if (alarm.start().isValid()) {
             
-            trigger.date_time(DC::fromDateTime(alarm.start()));
+            trigger.date_time(fromDateTime(alarm.start()));
         } else {
             if (!alarm.relativeStart().isValid()) {
                 std::cerr << "no start and no relativeStart" << std::endl;
@@ -1088,15 +1304,6 @@ void setAlarms(typename KolabType::components_type& components, const IncidenceT
     }
 }
 
-// typename KolabTypes::DatePtr toDate(const icalendar_2_0::DateTimeType &dtProperty)
-// {
-//     typedef DateTimeConverter<Kolab::DateTime> DC;
-//     typename KolabTypes::DatePtr date;
-//     if (dtProperty.date_time()) {
-//         date = DC::toDate(dtProperty.date_time());
-//     }
-//     return date;
-// }
 
 
 template <typename IncidenceType, typename KolabType>
@@ -1141,7 +1348,7 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
         }
         
         if (prop.trigger().date_time()) {
-            alarm.setStart(*DateTimeConverter<Kolab::DateTime>::toDate(*prop.trigger().date_time()));
+            alarm.setStart(*toDate(*prop.trigger().date_time()));
             if (!alarm.start().isUTC()) {
                 std::cerr << "The start date time must be in UTC "<< std::endl;
                 continue;
@@ -1179,9 +1386,16 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
     incidence.setAlarms(alarms);
 }
 
+//--- Alarms ---
+
+class Incidence; //Just for Trait
+
+///Trait for Incidence object
+template <typename T, typename I> 
+struct IncidenceConverter;
+
 template <typename T> struct IncidenceConverter < Incidence, T >
 {
-    typedef DateTimeConverter< DateTime> DC;
     static std::string uid(const T &inc) {
         if (inc.uid().empty()) { //generate new UID
             return getUID();
@@ -1190,58 +1404,58 @@ template <typename T> struct IncidenceConverter < Incidence, T >
     }
     
     static xml_schema::date_time dtstamp() {
-        return DC::fromDateTime(getCurrentTime());
+        return fromDateTime(getCurrentTime());
     }
     
     static xml_schema::date_time created(const T &inc) {
         if (inc.created().isValid()) {
-            return DC::fromDateTime(inc.created());
+            return fromDateTime(inc.created());
         }
-        return DC::fromDateTime(getCurrentTime());
+        return fromDateTime(getCurrentTime());
     }
 
 };
 
-const char* const TRANSPARENT = "TRANSPARENT";
-const char* const OPAQUE = "OPAQUE";
+
+///Trait for incidence properties specialized for Event/Todo/Journal
+template <typename T> struct IncidenceTrait;
 
 template < > struct IncidenceTrait <Kolab::Event>
 {
     typedef icalendar_2_0::KolabEvent KolabType;
     typedef Kolab::Event IncidenceType;
     typedef boost::shared_ptr<Kolab::Event> IncidencePtr;
-    typedef Kolab::Incidence Incidence;
-    
+
     static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
     {
-        KolabType::properties_type &prop = vevent.properties();
-        
-        getIncidenceProperties<KolabType::properties_type>(prop, event);
+        icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+        getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
 
         if (event.end().isValid()) {
-            prop.dtend(fromDate<KolabTypes, KolabType::properties_type::dtend_type>(event.end()));
+            prop.dtend(fromDate<icalendar_2_0::KolabEvent::properties_type::dtend_type>(event.end()));
         } else if (event.duration().isValid()) {
-            prop.duration(KolabType::properties_type::duration_type(fromDuration(event.duration())));
+            prop.duration(icalendar_2_0::KolabEvent::properties_type::duration_type(fromDuration(event.duration())));
         }
         
         if (event.transparency()) {
-            prop.transp( KolabType::properties_type::transp_type(TRANSPARENT));
+            prop.transp( icalendar_2_0::KolabEvent::properties_type::transp_type(TRANSPARENT));
         }
     }
     
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabEvent inc) //TODO to base trait
     {
         components.vevent().push_back(inc);
     }
 
     static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
     {
-        const KolabType::properties_type &prop = vevent.properties();
+        const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
 
-        setIncidenceProperties<Kolab::Event, KolabType::properties_type>(event, prop);
+        setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
 
         if (prop.dtend()) {
-            event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
+            event.setEnd(*toDate(*prop.dtend()));
             if (event.end().isUTC() != event.end().isUTC() && 
                 event.end().timezone() != event.end().timezone() &&
                 event.end().isDateOnly() != event.end().isDateOnly()) {
@@ -1262,13 +1476,13 @@ template < > struct IncidenceTrait <Kolab::Event>
             }
         }
         if (vevent.components()) {
-            getAlarms<IncidenceType, KolabType>(event, *vevent.components());
+            getAlarms<Kolab::Event, icalendar_2_0::KolabEvent>(event, *vevent.components());
         }
     }
     
-    static void setComponents(KolabType::components_type& components, const Kolab::Event &incidence)
+    static void setComponents(icalendar_2_0::KolabEvent::components_type& components, const Kolab::Event &incidence)
     {
-        setAlarms<KolabType, IncidenceType>(components, incidence);
+        setAlarms<icalendar_2_0::KolabEvent, Kolab::Event>(components, incidence);
     }
      
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
@@ -1288,59 +1502,58 @@ template < > struct IncidenceTrait <Kolab::Todo>
     typedef icalendar_2_0::KolabTodo KolabType;
     typedef Kolab::Todo IncidenceType;
     typedef boost::shared_ptr<Kolab::Todo> IncidencePtr;
-    typedef Kolab::Incidence Incidence;
-    
-    static void writeIncidence(KolabType& vevent, const Kolab::Todo &todo)
+
+    static void writeIncidence(icalendar_2_0::KolabTodo& vevent, const Kolab::Todo &todo)
     {
-        KolabType::properties_type &prop = vevent.properties();
+        icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
         
-        getIncidenceProperties<KolabType::properties_type>(prop, todo);
+        getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
 
         if (!todo.relatedTo().empty()) {
-            KolabType::properties_type::related_to_sequence list;
+            icalendar_2_0::KolabTodo::properties_type::related_to_sequence list;
             BOOST_FOREACH(std::string relatedTo, todo.relatedTo()) {
-                list.push_back(KolabType::properties_type::related_to_type(relatedTo));
+                list.push_back(icalendar_2_0::KolabTodo::properties_type::related_to_type(relatedTo));
             }
             prop.related_to(list);
         }
         if (todo.due().isValid()) {
-            prop.due(fromDate<KolabTypes, KolabType::properties_type::due_type>(todo.due()));
+            prop.due(fromDate<icalendar_2_0::KolabTodo::properties_type::due_type>(todo.due()));
         }
         if (todo.percentComplete() > 0) {
-            prop.percent_complete(KolabType::properties_type::percent_complete_type(fromInt<icalendar_2_0::IntegerPropertyType::integer_type>(todo.percentComplete())));
+            prop.percent_complete(icalendar_2_0::KolabTodo::properties_type::percent_complete_type(fromInt<icalendar_2_0::IntegerPropertyType::integer_type>(todo.percentComplete())));
         }
     }
     
-    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabTodo inc) //TODO to base trait
     {
         components.vtodo().push_back(inc);
     }
 
     static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
     {
-        const KolabType::properties_type &prop = vevent.properties();
+        const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
 
-        setIncidenceProperties<Kolab::Todo, KolabType::properties_type>(todo, prop);
+        setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
 
         if (!prop.related_to().empty()) {
-            BOOST_FOREACH(KolabType::properties_type::related_to_type p, prop.related_to()) {
+            BOOST_FOREACH(icalendar_2_0::KolabTodo::properties_type::related_to_type p, prop.related_to()) {
                 todo.addRelatedTo(p.text());
             }
         }
         if (prop.due()) {
-            todo.setDue(*toDate<KolabTypes>(*prop.due()));
+            todo.setDue(*toDate(*prop.due()));
         }
         if (prop.percent_complete()) {
             todo.setPercentComplete(toInt(*prop.percent_complete()));
         }
         if (vevent.components()) {
-            getAlarms<IncidenceType, KolabType>(todo, *vevent.components());
+            getAlarms<Kolab::Todo, icalendar_2_0::KolabTodo>(todo, *vevent.components());
         }
     }
     
-    static void setComponents(KolabType::components_type& components, const Kolab::Todo &incidence)
+    static void setComponents(icalendar_2_0::KolabTodo::components_type& components, const Kolab::Todo &incidence)
     {
-        setAlarms<KolabType, IncidenceType>(components, incidence);
+        setAlarms<icalendar_2_0::KolabTodo, IncidenceType>(components, incidence);
     }
      
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
@@ -1356,6 +1569,121 @@ template < > struct IncidenceTrait <Kolab::Todo>
 };
 
 
+//////////////////////////////////=========================================
+
+
+template <typename T>
+std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
+    
+    using namespace icalendar_2_0;
+    typedef IncidenceConverter< Incidence, typename T::IncidenceType > IC;
+    typedef typename T::KolabType KolabType;
+
+    try {
+
+        typename KolabType::components_type eventComponents;
+        T::setComponents(eventComponents, incidence);
+
+        typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
+        typename KolabType::properties_type::dtstamp_type dtstamp;
+        dtstamp.date_time(IC::dtstamp());
+        typename KolabType::properties_type::created_type created;
+        created.date_time(IC::created(incidence));
+        typename KolabType::properties_type eventProps(uid, created, dtstamp);
+        
+        KolabType inc(eventProps);
+        if (!eventComponents.valarm().empty()) {
+            inc.components(eventComponents);
+        }
+        T::writeIncidence(inc, incidence);
+
+        
+        VcalendarType::components_type components;
+        T::addIncidence(components, inc);
+        
+        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME+KOLAB_LIB_VERSION); //FIXME own version field for lib version
+        VcalendarType::properties_type::version_type version(XCAL_VERSION);
+        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION);
+        
+        VcalendarType::properties_type properties(prodid, version, x_kolab_version);
+        
+        VcalendarType vcalendar(properties, components);
+        
+        IcalendarType icalendar(vcalendar);
+
+        xml_schema::namespace_infomap map;
+        map[""].name = XCAL_NAMESPACE;
+        
+        std::ostringstream ostringstream;
+        icalendar_2_0::icalendar(ostringstream, icalendar, map);
+        return ostringstream.str();
+    } catch  (const xml_schema::exception& e) {
+        std::cout << "failed to write Incidence" << std::endl;
+    } catch (...) {
+        std::cerr <<  "Unhandled exception" << std::endl;
+    }
+    return std::string();
+}
+
+
+template <typename T>
+typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
+{
+    typedef typename T::IncidencePtr IncidencePtr;
+    typedef typename T::IncidenceType IncidenceType;
+    typedef typename T::KolabType KolabType;
+    
+    try {
+        std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+        if (isUrl) {
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+        } else {
+            xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
+            if (doc.get()) {
+                icalendar = icalendar_2_0::icalendar(doc);
+            }
+        }
+        
+        if (!icalendar.get()) {
+            std::cerr << "failed to parse calendar!" << std::endl;
+            return IncidencePtr();
+        }
+
+        const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
+
+        std::vector < IncidencePtr > incidences;
+        for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
+            IncidencePtr e = IncidencePtr(new IncidenceType);
+            const KolabType &event = *it;
+            T::readIncidence(*e, event);
+            incidences.push_back(e);
+        }
+        
+        //TODO x_kolab_version
+
+        //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+//         foreach (KCalCore::Event * event, events) {
+//             if (!event->hasRecurrenceId()) {
+//                 return event;
+//             }
+//         }
+        if (incidences.size() != 1) {
+            std::cerr << "wrong number of incidences: " << incidences.size() << std::endl;
+        }
+        return *incidences.begin();
+    } catch  (const xml_schema::exception& e) {
+        std::cerr <<  e << std::endl;
+        std::cerr <<  "Failed to read incidence!" << std::endl;
+    } catch (...) {
+        std::cerr <<  "Unhandled exception" << std::endl;
+    }
+    return IncidencePtr();
+}
+
+    }
 }//Namespace
 
 #endif
\ No newline at end of file
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index 9a89863..d9443ed 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -25,11 +25,12 @@
 #include "global_definitions.h"
 #include "utils.h"
 
-const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
-const char* const INDIVIDUAL = "individual";
-const char* const GROUP = "group";
-
 namespace Kolab {
+    namespace XCARD {
+        
+    const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0";
+    const char* const INDIVIDUAL = "individual";
+    const char* const GROUP = "group";
     
 template <typename T> 
 std::string getType();
@@ -151,6 +152,8 @@ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
 
     return boost::shared_ptr<T>();
 }
+
+    }
     
 } //Namespace
 
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 9a78104..a3b7899 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -8,10 +8,10 @@ if (QT4_FOUND AND KDECORE_FOUND AND KCALCORE_FOUND)
     QT4_AUTOMOC(bindingstest.cpp)
     add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
     target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml kolabkcal ${XERCES_C})
-
-    QT4_AUTOMOC(kcalconversiontest.cpp)
-    add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxmlkcal ${XERCES_C})
+# 
+#     QT4_AUTOMOC(kcalconversiontest.cpp)
+#     add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+#     target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxmlkcal ${XERCES_C})
 
     QT4_AUTOMOC(conversiontest.cpp)
     add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC})
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
index cb9367c..5fe8f5e 100644
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@ -7,6 +7,8 @@
 
 Q_DECLARE_METATYPE(Kolab::Duration);
 Q_DECLARE_METATYPE(Kolab::DayPos);
+
+using namespace Kolab::XCAL;
  
 void ConversionTest::durationParserTest_data()
 {
@@ -23,7 +25,7 @@ void ConversionTest::durationParserTest()
 {
     QFETCH(QString, string);
     QFETCH(Kolab::Duration, expected);
-    const Kolab::Duration result = Kolab::toDuration(string.toStdString());
+    const Kolab::Duration result = toDuration(string.toStdString());
     QCOMPARE(result, expected);
 }
 
@@ -35,6 +37,7 @@ void ConversionTest::durationSerializerTest_data()
     QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false);
     QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false);
     QTest::newRow("Week") << "P1W" << Kolab::Duration(1, false);
+    QTest::newRow("Week") << "-P3W" << Kolab::Duration(3, false);
     QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true);
 }
 
@@ -42,7 +45,7 @@ void ConversionTest::durationSerializerTest()
 {
     QFETCH(Kolab::Duration, duration);
     QFETCH(QString, expected);
-    const std::string result = Kolab::fromDuration(duration);
+    const std::string result = fromDuration(duration);
     QCOMPARE(QString::fromStdString(result), expected);
 }
 
@@ -63,7 +66,7 @@ void ConversionTest::dayPosParserTest()
 {
     QFETCH(QString, string);
     QFETCH(Kolab::DayPos, expected);
-    const Kolab::DayPos result = Kolab::toDayPos(string.toStdString());
+    const Kolab::DayPos result = toDayPos(string.toStdString());
     QCOMPARE(result, expected);
 }
 
@@ -82,7 +85,7 @@ void ConversionTest::dayPosSerializerTest()
 {
     QFETCH(Kolab::DayPos, daypos);
     QFETCH(QString, expected);
-    const std::string result = Kolab::fromDayPos(daypos);
+    const std::string result = fromDayPos(daypos);
     QCOMPARE(QString::fromStdString(result), expected);
 }
 
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 4a01e7b..ee5061d 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -4,7 +4,7 @@
 #include <QtTest/QtTest>
 #include <kcalcore/recurrence.h>
 
-#include <lib/kcalconversions.h>
+// #include <lib/kcalconversions.h>
 #include <lib/kcalkolabformat.h>
 
 


commit 89b8aaf37945cdaed93ab34274c08672cc475a1b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Feb 7 02:07:56 2012 +0100

    Implemented alarms.

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index 7bf3cff..6c879d5 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -224,6 +224,7 @@ typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProp
     return date;
 }
 
+
 // template <typename T, typename I> 
 // typename T::DatePtr toDate(const I &dtProperty)
 // {
@@ -290,7 +291,6 @@ std::auto_ptr<I> fromDate(const typename T::DateType &dt)
     return ptr;
 }
 
-
 template <typename T>
 void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
 {
@@ -436,8 +436,6 @@ template <typename T> struct IncidenceTrait;
 
 
 
-
-
 template <typename T>
 typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 {
@@ -500,6 +498,10 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
 }
 
 
+const char* const DISPLAYALARM = "DISPLAY";
+const char* const EMAILALARM = "EMAIL";
+const char* const AUDIOALARM = "AUDIO";
+
 
 template <typename T>
 std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) {
@@ -511,6 +513,7 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
     try {
 
         typename KolabType::components_type eventComponents;
+        T::setComponents(eventComponents, incidence);
 
         typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
         typename KolabType::properties_type::dtstamp_type dtstamp;
@@ -519,8 +522,12 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
         created.date_time(IC::created(incidence));
         typename KolabType::properties_type eventProps(uid, created, dtstamp);
         
-        KolabType inc(eventProps, eventComponents);
+        KolabType inc(eventProps);
+        if (!eventComponents.valarm().empty()) {
+            inc.components(eventComponents);
+        }
         T::writeIncidence(inc, incidence);
+
         
         VcalendarType::components_type components;
         T::addIncidence(components, inc);
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 00aa254..d805194 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -545,18 +545,18 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
     
     switch (inc.secrecy()) {
         case Incidence::SecrecyConfidential:
-            prop.class_(properties::class_type("CONFIDENTIAL"));
+            prop.class_(typename T::class_type("CONFIDENTIAL"));
             break;
         case Incidence::SecrecyPrivate:
-            prop.class_(properties::class_type("PRIVATE"));
+            prop.class_(typename T::class_type("PRIVATE"));
             break;
         default:
-            prop.class_(properties::class_type("PUBLIC"));
+            prop.class_(typename T::class_type("PUBLIC"));
             break;
     }
 
     if (inc.dtStart().isValid()) {
-        properties::dtstart_type dtstart;
+        typename T::dtstart_type dtstart;
         setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
         prop.dtstart(dtstart);
     }
@@ -607,7 +607,7 @@ template < > struct IncidenceTrait <KCalCore::Event>
         getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
 
         if (event.hasEndDate() && event.dtEnd().isValid()) {
-            icalendar_2_0::properties::dtend_type dtend;
+            icalendar_2_0::KolabEvent::properties_type::dtend_type dtend;
             setDateTimeProperty<KCalCoreTypes>(dtend, event.dtEnd());
             prop.dtend(dtend);
         } else if (event.hasDuration()) {
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 2a5b6bd..f9ca69a 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -178,15 +178,12 @@ bool DateTime::isUTC() const
 
 std::string DateTime::timezone() const
 {
-        return d->timezone;
+    return d->timezone;
 }
 
 bool DateTime::isValid() const
 {
-    if (d->year >= 0 && d->month >= 0 && d->day >= 0) {
-        return true;
-    }
-    return false;
+    return (d->year >= 0 && d->month >= 0 && d->day >= 0);
 }
 
 struct RecurrenceRule::Private
@@ -518,13 +515,10 @@ Attachment::~Attachment()
 
 bool Attachment::operator==(const Kolab::Attachment &other) const
 {
-    if ( d->uri == other.uri() &&
+    return ( d->uri == other.uri() &&
         d->data == other.data() &&
         d->label == other.label() &&
-        d->mimetype == other.mimetype() ) {
-        return true;
-    }
-    return false;
+        d->mimetype == other.mimetype() );
 }
 
 void Attachment::setUri(const std::string &uri, const std::string& mimetype)
@@ -564,6 +558,165 @@ std::string Attachment::data() const
     return d->data;
 }
 
+bool Attachment::isValid() const
+{
+    return !d->mimetype.empty(); //TODO use isValid variable
+}
+
+
+
+struct Alarm::Private
+{
+    Private(): relativeTo(Start),
+    numrepeat(0),
+    type(Alarm::InvalidAlarm) {};
+    std::string text;
+    Attachment audioFile;
+    std::string summary;
+    std::vector<std::string> attendees;
+    DateTime start;
+    Duration relativeDuration;
+    Relative relativeTo;
+    Duration duration;
+    int numrepeat;
+    Type type;
+    
+};
+
+Alarm::Alarm()
+:   d(new Alarm::Private)
+{
+}
+
+Alarm::Alarm(const std::string &text)
+:   d(new Alarm::Private)
+{
+    d->text = text;
+    d->type = DisplayAlarm;
+}
+
+
+Alarm::Alarm(const Kolab::Attachment& audio)
+:   d(new Alarm::Private)
+{
+    d->audioFile = audio;
+    d->type = AudioAlarm;
+}
+
+Alarm::Alarm(const std::string& summary, const std::string& description, const std::vector< std::string > attendees)
+:   d(new Alarm::Private)
+{
+    d->summary = summary;
+    d->text = description;
+    d->attendees = attendees;
+    d->type = EMailAlarm;
+    
+}
+
+Alarm::Alarm(const Kolab::Alarm &other)
+:   d(new Alarm::Private)
+{
+    *d = *other.d;
+}
+
+void Alarm::operator=(const Kolab::Alarm &other)
+{
+    *d = *other.d;
+}
+
+Alarm::~Alarm()
+{
+}
+
+bool Alarm::operator==(const Kolab::Alarm &other) const
+{
+    return ( d->text == other.description() &&
+        d->text == other.description() &&
+        d->audioFile == other.audioFile() &&
+        d->summary == other.summary() &&
+        d->attendees == other.attendees() &&
+        d->start == other.start() &&
+        d->relativeDuration == other.relativeStart() &&
+        d->relativeTo == other.relativeTo() &&
+        d->duration == other.duration() &&
+        d->numrepeat == other.numrepeat() );
+}
+
+std::string Alarm::text() const
+{
+    return d->text;
+}
+
+Attachment Alarm::audioFile() const
+{
+    return d->audioFile;
+}
+
+std::string Alarm::summary() const
+{
+    return d->summary;
+}
+
+std::string Alarm::description() const
+{
+    return d->text;
+}
+
+std::vector< std::string > Alarm::attendees() const
+{
+    return d->attendees;
+}
+
+void Alarm::setStart(const Kolab::DateTime &start)
+{
+    d->start = start;
+}
+
+DateTime Alarm::start() const
+{
+    return d->start;
+}
+
+void Alarm::setRelativeStart(const Kolab::Duration &duration, Relative relativeTo)
+{
+    d->relativeDuration = duration;
+    d->relativeTo = relativeTo;
+}
+
+Duration Alarm::relativeStart() const
+{
+    return d->relativeDuration;
+}
+
+Relative Alarm::relativeTo() const
+{
+    return d->relativeTo;
+}
+
+void Alarm::setDuration(const Kolab::Duration &duration, int numrepeat)
+{
+    d->numrepeat = numrepeat;
+    d->duration = duration;
+}
+
+Duration Alarm::duration() const
+{
+    return d->duration;
+}
+
+int Alarm::numrepeat() const
+{
+    return d->numrepeat;
+}
+
+Alarm::Type Alarm::type() const
+{
+    return d->type;
+}
+
+
+
+
 
 
 }//Namespace
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index c4d3dd1..6f43ac8 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -99,21 +99,118 @@ private:
     bool mIsValid;
 };
 
-enum Related {
+class Attachment {
+public:
+    Attachment();
+    Attachment(const Kolab::Attachment &);
+    ~Attachment();
+
+    void operator=(const Attachment &);
+    bool operator==(const Attachment &) const;
+
+    void setUri(const std::string &uri, const std::string &mimetype);
+    std::string uri() const;
+
+     ///Un-encoded binary content, Implies embedded, will be encoded
+     void setData(const std::string &, const std::string &mimetype);
+     ///Decoded binary content.
+     std::string data() const;
+     //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement?
+//     ///Base64 encoded binary content, Implies embedded
+//      void setEncodedData(const std::string &, const std::string &mimetype);
+
+    std::string mimetype() const;
+
+    ///User visible label
+    void setLabel(const std::string &);
+    std::string label() const;
+    
+    bool isValid() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+enum Relative {
     Start,
     End
 };
 
-struct Alarm {
-    //TODO
-//     void setRelativeStart(const Duration &, Related);
-//     void setStart(const DateTime &);
-//     void setDuration(const Duration &, int numrepeat);
-//     
-//     //The following alarm types are mutual exclusive (implement as constructor?)
-//     void setDisplayAlarm(const std::string &text);
-//     void setAudioAlarm(const Attachment &audio);
-//     void setEmailAlarm(const std::string &summary, const std::string &description, const std::vector<std::string> attendees);
+struct Duration {
+    Duration():mWeeks(0), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(false), valid(false){};
+    Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){};
+    Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){};
+    bool operator==(const Duration &other) const{ return (mWeeks == other.mWeeks && 
+                                                            mDays == other.mDays &&
+                                                            mHours == other.mHours &&
+                                                            mMinutes == other.mMinutes &&
+                                                            mSeconds == other.mSeconds &&
+                                                            mNegative == other.mNegative &&
+                                                            valid == other.valid );};
+    int weeks() const { return mWeeks; };
+    int days() const { return mDays; };
+    int hours() const { return mHours; };
+    int minutes() const { return mMinutes; };
+    int seconds() const { return mSeconds; };
+
+    bool isNegative() const { return mNegative; };
+    bool isValid() const { return valid; };
+private:
+    int mWeeks;
+    int mDays;
+    int mHours;
+    int mMinutes;
+    int mSeconds;
+    bool mNegative;
+    bool valid;
+};
+
+class Alarm {
+public:
+    enum Type {
+        InvalidAlarm,
+        EMailAlarm,
+        DisplayAlarm,
+        AudioAlarm
+    };
+    
+    Alarm();
+    Alarm(const Alarm &);
+    ~Alarm();
+
+    void operator=(const Alarm &);
+    bool operator==(const Alarm &other) const;
+
+    ///EMail Alarm
+    Alarm(const std::string &summary, const std::string &description, const std::vector<std::string> attendees);
+    std::string summary() const;
+    std::string description() const;
+    std::vector<std::string> attendees() const;
+
+    ///Display Alarm
+    Alarm(const std::string &text);
+    std::string text() const;
+
+    ///Audio Alarm
+    Alarm(const Attachment &audio);
+    Attachment audioFile() const;
+    
+    void setRelativeStart(const Duration &, Relative);
+    Duration relativeStart() const;
+    Relative relativeTo() const;
+    
+    void setStart(const DateTime &);
+    DateTime start() const;
+
+    void setDuration(const Duration &, int numrepeat);
+    Duration duration() const;
+    int numrepeat() const;
+    
+    Type type() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
 };
 
 
@@ -183,34 +280,6 @@ private:
     boost::scoped_ptr<Private> d;
 };
 
-struct Duration {
-    Duration():valid(false){};
-    Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){};
-    Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){};
-    bool operator==(const Duration &other) const{ return (mWeeks == other.mWeeks && 
-                                                            mDays == other.mDays &&
-                                                            mHours == other.mHours &&
-                                                            mMinutes == other.mMinutes &&
-                                                            mSeconds == other.mSeconds &&
-                                                            mNegative == other.mNegative &&
-                                                            valid == other.valid );};
-    int weeks() const { return mWeeks; };
-    int days() const { return mDays; };
-    int hours() const { return mHours; };
-    int minutes() const { return mMinutes; };
-    int seconds() const { return mSeconds; };
-
-    bool isNegative() const { return mNegative; };
-    bool isValid() const { return valid; };
-private:
-    int mWeeks;
-    int mDays;
-    int mHours;
-    int mMinutes;
-    int mSeconds;
-    bool mNegative;
-    bool valid;
-};
 
 enum PartStatus {
     PartNeedsAction,
@@ -260,37 +329,6 @@ private:
 std::vector<Attendee> operator<<(std::vector<Attendee>, const Attendee&);
 
 
-class Attachment {
-public:
-    Attachment();
-    Attachment(const Kolab::Attachment &);
-    ~Attachment();
-
-    void operator=(const Attachment &);
-    bool operator==(const Attachment &) const;
-
-    void setUri(const std::string &uri, const std::string &mimetype);
-    std::string uri() const;
-
-     ///Un-encoded binary content, Implies embedded, will be encoded
-     void setData(const std::string &, const std::string &mimetype);
-     ///Decoded binary content.
-     std::string data() const;
-     //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement?
-//     ///Base64 encoded binary content, Implies embedded
-//      void setEncodedData(const std::string &, const std::string &mimetype);
-
-    std::string mimetype() const;
-
-    ///User visible label
-    void setLabel(const std::string &);
-    std::string label() const;
-
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
-
 struct CustomProperty {
     CustomProperty(const std::string &i, const std::string &v)
     : identifier(i), value(v) {};
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
index 7beec79..1775895 100644
--- a/c++/lib/kolabtodo.cpp
+++ b/c++/lib/kolabtodo.cpp
@@ -315,4 +315,14 @@ std::vector< CustomProperty > Todo::customProperties() const
     return d->customProperties;
 }
 
+void Todo::setAlarms(const std::vector< Alarm > &alarms)
+{
+    d->alarms = alarms;
+}
+
+std::vector< Alarm > Todo::alarms() const
+{
+    return d->alarms;
+}
+
 }
\ No newline at end of file
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
index 4533f93..1271bc0 100644
--- a/c++/lib/kolabtodo.h
+++ b/c++/lib/kolabtodo.h
@@ -106,6 +106,10 @@ public:
     
     void setCustomProperties(const std::vector<CustomProperty> &);
     std::vector<CustomProperty> customProperties() const;
+    
+    void setAlarms(const std::vector<Alarm> &);
+    std::vector<Alarm> alarms() const;
+    
 private:
     struct Private;
     boost::scoped_ptr<Private> d;
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index f9ae5c3..752c162 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -559,6 +559,42 @@ void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string
 //     }
 // }
 
+template <typename T>
+Kolab::Attachment toAttachment(T aProp)
+{
+    Kolab::Attachment a;
+    std::string mimetype;
+    if (aProp.parameters()) {
+        const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
+        for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+            if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
+                mimetype = p->text();
+            }
+            if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
+                if (p->text() != BASE64) {
+                    std::cerr << "wrong encoding";
+                    return Kolab::Attachment();
+                }
+            }
+            if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
+                a.setLabel(p->text());
+            }
+        }
+    }
+    if (mimetype.empty()) {
+        std::cerr << "no mimetype" << std::endl;
+    }
+
+    if (aProp.uri()) {
+        a.setUri(*aProp.uri(), mimetype);
+    } else if (aProp.binary()) {
+        a.setData(base64_decode(*aProp.binary()), mimetype);
+    } else {
+        std::cerr << "not uri and no data available" << std::endl;
+    }
+    return a;
+}
+
 
 template <typename I, typename T>
 void setIncidenceProperties(I &inc, const T &prop)
@@ -670,7 +706,7 @@ void setIncidenceProperties(I &inc, const T &prop)
     
     if (prop.attendee().size()) {
         std::vector<Kolab::Attendee> attendees;
-        BOOST_FOREACH(icalendar_2_0::properties::attendee_type aProp, prop.attendee()) {
+        BOOST_FOREACH(typename T::attendee_type aProp, prop.attendee()) {
             Kolab::Attendee a(toString(aProp.cal_address()));
             if (aProp.parameters()) {
                 const icalendar_2_0::AttendeePropType::parameters_type &parameters = *aProp.parameters();
@@ -705,32 +741,11 @@ void setIncidenceProperties(I &inc, const T &prop)
     
     if (prop.attach().size()) {
         std::vector<Kolab::Attachment> attachments;
-        BOOST_FOREACH(icalendar_2_0::properties::attach_type aProp, prop.attach()) {
-            Kolab::Attachment a;
-            std::string mimetype;
-            if (aProp.parameters()) {
-                const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
-                for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-                    if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
-                        mimetype = p->text();
-                    }
-                    if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
-                        if (p->text() != BASE64) {
-                            std::cout << "wrong encoding";
-                            continue;
-                        }
-                    }
-                    if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
-                        a.setLabel(p->text());
-                    }
-                }
-            }
-
-            if (aProp.uri()) {
-                a.setUri(*aProp.uri(), mimetype);
-            }
-            if (aProp.binary()) {
-                a.setData(base64_decode(*aProp.binary()), mimetype);
+        BOOST_FOREACH(typename T::attach_type aProp, prop.attach()) {
+            const Kolab::Attachment &a = toAttachment<typename T::attach_type>(aProp);
+            if (!a.isValid()) {
+                std::cerr << "invalid attachment" << std::endl;
+                continue;
             }
             attachments.push_back(a);
         }
@@ -739,7 +754,7 @@ void setIncidenceProperties(I &inc, const T &prop)
     
     if (prop.x_custom().size()) {
         std::vector<Kolab::CustomProperty> customProperties;
-        BOOST_FOREACH(icalendar_2_0::properties::x_custom_type p, prop.x_custom()) {
+        BOOST_FOREACH(typename T::x_custom_type p, prop.x_custom()) {
             customProperties.push_back(CustomProperty(p.identifier(), p.value()));
         }
         inc.setCustomProperties(customProperties);
@@ -822,7 +837,27 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
     return rruleProp;
 }
 
-
+icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a)
+{
+    icalendar_2_0::AttachPropType attachment;
+    icalendar_2_0::AttachPropType::parameters_type p;
+    p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
+    if (!a.label().empty()) {
+        p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
+    }
+    
+    if (!a.uri().empty()) {
+        attachment.uri(a.uri());
+    } else  if (!a.data().empty()) {
+        attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
+        p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
+    } else {
+        std::cerr << "no uri and no data" << std::endl;
+    }
+    
+    attachment.parameters(p);
+    return attachment;
+}
 
 
 template <typename T, typename I>
@@ -979,26 +1014,8 @@ void getIncidenceProperties(T &prop, const I &inc)
     }
     
     if (!inc.attachments().empty()) {
-        
         BOOST_FOREACH(const Kolab::Attachment &a, inc.attachments()) {
-            typename properties::attach_type attachment;
-            typename properties::attach_type::parameters_type p;
-            
-            p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
-            
-            if (!a.label().empty()) {
-                p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
-            }
-            
-            if (!a.uri().empty()) {
-                attachment.uri(a.uri());
-            } else  if (!a.data().empty()) {
-                attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
-                p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
-            }
-            
-            attachment.parameters(p);
-            prop.attach().push_back(attachment);
+            prop.attach().push_back(fromAttachment(a));
         }
     }
     
@@ -1010,6 +1027,158 @@ void getIncidenceProperties(T &prop, const I &inc)
 
 }
 
+const char* const START = "START";
+const char* const END = "END";
+
+template <typename KolabType, typename IncidenceType>
+void setAlarms(typename KolabType::components_type& components, const IncidenceType &incidence)
+{
+    typedef DateTimeConverter< DateTime> DC;
+    BOOST_FOREACH(const Kolab::Alarm &alarm, incidence.alarms()) {
+        typedef icalendar_2_0::ValarmType::properties_type PropType;
+        
+        PropType::trigger_type trigger;
+        if (alarm.start().isValid()) {
+            
+            trigger.date_time(DC::fromDateTime(alarm.start()));
+        } else {
+            if (!alarm.relativeStart().isValid()) {
+                std::cerr << "no start and no relativeStart" << std::endl;
+                continue;
+            }
+            trigger.duration(PropType::trigger_type::duration_type(fromDuration(alarm.relativeStart())));
+            icalendar_2_0::ArrayOfParameters parameters;
+            if (alarm.relativeTo() == Kolab::End) {
+                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(END));
+            } else {
+                parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(START));
+            }
+            trigger.parameters(parameters);
+        }
+
+        std::auto_ptr<PropType> p;
+        switch(alarm.type()) {
+            case Kolab::Alarm::DisplayAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(DISPLAYALARM), trigger));
+                p->description(PropType::description_type(alarm.description()));
+                break;
+            case Kolab::Alarm::EMailAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(EMAILALARM), trigger));
+                p->summary(PropType::summary_type(alarm.summary()));
+                p->description(PropType::description_type(alarm.description()));
+                BOOST_FOREACH(const std::string &attendee, alarm.attendees()) {
+                    p->attendee().push_back(icalendar_2_0::ContactType(attendee));
+                }
+                break;
+            case Kolab::Alarm::AudioAlarm:
+                p = std::auto_ptr<PropType>(new PropType(PropType::action_type(AUDIOALARM), trigger));
+                p->description(PropType::description_type(alarm.description()));
+                p->attach(fromAttachment(alarm.audioFile()));
+                break;
+            default:
+                std::cerr << "invalid alarm" << std::endl;
+                continue;
+        }
+        if (alarm.duration().isValid()) {
+            p->duration(PropType::duration_type(fromDuration(alarm.duration())));
+            p->repeat(PropType::repeat_type(fromInt<PropType::repeat_type::integer_type>(alarm.numrepeat())));
+        }
+
+        components.valarm().push_back(icalendar_2_0::ValarmType(p));
+    }
+}
+
+// typename KolabTypes::DatePtr toDate(const icalendar_2_0::DateTimeType &dtProperty)
+// {
+//     typedef DateTimeConverter<Kolab::DateTime> DC;
+//     typename KolabTypes::DatePtr date;
+//     if (dtProperty.date_time()) {
+//         date = DC::toDate(dtProperty.date_time());
+//     }
+//     return date;
+// }
+
+
+template <typename IncidenceType, typename KolabType>
+void getAlarms(IncidenceType &incidence, const typename KolabType::components_type &components)
+{
+    typedef icalendar_2_0::ValarmType::properties_type PropType;
+    std::vector<Kolab::Alarm> alarms;
+    BOOST_FOREACH(const typename KolabType::components_type::valarm_type &valarm, components.valarm()) {
+        const icalendar_2_0::ValarmType::properties_type &prop = valarm.properties();
+
+        Kolab::Alarm alarm;
+        if (prop.action().text() == DISPLAYALARM) {
+            if (!prop.description()) {
+                std::cerr << "description is missing" << std::endl;
+                continue;
+            }
+            alarm = Kolab::Alarm((*prop.description()).text());
+        } else if (prop.action().text() == EMAILALARM) {
+            std::vector<std::string> attendees;
+            for (typename PropType::attendee_const_iterator at(prop.attendee().begin()); at != prop.attendee().end(); at++) {
+                attendees.push_back((*at).cal_address());
+            }
+            if (!prop.description() || !prop.summary()) {
+                std::cerr << "description or summary is missing" << std::endl;
+                continue;
+            }
+            alarm = Kolab::Alarm((*prop.summary()).text(), (*prop.description()).text(), attendees);
+        } else if (prop.action().text() == AUDIOALARM) {
+            if (!prop.attach()) {
+                std::cerr << "audio file is missing" << std::endl;
+                continue;
+            }
+            const Kolab::Attachment &attach = toAttachment<icalendar_2_0::properties::attach_type>(*prop.attach());
+            if (!attach.isValid()) {
+                std::cerr << "audio file is invalid" << std::endl;
+                continue;
+            }
+            alarm = Kolab::Alarm(attach);
+        } else {
+            std::cerr << "unknown alarm type " << prop.action().text() << std::endl;
+            continue;
+        }
+        
+        if (prop.trigger().date_time()) {
+            alarm.setStart(*DateTimeConverter<Kolab::DateTime>::toDate(*prop.trigger().date_time()));
+            if (!alarm.start().isUTC()) {
+                std::cerr << "The start date time must be in UTC "<< std::endl;
+                continue;
+            }
+        } else if (prop.trigger().duration()) {
+            Kolab::Relative relativeTo = Kolab::Start;
+            if (prop.trigger().parameters()) {
+                BOOST_FOREACH(const icalendar_2_0::ArrayOfParameters::baseParameter_type &param, (*prop.trigger().parameters()).baseParameter()) {
+                    if (const icalendar_2_0::RelatedParamType *rel = dynamic_cast<const icalendar_2_0::RelatedParamType*> (&param)) {
+                        if (rel->text() == START) {
+                            relativeTo = Kolab::Start;
+                        } else if (rel->text() == END) {
+                            relativeTo = Kolab::End;
+                        } else {
+                            std::cerr << "relativeTo not specified, default to start " << std::endl;
+                        }
+                    }
+                }
+            }
+            
+            alarm.setRelativeStart(toDuration(*prop.trigger().duration()), relativeTo);
+        } else {
+            std::cerr << "no duration and not starttime " << std::endl;
+            continue;
+        }
+        if (prop.duration()) {
+            int repeat = 0;
+            if (prop.repeat()) {
+                repeat = toInt(*prop.repeat());
+            }
+            alarm.setDuration(toDuration((*prop.duration()).duration()), repeat); //TODO check duration?
+        }
+        alarms.push_back(alarm);
+    }
+    incidence.setAlarms(alarms);
+}
+
 template <typename T> struct IncidenceConverter < Incidence, T >
 {
     typedef DateTimeConverter< DateTime> DC;
@@ -1092,6 +1261,14 @@ template < > struct IncidenceTrait <Kolab::Event>
                 }
             }
         }
+        if (vevent.components()) {
+            getAlarms<IncidenceType, KolabType>(event, *vevent.components());
+        }
+    }
+    
+    static void setComponents(KolabType::components_type& components, const Kolab::Event &incidence)
+    {
+        setAlarms<KolabType, IncidenceType>(components, incidence);
     }
      
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
@@ -1156,6 +1333,14 @@ template < > struct IncidenceTrait <Kolab::Todo>
         if (prop.percent_complete()) {
             todo.setPercentComplete(toInt(*prop.percent_complete()));
         }
+        if (vevent.components()) {
+            getAlarms<IncidenceType, KolabType>(todo, *vevent.components());
+        }
+    }
+    
+    static void setComponents(KolabType::components_type& components, const Kolab::Todo &incidence)
+    {
+        setAlarms<KolabType, IncidenceType>(components, incidence);
     }
      
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 454a965..b696f9b 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -16,6 +16,7 @@
 #include <lib/kolabkcalconversion.h>
 #include <iostream>
 #include <fstream>
+#include "serializers.h"
 
 //TODO remove
 void BindingsTest::writeContact()
@@ -171,6 +172,23 @@ void setIncidence(T &ev)
     properties.push_back(Kolab::CustomProperty("ident", "value"));
     properties.push_back(Kolab::CustomProperty("ident", "value"));
     ev.setCustomProperties(properties);
+    
+    std::vector<Kolab::Alarm> alarms;
+    Kolab::Alarm dispAlarm("ident");
+    dispAlarm.setRelativeStart(Kolab::Duration(3, true), Kolab::Start);
+    alarms.push_back(dispAlarm);
+    std::vector<std::string> att;
+    att.push_back("attendee1");
+    att.push_back("attendee2");
+    Kolab::Alarm emailAlarm("ident", "value", att);
+    emailAlarm.setStart(Kolab::DateTime(2003,2,3,2,3,4, true));
+    alarms.push_back(emailAlarm);
+    Kolab::Attachment audiofile;
+    audiofile.setUri("ksdjlksdflj", "sdkljdfl");
+    Kolab::Alarm audio(audiofile);
+    audio.setStart(Kolab::DateTime(2003,2,3,2,3,4, true));
+    alarms.push_back(audio);
+    ev.setAlarms(alarms);
 }
 
 template <typename T>
@@ -220,6 +238,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.attendees(), re.attendees());
     QCOMPARE(ev.attachments(), re.attachments());
     QCOMPARE(ev.customProperties(), re.customProperties());
+    QCOMPARE(ev.alarms(), re.alarms());
 }
 
 
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
index 30bef2d..8548b62 100644
--- a/c++/tests/serializers.h
+++ b/c++/tests/serializers.h
@@ -99,6 +99,49 @@ namespace QTest {
         ba += ")";
         return qstrdup(ba.data());
     }
+    
+    template<>
+    char *toString(const Kolab::Attachment &a)
+    {
+        QByteArray ba = "Kolab::Attachment(";
+        ba += QString::fromStdString(a.uri()).toAscii() + ", " + QString::fromStdString(a.mimetype()).toAscii()+ ", " + 
+        QString::fromStdString(a.label()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Attachment> &v)
+    {
+        QByteArray ba = "vector<Kolab::Attachment>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Alarm &a)
+    {
+        QByteArray ba = "Kolab::Alarm(";
+        ba += QByteArray::number(a.type()) + ", " + QString::fromStdString(a.summary()).toAscii()+ ", " + 
+        QString::fromStdString(a.text()).toAscii()+", " +toString(a.duration()) + ", " + QByteArray::number(a.numrepeat())+  ", " + toString(a.start()) +
+        + toString(a.relativeStart())  + ", " +  QByteArray::number(a.relativeTo()) + toString(a.audioFile()) +  ", " + toString(a.attendees());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Alarm> &v)
+    {
+        QByteArray ba = "vector<Kolab::Alarm>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ "\n";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
 
  }
  
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 1c72be8..f18773e 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -59,7 +59,6 @@ Test.</text>
              </description>
 
            </properties>
-           <components/>
          </vevent>
 <!--         <vevent>
            <properties>
@@ -90,4 +89,4 @@ Test.</text>
          </vevent>-->
        </components>
      </vcalendar>
-</icalendar>
\ No newline at end of file
+</icalendar>
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 0d7ecc6..5a5ec95 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -47,6 +47,32 @@
         </xs:complexContent>
     </xs:complexType>
 
+    <xs:complexType name="ContactType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="CalAddressPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+    <!-- 3.6.6 Alarm Component -->
+    <xs:complexType name="ValarmType" mixed="false">
+        <xs:sequence>
+            <xs:element name="properties">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="action" type="ActionPropType"/>
+                        <xs:element name="summary" type="TextPropertyType" minOccurs="0"/>
+                        <xs:element name="description" type="TextPropertyType" minOccurs="0"/>
+                        <xs:element name="attendee" type="ContactType" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="attach" type="AttachPropType" minOccurs="0"/>
+                        <xs:element name="trigger" type="TriggerPropType"/>
+                        <xs:element name="duration" type="DurationPropType" minOccurs="0"/>
+                        <xs:element name="repeat" type="RepeatPropType" minOccurs="0"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
     <xs:complexType name="KolabEvent" >
         <xs:sequence>
             <xs:element name="properties">
@@ -78,9 +104,11 @@
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
-            <xs:element name="components">
+            <xs:element name="components" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
-                <!--TODO valarm-->
+                    <xs:sequence>
+                        <xs:element name="valarm" type="ValarmType" minOccurs="1" maxOccurs="unbounded"/>
+                    </xs:sequence>
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
@@ -117,9 +145,11 @@
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
-            <xs:element name="components">
+            <xs:element name="components" minOccurs="0" maxOccurs="1">
                 <xs:complexType>
-                <!--TODO valarm-->
+                    <xs:sequence>
+                        <xs:element name="valarm" type="ValarmType" minOccurs="1" maxOccurs="unbounded"/>
+                    </xs:sequence>
                 </xs:complexType>
             </xs:element>
         </xs:sequence>


commit 5de2c196da184d0b5aabbd62c134cd2698bd5801
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Feb 7 02:04:16 2012 +0100

    regex didn't work for weeks for some reason, this way it does. It's not entirely clear to me why though...

diff --git a/schemas/ical/iCalendar-valtypes.xsd b/schemas/ical/iCalendar-valtypes.xsd
index bb64480..8b91dfa 100644
--- a/schemas/ical/iCalendar-valtypes.xsd
+++ b/schemas/ical/iCalendar-valtypes.xsd
@@ -99,7 +99,7 @@
       </xs:documentation>
     </xs:annotation>
     <xs:restriction base="xs:string">
-      <xs:pattern value="(\+|\-)?P((\d+Y)?(\d+M)?(\d+D)?T?(\d+H)?(\d+M)?(\d+S)?)|(\d+W)"/>
+      <xs:pattern value="(\+|\-)?P((\d+W)|((\d+Y)?(\d+M)?(\d+D)?T?(\d+H)?(\d+M)?(\d+S)?))"/>
     </xs:restriction>
   </xs:simpleType>
   


commit c41ebac13d4b4796d224d71c8850b9eea502e7b5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 5 23:23:07 2012 +0100

    ByDay parser/serializer

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index ac702e2..2a5b6bd 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -244,12 +244,12 @@ RecurrenceRule::Frequency RecurrenceRule::frequency() const
     return d->freq;
 }
 
-void RecurrenceRule::setWeekStart(RecurrenceRule::Weekday weekstart)
+void RecurrenceRule::setWeekStart(Kolab::Weekday weekstart)
 {
     d->weekstart = weekstart;
 }
 
-RecurrenceRule::Weekday RecurrenceRule::weekStart() const
+Kolab::Weekday RecurrenceRule::weekStart() const
 {
     return d->weekstart;
 }
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 1d28a2d..c4d3dd1 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -76,10 +76,27 @@ enum Status {
     Final
 };
 
+enum Weekday {
+    Monday,
+    Tuesday,
+    Wednesday,
+    Thursday,
+    Friday,
+    Saturday,
+    Sunday
+};
+
 struct DayPos {
-    void operator=(const DayPos &){};
-    bool operator==(const DayPos &) const{ return false;};
-    //TODO
+    DayPos(): mIsValid(false){};
+    DayPos(int occurrence, Weekday weekday): mOccurrence(occurrence), mWeekday(weekday), mIsValid(true){};
+    bool operator==(const DayPos &other) const { return mOccurrence == other.mOccurrence && mWeekday == other.mWeekday; };
+    int occurence() const { return mOccurrence; };
+    Weekday weekday() const { return mWeekday; };
+    bool isValid() { return mIsValid; };
+private:
+    int mOccurrence;
+    Weekday mWeekday;
+    bool mIsValid;
 };
 
 enum Related {
@@ -123,16 +140,6 @@ public:
     void setFrequency(Frequency);
     Frequency frequency() const;
     
-    enum Weekday {
-        Monday,
-        Tuesday,
-        Wednesday,
-        Thursday,
-        Friday,
-        Saturday,
-        Sunday
-    };
-    
     void setWeekStart(Weekday);
     Weekday weekStart() const;
     
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 03a44cb..f9ae5c3 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -65,6 +65,102 @@ std::string toString(const icalendar_2_0::TextPropertyType &s)
     return s.text();
 }
 
+
+const char* const MO = "MO";
+const char* const TU = "TU";
+const char* const WE = "WE";
+const char* const TH = "TH";
+const char* const FR = "FR";
+const char* const SA = "SA";
+const char* const SU = "SU";
+
+std::string fromDayPos(const Kolab::DayPos &d)
+{   
+    std::string s;
+    if (d.occurence() != 0) {
+        s.append(boost::lexical_cast<std::string>(d.occurence()));
+    }
+    switch (d.weekday()) {
+        case Kolab::Monday:
+            s.append(MO);
+            break;
+        case Kolab::Tuesday:
+            s.append(TU);
+            break;
+        case Kolab::Wednesday:
+            s.append(WE);
+            break;
+        case Kolab::Thursday:
+            s.append(TH);
+            break;
+        case Kolab::Friday:
+            s.append(FR);
+            break;
+        case Kolab::Saturday:
+            s.append(SA);
+            break;
+        case Kolab::Sunday:
+            s.append(SU);
+            break;
+    }
+    return s;
+}
+
+Kolab::DayPos toDayPos(const std::string &s)
+{
+    std::string number;
+    bool gotOccurrence = false;
+    int occurrence = 0;
+    for (std::string::const_iterator it = s.begin(); it != s.end(); it++) {
+        switch(*it) {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case '+':
+            case '-':
+                number.push_back(*it);
+                break;
+            default:
+                if (!gotOccurrence && !number.empty()) {
+                    try {
+                        occurrence = boost::lexical_cast<int>(number);
+                    } catch(boost::bad_lexical_cast &) {
+                        std::cerr << "failed to convert: " <<  number <<  std::endl;
+                        return DayPos();
+                    }
+                    number.clear();
+                }
+                gotOccurrence = true;
+                number.push_back(*it);
+                break;
+        }
+    }
+
+    if (number == MO) {
+        return DayPos(occurrence, Kolab::Monday);
+    } else if (number == TU) {
+        return DayPos(occurrence, Kolab::Tuesday);
+    } else if (number == WE) {
+        return DayPos(occurrence, Kolab::Wednesday);
+    } else if (number == TH) {
+        return DayPos(occurrence, Kolab::Thursday);
+    } else if (number == FR) {
+        return DayPos(occurrence, Kolab::Friday);
+    } else if (number == SA) {
+        return DayPos(occurrence, Kolab::Saturday);
+    } else if (number == SU) {
+        return DayPos(occurrence, Kolab::Sunday);
+    }
+    return DayPos();
+}
+
 std::string fromDuration(const Kolab::Duration &d)
 {
     std::string s;
@@ -330,25 +426,25 @@ template <> struct RecurrenceConverter < RecurrenceRule >
 
         switch (wkst) {
             case WeekdayRecurType::MO:
-                r->setWeekStart(RecurrenceRule::Monday);
+                r->setWeekStart(Kolab::Monday);
                 break;
             case WeekdayRecurType::TU:
-                r->setWeekStart(RecurrenceRule::Tuesday);
+                r->setWeekStart(Kolab::Tuesday);
                 break;
             case WeekdayRecurType::WE:
-                r->setWeekStart(RecurrenceRule::Wednesday);
+                r->setWeekStart(Kolab::Wednesday);
                 break;
             case WeekdayRecurType::TH:
-                r->setWeekStart(RecurrenceRule::Thursday);
+                r->setWeekStart(Kolab::Thursday);
                 break;
             case WeekdayRecurType::FR:
-                r->setWeekStart(RecurrenceRule::Friday);
+                r->setWeekStart(Kolab::Friday);
                 break;
             case WeekdayRecurType::SA:
-                r->setWeekStart(RecurrenceRule::Saturday);
+                r->setWeekStart(Kolab::Saturday);
                 break;
             case WeekdayRecurType::SU:
-                r->setWeekStart(RecurrenceRule::Sunday);
+                r->setWeekStart(Kolab::Sunday);
                 break;
             default:
                 std::cout << "invalid unhandled weekday" << wkst;
@@ -401,11 +497,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
     {
         std::vector<DayPos> by;
         for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
-            //TODO implement parser for format
-//             switch () {
-//                 
-//             }
-            //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+            by.push_back(toDayPos(*it));
         }
         r->setByday(by);
     }
@@ -704,7 +796,11 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
     }
     
     if (!r.byday().empty()) {
-        //TODO
+        RecurType::byday_sequence byday;
+        BOOST_FOREACH(const Kolab::DayPos &daypos, r.byday()) {
+            byday.push_back(fromDayPos(daypos));
+        }
+        recur.byday(byday);
     }
     
     if (!r.bymonthday().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 4779def..454a965 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -107,7 +107,11 @@ void setIncidence(T &ev)
     rule.setBysecond(list);
     rule.setByminute(list);
     rule.setByhour(list);
-//     rule.setByday(list); //TODO
+    std::vector<Kolab::DayPos> byday;
+    byday.push_back(Kolab::DayPos(15, Kolab::Friday));
+    byday.push_back(Kolab::DayPos(0, Kolab::Monday));
+    byday.push_back(Kolab::DayPos(-3, Kolab::Monday));
+    rule.setByday(byday);
     rule.setBymonthday(list);
     rule.setByyearday(list);
     rule.setByweekno(list);
@@ -195,7 +199,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(r1.byminute(), r2.byminute());
     QCOMPARE(r1.byhour(), r2.byhour());
 //     QEXPECT_FAIL("", "Implement Day parser", Continue);
-//     QCOMPARE(r1.byday(), r2.byday());
+    QCOMPARE(r1.byday(), r2.byday());
     QCOMPARE(r1.bymonthday(), r2.bymonthday());
     QCOMPARE(r1.byyearday(), r2.byyearday());
     QCOMPARE(r1.byweekno(), r2.byweekno());
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
index df19a75..cb9367c 100644
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@ -6,6 +6,7 @@
 #include "serializers.h"
 
 Q_DECLARE_METATYPE(Kolab::Duration);
+Q_DECLARE_METATYPE(Kolab::DayPos);
  
 void ConversionTest::durationParserTest_data()
 {
@@ -46,6 +47,45 @@ void ConversionTest::durationSerializerTest()
 }
 
 
+void ConversionTest::dayPosParserTest_data()
+{
+    QTest::addColumn<Kolab::DayPos>("expected");
+    QTest::addColumn<QString>("string");
+
+    QTest::newRow("positive") << Kolab::DayPos(15, Kolab::Wednesday) << "15WE";
+    QTest::newRow("positive with +") << Kolab::DayPos(15, Kolab::Wednesday) << "+15WE";
+    QTest::newRow("negative") << Kolab::DayPos(-15, Kolab::Wednesday) << "-15WE";
+    QTest::newRow("all occurrences") << Kolab::DayPos(0, Kolab::Wednesday) << "WE";
+
+}
+
+void ConversionTest::dayPosParserTest()
+{
+    QFETCH(QString, string);
+    QFETCH(Kolab::DayPos, expected);
+    const Kolab::DayPos result = Kolab::toDayPos(string.toStdString());
+    QCOMPARE(result, expected);
+}
+
+void ConversionTest::dayPosSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::DayPos>("daypos");
+
+    QTest::newRow("pos") << "15WE" << Kolab::DayPos(15, Kolab::Wednesday);
+    QTest::newRow("negative") << "-15WE" << Kolab::DayPos(-15, Kolab::Wednesday);
+    QTest::newRow("all occurrences") << "WE" << Kolab::DayPos(0, Kolab::Wednesday);
+
+}
+
+void ConversionTest::dayPosSerializerTest()
+{
+    QFETCH(Kolab::DayPos, daypos);
+    QFETCH(QString, expected);
+    const std::string result = Kolab::fromDayPos(daypos);
+    QCOMPARE(QString::fromStdString(result), expected);
+}
+
 
 QTEST_MAIN( ConversionTest )
 
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
index 989ec95..8672b99 100644
--- a/c++/tests/conversiontest.h
+++ b/c++/tests/conversiontest.h
@@ -14,6 +14,12 @@ class ConversionTest : public QObject
     
     void durationSerializerTest_data();
     void durationSerializerTest();
+    
+    void dayPosParserTest_data();
+    void dayPosParserTest();
+    
+    void dayPosSerializerTest_data();
+    void dayPosSerializerTest();
 };
 
 #endif // CONVERSIONTEST_H
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
index a4d386b..30bef2d 100644
--- a/c++/tests/serializers.h
+++ b/c++/tests/serializers.h
@@ -90,6 +90,15 @@ namespace QTest {
         ba += ")";
         return qstrdup(ba.data());
     }
+    
+    template<>
+    char *toString(const Kolab::DayPos &dt)
+    {
+        QByteArray ba = "Kolab::DayPos(";
+        ba += QByteArray::number(dt.occurence()) + ", " + QByteArray::number(dt.weekday());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
 
  }
  
diff --git a/schemas/ical/iCalendar-valtypes.xsd b/schemas/ical/iCalendar-valtypes.xsd
index b0ae12c..bb64480 100644
--- a/schemas/ical/iCalendar-valtypes.xsd
+++ b/schemas/ical/iCalendar-valtypes.xsd
@@ -215,7 +215,8 @@
   
   <xs:simpleType name="BydayRecurType">
     <xs:restriction base="xs:string">
-        <xs:pattern value="((\-)?N)?(SU|MO|TU|WE|TH|FR|SA)"/>
+      <!--For some reason N doesn't match the number and was therefore replaced by \d\d? (number are only up to 53 valid)-->
+        <xs:pattern value="((\-|\+)?\d\d?)?(SU|MO|TU|WE|TH|FR|SA)"/>
     </xs:restriction>
   </xs:simpleType>
   


commit 674acc50ee572df31cd121d44034be27a8158b0e
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sun Feb 5 22:07:34 2012 +0100

    RelatedTo property, Duration, comments

diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index 7002b31..466c494 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -1,3 +1,8 @@
+== General Design Notes==
+
+* Although many values are optional, the library doesn't differentiate between set and not set values. The approach taken is to not write out values which are still on the default value in order to keep objects small.
+The downside of this is that an xml object could be modified although no values have been modified (because default values are not written out again).
+
 == Libraries ==
 
 === libkolabxml ===
@@ -18,7 +23,7 @@ Library to provide converters to KCalCore containers as well as advanced functio
 === kolabxmlkcal (deprecated) ===
 
 First approach which does a direct mapping from xml to KCalCore containers. 
-It tourned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
+It turned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
 Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend.
 
 == Code architecture ==
@@ -45,7 +50,7 @@ Providing non-const references to the value through an accessor function doesn't
 Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
 
 The containers do not use inheritance to ensure maximum compatibilty with SWIG (although SWIG provides inheritance for some languages).
-They we're also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur.
+They were also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur.
 
 The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
 
@@ -86,4 +91,4 @@ For further performance improvements read this: http://xerces.apache.org/xerces2
 All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that.
 If an error occurs a message is printed to the standard error output and a default constructed value is returned.
 
-Writing doesn't provide any validation (as it is hardly useful). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
\ No newline at end of file
+Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
\ No newline at end of file
diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
index 5cfe7b2..9c8bfce 100644
--- a/c++/lib/incidence_p.h
+++ b/c++/lib/incidence_p.h
@@ -37,6 +37,7 @@ namespace Kolab {
         int sequence;
         Classification classification;
         std::vector< std::string > categories;
+        std::vector< std::string > relatedTo;
         DateTime start;
         
         DateTime recurrenceID;
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 89f5d84..1d28a2d 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -78,6 +78,7 @@ enum Status {
 
 struct DayPos {
     void operator=(const DayPos &){};
+    bool operator==(const DayPos &) const{ return false;};
     //TODO
 };
 
@@ -176,7 +177,32 @@ private:
 };
 
 struct Duration {
-    //TODO
+    Duration():valid(false){};
+    Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){};
+    Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){};
+    bool operator==(const Duration &other) const{ return (mWeeks == other.mWeeks && 
+                                                            mDays == other.mDays &&
+                                                            mHours == other.mHours &&
+                                                            mMinutes == other.mMinutes &&
+                                                            mSeconds == other.mSeconds &&
+                                                            mNegative == other.mNegative &&
+                                                            valid == other.valid );};
+    int weeks() const { return mWeeks; };
+    int days() const { return mDays; };
+    int hours() const { return mHours; };
+    int minutes() const { return mMinutes; };
+    int seconds() const { return mSeconds; };
+
+    bool isNegative() const { return mNegative; };
+    bool isValid() const { return valid; };
+private:
+    int mWeeks;
+    int mDays;
+    int mHours;
+    int mMinutes;
+    int mSeconds;
+    bool mNegative;
+    bool valid;
 };
 
 enum PartStatus {
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index ed61bec..16eb19e 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -18,9 +18,7 @@
 #include "kolabformat.h"
 
 #include <iostream>
-#include "kolabcontainers.h"
 #include "xcalconversions.h"
-#include "kolabtodo.h"
 
 #include "xcardconversions.h"
 
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
index 36894b0..7beec79 100644
--- a/c++/lib/kolabtodo.cpp
+++ b/c++/lib/kolabtodo.cpp
@@ -118,6 +118,21 @@ std::vector< std::string > Todo::categories() const
     return d->categories;
 }
 
+void Todo::setRelatedTo(const std::vector< std::string > &related)
+{
+    d->relatedTo = related;
+}
+
+void Todo::addRelatedTo(const std::string &related)
+{
+    d->relatedTo.push_back(related);
+}
+
+std::vector< std::string > Todo::relatedTo() const
+{
+    return d->relatedTo;
+}
+
 void Todo::setStart(const Kolab::DateTime &start)
 {
     d->start = start;
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
index a023f20..4533f93 100644
--- a/c++/lib/kolabtodo.h
+++ b/c++/lib/kolabtodo.h
@@ -51,6 +51,10 @@ public:
     void addCategory(const std::string &);
     std::vector<std::string> categories() const;
     
+    void setRelatedTo(const std::vector<std::string> &);
+    void addRelatedTo(const std::string &);
+    std::vector<std::string> relatedTo() const;
+    
     void setStart(const DateTime &);
     DateTime start() const;
     
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
index 549b2da..d0cf739 100644
--- a/c++/lib/utils.h
+++ b/c++/lib/utils.h
@@ -19,7 +19,7 @@
 #define UTILS_H
 
 #include <string>
-#include <kolabcontainers.h>
+#include "kolabcontainers.h"
 
 namespace Kolab {
 
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 048666d..03a44cb 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -19,15 +19,21 @@
 #define XCALCONVERSIONS_H
 
 #include "genericxcalconverions.h"
-#include "kolabcontainers.h"
+
 #include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include "kolabcontainers.h"
 #include "kolabtodo.h"
+#include "kolabevent.h"
 #include "utils.h"
 #include "base64.h"
+
 namespace Kolab {
 
 class Incidence;
 
+//TODO we can get rid of this construct (was used for the kcalcore/kolab in parallel masterplan)
 struct KolabTypes
 {
     typedef DateTime DateType;
@@ -53,11 +59,138 @@ std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
     return ptr;
 }
 
+//TODO doesn't seem very useful after all, remove
 std::string toString(const icalendar_2_0::TextPropertyType &s)
 {
     return s.text();
 }
 
+std::string fromDuration(const Kolab::Duration &d)
+{
+    std::string s;
+    if (!d.isValid()) {
+        return s;
+    }
+    if (d.isNegative()) {
+        s.push_back('-');
+    }
+    s.push_back('P');
+    try {
+        if (d.weeks() > 0) {
+            s.append(boost::lexical_cast<std::string>(d.weeks()));
+            s.push_back('W');
+        }
+        if (d.days() > 0) {
+            s.append(boost::lexical_cast<std::string>(d.days()));
+            s.push_back('D');
+        }
+        if (d.hours() > 0 || d.minutes() > 0 || d.seconds() > 0) {
+            s.push_back('T');
+            if (d.hours() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.hours()));
+                s.push_back('H');
+            }
+            if (d.minutes() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.minutes()));
+                s.push_back('M');
+            }
+            if (d.seconds() > 0) {
+                s.append(boost::lexical_cast<std::string>(d.seconds()));
+                s.push_back('S');
+            }
+        }
+        
+    } catch(boost::bad_lexical_cast &) { 
+        std::cerr << "failed to convert duration"<<  std::endl;
+        return std::string();
+    }
+    return s;
+}
+
+Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d)
+{
+    int weeks = 0;
+    int days = 0;
+    int hours = 0;
+    int minutes = 0;
+    int seconds = 0;
+    bool negative = false;
+
+    std::string number;
+
+    for (std::string::const_iterator it = d.begin(); it != d.end(); it++) {
+        switch(*it) {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                number.push_back(*it);
+                break;
+            case 'H':
+                try {
+                    hours = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) {
+                    std::cerr << "failed to convert: " <<  number <<  std::endl;
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'M':
+                try {
+                    minutes = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) {
+                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'S':
+                try {
+                    seconds = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case 'T':
+                break;
+            case 'W':
+                try {
+                    weeks = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    return Duration();
+                }
+                return Duration(weeks, negative);
+            case 'D':
+                try {
+                    days = boost::lexical_cast<int>(number);
+                } catch(boost::bad_lexical_cast &) { 
+                    std::cerr << "failed to convert: " << number <<  std::endl;
+                    return Duration();
+                }
+                number.clear();
+                break;
+            case '+':
+                break;
+            case '-':
+                negative = true;
+                break;
+            case 'P':
+                break;
+            default:
+                std::cerr << "error: " << *it << std::endl;
+        }
+    }
+    return Duration(days, hours, minutes, seconds, negative);
+}
 // template <typename T>
 // std::auto_ptr<T> fromString(const std::string &s)
 // {
@@ -327,6 +460,13 @@ void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string
     email = cal.cal_address();
 }
 
+// template <typename T> setProperty(T::parameters_type::baseParameter_const_iterator it, void (*set)(std::string))
+// {
+//     if (const T * p = dynamic_cast<const T*> (&*it)) {
+//         set(p->text());
+//     }
+// }
+
 
 template <typename I, typename T>
 void setIncidenceProperties(I &inc, const T &prop)
@@ -815,9 +955,9 @@ template < > struct IncidenceTrait <Kolab::Event>
 
         if (event.end().isValid()) {
             prop.dtend(fromDate<KolabTypes, KolabType::properties_type::dtend_type>(event.end()));
-        }/* else if (event.duration().isValid()) {
-            //TODO
-        }*/
+        } else if (event.duration().isValid()) {
+            prop.duration(KolabType::properties_type::duration_type(fromDuration(event.duration())));
+        }
         
         if (event.transparency()) {
             prop.transp( KolabType::properties_type::transp_type(TRANSPARENT));
@@ -837,17 +977,15 @@ template < > struct IncidenceTrait <Kolab::Event>
 
         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";
-//             }
+            if (event.end().isUTC() != event.end().isUTC() && 
+                event.end().timezone() != event.end().timezone() &&
+                event.end().isDateOnly() != event.end().isDateOnly()) {
+                std::cerr << "dtEnd has wrong timespec" << std::endl;;
+            }
         } else if (prop.duration()) {
-            //TODO implement
-    //          KCalCore::Duration duration.;
-    //          event.setDuration(duration << prop.duration());
+            event.setDuration(toDuration((*prop.duration()).duration()));
         }
-        //TODO check for equality of timespecs
-        
+
         if (prop.transp()) {
             if (toString(*prop.transp()) == TRANSPARENT) {
                 event.setTransparency(true);
@@ -885,12 +1023,19 @@ template < > struct IncidenceTrait <Kolab::Todo>
         
         getIncidenceProperties<KolabType::properties_type>(prop, todo);
 
+        if (!todo.relatedTo().empty()) {
+            KolabType::properties_type::related_to_sequence list;
+            BOOST_FOREACH(std::string relatedTo, todo.relatedTo()) {
+                list.push_back(KolabType::properties_type::related_to_type(relatedTo));
+            }
+            prop.related_to(list);
+        }
         if (todo.due().isValid()) {
             prop.due(fromDate<KolabTypes, KolabType::properties_type::due_type>(todo.due()));
         }
-//         if (todo.transparency()) {
-//             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
-//         }
+        if (todo.percentComplete() > 0) {
+            prop.percent_complete(KolabType::properties_type::percent_complete_type(fromInt<icalendar_2_0::IntegerPropertyType::integer_type>(todo.percentComplete())));
+        }
     }
     
     static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
@@ -904,16 +1049,17 @@ template < > struct IncidenceTrait <Kolab::Todo>
 
         setIncidenceProperties<Kolab::Todo, KolabType::properties_type>(todo, prop);
 
-        if (prop.related_to()) {
-            //TODO
+        if (!prop.related_to().empty()) {
+            BOOST_FOREACH(KolabType::properties_type::related_to_type p, prop.related_to()) {
+                todo.addRelatedTo(p.text());
+            }
         }
         if (prop.due()) {
             todo.setDue(*toDate<KolabTypes>(*prop.due()));
         }
         if (prop.percent_complete()) {
-            //TODO
+            todo.setPercentComplete(toInt(*prop.percent_complete()));
         }
-
     }
      
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index c3413f7..9a78104 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -12,6 +12,10 @@ if (QT4_FOUND AND KDECORE_FOUND AND KCALCORE_FOUND)
     QT4_AUTOMOC(kcalconversiontest.cpp)
     add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
     target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxmlkcal ${XERCES_C})
+
+    QT4_AUTOMOC(conversiontest.cpp)
+    add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC})
+    target_link_libraries(conversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C})
 else()
     message(WARNING "Could not build tests because kdepimlibs, kdelibs or qt is missing")
 endif()
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 91a0683..4779def 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,84 +17,6 @@
 #include <iostream>
 #include <fstream>
 
-namespace QTest {
-    template<>
-    char *toString(const Kolab::DateTime &dt)
-    {
-        QByteArray ba = "Kolab::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::vector<Kolab::DateTime> &v)
-    {
-        QByteArray ba = "vector<Kolab::DateTime>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const Kolab::Attendee &a)
-    {
-        QByteArray ba = "Kolab::Attendee(";
-        ba += QString::fromStdString(a.email()).toAscii() + ", " + QString::fromStdString(a.name()).toAscii()+ ", " + 
-        QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role())  + ", " + QByteArray::number(a.rsvp())  + ", " + 
-        QString::fromStdString(a.uid()).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<Kolab::Attendee> &v)
-    {
-        QByteArray ba = "vector<Kolab::Attendee>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-     
-    template<>
-    char *toString(const std::string &s)
-    {
-        QByteArray ba = "string(";
-        ba += QString::fromStdString(s).toAscii();
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<std::string> &v)
-    {
-        QByteArray ba = "vector<std::string>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QByteArray(toString(v.at(i)))+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const std::vector<int> &v)
-    {
-        QByteArray ba = "vector<int>(";
-        for (int i = 0; i < v.size(); i++) {
-            ba += QString::number(v.at(i)).toAscii()+ ", ";
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-
- }
- 
 //TODO remove
 void BindingsTest::writeContact()
 {
@@ -183,6 +105,14 @@ void setIncidence(T &ev)
     list.push_back(1);
     list.push_back(3);
     rule.setBysecond(list);
+    rule.setByminute(list);
+    rule.setByhour(list);
+//     rule.setByday(list); //TODO
+    rule.setBymonthday(list);
+    rule.setByyearday(list);
+    rule.setByweekno(list);
+    rule.setBymonth(list);
+    
     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));
@@ -262,6 +192,14 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(r1.count(), r2.count());
     QCOMPARE(r1.end(), r2.end());
     QCOMPARE(r1.bysecond(), r2.bysecond());
+    QCOMPARE(r1.byminute(), r2.byminute());
+    QCOMPARE(r1.byhour(), r2.byhour());
+//     QEXPECT_FAIL("", "Implement Day parser", Continue);
+//     QCOMPARE(r1.byday(), r2.byday());
+    QCOMPARE(r1.bymonthday(), r2.bymonthday());
+    QCOMPARE(r1.byyearday(), r2.byyearday());
+    QCOMPARE(r1.byweekno(), r2.byweekno());
+    QCOMPARE(r1.bymonth(), r2.bymonth());
         
     //Rest
     QCOMPARE(ev.recurrenceDates(), re.recurrenceDates());
@@ -287,11 +225,10 @@ 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::writeEvent(ev);
-    //std::cout << result << endl;
+    std::cout << result << endl;
     Kolab::Event e = Kolab::readEvent(result, false);
     const Kolab::Event &re = e;
     checkIncidence(ev, re);
@@ -303,18 +240,36 @@ void BindingsTest::eventCompletness()
     
 }
 
+void BindingsTest::eventDuration()
+{
+    Kolab::Event ev;
+    ev.setDuration(Kolab::Duration(11,22,33,44, true));
+
+    const std::string result = Kolab::writeEvent(ev);
+//     std::cout << result << endl;
+    const Kolab::Event e = Kolab::readEvent(result, false);
+    QVERIFY(ev.duration().isValid());
+    QCOMPARE(ev.duration(), e.duration());
+}
+
 void BindingsTest::todoCompletness()
 {
     Kolab::Todo ev;
     setIncidence(ev);
     ev.setDue(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+    ev.addRelatedTo("rel1");
+    ev.addRelatedTo("rel2");
+    ev.setPercentComplete(50);
     
     std::string result = Kolab::writeTodo(ev);
-//     std::cout << result << endl;
+    std::cout << result << endl;
     Kolab::Todo e = Kolab::readTodo(result, false);
     const Kolab::Todo &re = e;
     checkIncidence(ev, re);
     QCOMPARE(ev.due(), re.due());
+    QCOMPARE(ev.relatedTo(), re.relatedTo());
+    QCOMPARE(ev.percentComplete(), re.percentComplete());
+
     
 }
 
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 2146c48..aa140b1 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -4,6 +4,18 @@
 #include <QtCore/QObject>
 #include <QtTest/QtTest>
 
+/*
+ * The test are roundtrip tests, which simply write an object out and read it again. The two objects are then compared for equality.
+ * This assumes that containers are working (comparison operators and adding/removing values).
+ * 
+ * Testing it properly would mean to add loads of testfiles in text so we could:
+ * serialize => compare to text representation
+ * deserialize => check values
+ * 
+ * If we would do this ideally for every property on every type that would result in a lot of work.
+ *
+ */ 
+
 class BindingsTest : public QObject
 {
   Q_OBJECT
@@ -18,6 +30,7 @@ class BindingsTest : public QObject
     void roundtripReverseEvent();
     void BenchmarkRoundtrip();
     void eventCompletness();
+    void eventDuration();
     void todoCompletness();
     
     void BenchmarkRoundtripKolab();
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
new file mode 100644
index 0000000..df19a75
--- /dev/null
+++ b/c++/tests/conversiontest.cpp
@@ -0,0 +1,54 @@
+#include "conversiontest.h"
+
+#include <QtTest/QtTest>
+#include <lib/xcalconversions.h>
+
+#include "serializers.h"
+
+Q_DECLARE_METATYPE(Kolab::Duration);
+ 
+void ConversionTest::durationParserTest_data()
+{
+    QTest::addColumn<Kolab::Duration>("expected");
+    QTest::addColumn<QString>("string");
+
+    QTest::newRow("Time") << Kolab::Duration(0,2,3,4, false) << "+PT2H3M4S";
+    QTest::newRow("Day") << Kolab::Duration(1,2,3,4, false) << "+P1DT2H3M4S";
+    QTest::newRow("Week") << Kolab::Duration(1, false) << "+P1W";
+    QTest::newRow("Week Multidigit, negative") << Kolab::Duration(23, true) << "-P23W";
+}
+
+void ConversionTest::durationParserTest()
+{
+    QFETCH(QString, string);
+    QFETCH(Kolab::Duration, expected);
+    const Kolab::Duration result = Kolab::toDuration(string.toStdString());
+    QCOMPARE(result, expected);
+}
+
+void ConversionTest::durationSerializerTest_data()
+{
+    QTest::addColumn<QString>("expected");
+    QTest::addColumn<Kolab::Duration>("duration");
+
+    QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false);
+    QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false);
+    QTest::newRow("Week") << "P1W" << Kolab::Duration(1, false);
+    QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true);
+}
+
+void ConversionTest::durationSerializerTest()
+{
+    QFETCH(Kolab::Duration, duration);
+    QFETCH(QString, expected);
+    const std::string result = Kolab::fromDuration(duration);
+    QCOMPARE(QString::fromStdString(result), expected);
+}
+
+
+
+QTEST_MAIN( ConversionTest )
+
+#include "conversiontest.moc"
+
+
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
new file mode 100644
index 0000000..989ec95
--- /dev/null
+++ b/c++/tests/conversiontest.h
@@ -0,0 +1,19 @@
+
+#ifndef CONVERSIONTEST_H
+#define CONVERSIONTEST_H
+
+#include <QObject>
+
+class ConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+
+    void durationParserTest_data();
+    void durationParserTest();
+    
+    void durationSerializerTest_data();
+    void durationSerializerTest();
+};
+
+#endif // CONVERSIONTEST_H
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
new file mode 100644
index 0000000..a4d386b
--- /dev/null
+++ b/c++/tests/serializers.h
@@ -0,0 +1,97 @@
+#ifndef SERIALIZERS_H
+#define SERIALIZERS_H
+
+#include <QByteArray>
+#include <QString>
+#include <lib/kolabformat.h>
+
+namespace QTest {
+    template<>
+    char *toString(const Kolab::DateTime &dt)
+    {
+        QByteArray ba = "Kolab::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::vector<Kolab::DateTime> &v)
+    {
+        QByteArray ba = "vector<Kolab::DateTime>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Attendee &a)
+    {
+        QByteArray ba = "Kolab::Attendee(";
+        ba += QString::fromStdString(a.email()).toAscii() + ", " + QString::fromStdString(a.name()).toAscii()+ ", " + 
+        QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role())  + ", " + QByteArray::number(a.rsvp())  + ", " + 
+        QString::fromStdString(a.uid()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Attendee> &v)
+    {
+        QByteArray ba = "vector<Kolab::Attendee>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+     
+    template<>
+    char *toString(const std::string &s)
+    {
+        QByteArray ba = "string(";
+        ba += QString::fromStdString(s).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<std::string> &v)
+    {
+        QByteArray ba = "vector<std::string>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<int> &v)
+    {
+        QByteArray ba = "vector<int>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QString::number(v.at(i)).toAscii()+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Duration &dt)
+    {
+        QByteArray ba = "Kolab::Duration(";
+        ba += QByteArray::number(dt.weeks()) + ", " + QByteArray::number(dt.days())+ ", " + QByteArray::number(dt.hours()) + ", ";
+        ba += QByteArray::number(dt.minutes()) + ", " + QByteArray::number(dt.seconds()) + ", " + QByteArray::number(dt.isNegative());
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+ }
+ 
+#endif
+ 
\ No newline at end of file
diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
index 86130ab..07d25d6 100644
--- a/schemas/ical/iCalendar-props.xsd
+++ b/schemas/ical/iCalendar-props.xsd
@@ -620,15 +620,15 @@
   </xs:complexType>
     
   <!-- 3.8.4.5 Related-To -->
-  <!-- Before extensions to allow different value types
+<!--   Before extensions to allow different value types-->
   <xs:complexType name="RelatedToPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcal:TextPropertyType"/>
     </xs:complexContent>
   </xs:complexType>
-   -->
    
-  <xs:complexType name="RelatedToPropType">
+   
+<!--  <xs:complexType name="RelatedToPropType">
     <xs:complexContent mixed="false">
       <xs:extension base="xcal:BasePropertyType">
         <xs:choice> 
@@ -638,7 +638,7 @@
         </xs:choice>
       </xs:extension>
     </xs:complexContent>
-  </xs:complexType>
+  </xs:complexType>-->
     
   <!-- 3.8.4.6 Uniform Resource Locator -->
   <xs:complexType name="UrlPropType">
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 3d58fd4..0d7ecc6 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -97,7 +97,7 @@
                         <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="related-to" type="RelatedToPropType" minOccurs="0"  maxOccurs="unbounded"/>
                         <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
                         <xs:element name="due" type="DuePropType" minOccurs="0"/>
                         <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
@@ -136,7 +136,7 @@
                         <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="related-to" type="RelatedToPropType" minOccurs="0" maxOccurs="unbounded"/>
                         <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
                         <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
                         <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>


commit 6b19db33fe30854780de837287e1a52238f4a0e0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sat Feb 4 16:11:25 2012 +0100

    CustomProperties

diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index e605e2d..89f5d84 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -259,6 +259,10 @@ private:
 };
 
 struct CustomProperty {
+    CustomProperty(const std::string &i, const std::string &v)
+    : identifier(i), value(v) {};
+
+    bool operator==(const CustomProperty &other) const{ return (identifier == other.identifier && value == other.value);};
     std::string identifier;
     std::string value;
 };
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 2004aa9..048666d 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -506,7 +506,11 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     if (prop.x_custom().size()) {
-        //TODO
+        std::vector<Kolab::CustomProperty> customProperties;
+        BOOST_FOREACH(icalendar_2_0::properties::x_custom_type p, prop.x_custom()) {
+            customProperties.push_back(CustomProperty(p.identifier(), p.value()));
+        }
+        inc.setCustomProperties(customProperties);
     }
 
 }
@@ -763,7 +767,9 @@ void getIncidenceProperties(T &prop, const I &inc)
     }
     
     if (!inc.customProperties().empty()) {
-        //TODO
+        BOOST_FOREACH(const Kolab::CustomProperty &a, inc.customProperties()) {
+            prop.x_custom().push_back(typename properties::x_custom_type(a.identifier, a.value));
+        }
     }
 
 }
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 21d2f7b..91a0683 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -233,7 +233,10 @@ void setIncidence(T &ev)
     attachments.push_back(attach3);
     
     ev.setAttachments(attachments);
-    //x-prop
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    ev.setCustomProperties(properties);
 }
 
 template <typename T>
@@ -274,6 +277,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.organizerName(), re.organizerName());
     QCOMPARE(ev.attendees(), re.attendees());
     QCOMPARE(ev.attachments(), re.attachments());
+    QCOMPARE(ev.customProperties(), re.customProperties());
 }
 
 


commit 972afa598d7b2ea2fcc8c69f6761e237defdd9fd
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sat Feb 4 15:51:44 2012 +0100

    test multiple attendees

diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 970eada..21d2f7b 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -201,9 +201,8 @@ void setIncidence(T &ev)
     attendee.setRSVP(true);
     attendee.setUid("uid");
     
-    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee);
-    //Attendee
-    //attach
+    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
+    
     std::vector<Kolab::Attachment> attachments;
     
     Kolab::Attachment attach;


commit 4623b9662aef6fa2d2401edcf8a5e0a15ded2d83
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sat Feb 4 15:50:17 2012 +0100

    x-uid param

diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index d406485..2004aa9 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -461,10 +461,9 @@ void setIncidenceProperties(I &inc, const T &prop)
                     if (const icalendar_2_0::RsvpParamType * p = dynamic_cast<const icalendar_2_0::RsvpParamType*> (&*it)) {
                         a.setRSVP(p->boolean());
                     }
-//                     if (const icalendar_2_0::UriParameterType * p = dynamic_cast<const icalendar_2_0::UriParameterType*> (&*it)) {
-//                         a.setUid(p->);
-//                     }
-//TODO x-uid
+                    if (const icalendar_2_0::XuidParamType * p = dynamic_cast<const icalendar_2_0::XuidParamType*> (&*it)) {
+                        a.setUid(p->text());
+                    }
                 }
             }
             attendees.push_back(a);
@@ -729,10 +728,9 @@ void getIncidenceProperties(T &prop, const I &inc)
                 p.baseParameter().push_back(icalendar_2_0::RsvpParamType(true));
             }
             
-//             if (a.uid().empty()) {
-//                 p.baseParameter().push_back(icalendar_2_0::UidPropType(a.uid()));
-//             }
-//TODO x-uid
+            if (!a.uid().empty()) {
+                p.baseParameter().push_back(icalendar_2_0::XuidParamType(a.uid()));
+            }
 
             attendee.parameters(p);
             prop.attendee().push_back(attendee);
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index f6daa1a..970eada 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -273,7 +273,6 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.location(), re.location());
     QCOMPARE(ev.organizerEmail(), re.organizerEmail());
     QCOMPARE(ev.organizerName(), re.organizerName());
-    QEXPECT_FAIL("", "Implement x-uid", Continue);
     QCOMPARE(ev.attendees(), re.attendees());
     QCOMPARE(ev.attachments(), re.attachments());
 }
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 2614c5f..3d58fd4 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -15,6 +15,13 @@
     </xs:complexType>
     <xs:element name="x-label" type="XlabelParamType" substitutionGroup="baseParameter"/>
 
+    <xs:complexType name="XuidParamType" mixed="false">
+        <xs:complexContent>
+            <xs:extension base="TextParameterType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="x-uid" type="XuidParamType" substitutionGroup="baseParameter"/>
+
 <!--            -->
 
     <xs:complexType name="KolabVersion" >


commit 86455935eb5b667709b3240b2c7fe09dfb110768
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sat Feb 4 15:49:43 2012 +0100

    Attachments

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index e715b36..b48e630 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -9,7 +9,7 @@ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC " ) #always generate shared libraries with -fPIC
 
 #Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml ${XERCES_C})
 
 #For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
diff --git a/c++/lib/base64.cpp b/c++/lib/base64.cpp
new file mode 100644
index 0000000..071b05c
--- /dev/null
+++ b/c++/lib/base64.cpp
@@ -0,0 +1,123 @@
+/* 
+   base64.cpp and base64.h
+
+   Copyright (C) 2004-2008 René Nyffenegger
+
+   This source code is provided 'as-is', without any express or implied
+   warranty. In no event will the author be held liable for any damages
+   arising from the use of this software.
+
+   Permission is granted to anyone to use this software for any purpose,
+   including commercial applications, and to alter it and redistribute it
+   freely, subject to the following restrictions:
+
+   1. The origin of this source code must not be misrepresented; you must not
+      claim that you wrote the original source code. If you use this source code
+      in a product, an acknowledgment in the product documentation would be
+      appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+      misrepresented as being the original source code.
+
+   3. This notice may not be removed or altered from any source distribution.
+
+   René Nyffenegger rene.nyffenegger at adp-gmbh.ch
+
+*/
+
+#include "base64.h"
+#include <iostream>
+
+static const std::string base64_chars = 
+             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+             "abcdefghijklmnopqrstuvwxyz"
+             "0123456789+/";
+
+
+static inline bool is_base64(unsigned char c) {
+  return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
+  std::string ret;
+  int i = 0;
+  int j = 0;
+  unsigned char char_array_3[3];
+  unsigned char char_array_4[4];
+
+  while (in_len--) {
+    char_array_3[i++] = *(bytes_to_encode++);
+    if (i == 3) {
+      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+      char_array_4[3] = char_array_3[2] & 0x3f;
+
+      for(i = 0; (i <4) ; i++)
+        ret += base64_chars[char_array_4[i]];
+      i = 0;
+    }
+  }
+
+  if (i)
+  {
+    for(j = i; j < 3; j++)
+      char_array_3[j] = '\0';
+
+    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+    char_array_4[3] = char_array_3[2] & 0x3f;
+
+    for (j = 0; (j < i + 1); j++)
+      ret += base64_chars[char_array_4[j]];
+
+    while((i++ < 3))
+      ret += '=';
+
+  }
+
+  return ret;
+
+}
+
+std::string base64_decode(std::string const& encoded_string) {
+  int in_len = encoded_string.size();
+  int i = 0;
+  int j = 0;
+  int in_ = 0;
+  unsigned char char_array_4[4], char_array_3[3];
+  std::string ret;
+
+  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
+    char_array_4[i++] = encoded_string[in_]; in_++;
+    if (i ==4) {
+      for (i = 0; i <4; i++)
+        char_array_4[i] = base64_chars.find(char_array_4[i]);
+
+      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+      for (i = 0; (i < 3); i++)
+        ret += char_array_3[i];
+      i = 0;
+    }
+  }
+
+  if (i) {
+    for (j = i; j <4; j++)
+      char_array_4[j] = 0;
+
+    for (j = 0; j <4; j++)
+      char_array_4[j] = base64_chars.find(char_array_4[j]);
+
+    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
+  }
+
+  return ret;
+}
\ No newline at end of file
diff --git a/c++/lib/base64.h b/c++/lib/base64.h
new file mode 100644
index 0000000..ceb1357
--- /dev/null
+++ b/c++/lib/base64.h
@@ -0,0 +1,4 @@
+#include <string>
+
+std::string base64_encode(unsigned char const* , unsigned int len);
+std::string base64_decode(std::string const& s);
\ No newline at end of file
diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index 190a316..7bf3cff 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -40,6 +40,8 @@ const char* const TZ_PREFIX = "/kolab.org/";
 
 const char* const THISANDFUTURE = "THISANDFUTURE";
 
+const char* const BASE64 = "BASE64";
+
 const char* const NEEDSACTION = "NEEDS-ACTION";
 const char* const COMPLETED = "OPAQUE";
 const char* const INPROCESS = "IN-PROCESS";
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index eb01ed0..ac702e2 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -488,8 +488,81 @@ std::vector<Attendee> operator<<(std::vector<Attendee> v, const Attendee &a)
 
 
 
+struct Attachment::Private
+{
+    std::string uri;
+    std::string data;
+    std::string mimetype;
+    std::string label;
+};
+
+Attachment::Attachment()
+:   d(new Attachment::Private)
+{
+}
 
+Attachment::Attachment(const Kolab::Attachment &other)
+:   d(new Attachment::Private)
+{
+    *d = *other.d;
+}
+
+void Attachment::operator=(const Kolab::Attachment &other)
+{
+    *d = *other.d;
+}
+
+Attachment::~Attachment()
+{
+}
+
+bool Attachment::operator==(const Kolab::Attachment &other) const
+{
+    if ( d->uri == other.uri() &&
+        d->data == other.data() &&
+        d->label == other.label() &&
+        d->mimetype == other.mimetype() ) {
+        return true;
+    }
+    return false;
+}
 
+void Attachment::setUri(const std::string &uri, const std::string& mimetype)
+{
+    d->uri = uri;
+    d->mimetype = mimetype;
+}
+
+std::string Attachment::uri() const
+{
+    return d->uri;
+}
+
+std::string Attachment::mimetype() const
+{
+    return d->mimetype;
+}
+
+void Attachment::setLabel(const std::string &label)
+{
+    d->label = label;
+}
+
+std::string Attachment::label() const
+{
+    return d->label;
+}
+
+void Attachment::setData(const std::string &data, const std::string& mimetype)
+{
+    d->data = data;
+    d->mimetype = mimetype;
+}
+
+std::string Attachment::data() const
+{
+    return d->data;
+}
 
 
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 928448b..e605e2d 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -228,19 +228,34 @@ std::vector<Attendee> operator<<(std::vector<Attendee>, const Attendee&);
 
 
 class Attachment {
-// public:
-//     /**
-//      * If @param embedd is set, the file is embedded during serialization.
-//      */
-//     void setFile(const std::string uri, const std::string &mimetype, bool embedd);
-//     ///Unencodedn binary content, Implies embedded
-//     void setUnencoded(const std::string &, const std::string &mimetype);
+public:
+    Attachment();
+    Attachment(const Kolab::Attachment &);
+    ~Attachment();
+
+    void operator=(const Attachment &);
+    bool operator==(const Attachment &) const;
+
+    void setUri(const std::string &uri, const std::string &mimetype);
+    std::string uri() const;
+
+     ///Un-encoded binary content, Implies embedded, will be encoded
+     void setData(const std::string &, const std::string &mimetype);
+     ///Decoded binary content.
+     std::string data() const;
+     //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement?
 //     ///Base64 encoded binary content, Implies embedded
-//     void setEncoded(const std::string &, const std::string &mimetype);
-//     ///User visible label
-//     void setLabel(const std::string &);
-//TODO
+//      void setEncodedData(const std::string &, const std::string &mimetype);
+
+    std::string mimetype() const;
 
+    ///User visible label
+    void setLabel(const std::string &);
+    std::string label() const;
+
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
 };
 
 struct CustomProperty {
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index cd137bd..d406485 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -23,6 +23,7 @@
 #include <boost/foreach.hpp>
 #include "kolabtodo.h"
 #include "utils.h"
+#include "base64.h"
 namespace Kolab {
 
 class Incidence;
@@ -472,7 +473,37 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     if (prop.attach().size()) {
-        //TODO
+        std::vector<Kolab::Attachment> attachments;
+        BOOST_FOREACH(icalendar_2_0::properties::attach_type aProp, prop.attach()) {
+            Kolab::Attachment a;
+            std::string mimetype;
+            if (aProp.parameters()) {
+                const icalendar_2_0::AttachPropType ::parameters_type &parameters = *aProp.parameters();
+                for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                    if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast<const icalendar_2_0::FmttypeParamType*> (&*it)) {
+                        mimetype = p->text();
+                    }
+                    if (const icalendar_2_0::EncodingParamType *p = dynamic_cast<const icalendar_2_0::EncodingParamType*> (&*it)) {
+                        if (p->text() != BASE64) {
+                            std::cout << "wrong encoding";
+                            continue;
+                        }
+                    }
+                    if (const icalendar_2_0::XlabelParamType *p = dynamic_cast<const icalendar_2_0::XlabelParamType*> (&*it)) {
+                        a.setLabel(p->text());
+                    }
+                }
+            }
+
+            if (aProp.uri()) {
+                a.setUri(*aProp.uri(), mimetype);
+            }
+            if (aProp.binary()) {
+                a.setData(base64_decode(*aProp.binary()), mimetype);
+            }
+            attachments.push_back(a);
+        }
+        inc.setAttachments(attachments);
     }
     
     if (prop.x_custom().size()) {
@@ -710,7 +741,27 @@ void getIncidenceProperties(T &prop, const I &inc)
     }
     
     if (!inc.attachments().empty()) {
-        //TODO
+        
+        BOOST_FOREACH(const Kolab::Attachment &a, inc.attachments()) {
+            typename properties::attach_type attachment;
+            typename properties::attach_type::parameters_type p;
+            
+            p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype()));
+            
+            if (!a.label().empty()) {
+                p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label()));
+            }
+            
+            if (!a.uri().empty()) {
+                attachment.uri(a.uri());
+            } else  if (!a.data().empty()) {
+                attachment.binary(base64_encode(reinterpret_cast<const unsigned char*>(a.data().c_str()), a.data().length()));
+                p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64));
+            }
+            
+            attachment.parameters(p);
+            prop.attach().push_back(attachment);
+        }
     }
     
     if (!inc.customProperties().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 7cf085d..f6daa1a 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -14,6 +14,8 @@
 #include <lib/kolabformat.h>
 #include <kdebug.h>
 #include <lib/kolabkcalconversion.h>
+#include <iostream>
+#include <fstream>
 
 namespace QTest {
     template<>
@@ -202,6 +204,36 @@ void setIncidence(T &ev)
     ev.setAttendees(std::vector<Kolab::Attendee>() << attendee);
     //Attendee
     //attach
+    std::vector<Kolab::Attachment> attachments;
+    
+    Kolab::Attachment attach;
+    attach.setData("data????*?*?*?*?*?", "mimetype");
+    attach.setLabel("label");
+    attachments.push_back(attach);
+    
+    Kolab::Attachment attach2;
+    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
+    attach2.setLabel("labe2l");
+    attachments.push_back(attach2);
+    
+    Kolab::Attachment attach3;
+    using namespace std;
+    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
+    if (file.is_open()) {
+        int size = file.tellg();
+        char *memblock = new char [size];
+        file.seekg (0, ios::beg);
+        file.read (memblock, size);
+        file.close();
+
+        attach3.setData(string(memblock, size), "mimetype");
+
+        delete[] memblock;
+    }
+    attach3.setLabel("labe3l");
+    attachments.push_back(attach3);
+    
+    ev.setAttachments(attachments);
     //x-prop
 }
 
@@ -243,6 +275,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.organizerName(), re.organizerName());
     QEXPECT_FAIL("", "Implement x-uid", Continue);
     QCOMPARE(ev.attendees(), re.attendees());
+    QCOMPARE(ev.attachments(), re.attachments());
 }
 
 
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 3fe2af5..2614c5f 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -6,6 +6,17 @@
 
     <xs:include schemaLocation="iCalendar-props.xsd" />
 
+<!--Custom Parameters-->
+
+    <xs:complexType name="XlabelParamType" mixed="false">
+        <xs:complexContent>
+            <xs:extension base="TextParameterType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="x-label" type="XlabelParamType" substitutionGroup="baseParameter"/>
+
+<!--            -->
+
     <xs:complexType name="KolabVersion" >
         <xs:complexContent mixed="false">
             <xs:extension base="BasePropertyType">


commit 0ee9d0e06b484dc70b7d7b47fa72f104617e22bc
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Feb 3 22:22:26 2012 +0100

    Attendee implementation with tests

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index 524a5ae..190a316 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -31,6 +31,7 @@
 
 #include <fstream>
 #include <iostream>
+#include "kolabcontainers.h"
 
 const char* const XCAL_VERSION = "2.0";
 const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
@@ -52,8 +53,23 @@ const char* const CONFIDENTIAL = "CONFIDENTIAL";
 const char* const PRIVATE = "PRIVATE";
 const char* const PUBLIC = "PUBLIC";
 
+const char* const PARTACCEPTED = "ACCEPTED";
+const char* const PARTDECLINED = "DECLINED";
+const char* const PARTDELEGATED = "DELEGATED";
+const char* const PARTNEEDSACTION = "NEEDS-ACTION";
+const char* const PARTTENTATIVE = "TENTATIVE";
+
+const char* const CHAIR = "CHAIR";
+const char* const NONPARTICIPANT = "NON-PARTICIPANT";
+const char* const OPTIONAL = "OPT-PARTICIPANT";
+const char* const REQUIRED = "REQ-PARTICIPANT";
+
+
 namespace Kolab {
 
+
+//=== Generic ===
+    
 template <typename T>
 int convertToInt(T integer)
 {
@@ -91,6 +107,82 @@ int toInt(const icalendar_2_0::IntegerPropertyType &prop)
     return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
 }
 
+//----------------
+
+//=== Attendee ===
+
+std::string mapPartStat(PartStatus status)
+{
+    switch (status) {
+        case PartAccepted:
+            return PARTACCEPTED;
+        case PartDeclined:
+            return PARTDECLINED;
+        case PartDelegated:
+            return PARTDELEGATED;
+        case PartNeedsAction:
+            return PARTNEEDSACTION;
+        case PartTentative:
+            return PARTTENTATIVE;
+    }
+    std::cout << "PartStat not handled: " << status;
+    return std::string();
+}
+
+PartStatus mapPartStat(const std::string &status)
+{
+    if (status == PARTACCEPTED) {
+        return PartAccepted;
+    } else if (status == PARTDECLINED) {
+        return PartDeclined;
+    } else if (status == PARTDELEGATED) {
+        return PartDelegated;
+    } else if (status == PARTNEEDSACTION) {
+        return PartNeedsAction;
+    } else if (status == PARTTENTATIVE) {
+        return PartTentative;
+    }
+    std::cout << "Unhandled partstatus" << status;
+    return PartNeedsAction;
+}
+
+std::string mapRole(Role status)
+{
+    switch (status) {
+        case Chair:
+            return std::string(CHAIR);
+        case NonParticipant:
+            return NONPARTICIPANT;
+        case Optional:
+            return OPTIONAL;
+        case Required:
+            return REQUIRED;
+    }
+    std::cout << "PartStat not handled: " << status;
+    return std::string();
+}
+
+Role mapRole(const std::string &status)
+{
+    if (status == CHAIR) {
+        return Chair;
+    } else if (status == NONPARTICIPANT) {
+        return NonParticipant;
+    } else if (status == OPTIONAL) {
+        return Optional;
+    } else if (status == REQUIRED) {
+        return Required;
+    }
+    std::cout << "Unhandled Role" << status;
+    return Required;
+}
+
+
+
+
+
+//----------------
+
 ///trait to convert date-time values
 template <typename T> 
 struct DateTimeConverter;
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 7f9fdaf..eb01ed0 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -229,8 +229,6 @@ void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
     *d = *other.d;
 }
 
-
-
 RecurrenceRule::~RecurrenceRule()
 {
     
@@ -377,6 +375,119 @@ bool RecurrenceRule::isValid() const
 
 
 
+struct Attendee::Private
+{
+    Private()
+    : partStat(PartNeedsAction),
+    role(Required),
+    rsvp(false){};
+    
+    std::string email;
+    std::string name;
+    PartStatus partStat;
+    std::string uid;
+    Role role;
+    bool rsvp;
+};
+
+Attendee::Attendee(const std::string& email)
+:   d(new Attendee::Private)
+{
+   d->email = email; 
+}
+
+Attendee::Attendee(const Kolab::Attendee &other)
+:   d(new Attendee::Private)
+{
+    *d = *other.d;
+}
+
+void Attendee::operator=(const Kolab::Attendee &other)
+{
+    *d = *other.d;
+}
+
+Attendee::~Attendee()
+{
+    
+}
+
+bool Attendee::operator==(const Kolab::Attendee &other) const
+{
+    if ( d->email == other.email() &&
+        d->name == other.name() &&
+        d->partStat == other.partStat() &&
+        d->uid == other.uid() &&
+        d->role == other.role() &&
+        d->rsvp== other.rsvp()) {
+        return true;
+    }
+    return false;
+}
+
+std::string Attendee::email() const
+{
+    return d->email;
+}
+
+void Attendee::setName(const std::string &name)
+{
+    d->name = name;
+}
+
+std::string Attendee::name() const
+{
+    return d->name;
+}
+
+void Attendee::setPartStat(PartStatus partStat)
+{
+    d->partStat = partStat;
+}
+
+PartStatus Attendee::partStat() const
+{
+    return d->partStat;
+}
+
+void Attendee::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Attendee::uid() const
+{
+    return d->uid;
+}
+
+void Attendee::setRole(Role role)
+{
+    d->role = role;
+}
+
+Role Attendee::role() const
+{
+    return d->role;
+}
+
+void Attendee::setRSVP(bool rsvp)
+{
+    d->rsvp = rsvp;
+}
+
+bool Attendee::rsvp() const
+{
+    return d->rsvp;
+}
+
+std::vector<Attendee> operator<<(std::vector<Attendee> v, const Attendee &a)
+{
+    v.push_back(a);
+    return v;
+}
+
+
+
 
 
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index ca8a7a5..928448b 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -195,14 +195,38 @@ enum Role {
 };
 
 class Attendee {
-// public:
-//     Attendee(const std::string &email);
-//     void setName(const std::string &);
-//     void setPartStat(PartStatus);
-//     void setUid(const std::string &);
-//     void setRole(Role);
+public:
+    Attendee(const std::string &email);
+    Attendee(const Attendee &);
+    ~Attendee();
+
+    void operator=(const Attendee &);
+    bool operator==(const Attendee &) const;
+
+    std::string email() const;
+
+    void setName(const std::string &);
+    std::string name() const;
+
+    void setPartStat(PartStatus);
+    PartStatus partStat() const;
+
+    void setUid(const std::string &);
+    std::string uid() const;
+
+    void setRole(Role);
+    Role role() const;
+
+    void setRSVP(bool);
+    bool rsvp() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
 };
 
+std::vector<Attendee> operator<<(std::vector<Attendee>, const Attendee&);
+
+
 class Attachment {
 // public:
 //     /**
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index e5eb50c..cd137bd 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -436,7 +436,39 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     if (prop.attendee().size()) {
-        //TODO
+        std::vector<Kolab::Attendee> attendees;
+        BOOST_FOREACH(icalendar_2_0::properties::attendee_type aProp, prop.attendee()) {
+            Kolab::Attendee a(toString(aProp.cal_address()));
+            if (aProp.parameters()) {
+                const icalendar_2_0::AttendeePropType::parameters_type &parameters = *aProp.parameters();
+                for (icalendar_2_0::AttendeePropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                    if (const icalendar_2_0::CnParamType * p = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
+                        a.setName(p->text());
+                    }
+                    if (const icalendar_2_0::PartstatParamType * p = dynamic_cast<const icalendar_2_0::PartstatParamType*> (&*it)) {
+                        PartStatus s = mapPartStat(p->text());
+                        if (s != PartNeedsAction) {
+                            a.setPartStat(s);
+                        }
+                    }
+                    if (const icalendar_2_0::RoleParamType * p = dynamic_cast<const icalendar_2_0::RoleParamType*> (&*it)) {
+                        Role s = mapRole(p->text());
+                        if (s != Required) {
+                            a.setRole(s);
+                        }
+                    }
+                    if (const icalendar_2_0::RsvpParamType * p = dynamic_cast<const icalendar_2_0::RsvpParamType*> (&*it)) {
+                        a.setRSVP(p->boolean());
+                    }
+//                     if (const icalendar_2_0::UriParameterType * p = dynamic_cast<const icalendar_2_0::UriParameterType*> (&*it)) {
+//                         a.setUid(p->);
+//                     }
+//TODO x-uid
+                }
+            }
+            attendees.push_back(a);
+        }
+        inc.setAttendees(attendees);
     }
     
     if (prop.attach().size()) {
@@ -521,6 +553,8 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
 }
 
 
+
+
 template <typename T, typename I>
 void getIncidenceProperties(T &prop, const I &inc)
 {
@@ -639,8 +673,40 @@ void getIncidenceProperties(T &prop, const I &inc)
         prop.organizer(organizer);
     }
     
-    if (!inc.attendees().empty()) {
-        //TODO
+    if (!inc.attendees().empty()) {        
+        
+        BOOST_FOREACH(const Kolab::Attendee &a, inc.attendees()) {
+            typename properties::attendee_type attendee(a.email());
+            
+            typename properties::attendee_type::parameters_type p;
+            if (!a.name().empty()) {
+                icalendar_2_0::CnParamType name(a.name());
+                p.baseParameter().push_back(name);
+            }
+            
+            std::string stat = mapPartStat(a.partStat());
+            if (!stat.empty()) {
+                p.baseParameter().push_back(icalendar_2_0::PartstatParamType(stat));
+            }
+            
+            std::string r = mapRole(a.role());
+            if (!r.empty()) {
+                p.baseParameter().push_back(icalendar_2_0::RoleParamType(r));
+            }
+            
+            if (a.rsvp()) {
+                p.baseParameter().push_back(icalendar_2_0::RsvpParamType(true));
+            }
+            
+//             if (a.uid().empty()) {
+//                 p.baseParameter().push_back(icalendar_2_0::UidPropType(a.uid()));
+//             }
+//TODO x-uid
+
+            attendee.parameters(p);
+            prop.attendee().push_back(attendee);
+
+        }
     }
     
     if (!inc.attachments().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index f8b5619..7cf085d 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -16,33 +16,91 @@
 #include <lib/kolabkcalconversion.h>
 
 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 Kolab::DateTime &dt)
+    {
+        QByteArray ba = "Kolab::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::vector<Kolab::DateTime> &v)
+    {
+        QByteArray ba = "vector<Kolab::DateTime>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const Kolab::Attendee &a)
+    {
+        QByteArray ba = "Kolab::Attendee(";
+        ba += QString::fromStdString(a.email()).toAscii() + ", " + QString::fromStdString(a.name()).toAscii()+ ", " + 
+        QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role())  + ", " + QByteArray::number(a.rsvp())  + ", " + 
+        QString::fromStdString(a.uid()).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<Kolab::Attendee> &v)
+    {
+        QByteArray ba = "vector<Kolab::Attendee>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
      
     template<>
-     char *toString(const std::string &s)
-     {
-         QByteArray ba = "string(";
-         ba += QString::fromStdString(s).toAscii();
-         ba += ")";
-         return qstrdup(ba.data());
-     }
+    char *toString(const std::string &s)
+    {
+        QByteArray ba = "string(";
+        ba += QString::fromStdString(s).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<std::string> &v)
+    {
+        QByteArray ba = "vector<std::string>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QByteArray(toString(v.at(i)))+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const std::vector<int> &v)
+    {
+        QByteArray ba = "vector<int>(";
+        for (int i = 0; i < v.size(); i++) {
+            ba += QString::number(v.at(i)).toAscii()+ ", ";
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
  }
  
+//TODO remove
 void BindingsTest::writeContact()
 {
     Kolab::Contact contact;
     std::cout << Kolab::writeContact(contact) << std::endl;
 }
 
+//TODO remove
 void BindingsTest::readEvent()
 {
     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
@@ -57,6 +115,7 @@ void BindingsTest::readEvent()
     QCOMPARE(event.summary(), std::string("Event #2"));
 }
 
+//TODO remove
 void BindingsTest::writeEvent()
 {
     Kolab::Event event;
@@ -70,6 +129,7 @@ void BindingsTest::writeEvent()
     std::cout << Kolab::writeEvent(event) << std::endl;
 }
 
+//TODO remove
 void BindingsTest::roundtripEvent()
 {
     Kolab::Event event;
@@ -84,6 +144,7 @@ void BindingsTest::roundtripEvent()
     std::cout << result << std::endl;
 }
 
+//TODO remove
 void BindingsTest::roundtripReverseEvent()
 {
     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
@@ -130,6 +191,15 @@ void setIncidence(T &ev)
     ev.setStatus(Kolab::Confirmed);
     ev.setLocation("location");
     ev.setOrganizer("email","organizer");
+    
+    Kolab::Attendee attendee("email");
+    attendee.setName("name");
+    attendee.setPartStat(Kolab::PartDelegated);
+    attendee.setRole(Kolab::Chair);
+    attendee.setRSVP(true);
+    attendee.setUid("uid");
+    
+    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee);
     //Attendee
     //attach
     //x-prop
@@ -138,15 +208,17 @@ void setIncidence(T &ev)
 template <typename T>
 void checkIncidence(const T &ev, const T &re)
 {
+    //Common to all
+    
     QCOMPARE(ev.uid(), re.uid());
     QCOMPARE(ev.created(), re.created());
-    QVERIFY(re.lastModified().isValid());
+    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
     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.categories(), re.categories());
     QCOMPARE(ev.start(), re.start());
     
+    //Recurrence
     const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
     const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
     QCOMPARE(r1.isValid(), r2.isValid());
@@ -155,14 +227,11 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(r1.weekStart(), r2.weekStart());
     QCOMPARE(r1.count(), r2.count());
     QCOMPARE(r1.end(), r2.end());
-    QCOMPARE(r1.bysecond().size(), r2.bysecond().size());
-    QCOMPARE(r1.bysecond().at(0), r2.bysecond().at(0));
-    QCOMPARE(r1.bysecond().at(1), r2.bysecond().at(1));
-    
-    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(r1.bysecond(), r2.bysecond());
+        
+    //Rest
+    QCOMPARE(ev.recurrenceDates(), re.recurrenceDates());
+    QCOMPARE(ev.exceptionDates(), re.exceptionDates());
     QCOMPARE(ev.recurrenceID(), re.recurrenceID());
     QCOMPARE(ev.thisAndFuture(), re.thisAndFuture());
     QCOMPARE(ev.summary(), re.summary());
@@ -172,6 +241,8 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.location(), re.location());
     QCOMPARE(ev.organizerEmail(), re.organizerEmail());
     QCOMPARE(ev.organizerName(), re.organizerName());
+    QEXPECT_FAIL("", "Implement x-uid", Continue);
+    QCOMPARE(ev.attendees(), re.attendees());
 }
 
 
@@ -185,11 +256,14 @@ void BindingsTest::eventCompletness()
     ev.setTransparency(true);
     
     std::string result = Kolab::writeEvent(ev);
-//     std::cout << result << endl;
+    //std::cout << result << endl;
     Kolab::Event e = Kolab::readEvent(result, false);
     const Kolab::Event &re = e;
     checkIncidence(ev, re);
     QCOMPARE(ev.end(), re.end());
+//     QEXPECT_FAIL("", "Will fix in the next release", Continue);
+//     QVERIFY(ev.duration().isValid());
+//     QCOMPARE(ev.duration(), re.duration());
     QCOMPARE(ev.transparency(), re.transparency());
     
 }


commit e842f6a292ecf16a6789ea0180118dc8ea2638e3
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Feb 3 22:21:03 2012 +0100

    Use separate version numbers for implementation and implemented format specification.

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index 39973fa..524a5ae 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -385,6 +385,8 @@ typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl)
             T::readIncidence(*e, event);
             incidences.push_back(e);
         }
+        
+        //TODO x_kolab_version
 
         //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
 //         foreach (KCalCore::Event * event, events) {
@@ -429,9 +431,9 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
         VcalendarType::components_type components;
         T::addIncidence(components, inc);
         
-        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME);
+        VcalendarType::properties_type::prodid_type prodid(productid+KOLAB_LIBNAME+KOLAB_LIB_VERSION); //FIXME own version field for lib version
         VcalendarType::properties_type::version_type version(XCAL_VERSION);
-        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_VERSION);
+        VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION);
         
         VcalendarType::properties_type properties(prodid, version, x_kolab_version);
         
diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
index 5c2f170..38d31dd 100644
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@ -19,6 +19,7 @@
 #define GLOBAL_DEFINITIONS_H
 
 const char* const KOLAB_LIBNAME = "libkolabxml";
-const char* const KOLAB_VERSION = "2.9.0";
+const char* const KOLAB_LIB_VERSION = "0.9";
+const char* const KOLAB_FORMAT_VERSION = "2.9.0";
 
 #endif
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index c672f93..9a89863 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -81,7 +81,7 @@ std::string serializeCard(const T &card, const std::string prod = std::string())
 
     try {
         vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
-        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_VERSION);
+        vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
         vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME);
         vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
         vcard_4_0::vcard::kind_type kind(getType<T>());


commit 04e0b64d4c9548e103c57eca893bf5c8f3edaca3
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Jan 30 22:43:21 2012 +0100

    Don't use typename where not needed, it's illegal in c++03.

diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index cfabe13..00aa254 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -33,11 +33,11 @@ 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 boost::shared_ptr<KDateTime> DatePtr;
+    typedef KCalCore::RecurrenceRule RecurrenceType;
+    typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
     typedef QString StringType;
-    typedef typename KCalCore::Incidence IncidenceType;
+    typedef KCalCore::Incidence IncidenceType;
 };
 
 
@@ -67,12 +67,12 @@ void setString(icalendar_2_0::TextPropertyType &p, const QString &s)
 // }
 
 
-typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+typedef KCalCoreTypes::RecurrencePtr RecurrencePtr;
 
 template <> struct DateTimeConverter<KDateTime>
 {
     typedef KDateTime Type;
-    typedef typename boost::shared_ptr<KDateTime> Ptr;
+    typedef boost::shared_ptr<KDateTime> Ptr;
 
     static Ptr toDate(const  xml_schema::date &dt)
     {
@@ -144,8 +144,8 @@ 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)
+    typedef KCalCoreTypes::RecurrenceType Type;
+    typedef 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)
     {
@@ -369,7 +369,7 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename
 {
     using namespace icalendar_2_0;
     
-    typedef RecurrenceConverter< typename KCalCore::RecurrenceRule > RC;
+    typedef RecurrenceConverter< KCalCore::RecurrenceRule > RC;
     typedef DateTimeConverter< KDateTime> DC;
     
     std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
@@ -595,10 +595,10 @@ template <> struct IncidenceConverter < KCalCore::Incidence, 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;
+    typedef icalendar_2_0::KolabEvent KolabType;
+    typedef KCalCore::Event IncidenceType;
+    typedef KCalCore::Event::Ptr IncidencePtr;
+    typedef KCalCore::Incidence Incidence;
     
     static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
     {
@@ -657,9 +657,9 @@ template < > struct IncidenceTrait <KCalCore::Event>
 
 template < > struct IncidenceTrait <KCalCore::Todo>
 {
-    typedef typename icalendar_2_0::KolabTodo KolabType;
-    typedef typename KCalCore::Todo IncidenceType;
-    typedef typename KCalCore::Incidence Incidence;
+    typedef icalendar_2_0::KolabTodo KolabType;
+    typedef KCalCore::Todo IncidenceType;
+    typedef KCalCore::Incidence Incidence;
     
     static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
     {
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 26e3f17..e5eb50c 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -30,9 +30,9 @@ class Incidence;
 struct KolabTypes
 {
     typedef DateTime DateType;
-    typedef typename boost::shared_ptr<DateTime> DatePtr;
+    typedef boost::shared_ptr<DateTime> DatePtr;
     typedef RecurrenceRule RecurrenceType;
-    typedef typename std::auto_ptr<RecurrenceRule> RecurrencePtr;
+    typedef std::auto_ptr<RecurrenceRule> RecurrencePtr;
     typedef std::string StringType;
     typedef Incidence IncidenceType;
 };
@@ -68,7 +68,7 @@ std::string toString(const icalendar_2_0::TextPropertyType &s)
 template <> struct DateTimeConverter<DateTime>
 {
     typedef DateTime Type;
-    typedef typename boost::shared_ptr<DateTime> Ptr;
+    typedef boost::shared_ptr<DateTime> Ptr;
 
     static Ptr toDate(const  xml_schema::date &dt)
     {
@@ -131,8 +131,8 @@ template <> struct DateTimeConverter<DateTime>
 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)
+    typedef KolabTypes::RecurrenceType Type;
+    typedef 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)
     {
@@ -522,7 +522,7 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
 
 
 template <typename T, typename I>
-void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to template
+void getIncidenceProperties(T &prop, const I &inc)
 {
     using namespace icalendar_2_0;
     
@@ -681,10 +681,10 @@ const char* const OPAQUE = "OPAQUE";
 
 template < > struct IncidenceTrait <Kolab::Event>
 {
-    typedef typename icalendar_2_0::KolabEvent KolabType;
-    typedef typename Kolab::Event IncidenceType;
-    typedef typename boost::shared_ptr<Kolab::Event> IncidencePtr;
-    typedef typename Kolab::Incidence Incidence;
+    typedef icalendar_2_0::KolabEvent KolabType;
+    typedef Kolab::Event IncidenceType;
+    typedef boost::shared_ptr<Kolab::Event> IncidencePtr;
+    typedef Kolab::Incidence Incidence;
     
     static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
     {
@@ -693,7 +693,7 @@ template < > struct IncidenceTrait <Kolab::Event>
         getIncidenceProperties<KolabType::properties_type>(prop, event);
 
         if (event.end().isValid()) {
-            prop.dtend(fromDate<KolabTypes, typename KolabType::properties_type::dtend_type>(event.end()));
+            prop.dtend(fromDate<KolabTypes, KolabType::properties_type::dtend_type>(event.end()));
         }/* else if (event.duration().isValid()) {
             //TODO
         }*/
@@ -753,10 +753,10 @@ template < > struct IncidenceTrait <Kolab::Event>
 
 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;
+    typedef icalendar_2_0::KolabTodo KolabType;
+    typedef Kolab::Todo IncidenceType;
+    typedef boost::shared_ptr<Kolab::Todo> IncidencePtr;
+    typedef Kolab::Incidence Incidence;
     
     static void writeIncidence(KolabType& vevent, const Kolab::Todo &todo)
     {
@@ -765,7 +765,7 @@ template < > struct IncidenceTrait <Kolab::Todo>
         getIncidenceProperties<KolabType::properties_type>(prop, todo);
 
         if (todo.due().isValid()) {
-            prop.due(fromDate<KolabTypes, typename KolabType::properties_type::due_type>(todo.due()));
+            prop.due(fromDate<KolabTypes, KolabType::properties_type::due_type>(todo.due()));
         }
 //         if (todo.transparency()) {
 //             prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));


commit 3c99fac7b3bed9508c7be3a3a992fff7a7127d1d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Jan 30 21:59:57 2012 +0100

    Don't use internal headers.

diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index e6b746e..1c8b7ee 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -19,7 +19,7 @@
 #define XMLPARSER_WRAPPER_H
 
 #include <string>
-#include <auto_ptr.h>
+#include <memory>
 #include <bindings/kolabformat-xcal.hxx>
 #include <xsd/cxx/tree/error-handler.hxx>
 #include <boost/scoped_ptr.hpp>


commit 5795d0f8008de7231667df14d25cc31b4eb04ce9
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Dec 30 18:08:09 2011 +0100

    Correct typo in Frequency (was: Frequencey)

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index b3a6dbf..7f9fdaf 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -197,7 +197,7 @@ struct RecurrenceRule::Private
     count(-1),
     interval(1){};
     
-    Frequencey freq;
+    Frequency freq;
     Weekday weekstart;
     DateTime end;
     int count;
@@ -236,12 +236,12 @@ RecurrenceRule::~RecurrenceRule()
     
 }
 
-void RecurrenceRule::setFrequency(RecurrenceRule::Frequencey freq)
+void RecurrenceRule::setFrequency(RecurrenceRule::Frequency freq)
 {
     d->freq = freq;
 }
 
-RecurrenceRule::Frequencey RecurrenceRule::frequency() const
+RecurrenceRule::Frequency RecurrenceRule::frequency() const
 {
     return d->freq;
 }
@@ -382,4 +382,4 @@ bool RecurrenceRule::isValid() const
 
 
 
-}//Namespace
\ No newline at end of file
+}//Namespace
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 6b49a5c..ca8a7a5 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -108,7 +108,7 @@ public:
 
     void operator=(const RecurrenceRule &);
     
-    enum Frequencey {
+    enum Frequency {
         None,
         Yearly,
         Monthly,
@@ -119,8 +119,8 @@ public:
         Secondly
     };
     
-    void setFrequency(Frequencey);
-    Frequencey frequency() const;
+    void setFrequency(Frequency);
+    Frequency frequency() const;
     
     enum Weekday {
         Monday,
@@ -254,4 +254,4 @@ class Configuration {
     
 }
 
-#endif
\ No newline at end of file
+#endif


commit 80967dbc443b01943f3de501646d4cc5cf928d0b
Merge: 60bd411 2f6b952
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Dec 30 16:37:47 2011 +0100

    Merge branch 'c++/master' of ssh://git.kolabsys.com/git/libkolabxml into c++/master



commit 60bd411198f088bcf1ae114d917ecefce6175f5f
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Dec 30 16:37:24 2011 +0100

    Add a little script that does everything for you </instagib>

diff --git a/c++/autogen.sh b/c++/autogen.sh
new file mode 100755
index 0000000..8ed1fd5
--- /dev/null
+++ b/c++/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Rebuilds the entire foo in one go. One shot, one kill.
+
+rm -rf build/
+mkdir -p build
+cd build
+cmake ..
+make


commit 2f6b95239ae715fe9026ae51bb0091396d2b2cd1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 30 16:34:53 2011 +0100

    copy test files to build directory

diff --git a/c++/lib/php/CMakeLists.txt b/c++/lib/php/CMakeLists.txt
index f5bbc6c..f778f6e 100644
--- a/c++/lib/php/CMakeLists.txt
+++ b/c++/lib/php/CMakeLists.txt
@@ -22,6 +22,8 @@ target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
 
+file(COPY test.php DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
 install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
 
 install( FILES
diff --git a/c++/lib/python/CMakeLists.txt b/c++/lib/python/CMakeLists.txt
index 0521acb..a0a99c6 100644
--- a/c++/lib/python/CMakeLists.txt
+++ b/c++/lib/python/CMakeLists.txt
@@ -24,6 +24,8 @@ target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
+file(COPY test.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
 install(TARGETS pythonbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
 
 install( FILES


commit a9b0928832678edc2db073e6062ff6716ac5086d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 30 16:26:51 2011 +0100

    moved php/python bindings to two separate directories

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index fe6fbcd..e715b36 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -58,69 +58,11 @@ endif()
 
 #-----------------------SWIG--------------------
 
-if (NOT SWIG_FOUND)
+if (SWIG_FOUND)
+    set(KOLAB_CONTAINER_HEADERS ../kolabcontainers.h ../kolabevent.h ../kolabtodo.h)
+    add_subdirectory(python)
+    add_subdirectory(php)
+else()
     message(WARNING "Could not build SWIG bindings, because SWIG is missing.")
-    return()
 endif()
 
-set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
-
-#Generate Python wrapper
-set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
-    COMMAND ${SWIG} -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
-    COMMENT "Generating python bindings"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS kolabformat.i  ${KOLAB_CONTAINER_HEADERS}
-    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})
-
-#Generate PHP wrapper
-set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) 
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
-    COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
-    COMMENT "Generating php bindings"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS kolabformat.i ${KOLAB_CONTAINER_HEADERS}
-    VERBATIM
-    )
-SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
-ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
-
-
-#Compile Python Bindings
-find_package(PythonLibs)
-include_directories(${PYTHON_INCLUDE_DIRS})
-
-# python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-
-add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
-SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
-SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
-
-install(TARGETS pythonbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
-
-install( FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.py
-  test.py
-  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
-
-#Compile PHP Bindings
-# Since there is no php library we can't compile with -Wl,--no-undefined
-find_package(PHP4)
-include_directories(${PHP4_INCLUDE_PATH})
-add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
-target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
-
-install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
-
-install( FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php
-  test.php
-  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
diff --git a/c++/lib/php/CMakeLists.txt b/c++/lib/php/CMakeLists.txt
new file mode 100644
index 0000000..f5bbc6c
--- /dev/null
+++ b/c++/lib/php/CMakeLists.txt
@@ -0,0 +1,30 @@
+#Generate PHP wrapper
+include_directories(../)
+
+set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
+    COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  ../kolabformat.i
+    COMMENT "Generating php bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS ../kolabformat.i ${KOLAB_CONTAINER_HEADERS}
+    VERBATIM
+    )
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
+
+
+#Compile PHP Bindings
+# Since there is no php library we can't compile with -Wl,--no-undefined
+find_package(PHP4)
+include_directories(${PHP4_INCLUDE_PATH})
+add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
+target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+
+install(TARGETS phpbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
+
+install( FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php
+  test.php
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/phpbindings)
\ No newline at end of file
diff --git a/c++/lib/php/test.php b/c++/lib/php/test.php
new file mode 100644
index 0000000..f3f514e
--- /dev/null
+++ b/c++/lib/php/test.php
@@ -0,0 +1,31 @@
+//run using "php -d enable_dl=On -d extension=./kolabformat.so  test.php"
+
+<?php
+include("kolabformat.php");
+
+$e = new Event();
+$d = new c_DateTime(2009,10,12);
+print $e->exceptionDates()->size();
+$e->addExceptionDate($d);
+print $e->exceptionDates()->size();
+
+$r = new RecurrenceRule();
+$r->setFrequency(RecurrenceRule::Minutely);
+
+$bysec = new vectori();
+$bysec->push(1);
+$bysec->push(3);
+
+$r->setBySecond($bysec);
+$e->setRecurrenceRule($r);
+
+$string = writeEvent($e);
+print $string;
+$e1 = readEvent($string, false);
+$string = writeEvent($e1);
+print $string;
+?>
+
+
+
+
diff --git a/c++/lib/python/CMakeLists.txt b/c++/lib/python/CMakeLists.txt
new file mode 100644
index 0000000..0521acb
--- /dev/null
+++ b/c++/lib/python/CMakeLists.txt
@@ -0,0 +1,32 @@
+#Generate Python wrapper
+include_directories(../)
+
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
+    COMMAND ${SWIG} -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} ../kolabformat.i
+    COMMENT "Generating python bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS ../kolabformat.i ${KOLAB_CONTAINER_HEADERS}
+    VERBATIM
+    )
+
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
+#Compile Python Bindings
+find_package(PythonLibs)
+include_directories(${PYTHON_INCLUDE_DIRS})
+
+# python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
+add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
+
+install(TARGETS pythonbindings LIBRARY DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
+
+install( FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.py
+  test.py
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
\ No newline at end of file
diff --git a/c++/lib/python/test.py b/c++/lib/python/test.py
new file mode 100644
index 0000000..5bc9799
--- /dev/null
+++ b/c++/lib/python/test.py
@@ -0,0 +1,16 @@
+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()
+
+string = kolabformat.writeEvent(e);
+print string;
+e1 = kolabformat.readEvent(string, False);
+string = kolabformat.writeEvent(e1);
+print string;
\ No newline at end of file
diff --git a/c++/lib/test.php b/c++/lib/test.php
deleted file mode 100644
index f3f514e..0000000
--- a/c++/lib/test.php
+++ /dev/null
@@ -1,31 +0,0 @@
-//run using "php -d enable_dl=On -d extension=./kolabformat.so  test.php"
-
-<?php
-include("kolabformat.php");
-
-$e = new Event();
-$d = new c_DateTime(2009,10,12);
-print $e->exceptionDates()->size();
-$e->addExceptionDate($d);
-print $e->exceptionDates()->size();
-
-$r = new RecurrenceRule();
-$r->setFrequency(RecurrenceRule::Minutely);
-
-$bysec = new vectori();
-$bysec->push(1);
-$bysec->push(3);
-
-$r->setBySecond($bysec);
-$e->setRecurrenceRule($r);
-
-$string = writeEvent($e);
-print $string;
-$e1 = readEvent($string, false);
-$string = writeEvent($e1);
-print $string;
-?>
-
-
-
-
diff --git a/c++/lib/test.py b/c++/lib/test.py
deleted file mode 100644
index 5bc9799..0000000
--- a/c++/lib/test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-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()
-
-string = kolabformat.writeEvent(e);
-print string;
-e1 = kolabformat.readEvent(string, False);
-string = kolabformat.writeEvent(e1);
-print string;
\ No newline at end of file


commit 866586944a3abfd5af4e3b5f48386fc58bd8722e
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Fri Dec 30 15:56:39 2011 +0100

    link against QtCore

diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 724087a..c3413f7 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -3,15 +3,15 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
-if (KDECORE_FOUND AND KCALCORE_FOUND)
+if (QT4_FOUND AND KDECORE_FOUND AND KCALCORE_FOUND)
     message("Buildings tests")
     QT4_AUTOMOC(bindingstest.cpp)
     add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml kolabkcal ${XERCES_C})
+    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml kolabkcal ${XERCES_C})
 
     QT4_AUTOMOC(kcalconversiontest.cpp)
     add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal ${XERCES_C})
+    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxmlkcal ${XERCES_C})
 else()
-    message(WARNING "Could not build tests because kdepimlibs is missing")
-endif()
\ No newline at end of file
+    message(WARNING "Could not build tests because kdepimlibs, kdelibs or qt is missing")
+endif()


commit 3d2fef6d9507054a3fa49912d1fcd458baa283ed
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 30 15:08:27 2011 +0100

    remove unused kcal directory

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 39c729a..2e4dd72 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -107,4 +107,3 @@ if (${QT_FOUND})
     add_subdirectory(tests)
 endif()
 
-add_subdirectory(kcal)
\ No newline at end of file


commit ddc1de13c5ad58dc28172f6d5819929c3ac24da3
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 14:23:29 2011 +0100

    add recurrencerule to example

diff --git a/c++/lib/test.php b/c++/lib/test.php
index 7a5e36b..f3f514e 100644
--- a/c++/lib/test.php
+++ b/c++/lib/test.php
@@ -4,11 +4,21 @@
 include("kolabformat.php");
 
 $e = new Event();
-$d = new c_DateTime(1,1,1);
+$d = new c_DateTime(2009,10,12);
 print $e->exceptionDates()->size();
-$e->addExceptionDate( $d);
+$e->addExceptionDate($d);
 print $e->exceptionDates()->size();
 
+$r = new RecurrenceRule();
+$r->setFrequency(RecurrenceRule::Minutely);
+
+$bysec = new vectori();
+$bysec->push(1);
+$bysec->push(3);
+
+$r->setBySecond($bysec);
+$e->setRecurrenceRule($r);
+
 $string = writeEvent($e);
 print $string;
 $e1 = readEvent($string, false);


commit 98d4dff56b78d066ff5690e506f38f6c9abacd2b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 14:23:03 2011 +0100

    Fix bysecond

diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 2d81baa..26e3f17 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -452,7 +452,7 @@ void setIncidenceProperties(I &inc, const T &prop)
 template <typename T, typename I>
 T fromList(const std::vector<int> &input) {
     T list;
-    BOOST_FOREACH(int i, list) {
+    BOOST_FOREACH(int i, input) {
         list.push_back(convertToInt<I>(i));
     }
     return list;
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 0690785..f8b5619 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -116,6 +116,10 @@ void setIncidence(T &ev)
     Kolab::RecurrenceRule rule;
     rule.setFrequency(Kolab::RecurrenceRule::Daily);
     rule.setCount(5);
+    std::vector<int> list;
+    list.push_back(1);
+    list.push_back(3);
+    rule.setBysecond(list);
     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));
@@ -151,6 +155,9 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(r1.weekStart(), r2.weekStart());
     QCOMPARE(r1.count(), r2.count());
     QCOMPARE(r1.end(), r2.end());
+    QCOMPARE(r1.bysecond().size(), r2.bysecond().size());
+    QCOMPARE(r1.bysecond().at(0), r2.bysecond().at(0));
+    QCOMPARE(r1.bysecond().at(1), r2.bysecond().at(1));
     
     QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
     QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));


commit 5e02e2b6f2826e291b37027a9fd5b0eedbc88d79
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 29 13:54:43 2011 +0100

    Added LGPL licence headers

diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 69bc685..25140bd 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "XMLParserWrapper.h"
 
 #include <memory>   // std::auto_ptr
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 40038f4..e6b746e 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef XMLPARSER_WRAPPER_H
 #define XMLPARSER_WRAPPER_H
 
diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index 9e9519d..39973fa 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef KOLAB_CONVERSIONS_H
 #define KOLAB_CONVERSIONS_H
 
diff --git a/c++/lib/global_definitions.h b/c++/lib/global_definitions.h
index 1e9da5f..5c2f170 100644
--- a/c++/lib/global_definitions.h
+++ b/c++/lib/global_definitions.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef GLOBAL_DEFINITIONS_H
 #define GLOBAL_DEFINITIONS_H
 
diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
index eed058b..5cfe7b2 100644
--- a/c++/lib/incidence_p.h
+++ b/c++/lib/incidence_p.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef INCIDENCE_P
 #define INCIDENCE_P
 
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 725dd11..cfabe13 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef KOLAB_KCALCONVERSIONS_H
 #define KOLAB_KCALCONVERSIONS_H
 
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index bb4e711..1922fa4 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabformat.h"
 
 #include <kcalcore/event.h>
diff --git a/c++/lib/kcalkolabformat.h b/c++/lib/kcalkolabformat.h
index 0d617c6..9afa7bd 100644
--- a/c++/lib/kcalkolabformat.h
+++ b/c++/lib/kcalkolabformat.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #ifndef KCALKOLABFORMAT_H
 #define KCALKOLABFORMAT_H
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 03809b5..b3a6dbf 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabcontainers.h"
 #include "incidence_p.h"
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 402e126..6b49a5c 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef KOLAB_CONTAINERS_H
 #define KOLAB_CONTAINERS_H
 #include <string>
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
index 8a6df74..821b819 100644
--- a/c++/lib/kolabevent.cpp
+++ b/c++/lib/kolabevent.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabevent.h"
 #include "incidence_p.h"
 
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
index 9634572..866bf27 100644
--- a/c++/lib/kolabevent.h
+++ b/c++/lib/kolabevent.h
@@ -1,4 +1,19 @@
-
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #ifndef KOLAB_EVENT_H
 #define KOLAB_EVENT_H
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 7f91eb9..ed61bec 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabformat.h"
 
 #include <iostream>
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 2cd67e4..d0a8b62 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #ifndef KOLABFORMAT_H
 #define KOLABFORMAT_H
diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index d40d819..a89730c 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabkcalconversion.h"
 
 #include <kcalcore/recurrence.h>
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index e7c1d88..68f43dd 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef KOLABKCALCONVERSION_H
 #define KOLABKCALCONVERSION_H
 
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
index d3b7a5e..36894b0 100644
--- a/c++/lib/kolabtodo.cpp
+++ b/c++/lib/kolabtodo.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "kolabtodo.h"
 #include "incidence_p.h"
 
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
index 60c677a..a023f20 100644
--- a/c++/lib/kolabtodo.h
+++ b/c++/lib/kolabtodo.h
@@ -1,4 +1,19 @@
-
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #ifndef KOLAB_TODO_H
 #define KOLAB_TODO_H
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index 44246b1..e428c5e 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include "utils.h"
 #include <string>
 #include <boost/uuid/uuid.hpp>
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
index 5ef5f2e..549b2da 100644
--- a/c++/lib/utils.h
+++ b/c++/lib/utils.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef UTILS_H
 #define UTILS_H
 
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 3f565c2..2d81baa 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef XCALCONVERSIONS_H
 #define XCALCONVERSIONS_H
 
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index 7d5038f..c672f93 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2011  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef KOLABXCARDCONVERSION_H
 #define KOLABXCARDCONVERSION_H
 


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

    Drafted some containers

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


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

    remaining by*** rules (except byday)

diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index fad6b78..3f565c2 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -472,8 +472,34 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
         recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
     }
     
-    //TODO remainting by rules
+    if (!r.byminute().empty()) {
+        recur.byminute(fromList<RecurType::byminute_sequence, xml_schema::non_negative_integer>(r.byminute()));
+    }
+    
+    if (!r.byhour().empty()) {
+        recur.byhour(fromList<RecurType::byhour_sequence, xml_schema::non_negative_integer>(r.byhour()));
+    }
+    
+    if (!r.byday().empty()) {
+        //TODO
+    }
+    
+    if (!r.bymonthday().empty()) {
+        recur.bymonthday(fromList<RecurType::bymonthday_sequence, xml_schema::integer>(r.bymonthday()));
+    }
+    
+    if (!r.byyearday().empty()) {
+        recur.byyearday(fromList<RecurType::byyearday_sequence, xml_schema::integer>(r.byyearday()));
+    }
     
+    if (!r.byweekno().empty()) {
+        recur.byweekno(fromList<RecurType::byweekno_sequence, xml_schema::integer>(r.byweekno()));
+    }
+    
+    if (!r.bymonth().empty()) {
+        recur.bymonth(fromList<RecurType::bymonth_sequence, xml_schema::integer>(r.bymonth()));
+    }
+
     return rruleProp;
 }
 


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

    conditionally compile swig bindings

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 873ebcc..39c729a 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -21,6 +21,12 @@ else (XERCES_C)
     "xerces NOT found!")
 endif(XERCES_C)
 
+find_program(SWIG swig /usr/bin/)
+if(SWIG)
+    set(SWIG_FOUND ON)
+    message("SWIG found")
+endif(SWIG)
+
 #We search for the needed libraries manually because FindKDE.cmake sets a miriad of linker options which we don't want.
 find_library(KDECORE NAMES kdecore)
 if(KDECORE)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index d591a30..fe6fbcd 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -58,12 +58,17 @@ endif()
 
 #-----------------------SWIG--------------------
 
+if (NOT SWIG_FOUND)
+    message(WARNING "Could not build SWIG bindings, because SWIG is missing.")
+    return()
+endif()
+
 set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
 
 #Generate Python wrapper
 set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
-    COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
+    COMMAND ${SWIG} -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
     COMMENT "Generating python bindings"
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     DEPENDS kolabformat.i  ${KOLAB_CONTAINER_HEADERS}
@@ -76,7 +81,7 @@ ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURC
 #Generate PHP wrapper
 set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
-    COMMAND swig -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
+    COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
     COMMENT "Generating php bindings"
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     DEPENDS kolabformat.i ${KOLAB_CONTAINER_HEADERS}


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

    Updated development info.

diff --git a/c++/README b/c++/README
index 2faa412..ba1f383 100644
--- a/c++/README
+++ b/c++/README
@@ -1,6 +1,18 @@
-Build with
+Build with:
 
-mkdir build
-cd build
-cmake ..
-make
+$mkdir build
+$cd build
+$cmake ..
+$make
+
+
+Minimum requirements are:
+-cmake 2.8
+-boost >1.47
+-xerces-c >3.0
+-cxx >3.0 (http://www.codesynthesis.com/products/xsd/)
+
+For further features:
+-SWIG >2.0
+-QT >4.7
+-KCalCore/KDECore >4.7
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index 4edd1c1..7002b31 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -17,7 +17,7 @@ Library to provide converters to KCalCore containers as well as advanced functio
 
 === kolabxmlkcal (deprecated) ===
 
-First approach does a direct mapping from xml to KCalCore containers. 
+First approach which does a direct mapping from xml to KCalCore containers. 
 It tourned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
 Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend.
 
@@ -50,6 +50,18 @@ They we're also designed to be easily copieable and make therefore minimal use o
 The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
 
 The validity of the containers can be checked using the isValid() function.
+
+=== Why KCalCore containers were not directly used ===
+
+KCalCore provides containers for all ical based functionality (events/todos/journals).
+
+They were not directly used because:
+- dependencies: depends on kdelibs and qt (event qt gui). Some serious work would be needed to be able to ship those containers with a minimum set of dependencies.
+- SWIG: It seems difficult to properly wrap those containers using SWIG (inheritance heavily used, Qt containers (for which we have no bindings), not easily copiable (special copy memberfucntion is needed due to internal use of pointers))
+- Consistency: because we anyways have containers out of the scope of KCalCore, we can provide this way a consistent interface, which represents exactly the Kolab defined functionality (while KCalCore would be a close, but not a perfect match).
+
+Overall using our own containers seems like the safer and more flexible approach. This way it's also possible to provide a reading/writing library with a minimum set of dependencies.
+
 == SWIG language bindings ==
 
 Bindings for PHP and Python are provided through SWIG.


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

    organizer completed

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


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

    This and future

diff --git a/c++/lib/genericxcalconverions.h b/c++/lib/genericxcalconverions.h
index c747c6d..9e9519d 100644
--- a/c++/lib/genericxcalconverions.h
+++ b/c++/lib/genericxcalconverions.h
@@ -20,6 +20,8 @@ const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0";
 
 const char* const TZ_PREFIX = "/kolab.org/";
 
+const char* const THISANDFUTURE = "THISANDFUTURE";
+
 const char* const NEEDSACTION = "NEEDS-ACTION";
 const char* const COMPLETED = "OPAQUE";
 const char* const INPROCESS = "IN-PROCESS";
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index db7bd28..5dfa9c8 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -360,8 +360,15 @@ void setIncidenceProperties(I &inc, const T &prop)
     }
     
     if (prop.recurrence_id()) {
-        //TODO THISANDFUTURE range
-        bool thisandfuture = true;
+        bool thisandfuture = false;
+        if (prop.recurrence_id()->parameters()) {
+            const icalendar_2_0::RecurrenceIdPropType::parameters_type &parameters = *prop.recurrence_id()->parameters();
+            for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                if (dynamic_cast<const icalendar_2_0::RangeParamType*> (&*it)) {
+                    thisandfuture = true;
+                }
+            }
+        }
         inc.setRecurrenceID(*toDate<KolabTypes>(*prop.recurrence_id()), thisandfuture);
     }
     
@@ -517,8 +524,17 @@ void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to t
     }
     
     if (inc.recurrenceID().isValid()) {
-        //TODO THISANDFUTURE
-        prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
+        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID());
+        if (inc.thisAndFuture()) {
+            if (!recurrenceId->parameters()) {
+                recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
+            }
+            typename properties::recurrence_id_type::parameters_type &parameters = *recurrenceId->parameters(); //There is maybe already a timezone set
+            icalendar_2_0::RangeParamType range(THISANDFUTURE);
+            parameters.baseParameter().push_back(range);
+        }
+        
+        prop.recurrence_id(recurrenceId);
     }
     
     if (!inc.summary().empty()) {
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 0c2f31d..de9b875 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -119,7 +119,7 @@ void setIncidence(T &ev)
     ev.setRecurrenceRule(rule);
     ev.addRecurrenceDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
     ev.addExceptionDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
-    ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), false);
+    ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), true);
     ev.setSummary("summary");
     ev.setDescription("description");
     ev.setPriority(3);
@@ -157,6 +157,7 @@ void checkIncidence(const T &ev, const T &re)
     QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
     QCOMPARE(ev.exceptionDates().at(0), re.exceptionDates().at(0));
     QCOMPARE(ev.recurrenceID(), re.recurrenceID());
+    QCOMPARE(ev.thisAndFuture(), re.thisAndFuture());
     QCOMPARE(ev.summary(), re.summary());
     QCOMPARE(ev.description(), re.description());
     QCOMPARE(ev.priority(), re.priority());


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

    updated background info

diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
index fe61d7d..4edd1c1 100644
--- a/c++/lib/DEVELOPMENT
+++ b/c++/lib/DEVELOPMENT
@@ -1,4 +1,36 @@
+== Libraries ==
 
+=== libkolabxml ===
+Dependencies:
+* boost
+* xerces
+
+The core library providing the xml-serialization functions and containers for all types.
+
+=== libkolabkcal ===
+Dependencies:
+* libkolabxml
+* kcalcore
+* kdecore
+
+Library to provide converters to KCalCore containers as well as advanced functionality from KCalCore (such as expansion of recurrences) through SWIG bindings.
+
+=== kolabxmlkcal (deprecated) ===
+
+First approach does a direct mapping from xml to KCalCore containers. 
+It tourned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers.
+Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend.
+
+== Code architecture ==
+
+Care was taken to implement each conversion/mapping only once. The code makes heavy use of templates to achieve this.
+Due to the different formats the conversion functions were split up among formats (not much to share between those).
+
+xCal: genericxcalconversions.h, xcalconversions.h (genericxcalconversions are implementations which work for both Kolab Containers and KCalCore containers)
+xCard: kolabxcardconversions.h
+kolab: kolabconversions.h (TODO)
+
+All conversions are typesafe as far as possible (i.e. a conversion from uint to int is always done through a numeric cast), to make sure there are no hard-to-track-down edge cases (such as an overflow).
 
 == Kolab Containers ==
 
@@ -11,3 +43,35 @@ Datamembers are not directly exposed to provide binary compatibilty through the
 Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value).
 
 Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
+
+The containers do not use inheritance to ensure maximum compatibilty with SWIG (although SWIG provides inheritance for some languages).
+They we're also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur.
+
+The containers are meant to not contain any logic, all logic should be implemented in the serialization functions.
+
+The validity of the containers can be checked using the isValid() function.
+== SWIG language bindings ==
+
+Bindings for PHP and Python are provided through SWIG.
+
+"make install" produces two directories with the necessary files in build/lib/pythonbindings and build/lib/phpbindings.
+The test script should show the usage of the bindings.
+
+== Performance ==
+
+The biggest performance hog is the initialization of the parser. First, when loading the schema from disk upon initialization, parsing a single file took ~16ms on my machine (just for comparison).
+After compiling the schema to a binary representation, it still took ~7ms. By reusing the parser it went down to ~0.35ms.
+
+Writing the files is not validating and therefore always fast (doesn't need a special parser or alike). Once the parser is initialized, reading is roughly as fast as writing.
+
+Currently the parser is kept in a singleton (XMLParserWrapper).
+Alternatively one could control the lifetime from the bindings through an initialization object which keeps the parser alive through a shared pointer. This way the parser could be initialized on demand and the memory used by the parser could be freed between runs. 
+
+For further performance improvements read this: http://xerces.apache.org/xerces2-j/faq-performance.html
+
+== Error Handling ==
+
+All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that.
+If an error occurs a message is printed to the standard error output and a default constructed value is returned.
+
+Writing doesn't provide any validation (as it is hardly useful). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible.
\ No newline at end of file


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

    Renamed files to be a bit more consistent

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


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

    fully read/write cycle in php/python tests

diff --git a/c++/lib/test.php b/c++/lib/test.php
index 27ca971..7a5e36b 100644
--- a/c++/lib/test.php
+++ b/c++/lib/test.php
@@ -12,7 +12,8 @@ print $e->exceptionDates()->size();
 $string = writeEvent($e);
 print $string;
 $e1 = readEvent($string, false);
-
+$string = writeEvent($e1);
+print $string;
 ?>
 
 
diff --git a/c++/lib/test.py b/c++/lib/test.py
index 821bc94..5bc9799 100644
--- a/c++/lib/test.py
+++ b/c++/lib/test.py
@@ -8,3 +8,9 @@ ex.size()
 e.exceptionDates().size()
 e.setExceptionDates(ex)
 e.exceptionDates().size()
+
+string = kolabformat.writeEvent(e);
+print string;
+e1 = kolabformat.readEvent(string, False);
+string = kolabformat.writeEvent(e1);
+print string;
\ No newline at end of file


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

    disable verbose makefiles

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


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

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

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index bdbb476..f0a0776 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -1,20 +1,45 @@
 project(kolabxmlbindings)
 
 cmake_minimum_required(VERSION 2.8)
+cmake_policy(SET CMP0017 NEW)
 
 find_package(Boost REQUIRED)
+find_package(Qt4)
 find_program( XSDCXX xsdcxx /usr/bin/)
-
 if(XSDCXX)
     message("xsd code generator found")
 else (XSDCXX)
-    message("xsd code generator NOT found. Aborted.")
-    return()
+    message(FATAL_ERROR
+    "xsd code generator NOT found!")
 endif(XSDCXX)
 
-set(CMAKE_BUILD_TYPE Debug)
+find_library(XERCES_C NAMES xerces-c xerces-c_2)
+if(XERCES_C)
+    message("xerces found")
+else (XERCES_C)
+    message(FATAL_ERROR
+    "xerces NOT found!")
+endif(XERCES_C)
+
+#We search for the needed libraries manually because FindKDE.cmake sets a miriad of linker options which we don't want.
+find_library(KDECORE NAMES kdecore)
+if(KDECORE)
+    set(KDECORE_FOUND ON)
+    message("KDElibs found")
+endif(KDECORE)
+
+find_library(KCALCORE NAMES kcalcore)
+if(KCALCORE)
+    set(KCALCORE_FOUND ON)
+    message("KCalCore found")
+endif(KCALCORE)
 
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) 
+
+set( CMAKE_VERBOSE_MAKEFILE on )
+
+set(CMAKE_BUILD_TYPE Debug)
+
 set(CMAKE_BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
 file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
 
@@ -51,7 +76,7 @@ add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
 
 # Compile Schemas
 add_executable(xsdbin compiled/xsdbin.cxx)
-target_link_libraries(xsdbin xerces-c)
+target_link_libraries(xsdbin ${XERCES_C})
 
 add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
     COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR}   ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
@@ -72,5 +97,8 @@ include_directories( compiled )
 include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
 add_subdirectory(lib)
-add_subdirectory(tests)
+if (${QT_FOUND})
+    add_subdirectory(tests)
+endif()
 
+add_subdirectory(kcal)
\ No newline at end of file
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index e10ed53..d591a30 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -1,17 +1,19 @@
 
-
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #always generate shared libraries with -fPIC
-
 include_directories( ./ )
 include_directories( ../ )
 include_directories( ../build/ )
+include(${Boost_INCLUDE_DIRS})
 
 SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC " ) #always generate shared libraries with -fPIC
+
 #Library with serialization/deserialization code and kolab-containers
 add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp utils.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxml xerces-c)
+target_link_libraries(kolabxml ${XERCES_C})
 
+#For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
+set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wl,--no-undefined -Werror ")
 set_target_properties(kolabxml PROPERTIES VERSION 3.0.0 SOVERSION 0)
 install(TARGETS kolabxml LIBRARY DESTINATION lib)
 
@@ -26,41 +28,39 @@ install( FILES
 
 # use, i.e. don't skip the full RPATH for the build tree
 SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
-
-# when building, don't use the install RPATH already
-# (but later on when installing)
+# when building, don't use the install RPATH already(but later on when installing)
 SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
-
 SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
-
 # add the automatically determined parts of the RPATH
 # which point to directories outside the build tree to the install RPATH
 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-
 # the RPATH to be used when installing, but only if it's not a system directory
 LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
 IF("${isSystemDir}" STREQUAL "-1")
    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
 ENDIF("${isSystemDir}" STREQUAL "-1")
 
+#----- KCalCore libs
+if(KDECORE_FOUND AND KCALCORE_FOUND)
+    message("Building KCalCore dependend libraries.")
 
-#Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
-add_library(kolabkcal SHARED kolabkcalconversion.cpp)
-target_link_libraries(kolabkcal kolabxml)
-
-#Library with serialization/deserialization code for KCalCore containers (deprecated)
-add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-target_link_libraries(kolabxmlkcal xerces-c)
-
-
+    #Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
+    add_library(kolabkcal SHARED kolabkcalconversion.cpp)
+    target_link_libraries(kolabkcal kolabxml ${KCALCORE} ${KDECORE})
 
+    #Library with serialization/deserialization code for KCalCore containers (deprecated)
+    add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+    target_link_libraries(kolabxmlkcal xerces-c ${KCALCORE} ${KDECORE})
+else()
+    message(WARNING "Could not build KCalCore/KDElibs dependend libraries, because kdepimlibs/kdelibs is missing.")
+endif()
 
 
 #-----------------------SWIG--------------------
 
-
 set(KOLAB_CONTAINER_HEADERS kolabcontainers.h kolabevent.h kolabtodo.h)
 
+#Generate Python wrapper
 set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
     COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
@@ -73,7 +73,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
 SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
 ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
 
-
+#Generate PHP wrapper
 set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) 
 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
     COMMAND swig -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}  kolabformat.i
@@ -86,12 +86,14 @@ SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1
 ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
 
 
-#PYTHON
+#Compile Python Bindings
 find_package(PythonLibs)
 include_directories(${PYTHON_INCLUDE_DIRS})
+
+# python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
 add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-target_link_libraries(pythonbindings kolabxml xerces-c)
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
+target_link_libraries(pythonbindings kolabxml ${PYTHON_LIBRARY})
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
 SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
 
@@ -102,15 +104,12 @@ install( FILES
   test.py
   DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pythonbindings)
 
-
-#PHP
-# set( PHP_INCLUDES "`php-config --includes`")
-set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${PHP_INCLUDES} )
+#Compile PHP Bindings
+# Since there is no php library we can't compile with -Wl,--no-undefined
 find_package(PHP4)
 include_directories(${PHP4_INCLUDE_PATH})
 add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
-target_link_libraries(phpbindings kolabxml xerces-c)
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
+target_link_libraries(phpbindings kolabxml ${PHP_LIBRARIES})
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
 SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
 
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index 8992c13..bb4e711 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -16,18 +16,20 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
 
 KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
 {
-    
+    return KCalCore::Todo::Ptr();
 }
 
 
 std::string writeEvent(KCalCore::Event::Ptr event)
 {
 //      return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+    return std::string();
 }
 
 std::string writeTodo(KCalCore::Todo::Ptr todo)
 {
 //     return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
+    return std::string();
 }
 
 }
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 7d2f0af..1ec2752 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -1,5 +1,5 @@
-#ifndef KOLABKCALTOOLS_H
-#define KOLABKCALTOOLS_H
+#ifndef KOLABKCALCONVERSION_H
+#define KOLABKCALCONVERSION_H
 
 #include <kcalcore/recurrence.h>
 #include "kolabcontainers.h"
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index d2deb57..724087a 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,13 +1,17 @@
 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
-FIND_PACKAGE(Qt4 REQUIRED)
 include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) 
+if (KDECORE_FOUND AND KCALCORE_FOUND)
+    message("Buildings tests")
+    QT4_AUTOMOC(bindingstest.cpp)
+    add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
+    target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml kolabkcal ${XERCES_C})
 
-QT4_AUTOMOC(bindingstest.cpp)
-add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
-target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabkcal kolabxml xerces-c kcalcore)
-
-QT4_AUTOMOC(kcalconversiontest.cpp)
-add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
-target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
+    QT4_AUTOMOC(kcalconversiontest.cpp)
+    add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+    target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal ${XERCES_C})
+else()
+    message(WARNING "Could not build tests because kdepimlibs is missing")
+endif()
\ No newline at end of file


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

    make compile with Wall

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


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

    xCard skeleton prepared. A couple of smaller cleanups.

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


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

    don't compare last modified dates

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


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

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

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


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

    fixed test

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


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

    Buildsystem refactoring. First working PHP example.

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


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

    moved event to own file

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 0123348..03809b5 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -361,291 +361,7 @@ bool RecurrenceRule::isValid() const
 
 
 
-struct Event::Private: public PrivateIncidence
-{
-    Private()
-    : PrivateIncidence(), 
-    isTransparent(false){}
-
-    DateTime end;
-    bool isTransparent;
-    Duration duration;
-};
-
-Event::Event()
-: d(new Event::Private())
-{
-    
-}
-
-Event::Event(const Event &other)
-: d(new Event::Private())
-{
-    *d = *other.d;
-}
-
-Event::~Event()
-{
-    
-}
-
-void Event::setUid(const std::string &uid)
-{
-    d->uid = uid;
-}
-
-std::string Event::uid() const
-{
-    return d->uid;
-}
-
-void Event::setCreated(const Kolab::DateTime &created)
-{
-    d->created = created;
-}
-
-DateTime Event::created() const
-{
-    return d->created;
-}
-
-void Event::setLastModified(const Kolab::DateTime &lastMod)
-{
-    d->lastModified = lastMod;
-}
-
-DateTime Event::lastModified() const
-{
-    return d->lastModified;
-}
-
-void Event::setSequence(int sequence)
-{
-    d->sequence = sequence;
-}
-
-int Event::sequence() const
-{
-    return d->sequence;
-}
-
-void Event::setClassification(Classification class_)
-{
-    d->classification = class_;
-}
-
-Classification Event::classification() const
-{
-    return d->classification;
-}
-
-void Event::setCategories(const std::vector< std::string > &categories)
-{
-    d->categories = categories;
-}
-
-void Event::addCategory(const std::string &cat)
-{
-    d->categories.push_back(cat);
-}
-
-std::vector< std::string > Event::categories() const
-{
-    return d->categories;
-}
-
-void Event::setStart(const Kolab::DateTime &start)
-{
-    d->start = start;
-}
-
-DateTime Event::start() const
-{
-    return d->start;
-}
-
-void Event::setEnd(const Kolab::DateTime &end)
-{
-    d->end = end;
-}
-
-DateTime Event::end() const
-{
-    return d->end;
-}
-
-void Event::setDuration(const Duration &duration)
-{
-    d->duration = duration;
-}
-
-Duration Event::duration() const
-{
-    return d->duration;
-}
-
-
-void Event::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
-{
-    d->recurrenceID = rID;
-    d->thisAndFuture = thisandfuture;
-}
-
-DateTime Event::recurrenceID() const
-{
-    return d->recurrenceID;
-}
-
-bool Event::thisAndFuture() const
-{
-    return d->thisAndFuture;
-}
 
-void Event::setSummary(const std::string &summary)
-{
-    d->summary = summary;
-}
-
-std::string Event::summary() const
-{
-    return d->summary;
-}
-
-void Event::setDescription(const std::string &description)
-{
-    d->description = description;
-}
-
-std::string Event::description() const
-{
-    return d->description;
-}
-
-void Event::setPriority(int priority)
-{
-    d->priority = priority;
-}
-
-int Event::priority() const
-{
-    return d->priority;
-}
-
-void Event::setStatus(Status status)
-{
-    d->status = status;
-}
-
-Status Event::status() const
-{
-    return d->status;
-}
-
-void Event::setLocation(const std::string &location)
-{
-    d->location = location;
-}
-
-std::string Event::location() const
-{
-    return d->location;
-}
-
-void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
-{
-    d->rrule = rrule;
-}
-
-RecurrenceRule Event::recurrenceRule() const
-{
-    return d->rrule;
-}
-
-void Event::setRecurrenceDates(const std::vector< DateTime > &dates)
-{
-    d->recurrenceDates = dates;
-}
-
-void Event::addRecurrenceDate(const Kolab::DateTime &dt)
-{
-    d->recurrenceDates.push_back(dt);
-}
-
-std::vector< DateTime > Event::recurrenceDates() const
-{
-    return d->recurrenceDates;
-}
-
-void Event::setExceptionDates(const std::vector< DateTime > &dates)
-{
-    d->exceptionDates = dates;
-}
-
-void Event::addExceptionDate(const Kolab::DateTime &dt)
-{
-    d->exceptionDates.push_back(dt);
-}
-
-std::vector< DateTime > Event::exceptionDates() const
-{
-    return d->exceptionDates;
-}
-
-void Event::setTransparency(bool isTransparent)
-{
-    d->isTransparent = isTransparent;
-}
-
-bool Event::transparency() const
-{
-    return d->isTransparent;
-}
-
-void Event::setOrganizer(const std::string& email, const std::string& name)
-{
-    d->organizerEmail = email;
-    d->organizerName = name;
-}
-
-std::string Event::organizerEmail() const
-{
-    return d->organizerEmail;
-}
-
-std::string Event::organizerName() const
-{
-    return d->organizerName;
-}
-
-void Event::setAttendees(const std::vector< Attendee > &attendees)
-{
-    d->attendees = attendees;
-}
-
-std::vector< Attendee > Event::attendees() const
-{
-    return d->attendees;
-}
-
-void Event::setAttachments(const std::vector< Attachment > &attach)
-{
-    d->attachments = attach;
-}
-
-std::vector< Attachment > Event::attachments() const
-{
-    return d->attachments;
-}
-
-void Event::setCustomProperties(const std::vector< CustomProperty > &prop)
-{
-    d->customProperties = prop;
-}
-
-std::vector< CustomProperty > Event::customProperties() const
-{
-    return d->customProperties;
-}
 
 
 
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index e291287..c674311 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -159,90 +159,6 @@ class CustomProperty {
     //TODO
 };
     
-class Event {
-public:
-    Event();
-    ~Event();
-    Event(const Event &);
-    void operator=(const Event &);
-    
-    void setUid(const std::string &);
-    std::string uid() const;
-    
-    void setCreated(const DateTime &);
-    DateTime created() const;
-    
-    void setLastModified(const DateTime &);
-    DateTime lastModified() const;
-    
-    void setSequence(int);
-    int sequence() const;
-    
-    void setClassification(Classification);
-    Classification classification() const;
-
-    void setCategories(const std::vector<std::string> &);
-    void addCategory(const std::string &);
-    std::vector<std::string> categories() const;
-    
-    void setStart(const DateTime &);
-    DateTime start() const;
-    
-    void setEnd(const DateTime &);
-    DateTime end() const;
-    
-    void setDuration(const Duration &);
-    Duration duration() const;
-    
-    void setTransparency(bool isTransparent);
-    bool transparency() const;
-    
-    void setRecurrenceRule(const RecurrenceRule &);
-    RecurrenceRule recurrenceRule() const;
-    
-    void setRecurrenceDates(const std::vector<DateTime> &);
-    void addRecurrenceDate(const DateTime &);
-    std::vector<DateTime> recurrenceDates() const;
-    
-    void setExceptionDates(const std::vector<DateTime> &);
-    void addExceptionDate(const DateTime &);
-    std::vector<DateTime> exceptionDates() const;
-    
-    void setRecurrenceID(const DateTime &, bool thisandfuture);
-    DateTime recurrenceID() const;
-    bool thisAndFuture() const;
-    
-    void setSummary(const std::string &);
-    std::string summary() const;
-    
-    void setDescription(const std::string &);
-    std::string description() const;
-    
-    void setPriority(int);
-    int priority() const;
-    
-    void setStatus(Status);
-    Status status() const;
-    
-    void setLocation(const std::string &);
-    std::string location() const;
-    
-    void setOrganizer(const std::string &email, const std::string &name);
-    std::string organizerEmail() const;
-    std::string organizerName() const;
-    
-    void setAttendees(const std::vector<Attendee> &);
-    std::vector<Attendee> attendees() const;
-    
-    void setAttachments(const std::vector<Attachment> &);
-    std::vector<Attachment> attachments() const;
-    
-    void setCustomProperties(const std::vector<CustomProperty> &);
-    std::vector<CustomProperty> customProperties() const;
-private:
-    struct Private;
-    boost::scoped_ptr<Private> d;
-};
 
 
 class Contact {
diff --git a/c++/lib/kolabevent.cpp b/c++/lib/kolabevent.cpp
new file mode 100644
index 0000000..3dbc2a9
--- /dev/null
+++ b/c++/lib/kolabevent.cpp
@@ -0,0 +1,292 @@
+#include "kolabevent.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+struct Event::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence(), 
+    isTransparent(false){}
+
+    DateTime end;
+    bool isTransparent;
+    Duration duration;
+};
+
+Event::Event()
+: d(new Event::Private())
+{
+    
+}
+
+Event::Event(const Event &other)
+: d(new Event::Private())
+{
+    *d = *other.d;
+}
+
+Event::~Event()
+{
+    
+}
+
+void Event::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Event::uid() const
+{
+    return d->uid;
+}
+
+void Event::setCreated(const Kolab::DateTime &created)
+{
+    d->created = created;
+}
+
+DateTime Event::created() const
+{
+    return d->created;
+}
+
+void Event::setLastModified(const Kolab::DateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+DateTime Event::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Event::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Event::sequence() const
+{
+    return d->sequence;
+}
+
+void Event::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Event::classification() const
+{
+    return d->classification;
+}
+
+void Event::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Event::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Event::categories() const
+{
+    return d->categories;
+}
+
+void Event::setStart(const Kolab::DateTime &start)
+{
+    d->start = start;
+}
+
+DateTime Event::start() const
+{
+    return d->start;
+}
+
+void Event::setEnd(const Kolab::DateTime &end)
+{
+    d->end = end;
+}
+
+DateTime Event::end() const
+{
+    return d->end;
+}
+
+void Event::setDuration(const Duration &duration)
+{
+    d->duration = duration;
+}
+
+Duration Event::duration() const
+{
+    return d->duration;
+}
+
+
+void Event::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
+{
+    d->recurrenceID = rID;
+    d->thisAndFuture = thisandfuture;
+}
+
+DateTime Event::recurrenceID() const
+{
+    return d->recurrenceID;
+}
+
+bool Event::thisAndFuture() const
+{
+    return d->thisAndFuture;
+}
+
+void Event::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Event::summary() const
+{
+    return d->summary;
+}
+
+void Event::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Event::description() const
+{
+    return d->description;
+}
+
+void Event::setPriority(int priority)
+{
+    d->priority = priority;
+}
+
+int Event::priority() const
+{
+    return d->priority;
+}
+
+void Event::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Event::status() const
+{
+    return d->status;
+}
+
+void Event::setLocation(const std::string &location)
+{
+    d->location = location;
+}
+
+std::string Event::location() const
+{
+    return d->location;
+}
+
+void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+    d->rrule = rrule;
+}
+
+RecurrenceRule Event::recurrenceRule() const
+{
+    return d->rrule;
+}
+
+void Event::setRecurrenceDates(const std::vector< DateTime > &dates)
+{
+    d->recurrenceDates = dates;
+}
+
+void Event::addRecurrenceDate(const Kolab::DateTime &dt)
+{
+    d->recurrenceDates.push_back(dt);
+}
+
+std::vector< DateTime > Event::recurrenceDates() const
+{
+    return d->recurrenceDates;
+}
+
+void Event::setExceptionDates(const std::vector< DateTime > &dates)
+{
+    d->exceptionDates = dates;
+}
+
+void Event::addExceptionDate(const Kolab::DateTime &dt)
+{
+    d->exceptionDates.push_back(dt);
+}
+
+std::vector< DateTime > Event::exceptionDates() const
+{
+    return d->exceptionDates;
+}
+
+void Event::setTransparency(bool isTransparent)
+{
+    d->isTransparent = isTransparent;
+}
+
+bool Event::transparency() const
+{
+    return d->isTransparent;
+}
+
+void Event::setOrganizer(const std::string& email, const std::string& name)
+{
+    d->organizerEmail = email;
+    d->organizerName = name;
+}
+
+std::string Event::organizerEmail() const
+{
+    return d->organizerEmail;
+}
+
+std::string Event::organizerName() const
+{
+    return d->organizerName;
+}
+
+void Event::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Event::attendees() const
+{
+    return d->attendees;
+}
+
+void Event::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Event::attachments() const
+{
+    return d->attachments;
+}
+
+void Event::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Event::customProperties() const
+{
+    return d->customProperties;
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/kolabevent.h b/c++/lib/kolabevent.h
new file mode 100644
index 0000000..b7949b5
--- /dev/null
+++ b/c++/lib/kolabevent.h
@@ -0,0 +1,100 @@
+
+
+#ifndef KOLAB_EVENT_H
+#define KOLAB_EVENT_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+
+class Event {
+public:
+    Event();
+    ~Event();
+    Event(const Event &);
+    void operator=(const Event &);
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const DateTime &);
+    DateTime created() const;
+    
+    void setLastModified(const DateTime &);
+    DateTime lastModified() const;
+    
+    void setSequence(int);
+    int sequence() const;
+    
+    void setClassification(Classification);
+    Classification classification() const;
+
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setStart(const DateTime &);
+    DateTime start() const;
+    
+    void setEnd(const DateTime &);
+    DateTime end() const;
+    
+    void setDuration(const Duration &);
+    Duration duration() const;
+    
+    void setTransparency(bool isTransparent);
+    bool transparency() const;
+    
+    void setRecurrenceRule(const RecurrenceRule &);
+    RecurrenceRule recurrenceRule() const;
+    
+    void setRecurrenceDates(const std::vector<DateTime> &);
+    void addRecurrenceDate(const DateTime &);
+    std::vector<DateTime> recurrenceDates() const;
+    
+    void setExceptionDates(const std::vector<DateTime> &);
+    void addExceptionDate(const DateTime &);
+    std::vector<DateTime> exceptionDates() const;
+    
+    void setRecurrenceID(const DateTime &, bool thisandfuture);
+    DateTime recurrenceID() const;
+    bool thisAndFuture() const;
+    
+    void setSummary(const std::string &);
+    std::string summary() const;
+    
+    void setDescription(const std::string &);
+    std::string description() const;
+    
+    void setPriority(int);
+    int priority() const;
+    
+    void setStatus(Status);
+    Status status() const;
+    
+    void setLocation(const std::string &);
+    std::string location() const;
+    
+    void setOrganizer(const std::string &email, const std::string &name);
+    std::string organizerEmail() const;
+    std::string organizerName() const;
+    
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
+    
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 36de14f..7d2f0af 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -3,6 +3,7 @@
 
 #include <kcalcore/recurrence.h>
 #include "kolabcontainers.h"
+#include "kolabevent.h"
 #include <kcalcore/event.h>
 
 namespace Kolab {


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

    return by value to make it easily wrappable by SWIG

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


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

    moved kcal conversion code to separate library.
    
    +some cleanup

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


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

    cleanup

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


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

    xcard objects

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


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

    rename serialization functinos, centrally defined strings

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


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

    added journal schema

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


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

    always use typedefs (numbered names may change)

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


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 &); */


commit 0f7a59df7e5b0e3611cdbb67b8c501a991b8c114
Merge: 35b3fbc 55d7e02
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Nov 14 20:26:45 2011 +0100

    Merge branch 'master' into c++/master



commit 35b3fbcb7383f432e01ee9e51f194b422018ed1a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Nov 14 20:22:33 2011 +0100

    first xCal based reading/writing test

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 77458cf..dc1b2a3 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -1,30 +1,59 @@
 project(kolabxmlbindings)
 
-make_directory(bindings)
+cmake_minimum_required(VERSION 2.8)
+
+FIND_PACKAGE(Qt4 REQUIRED)
+include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
+
+set(CMAKE_BUILD_TYPE Debug)
+
+file(MAKE_DIRECTORY bindings)
 
 set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
-set( SCHEMAS  
-    ${SCHEMA_DIR}/base.xsd 
-    ${SCHEMA_DIR}/incidence.xsd 
-    ${SCHEMA_DIR}/event.xsd 
-    ${SCHEMA_DIR}/note.xsd )
-set( SCHEMA_SOURCEFILES  
+set( XSDCXX  /usr/bin/xsdcxx)
+
+file(GLOB KOLAB_SCHEMAS ${SCHEMA_DIR}/*.xsd)
+set( KOLAB_SCHEMA_SOURCEFILES  
     bindings/base.cxx
     bindings/incidence.cxx
     bindings/event.cxx
     bindings/note.cxx )
-set( XSDCXX  /usr/bin/xsdcxx)
 
-add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
-    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD --output-dir bindings ${SCHEMAS}
-    COMMENT "Generating XSD bindings"
+add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
+    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD --output-dir bindings ${KOLAB_SCHEMAS}
+    COMMENT "Generating Kolab XSD bindings"
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     VERBATIM
     )
 
+file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
+set( XCAL_SCHEMA_SOURCEFILES  
+    bindings/kolabformat.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
+)
+# --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}
+    COMMENT "Generating xCal XSD bindings"
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    VERBATIM
+    )
+
+set( SCHEMA_SOURCEFILES ${XCAL_SCHEMA_SOURCEFILES} ${KOLAB_SCHEMA_SOURCEFILES})
+
+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_subdirectory(tests)
\ No newline at end of file
+target_link_libraries(${kolabxml} xerces-c)
+add_subdirectory(tests)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index f2536a7..1e741ea 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -1,4 +1,5 @@
 #include "bindingstest.h"
+
 #include <QObject>
 #include <QtTest/QtTest>
 
@@ -6,12 +7,13 @@
 #include "bindings/iCalendar.hxx"
 #include "bindings/iCalendar-props.hxx"
 #include "bindings/iCalendar-valtypes.hxx"
+#include "bindings/kolabformat.hxx"
 
-#include "iostream"
-#include <xercesc/dom/DOMException.hpp>
+#include <iostream>
 
+#include <xercesc/dom/DOMException.hpp>
 #include <xercesc/dom/DOMImplementation.hpp>
-#include </home/chrigi/work/kolab/xmlformat/cxxtest/xsdcxx/xsd/libxsd/xsd/cxx/xml/string.hxx>
+
 
 void BindingsTest::writeNoteTest()
 {
@@ -59,7 +61,7 @@ void BindingsTest::writeReadNoteTest()
 
 }
 
-void BindingsTest::writeXCalEvent()
+void BindingsTest::writeKolabXCalEvent()
 {
     try {
     //Components
@@ -67,10 +69,111 @@ void BindingsTest::writeXCalEvent()
 
     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);
     
     
-    //Properties
+    //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);
+    } 
+}
+
+
+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);
+    } 
+}
+
+#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);
@@ -147,7 +250,7 @@ void BindingsTest::readXCalEvent()
 
 }
 
-
+#endif
 
 void BindingsTest::xercesException()
 {
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 9eb4f7a..4122321 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -9,8 +9,10 @@ class BindingsTest : public QObject
   Q_OBJECT
   private slots:
       
-    void writeXCalEvent();
-    void readXCalEvent();
+     void writeKolabXCalEvent();
+     void readKolabXCalEvent();
+    //void writeXCalEvent();
+    //void readXCalEvent();
       
     void writeNoteTest();
     void readNoteTest();
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index b88d835..0599471 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -223,4 +223,4 @@ class KCalConversionTest : public QObject
 #endif
 QTEST_MAIN( KCalConversionTest )
 
-#include "moc_kcalconversiontest.cxx"
+//#include "moc_kcalconversiontest.cxx"
diff --git a/c++/tests/testfiles/testevent.xml b/c++/tests/testfiles/testevent.xml
new file mode 100644
index 0000000..dd59990
--- /dev/null
+++ b/c++/tests/testfiles/testevent.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<vevent xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+
+  <properties>
+    <dtstart>
+      <date>2011-11-10+10:10</date>
+    </dtstart>
+    <rrule>
+      <recur>
+        <freq>DAILY</freq>
+        <count>2</count>
+        <byhour>3</byhour>
+      </recur>
+    </rrule>
+    <x-prop>
+        <parameters>
+        <pref><integer>1</integer></pref>
+        </parameters>                 <!-- Core vCard elements  -->
+        <text>value goes here</text>  <!-- are still accessible -->
+    </x-prop>
+
+  </properties>
+
+  <components/>
+
+</vevent>
diff --git a/c++/tests/testfiles/testkolabevent.xml b/c++/tests/testfiles/testkolabevent.xml
new file mode 100644
index 0000000..021f289
--- /dev/null
+++ b/c++/tests/testfiles/testkolabevent.xml
@@ -0,0 +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">
+
+  <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>
+          
+        </xcal:recur>
+      </xcal: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>
+
+</event>
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
new file mode 100644
index 0000000..fff27e1
--- /dev/null
+++ b/schemas/ical/kolabformat.xsd
@@ -0,0 +1,39 @@
+<?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"
+    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:element name="event" type="Event"/>
+
+    <xs:complexType name="Event">
+        <xs:sequence>
+            <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:element name="todo" type="Todo"/>
+
+    <xs:complexType name="Todo">
+        <xs:sequence>
+            <xs:element ref="xcal:vtodo" 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:complexType>
+
+    <xs:element name="x-kolab-customproperty" type="CustomType" substitutionGroup="xcal:baseProperty" /> 
+
+</xs:schema>
\ No newline at end of file


commit 2ce7b6accef55af731e1d99918e73ad4ce975697
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Nov 10 15:54:33 2011 +0100

    bindingstest, basic serialization

diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index b816f7a..d59dc7c 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,10 +1,12 @@
 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
 
-FIND_PACKAGE(Qt4 REQUIRED)
-
-QT4_WRAP_CPP(HEADERS_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 )
-
+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)
+add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
+target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
new file mode 100644
index 0000000..f2536a7
--- /dev/null
+++ b/c++/tests/bindingstest.cpp
@@ -0,0 +1,190 @@
+#include "bindingstest.h"
+#include <QObject>
+#include <QtTest/QtTest>
+
+#include "bindings/note.hxx"
+#include "bindings/iCalendar.hxx"
+#include "bindings/iCalendar-props.hxx"
+#include "bindings/iCalendar-valtypes.hxx"
+
+#include "iostream"
+#include <xercesc/dom/DOMException.hpp>
+
+#include <xercesc/dom/DOMImplementation.hpp>
+#include </home/chrigi/work/kolab/xmlformat/cxxtest/xsdcxx/xsd/libxsd/xsd/cxx/xml/string.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);
+    
+    xml_schema::namespace_infomap map;
+    map[""].name = "http://kolab.org";
+    map[""].schema = "note.xsd";
+
+    KolabXSD::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::Note> note(KolabXSD::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);
+    } catch  (const xml_schema::exception& e) {
+        std::cout << e << endl;
+        QVERIFY(false);
+    } 
+}
+
+void BindingsTest::writeReadNoteTest()
+{
+
+}
+
+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);
+    } 
+
+}
+
+
+
+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();
+}
+
+
+
+QTEST_MAIN( BindingsTest )
+
+#include "bindingstest.moc"
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
new file mode 100644
index 0000000..9eb4f7a
--- /dev/null
+++ b/c++/tests/bindingstest.h
@@ -0,0 +1,21 @@
+#ifndef BINDINGSTEST_H
+#define BINDINGSTEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+class BindingsTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+      
+    void writeXCalEvent();
+    void readXCalEvent();
+      
+    void writeNoteTest();
+    void readNoteTest();
+    void writeReadNoteTest();
+    void xercesException();
+};
+
+#endif
\ No newline at end of file


commit 04aba16b0dc2454163763d69e5860accf8e5fd9b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Nov 2 19:59:17 2011 +0100

    xcal schemas

diff --git a/schemas/ical/iCalendar-availability-extension.xsd b/schemas/ical/iCalendar-availability-extension.xsd
new file mode 100644
index 0000000..f960a88
--- /dev/null
+++ b/schemas/ical/iCalendar-availability-extension.xsd
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar availability extension 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:xcal="urn:ietf:params:xml:ns:icalendar-2.0" targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0" elementFormDefault="qualified">
+	<!-- This schema extension defines properties and components for the availability
+     components defined in draft-daboo-calendar-availability -->
+	<!-- ===================== Value-types ================================  -->
+	<xs:include schemaLocation="iCalendar-valtypes.xsd"/>
+	<!-- ===================== Components =================================  -->
+	<xs:include schemaLocation="iCalendar.xsd"/>
+	<!-- ===================== Properties =================================  -->
+	<xs:include schemaLocation="iCalendar-props.xsd"/>
+	<!-- =====================================================================
+       Calendar Properties
+       ===================================================================== -->
+	<!-- The BUSYTYPE property is used to specify the default busy time
+      type.  The values correspond to those used by the "FBTYPE"
+      parameter used on a "FREEBUSY" property, with the exception that
+      the "FREE" value is not used.  If not specified on a component
+      that allows this property, the default is "BUSY-UNAVAILABLE".
+      
+      busytypevalue = "BUSY" / "BUSY-UNAVAILABLE" /
+                        "BUSY-TENTATIVE" / iana-token / x-name
+                        ; Default is "BUSY-UNAVAILABLE"
+      
+   -->
+	<xs:complexType name="BusytypePropType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       encodingparam      = "ENCODING" "="
+                          ( "8BIT"
+          ; "8bit" text encoding is defined in [RFC2045]
+                          / "BASE64"
+          ; "BASE64" binary encoding format is defined in [RFC4648]
+                          )
+      busytypevalue = "BUSY" 
+                    / "BUSY-UNAVAILABLE" 
+                    / "BUSY-TENTATIVE" 
+                    / iana-token 
+                    / x-name
+                    
+                    ; Default is "BUSY-UNAVAILABLE".
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- =====================================================================
+       Calendar Components
+       ===================================================================== -->
+	<xs:complexType name="VavailabilityType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType">
+				<xs:sequence>
+					<xs:element name="components" type="xcal:ArrayOfVavailabilityContainedComponents"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="vavailability" type="xcal:VavailabilityType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:complexType name="ArrayOfVavailabilityContainedComponents">
+		<xs:sequence>
+			<xs:element ref="xcal:available" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:complexType name="AvailableType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="available" type="xcal:AvailableType" substitutionGroup="xcal:baseComponent"/>
+</xs:schema>
diff --git a/schemas/ical/iCalendar-bw-extensions.xsd b/schemas/ical/iCalendar-bw-extensions.xsd
new file mode 100644
index 0000000..68b3b52
--- /dev/null
+++ b/schemas/ical/iCalendar-bw-extensions.xsd
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar Bedeworks server integration 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. -->
+
+<!--Bedework 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"/>
+	<!-- ===================== Properties =================================  -->
+	<xs:include schemaLocation="iCalendar-props.xsd"/>
+	<!-- =====================================================================
+       3.2 Property parameter definitions
+       ===================================================================== -->
+	<!-- Bedework x-parameters -->
+	<xs:element name="x-bedework-uid" type="xcal:XBedeworkUidParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:complexType name="XBedeworkUidParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- =====================================================================
+       3.7 Calendar Properties
+       ===================================================================== -->
+	<xs:element name="x-bedework-cost" type="xcal:XBedeworkCostPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="x-bedework-exsynch-endtzid" type="xcal:XBedeworkExsynchEndtzidPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="x-bedework-exsynch-lastmod" type="xcal:XBedeworkExsynchLastmodPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="x-bedework-exsynch-organizer" type="xcal:OrganizerPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="x-bedework-exsynch-starttzid" type="xcal:XBedeworkExsynchStarttzidPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:complexType name="XBedeworkCostPropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="XBedeworkExsynchEndtzidPropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="XBedeworkExsynchLastmodPropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="XBedeworkExsynchStarttzidPropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+</xs:schema>
diff --git a/schemas/ical/iCalendar-link-extension.xsd b/schemas/ical/iCalendar-link-extension.xsd
new file mode 100644
index 0000000..a12cd53
--- /dev/null
+++ b/schemas/ical/iCalendar-link-extension.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar link extensions 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:xcal="urn:ietf:params:xml:ns:icalendar-2.0" targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0" elementFormDefault="qualified">
+	<!--Definition for the LINK extension property for icalendar -->
+	<xs:include schemaLocation="iCalendar-valtypes.xsd"/>
+	<!-- ===================== Properties =================================  -->
+	<xs:include schemaLocation="iCalendar-params.xsd"/>
+	<!-- ===================== Properties =================================  -->
+	<xs:include schemaLocation="iCalendar-props.xsd"/>
+	<!-- =====================================================================
+       3.2 Property parameter definitions
+       ===================================================================== -->
+	<!-- REL defines the type of relationship and may be a predefined value as
+       below or a URI which is globally unique and understood within the context
+       of its use.
+       
+       The standard relation types are:
+             "PARENT"    ; Parent relationship - Default
+             "CHILD"     ; Child relationship
+             "SIBLING"   ; Sibling relationship
+   -->
+	<xs:element name="rel" type="xcal:TextParameterType" substitutionGroup="xcal:baseParameter"/>
+	<!-- =====================================================================
+       3.7 Calendar Properties
+       ===================================================================== -->
+	<xs:complexType name="LinkPropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BasePropertyType">
+				<xs:choice>
+					<xs:element ref="xcal:uri"/>
+					<xs:element name="uid" type="xs:string"/>
+					<xs:element name="reference" type="xs:string"/>
+				</xs:choice>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="link" type="xcal:LinkPropType" substitutionGroup="xcal:baseProperty"/>
+</xs:schema>
diff --git a/schemas/ical/iCalendar-ms-extensions.xsd b/schemas/ical/iCalendar-ms-extensions.xsd
new file mode 100644
index 0000000..2539c99
--- /dev/null
+++ b/schemas/ical/iCalendar-ms-extensions.xsd
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar MS Exchange Server integration 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. -->
+
+<!--Bedework 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">
+
+  <!-- =====================================================================
+       3.7 Calendar Properties
+       ===================================================================== -->  
+            
+  <!-- ===================== Properties =================================  -->
+  <xs:include schemaLocation="iCalendar-props.xsd" />
+
+  <xs:element name="x-microsoft-cdo-busystatus" 
+              type="xcal:XMicrosoftCdoBusystatusPropType"
+              substitutionGroup="xcal:baseProperty" />
+
+  <xs:element name="x-microsoft-cdo-intendedstatus" 
+              type="xcal:XMicrosoftCdoIntendedstatusPropType"
+              substitutionGroup="xcal:baseProperty" />
+  
+  <xs:complexType name="XMicrosoftCdoBusystatusPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="XMicrosoftCdoIntendedstatusPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+</xs:schema>
diff --git a/schemas/ical/iCalendar-params.xsd b/schemas/ical/iCalendar-params.xsd
new file mode 100644
index 0000000..1392daa
--- /dev/null
+++ b/schemas/ical/iCalendar-params.xsd
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar object parameters 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. -->
+
+<!--non-normative, to support development of WS-Calendar - 2010/10/30. Refer to rfc5545 and xCal in the IETF for normative description-->
+<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"/>
+	<!-- =====================================================================
+       3.2 Property parameter definitions
+       ===================================================================== -->
+	<xs:complexType name="BaseParameterType" abstract="true"/>
+	<xs:element name="baseParameter" type="xcal:BaseParameterType"/>
+	<xs:complexType name="ArrayOfParameters">
+		<xs:sequence>
+			<xs:element ref="xcal:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<!-- =====================================================================
+       Define all the standard properties. By using a substitutionGroup we
+       make it easy to extend the list of parameters. As an example see 
+       the parameters defined in iCalendar-caldavsched-extensions.xsd
+       ===================================================================== -->
+	<xs:element name="altrep" type="xcal:AltrepParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="cn" type="xcal:CnParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="cutype" type="xcal:CutypeParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="delegated-from" type="xcal:DelegatedFromParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="delegated-to" type="xcal:DelegatedToParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="dir" type="xcal:DirParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="encoding" type="xcal:EncodingParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="fmttype" type="xcal:FmttypeParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="fbtype" type="xcal:FbtypeParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="language" type="xcal:LanguageParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="member" type="xcal:MemberParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="partstat" type="xcal:PartstatParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="range" type="xcal:RangeParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="related" type="xcal:RelatedParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="reltype" type="xcal:ReltypeParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="role" type="xcal:RoleParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="rsvp" type="xcal:RsvpParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="sent-by" type="xcal:SentByParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="tzid" type="xcal:TzidParamType" substitutionGroup="xcal:baseParameter"/>
+	<!-- Scheduling parameters for attendee or organizer -->
+	<xs:element name="schedule-agent" type="xcal:ScheduleAgentParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="schedule-force-send" type="xcal:ScheduleForceSendParamType" substitutionGroup="xcal:baseParameter"/>
+	<xs:element name="schedule-status" type="xcal:ScheduleStatusParamType" substitutionGroup="xcal:baseParameter"/>
+	<!-- Parameters that take a simple boolean value -->
+	<xs:complexType name="BooleanParameterType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element ref="xcal:boolean"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- Parameters that take a simple text value -->
+	<xs:complexType name="TextParameterType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element ref="xcal:text"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- Parameters that take a uri value -->
+	<xs:complexType name="UriParameterType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element ref="xcal:uri"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="CalAddressListParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element ref="xcal:cal-address" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="CalAddressParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element ref="xcal:cal-address"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.1 Alternate Text Representation -->
+	<xs:complexType name="AltrepParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:UriParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.2 Common Name -->
+	<xs:complexType name="CnParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.3 Calendar User Type -->
+	<xs:complexType name="CutypeParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       cutypeparam        = "CUTYPE" "="
+                          ("INDIVIDUAL"   ; An individual
+                         / "GROUP"        ; A group of individuals
+                         / "RESOURCE"     ; A physical resource
+                         / "ROOM"         ; A room resource
+                         / "UNKNOWN"      ; Otherwise not known
+                         / x-name         ; Experimental type
+                         / iana-token)    ; Other IANA-registered
+                                          ; type
+       ; Default is INDIVIDUAL
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.4 Delegators -->
+	<xs:complexType name="DelegatedFromParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:CalAddressListParamType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.5 Delegatees -->
+	<xs:complexType name="DelegatedToParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:CalAddressListParamType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.6 Directory Entry Reference -->
+	<xs:complexType name="DirParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:UriParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.7 Inline Encoding -->
+	<xs:complexType name="EncodingParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       encodingparam      = "ENCODING" "="
+                          ( "8BIT"
+          ; "8bit" text encoding is defined in [RFC2045]
+                          / "BASE64"
+          ; "BASE64" binary encoding format is defined in [RFC4648]
+                          )
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.8 Format Type -->
+	<xs:complexType name="FmttypeParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.9 Free/Busy Time Type -->
+	<xs:complexType name="FbtypeParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       fbtypeparam        = "FBTYPE" "=" 
+                         ("FREE" 
+                          / "BUSY"
+                          / "BUSY-UNAVAILABLE" 
+                          / "BUSY-TENTATIVE"
+                          / x-name  ; Some experimental iCalendar free/busy type.
+                          / iana-token)
+                ; Some other IANA-registered iCalendar free/busy type.
+       ; Default is BUSY
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.10 Language -->
+	<xs:complexType name="LanguageParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.11 Group or List Membership -->
+	<xs:complexType name="MemberParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:CalAddressListParamType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.12 Participation Status -->
+	<xs:complexType name="PartstatParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       partstat-event   = ("NEEDS-ACTION"    ; Event needs action
+                        / "ACCEPTED"         ; Event accepted
+                        / "DECLINED"         ; Event declined
+                        / "TENTATIVE"        ; Event tentatively
+                                             ; accepted
+                        / "DELEGATED"        ; Event delegated
+                        / x-name             ; Experimental status
+                        / iana-token)        ; Other IANA-registered
+                                             ; status
+       ; These are the participation statuses for a "VEVENT".
+       ; Default is NEEDS-ACTION.
+
+       partstat-todo    = ("NEEDS-ACTION"    ; To-do needs action
+                        / "ACCEPTED"         ; To-do accepted
+                        / "DECLINED"         ; To-do declined
+                        / "TENTATIVE"        ; To-do tentatively
+                                             ; accepted
+                        / "DELEGATED"        ; To-do delegated
+                        / "COMPLETED"        ; To-do completed
+                                             ; COMPLETED property has
+                                             ; DATE-TIME completed
+                        / "IN-PROCESS"       ; To-do in process of
+                                             ; being completed
+                        / x-name             ; Experimental status
+                        / iana-token)        ; Other IANA-registered
+                                             ; status
+       ; These are the participation statuses for a "VTODO".
+       ; Default is NEEDS-ACTION.
+
+       partstat-jour    = ("NEEDS-ACTION"    ; Journal needs action
+                        / "ACCEPTED"         ; Journal accepted
+                        / "DECLINED"         ; Journal declined
+                        / x-name             ; Experimental status
+                        / iana-token)        ; Other IANA-registered
+                                             ; status
+       ; These are the participation statuses for a "VJOURNAL".
+       ; Default is NEEDS-ACTION.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.13 Recurrence Identifier Range -->
+	<xs:simpleType name="RangeValueType">
+		<xs:restriction base="xs:token">
+			<xs:enumeration value="THISANDFUTURE"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:complexType name="RangeParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element name="text" type="xcal:RangeValueType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.14 Alarm Trigger Relationship -->
+	<xs:complexType name="RelatedParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       trigrelparam       = "RELATED" "="
+                           ("START"       ; Trigger off of start
+                          / "END")        ; Trigger off of end
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.15 Relationship Type -->
+	<xs:complexType name="ReltypeParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+       reltypeparam       = "RELTYPE" "="
+                           ("PARENT"    ; Parent relationship - Default
+                          / "CHILD"     ; Child relationship
+                          / "SIBLING"   ; Sibling relationship
+                          / iana-token  ; Some other IANA-registered
+                                        ; iCalendar relationship type
+                          / x-name)     ; A non-standard, experimental
+                                        ; relationship type
+        Ws-Calendar adds the values
+                           / "FINISHTOSTART"
+                           / "FINISHTOFINISH"
+                           / "STARTTOFINISH"
+                           / "STARTTOSTART"             
+                           
+       ; Default is PARENT
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.16 Participation Role -->
+	<xs:complexType name="RoleParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Standard values
+           "CHAIR" 
+           "REQ-PARTICIPANT" 
+           "OPT-PARTICIPANT" 
+           "NON-PARTICIPANT"
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.17 RSVP Expectation -->
+	<xs:complexType name="RsvpParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BooleanParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.18 Sent By -->
+	<xs:complexType name="SentByParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:CalAddressParamType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.2.19 Time Zone Identifier -->
+	<xs:complexType name="TzidParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- Scheduling parameters - Defined by CalDAV scheduling -->
+	<xs:complexType name="ScheduleAgentParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        scheduleagentparam = "SCHEDULE-AGENT" "="
+                        ("SERVER"      ; The server handles scheduling
+                       / "CLIENT"      ; The client handles scheduling
+                       / "NONE"        ; No automatic scheduling
+                       / x-name        ; Experimental type
+                       / iana-token)   ; Other IANA registered type
+                                       ;
+                                       ; Default is SERVER
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="ScheduleForceSendParamType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+      scheduleforcesendparam = "SCHEDULE-FORCE-SEND" "="
+                              ("REQUEST"    ; Force a "REQUEST"
+                             / "REPLY"      ; Force a "REPLY"
+                             / iana-token)  ; IANA registered method
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="ScheduleStatusParamType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextParameterType"/>
+		</xs:complexContent>
+	</xs:complexType>
+</xs:schema>
diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
new file mode 100644
index 0000000..c4dfc92
--- /dev/null
+++ b/schemas/ical/iCalendar-props.xsd
@@ -0,0 +1,773 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar object properties 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. -->
+
+<!--non-normative, to support development of WS-Calendar - 2010/10/30. 
+    Refer to rfc5545 and xCal in the IETF for normative description -->
+<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">
+
+  <!-- =====================================================================
+       3.7 Calendar Properties
+       ===================================================================== -->  
+            
+  <!-- ===================== Parameters =================================  -->
+  <xs:include schemaLocation="iCalendar-params.xsd" />
+
+  <!-- =====================================================================
+        BasePropertyType 
+        All properties are based off this type which defines a property as 
+        nothing more than a list of parameters. 
+        
+        We make no attempt to define valid parameters for each property as this
+        would complicate the schema significantly. Consumers can ignore 
+        property parameters they do not understand or expect. 
+       ===================================================================== -->  
+  <xs:complexType name="BasePropertyType" abstract="true" >
+    <xs:sequence>
+      <xs:element ref="xcal:parameters" 
+                  minOccurs="0" />
+    </xs:sequence>
+  </xs:complexType>
+  
+  <xs:element name="parameters" type="xcal:ArrayOfParameters"/>
+
+  <xs:element name="baseProperty" type="xcal:BasePropertyType" />
+
+  <xs:complexType name="ArrayOfProperties">
+    <xs:sequence>
+      <xs:element ref="xcal:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+  
+  <!-- =====================================================================
+       Define all the standard properties. By using a substitutionGroup we
+       make it easy to extend the list of properties. As an example see 
+       the properties defined in iCalendar-ms-extensions.xsd
+       ===================================================================== -->  
+  <xs:element name="calscale" type="xcal:CalscalePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="method" type="xcal:MethodPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="prodid" type="xcal:ProdidPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="version" type="xcal:VersionPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="attach" type="xcal:AttachPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="categories" type="xcal:CategoriesPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="class" type="xcal:ClassPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="comment" type="xcal:CommentPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="description" type="xcal:DescriptionPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="geo" type="xcal:GeoPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="location" type="xcal:LocationPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="percent-complete" type="xcal:PercentCompletePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="priority" type="xcal:PriorityPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="resources" type="xcal:ResourcesPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="status" type="xcal:StatusPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="summary" type="xcal:SummaryPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="completed" type="xcal:CompletedPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="dtend" type="xcal:DtendPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="dtstart" type="xcal:DtstartPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="due" type="xcal:DuePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="duration" type="xcal:DurationPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="freebusy" type="xcal:FreebusyPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="transp" type="xcal:TranspPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <!-- Comment out tzid for the moment. It has the same name as the parameter
+       and this is causing me some issues
+  <xs:element name="tzid" type="xcal:TzidPropType"
+              substitutionGroup="xcal:baseProperty" /> -->
+  <xs:element name="tzname" type="xcal:TznamePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="tzoffsetfrom" type="xcal:TzoffsetfromPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="tzoffsetto" type="xcal:TzoffsettoPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="tzurl" type="xcal:TzurlPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="attendee" type="xcal:AttendeePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="contact" type="xcal:ContactPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="organizer" type="xcal:OrganizerPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="recurrence-id" type="xcal:RecurrenceIdPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="url" type="xcal:UrlPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="uid" type="xcal:UidPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="exdate" type="xcal:ExdatePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="rdate" type="xcal:RdatePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="related-to" type="xcal:RelatedToPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="exrule" type="xcal:ExrulePropType"
+              substitutionGroup="xcal:baseProperty" /> 
+              
+  <xs:element name="rrule" type="xcal:RrulePropType"
+              substitutionGroup="xcal:baseProperty" /> 
+              
+  <xs:element name="action" type="xcal:ActionPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="repeat" type="xcal:RepeatPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="trigger" type="xcal:TriggerPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="created" type="xcal:CreatedPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="dtstamp" type="xcal:DtstampPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="last-modified" type="xcal:LastModifiedPropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="sequence" type="xcal:SequencePropType"
+              substitutionGroup="xcal:baseProperty" />
+              
+  <xs:element name="request-status" type="xcal:RequestStatusPropType"
+              substitutionGroup="xcal:baseProperty" />
+
+  <!-- Properties that take a simple text value -->
+  <xs:complexType name="TextPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence> 
+          <xs:element ref="xcal:text" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <xs:complexType name="TextListPropertyType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:text" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a calendar address value -->
+  <xs:complexType name="CalAddressPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:cal-address" />
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+ 
+  <!-- Properties that take a simple integer value -->
+  <xs:complexType name="IntegerPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:integer"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a uri value -->
+  <xs:complexType name="UriPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:uri"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a utc offset value -->
+  <xs:complexType name="UtcOffsetPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:utc-offset"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a date-time value -->
+  <xs:complexType name="DatetimePropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:date-time"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a utc-date-time value -->
+  <xs:complexType name="UtcDatetimePropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:utc-date-time"/>
+        </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="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:choice>
+            <xs:element ref="xcal:date-time"/>
+            <xs:element ref="xcal:date"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- Properties that take a recurrence value -->
+  <xs:complexType name="RecurPropertyType" >
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element name="recur" type="xcal:RecurType"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+     
+  <!-- 3.7.1 Calendar Scale -->
+  <xs:simpleType name="CalscaleValueType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="GREGORIAN"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:complexType name="CalscalePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element name="text" type="xcal:CalscaleValueType"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.7.2 Method -->
+  <xs:complexType name="MethodPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.7.3 Product Identifier -->
+  <xs:complexType name="ProdidPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.7.4 Version -->
+  <xs:complexType name="VersionPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8 Component Properties -->
+  <!-- 3.8.1 Descriptive Component Properties -->
+  <!-- 3.8.1.1 Attachment -->
+  <xs:complexType name="AttachPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:choice> 
+          <xs:element ref="xcal:uri"/>
+          <xs:element ref="xcal:binary"/>
+        </xs:choice>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.2 Categories -->
+  <xs:complexType name="CategoriesPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextListPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>  
+
+  <!-- 3.8.1.3 Classification -->
+  
+  <xs:complexType name="ClassPropType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+       classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token
+                  / x-name
+       ;Default is PUBLIC
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.4 Comment -->
+  <xs:complexType name="CommentPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.5 Description -->
+  <xs:complexType name="DescriptionPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.6 Geographic Position -->
+  <xs:complexType name="GeoPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:latitude"/>
+          <xs:element ref="xcal:longitude"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <xs:element name="latitude" type="xs:float"/>
+  <xs:element name="longitude" type="xs:float"/>
+  
+  <!-- 3.8.1.7 Location -->
+  <xs:complexType name="LocationPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.8 Percent Complete -->
+  <xs:complexType name="PercentCompletePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:IntegerPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.8.1.9 Priority -->
+  <xs:complexType name="PriorityPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:IntegerPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.1.10 Resources -->
+  <xs:complexType name="ResourcesPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextListPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.8.1.11 Status -->
+  <xs:complexType name="StatusPropType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+       status          = "STATUS" statparam ":" statvalue CRLF
+
+       statparam       = *(";" other-param)
+
+       statvalue       = (statvalue-event
+                       /  statvalue-todo
+                       /  statvalue-jour)
+
+       statvalue-event = "TENTATIVE"    ;Indicates event is tentative.
+                       / "CONFIRMED"    ;Indicates event is definite.
+                       / "CANCELLED"    ;Indicates event was cancelled.
+       ;Status values for a "VEVENT"
+
+       statvalue-todo  = "NEEDS-ACTION" ;Indicates to-do needs action.
+                       / "COMPLETED"    ;Indicates to-do completed.
+                       / "IN-PROCESS"   ;Indicates to-do in process of.
+                       / "CANCELLED"    ;Indicates to-do was cancelled.
+       ;Status values for "VTODO".
+
+       statvalue-jour  = "DRAFT"        ;Indicates journal is draft.
+                       / "FINAL"        ;Indicates journal is final.
+                       / "CANCELLED"    ;Indicates journal is removed.
+      ;Status values for "VJOURNAL".
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8.1.12 Summary -->
+  <xs:complexType name="SummaryPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2 Date and Time Component Properties -->
+  <!-- 3.8.2.1 Date/Time Completed -->
+  <xs:complexType name="CompletedPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.2 Date/Time End -->
+  <xs:complexType name="DtendPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.3 Date/Time Due -->
+  <xs:complexType name="DuePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.4 Date/Time Start -->
+  <xs:complexType name="DtstartPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.5 Duration -->
+  <xs:complexType name="DurationPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element  name="duration" type="xcal:DurationValueType"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.6 Free/Busy Time -->
+  <xs:complexType name="FreebusyPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element ref="xcal:period" maxOccurs="unbounded"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.2.7 Time Transparency -->
+  
+  <xs:complexType name="TranspPropType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+       transvalue = "OPAQUE"
+                   ;Blocks or opaque on busy time searches.
+                   / "TRANSPARENT"
+                   ;Transparent on busy time searches.
+       ;Default value is OPAQUE
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8.3 Time Zone Component Properties -->
+  <!-- 3.8.3.1 Time Zone Identifier -->
+  <xs:complexType name="TzidPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+        
+  <!-- 3.8.3.2 Time Zone Name -->
+  <xs:complexType name="TznamePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.3.3 Time Zone Offset From -->
+  <xs:complexType name="TzoffsetfromPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcOffsetPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.3.4 Time Zone Offset To -->
+  <xs:complexType name="TzoffsettoPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcOffsetPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.3.5 Time Zone URL -->
+  <xs:complexType name="TzurlPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4 Relationship Component Properties -->
+  <!-- 3.8.4.1 Attendee -->
+  <xs:complexType name="AttendeePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:CalAddressPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.2 Contact -->
+  <xs:complexType name="ContactPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.3 Organizer -->
+  <xs:complexType name="OrganizerPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:CalAddressPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.4 Recurrence ID -->
+  <xs:complexType name="RecurrenceIdPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.5 Related-To -->
+  <!-- Before extensions to allow different value types
+  <xs:complexType name="RelatedToPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+   -->
+   
+  <xs:complexType name="RelatedToPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:choice> 
+          <xs:element ref="xcal:uri"/>
+          <xs:element name="uid" type="xs:string"/>
+          <xs:element ref="xcal:text"/>
+        </xs:choice>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.6 Uniform Resource Locator -->
+  <xs:complexType name="UrlPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UriPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.4.7 Unique Identifier -->
+  <xs:complexType name="UidPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.5 Recurrence Component Properties -->
+  <!-- 3.8.5.1 Exception Date/Times -->
+  <xs:complexType name="ExdatePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.5.2 Recurrence Date/Times -->
+  <xs:complexType name="RdatePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:DateDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.5.3 Recurrence Rule -->
+  <xs:complexType name="RrulePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:RecurPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- x.x.x.x Deprecated ExRule -->
+  <xs:complexType name="ExrulePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:RecurPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.6 Alarm Component Properties -->
+  <!-- 3.8.6.1 Action -->
+  
+  <xs:complexType name="ActionPropType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+       actionvalue = "AUDIO" / "DISPLAY" / "EMAIL"
+                   / iana-token / x-name
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:TextPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8.6.2 Repeat Count -->
+  <xs:complexType name="RepeatPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:IntegerPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8.6.3 Trigger -->
+  <xs:complexType name="TriggerPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:choice>
+            <xs:element name="duration" type="xcal:DurationValueType"/>
+            <xs:element ref="xcal:date-time"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  
+  <!-- 3.8.7 Change Management Component Properties -->
+  <!-- 3.8.7.1 Date/Time Created -->
+  <xs:complexType name="CreatedPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+    
+  <!-- 3.8.7.2 Date/Time Stamp -->
+  <xs:complexType name="DtstampPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.8.7.3 Last Modified -->
+  <xs:complexType name="LastModifiedPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:UtcDatetimePropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.8.7.4 Sequence Number -->
+  <xs:complexType name="SequencePropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:IntegerPropertyType"/>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <!-- 3.8.8 Miscellaneous Component Properties -->
+  <!-- 3.8.8.3 Request Status -->
+  <xs:complexType name="RequestStatusPropType">
+    <xs:complexContent mixed="false">
+      <xs:extension base="xcal:BasePropertyType">
+        <xs:sequence>
+          <xs:element name="code" type="xs:string" />
+          <xs:element name="description" type="xs:string"/>
+          <xs:element name="extdata" type="xs:string"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+    
+    <!-- 
+           statcode   = 1*DIGIT 1*2("." 1*DIGIT)
+       ;Hierarchical, numeric return status code
+
+       statdesc   = text
+       ;Textual status description
+
+       extdata    = text
+       ;Textual exception data.  For example, the offending property
+       ;name and value or complete property line.
+     -->
+</xs:schema>
diff --git a/schemas/ical/iCalendar-valtypes.xsd b/schemas/ical/iCalendar-valtypes.xsd
new file mode 100644
index 0000000..d194837
--- /dev/null
+++ b/schemas/ical/iCalendar-valtypes.xsd
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar values 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. -->
+
+<!-- edited with XMLSpy v2010 rel. 3 sp1 (x64) (http://www.altova.com) by Toby Considine (TC9) -->
+<!--non-normative, to support development of WS-Calendar - 2010/10/30. Refer to rfc5545 and xCal in the IETF for normative description-->
+<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">
+          
+  <!-- =====================================================================
+       3.3 Property Value Data Types 
+       ===================================================================== -->
+          
+	<!-- 3.3.1 BINARY -->
+	<xs:element name="binary" type="xs:string"/>
+  
+	<!-- 3.3.2 BOOLEAN -->
+	<xs:element name="boolean" type="xs:boolean" />
+  
+	<!-- 3.3.3 CAL-ADDRESS -->
+  <xs:simpleType name="CalAddressType">
+    <xs:restriction base="xs:string"/>
+  </xs:simpleType>
+  
+  <xs:element name="cal-address" type="xcal:CalAddressType" />  
+  
+	<!-- 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="xcal:DateTimeType"/>
+  
+  <xs:simpleType name="UTCDateTimeType">
+    <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="utc-date-time" type="xcal:UTCDateTimeType"/>
+  
+	<!-- 3.3.6 DURATION 
+  We cannot have a duration value type here as the value-type element has the same 
+  name as the property.  
+	<xs:element name="duration" type="xs:duration"/>-->
+  
+  <xs:simpleType name="DurationValueType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        Durations are a problem: 
+           XML schema types allow Years, Months, Days, Hours, Minutes, Seconds
+           Ical allows Weeks, Days, Hours, Minutes, Seconds
+           
+        These overlap and we really need a combination of both.
+        So the compromise is to have a pattern restricted String type and note
+        that if data is to be exported into the icalendar world it cannot have 
+        years or months.
+        
+        Ultimately it is to be hoped the two worlds can be aligned.
+        
+        RFC5545 (icalendar) specifies
+        dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
+
+        dur-date   = dur-day [dur-time]
+        dur-time   = "T" (dur-hour / dur-minute / dur-second)
+        dur-week   = 1*DIGIT "W"
+        dur-hour   = 1*DIGIT "H" [dur-minute]
+        dur-minute = 1*DIGIT "M" [dur-second]
+        dur-second = 1*DIGIT "S"
+        dur-day    = 1*DIGIT "D"
+        
+        So P5W is valid: P5WT10M is not. If weeks re specified nothing else can be
+        
+        XML specifies
+           PnYnMnDTnHnMnS
+        
+        The elements must appear in the order specified and the 'T' is omitted 
+        if hours minutes and seconds are absent.
+      </xs:documentation>
+    </xs:annotation>
+    <xs:restriction base="xs:string">
+      <xs:pattern value="(\+|\-)?P((\d+Y)?(\d+M)?(\d+D)?T?(\d+H)?(\d+M)?(\d+S)?)|(\d+W)"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+	<!-- 3.3.7 FLOAT -->
+	<xs:element name="float" type="xs:float"/>
+  
+	<!-- 3.3.8 INTEGER -->
+	<xs:element name="integer" type="xs:integer"/>
+  
+	<!-- 3.3.9 PERIOD -->
+
+  <xs:complexType name="PeriodType">
+    <xs:sequence>
+      <xs:element name="start" type="xcal:DateTimeType" />
+      <xs:sequence>
+        <xs:choice>
+          <xs:element name="end" type="xcal:DateTimeType" />
+          <xs:element name="duration" type="xcal:DurationValueType" />
+        </xs:choice>
+      </xs:sequence>
+    </xs:sequence>
+  </xs:complexType>
+
+  <xs:element name="period" type="xcal:PeriodType" />
+     
+  <!-- 3.3.10 RECUR -->
+  <xs:complexType name="RecurType">
+    <xs:sequence>
+      <xs:element name="freq" type="xcal:FreqRecurType"/>
+      <xs:sequence>
+        <xs:choice minOccurs="0">
+          <xs:element ref="xcal:until" />
+          <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" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="byminute" type="xs:string"  
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="byhour" type="xs:string" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="byday" type="xs:string" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="byyearday" type="xs:string" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="bymonthday" type="xcal:BymonthdayRecurType" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="byweekno" type="xs:string" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="bymonth" type="xcal:BymonthRecurType" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="bysetpos" type="xs:integer" 
+                  minOccurs="0" maxOccurs="unbounded" />
+      <xs:element name="wkst" type="xcal:WeekdayRecurType" minOccurs="0" />
+    </xs:sequence>
+  </xs:complexType>
+  
+	<xs:simpleType name="FreqRecurType">
+		<xs:restriction base="xs:token">
+			<xs:enumeration value="SECONDLY"/>
+			<xs:enumeration value="MINUTELY"/>
+			<xs:enumeration value="HOURLY"/>
+			<xs:enumeration value="DAILY"/>
+			<xs:enumeration value="WEEKLY"/>
+			<xs:enumeration value="MONTHLY"/>
+			<xs:enumeration value="YEARLY"/>
+		</xs:restriction>
+	</xs:simpleType>
+  
+  <xs:element name="until" type="xcal:UntilRecurType"/>
+  
+  <xs:complexType name="UntilRecurType" >
+    <xs:sequence>
+      <xs:choice>
+        <xs:element ref="xcal:date" />
+        <xs:element ref="xcal:date-time" />
+      </xs:choice>
+    </xs:sequence>
+  </xs:complexType>
+
+  <xs:element name="count" type="xs:integer"/>
+  
+	<xs:simpleType name="WeekdayRecurType">
+		<xs:restriction base="xs:token">
+			<xs:enumeration value="SU"/>
+			<xs:enumeration value="MO"/>
+			<xs:enumeration value="TU"/>
+			<xs:enumeration value="WE"/>
+			<xs:enumeration value="TH"/>
+			<xs:enumeration value="FR"/>
+			<xs:enumeration value="SA"/>
+		</xs:restriction>
+	</xs:simpleType>
+  
+  <xs:simpleType name="BymonthdayRecurType">
+    <xs:restriction base="xs:integer">
+      <xs:minInclusive value="-31"/>
+      <xs:maxInclusive value="31"/>
+    </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"/>
+  
+	<!-- 3.3.12 TIME -->
+	<xs:element name="time" type="xs:string"/>
+  
+	<!-- 3.3.13 URI -->
+	<xs:simpleType name="UriType">
+    <xs:restriction base="xs:string"/>
+  </xs:simpleType>
+  
+  <xs:element name="uri" type="xcal:UriType" />  
+  
+	<!-- 3.3.14 UTC-OFFSET -->
+  <xs:simpleType name="UtcOffsetType">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="(\-|\+)?\d{2}:\d{2}"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:element name="utc-offset" type="xcal:UtcOffsetType" />  
+  
+</xs:schema>
diff --git a/schemas/ical/iCalendar-wscal-extensions.xsd b/schemas/ical/iCalendar-wscal-extensions.xsd
new file mode 100644
index 0000000..4f3c7fe
--- /dev/null
+++ b/schemas/ical/iCalendar-wscal-extensions.xsd
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- iCalendar service functionality extensions 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. -->
+
+<!--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"/>
+	<!-- ===================== Properties =================================  -->
+	<xs:include schemaLocation="iCalendar-props.xsd"/>
+	<!-- ===================== Components =================================  -->
+	<xs:include schemaLocation="iCalendar.xsd"/>
+	<!-- =====================================================================
+       3.2 Property parameter definitions
+       ===================================================================== -->
+	<!-- Parameters that take a duration value -->
+	<xs:complexType name="DurationParameterType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseParameterType">
+				<xs:sequence>
+					<xs:element name="duration" type="xs:duration"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- Gap is used in the RELATED-TO property -->
+	<xs:element name="gap" type="xcal:DurationParameterType" substitutionGroup="xcal:baseParameter"/>
+	<!-- Granularity is used in the VAVAILABILITY and AVAILABILITY components -->
+	<xs:element name="granularity" type="xcal:DurationPropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:complexType name="ToleranceValueType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+         A tolerance value is a set of durations which indicate the allowed
+         tolerance for the indicated value, e.g. startafter=PT5M indicates that
+         5 minutes late is acceptable. 
+      </xs:documentation>
+		</xs:annotation>
+		<xs:sequence>
+			<xs:element name="startbefore" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="startafter" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="endbefore" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="endafter" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="durationlong" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="durationshort" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+			<xs:element name="precision" type="xcal:DurationValueType" minOccurs="0" maxOccurs="1"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="tolerance" type="xcal:TolerancePropType" substitutionGroup="xcal:baseProperty"/>
+	<xs:complexType name="TolerancePropType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:BasePropertyType">
+				<xs:sequence>
+					<xs:element name="tolerate" type="xcal:ToleranceValueType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- =====================================================================
+       3.4 Calendar Components
+       ===================================================================== -->
+	<xs:complexType name="WsCalendarGluonType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+         A gluon takes vavailability.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType">
+				<xs:sequence>
+					<xs:element name="components" type="xcal:ArrayOfGluonContainedComponents"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="ArrayOfGluonContainedComponents" mixed="false">
+		<xs:sequence>
+			<xs:choice minOccurs="0" maxOccurs="unbounded">
+				<xs:element ref="xcal:vavailability"/>
+			</xs:choice>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="gluon" type="xcal:WsCalendarGluonType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:complexType name="WsCalendarIntervalType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+         An interval takes no sub-components.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="interval" type="xcal:WsCalendarIntervalType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<!-- =====================================================================
+       3.7 Calendar Properties
+       ===================================================================== -->
+	<xs:complexType name="WsCalendarTypeType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:TextPropertyType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="WsCalendarAttachType" mixed="false">
+		<xs:annotation>
+			<xs:documentation>types the content of the xCal attach element</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BasePropertyType">
+				<xs:choice minOccurs="0" maxOccurs="unbounded">
+					<xs:element ref="xcal:artifact"/>
+					<xs:element ref="xcal:artifactBase"/>
+					<xs:element ref="xcal:uri"/>
+					<xs:element ref="xcal:text"/>
+				</xs:choice>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="x-wsCalendar-attach" type="xcal:WsCalendarAttachType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="x-wscalendar-type" type="xcal:WsCalendarTypeType" substitutionGroup="xcal:baseProperty"/>
+	<xs:element name="artifact" type="xcal:ArtifactType"/>
+	<xs:complexType name="ArtifactType">
+		<xs:annotation>
+			<xs:documentation>
+        The artifact is here to handle elements that are not proper extensions 
+        of wsCalendar.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:restriction base="xs:anyType">
+				<xs:anyAttribute namespace="##other" processContents="lax"/>
+			</xs:restriction>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="artifactBase" type="xcal:ArtifactBaseType" block="">
+		<xs:annotation>
+			<xs:documentation>
+        The artifact Base is here for use in extending by other specifications 
+        allowing attributes from other namespaces to be added to 
+        ws-calendar-based schemas.
+      </xs:documentation>
+		</xs:annotation>
+	</xs:element>
+	<xs:complexType name="ArtifactBaseType" abstract="true" block="">
+		<xs:annotation>
+			<xs:documentation>
+        The artifact Base is here for use in extending by other specifications, 
+        to to allow attributes from other namespaces to be added to 
+        ws-calendar-based schemas.
+      </xs:documentation>
+		</xs:annotation>
+	</xs:complexType>
+</xs:schema>
diff --git a/schemas/ical/iCalendar.rng b/schemas/ical/iCalendar.rng
new file mode 100644
index 0000000..9bdafbd
--- /dev/null
+++ b/schemas/ical/iCalendar.rng
@@ -0,0 +1,1184 @@
+# Relax NG Schema for iCalendar in XML
+
+default namespace = "urn:ietf:params:xml:ns:icalendar-2.0"
+
+# 3.2 Property Parameters
+
+# 3.2.1 Alternate Text Representation
+
+altrepparam = element altrep {
+    value-uri
+}
+
+# 3.2.2 Common Name
+
+cnparam = element cn {
+    value-text
+}
+
+# 3.2.3 Calendar User Type
+
+cutypeparam = element cutype {
+    element text {
+        "INDIVIDUAL" |
+        "GROUP" |
+        "RESOURCE" |
+        "ROOM" |
+        "UNKNOWN"
+    }
+}
+
+# 3.2.4 Delegators
+
+delfromparam = element delegated-from {
+    value-cal-address+
+}
+
+# 3.2.5 Delegatees
+
+deltoparam = element delegated-to {
+    value-cal-address+
+}
+
+# 3.2.6 Directory Entry Reference
+
+dirparam = element dir {
+    value-uri
+}
+
+# 3.2.7 Inline Encoding
+
+encodingparam = element encoding {
+    element text {
+        "8BIT" |
+        "BASE64"
+    }
+}
+
+
+# 3.2.8 Format Type
+
+fmttypeparam = element fmttype {
+    value-text
+}
+
+# 3.2.9 Free/Busy Time Type
+
+fbtypeparam = element fbtype {
+    element text {
+        "FREE" |
+        "BUSY" |
+        "BUSY-UNAVAILABLE" |
+        "BUSY-TENTATIVE"
+    }
+}
+
+# 3.2.10 Language
+
+languageparam = element language {
+    value-text
+}
+
+# 3.2.11 Group or List Membership
+
+memberparam = element member {
+    value-cal-address+
+}
+
+# 3.2.12 Participation Status
+
+partstatparam = element partstat {
+    type-partstat-event |
+    type-partstat-todo |
+    type-partstat-jour
+}
+
+type-partstat-event = (
+    element text {
+        "NEEDS-ACTION" |
+        "ACCEPTED" |
+        "DECLINED" |
+        "TENTATIVE" |
+        "DELEGATED"
+    }
+)
+
+type-partstat-todo = (
+    element text {
+        "NEEDS-ACTION" |
+        "ACCEPTED" |
+        "DECLINED" |
+        "TENTATIVE" |
+        "DELEGATED" |
+        "COMPLETED" |
+        "IN-PROCESS"
+    }
+)
+
+type-partstat-jour = (
+    element text {
+        "NEEDS-ACTION" |
+        "ACCEPTED" |
+        "DECLINED"
+    }
+)
+
+# 3.2.13 Recurrence Identifier Range
+
+rangeparam = element range {
+    element text {
+        "THISANDFUTURE"
+    }
+}
+
+# 3.2.14 Alarm Trigger Relationship
+
+trigrelparam = element related {
+    element text {
+        "START" |
+        "END"
+    }
+}
+
+# 3.2.15 Relationship Type
+
+reltypeparam = element reltype {
+    element text {
+        "PARENT" |
+        "CHILD" |
+        "SIBLING"
+    }
+}
+
+# 3.2.16 Participation Role
+
+roleparam = element role {
+    element text {
+        "CHAIR" |
+        "REQ-PARTICIPANT" |
+        "OPT-PARTICIPANT" |
+        "NON-PARTICIPANT"
+    }
+}
+
+# 3.2.17 RSVP Expectation
+
+rsvpparam = element rsvp {
+    value-boolean
+}
+
+# 3.2.18 Sent By
+
+sentbyparam = element sent-by {
+    value-cal-address
+}
+
+# 3.2.19 Time Zone Identifier
+
+tzidparam = element tzid {
+    value-text
+}
+
+# 3.3 Property Value Data Types
+
+# 3.3.1 BINARY
+
+value-binary =  element binary {
+    xsd:string
+}
+
+# 3.3.2 BOOLEAN
+
+value-boolean = element boolean {
+    xsd:boolean
+}
+
+# 3.3.3 CAL-ADDRESS
+
+value-cal-address = element cal-address {
+    xsd:anyURI
+}
+
+# 3.3.4 DATE
+
+pattern-date = xsd:string {
+    pattern = "\d\d\d\d-\d\d-\d\d"
+}
+
+value-date = element date {
+    pattern-date
+}
+
+# 3.3.5 DATE-TIME
+
+pattern-date-time = xsd:string {
+    pattern = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ?"
+}
+
+value-date-time = element date-time {
+    pattern-date-time
+}
+
+# 3.3.6 DURATION
+
+pattern-duration = xsd:string {
+    pattern = "[+\-]?P(\d+W)|(\d+D)?"
+            ~ "(T(\d+H(\d+M)?(\d+S)?)|"
+            ~   "(\d+M(\d+S)?)|"
+            ~   "(\d+S))?"
+}
+
+value-duration = element duration {
+    pattern-duration
+}
+
+# 3.3.7 FLOAT
+
+value-float = element float {
+    xsd:float
+}
+
+# 3.3.8 INTEGER
+
+value-integer = element integer {
+    xsd:integer
+}
+
+# 3.3.9 PERIOD
+
+value-period = element period {
+    element start {
+        pattern-date-time
+    },
+    (
+        element end {
+            pattern-date-time
+        } |
+        element duration {
+            pattern-duration
+        }
+    )
+}
+
+# 3.3.10 RECUR
+
+value-recur = element recur {
+    type-freq,
+    (type-until | type-count)?,
+    element interval {
+        xsd:positiveInteger
+    }?,
+    type-bysecond*,
+    type-byminute*,
+    type-byhour*,
+    type-byday*,
+    type-bymonthday*,
+    type-byyearday*,
+    type-byweekno*,
+    type-bymonth*,
+    type-bysetpos*,
+    element wkst { type-weekday }?
+}
+
+type-freq = element freq {
+    "SECONDLY" |
+    "MINUTELY" |
+    "HOURLY"   |
+    "DAILY"    |
+    "WEEKLY"   |
+    "MONTHLY"  |
+    "YEARLY"
+}
+
+type-until = element until {
+    type-date |
+    type-date-time
+}
+
+type-count = element count {
+    xsd:positiveInteger
+}
+
+type-bysecond = element bysecond {
+    xsd:positiveInteger
+}
+
+type-byminute = element byminute {
+    xsd:positiveInteger
+}
+
+type-byhour = element byhour {
+    xsd:positiveInteger
+}
+
+type-weekday = (
+    "SU" |
+    "MO" |
+    "TU" |
+    "WE" |
+    "TH" |
+    "FR" |
+    "SA"
+)
+
+type-byday = element byday {
+    xsd:integer?,
+    type-weekday
+}
+
+type-bymonthday = element bymonthday {
+    xsd:integer
+}
+
+type-byyearday = element byyearday {
+    xsd:integer
+}
+
+type-byweekno = element byweekno {
+    xsd:integer
+}
+
+type-bymonth = element bymonth {
+    xsd:positiveInteger
+}
+
+type-bysetpos = element bysetpos {
+    xsd:integer
+}
+
+# 3.3.11 TEXT
+
+value-text = element text {
+    xsd:string
+}
+
+# 3.3.12 TIME
+
+pattern-time = xsd:string {
+    pattern = "\d\d:\d\d:\d\dZ?"
+}
+
+value-time = element time {
+    pattern-time
+}
+
+# 3.3.13 URI
+
+value-uri = element uri {
+    xsd:anyURI
+}
+
+# 3.3.14 UTC-OFFSET
+
+value-utc-offset = element utc-offset {
+    xsd:string { pattern = "[+\-]\d\d:\d\d" }
+}
+
+# UNKNOWN
+
+value-unknown = element unknown {
+    xsd:string
+}
+
+# 3.4 iCalendar Stream
+
+start = element icalendar {
+    vcalendar+
+}
+
+# 3.6 Calendar Components
+
+vcalendar = element vcalendar {
+    type-calprops,
+    type-component
+}
+
+type-calprops = element properties {
+    property-prodid &
+    property-version &
+    property-calscale? &
+    property-method?
+}
+
+type-component = element components {
+    (
+        component-vevent |
+        component-vtodo |
+        component-vjournal |
+        component-vfreebusy |
+        component-vtimezone
+    )*
+}
+
+# 3.6.1 Event Component
+
+component-vevent = element vevent {
+    type-eventprop,
+    element components {
+        component-valarm+
+    }?
+}
+
+type-eventprop = element properties {
+    property-dtstamp &
+    property-dtstart &
+    property-uid &
+
+    property-class? &
+    property-created? &
+    property-description? &
+    property-geo? &
+    property-last-mod? &
+    property-location? &
+    property-organizer? &
+    property-priority? &
+    property-seq? &
+    property-status-event? &
+    property-summary? &
+    property-transp? &
+    property-url? &
+    property-recurid? &
+
+    property-rrule? &
+
+    (property-dtend | property-duration)? &
+
+    property-attach* &
+    property-attendee* &
+    property-categories* &
+    property-comment* &
+    property-contact* &
+    property-exdate* &
+    property-rstatus* &
+    property-related* &
+    property-resources* &
+    property-rdate*
+}
+
+# 3.6.2 To-do Component
+
+component-vtodo = element vtodo {
+    type-todoprop,
+    element components {
+        component-valarm+
+    }?
+}
+
+type-todoprop = element properties {
+    property-dtstamp &
+    property-uid &
+
+    property-class? &
+    property-completed? &
+    property-created? &
+    property-description? &
+    property-geo? &
+    property-last-mod? &
+    property-location? &
+    property-organizer? &
+    property-percent? &
+    property-priority? &
+    property-recurid? &
+    property-seq? &
+    property-status-todo? &
+    property-summary? &
+    property-url? &
+
+    property-rrule? &
+
+    (
+        (property-dtstart?, property-dtend? ) |
+        (property-dtstart, property-duration)?
+    ) &
+
+    property-attach* &
+    property-attendee* &
+    property-categories* &
+    property-comment* &
+    property-contact* &
+    property-exdate* &
+    property-rstatus* &
+    property-related* &
+    property-resources* &
+    property-rdate*
+}
+
+# 3.6.3 Journal Component
+
+component-vjournal = element vjournal {
+    type-jourprop
+}
+
+type-jourprop = element properties {
+    property-dtstamp &
+    property-uid &
+
+    property-class? &
+    property-created? &
+    property-dtstart? &
+    property-last-mod? &
+    property-organizer? &
+    property-recurid? &
+    property-seq? &
+    property-status-jour? &
+    property-summary? &
+    property-url? &
+
+    property-rrule? &
+
+    property-attach* &
+    property-attendee* &
+    property-categories* &
+    property-comment* &
+    property-contact* &
+    property-description? &
+    property-exdate* &
+    property-related* &
+    property-rdate* &
+    property-rstatus*
+}
+
+# 3.6.4 Free/Busy Component
+
+component-vfreebusy = element vfreebusy {
+    type-fbprop
+}
+
+type-fbprop = element properties {
+    property-dtstamp &
+    property-uid &
+    property-contact? &
+    property-dtstart? &
+    property-dtend? &
+    property-duration? &
+    property-organizer? &
+    property-url? &
+
+    property-attendee* &
+    property-comment* &
+    property-freebusy* &
+    property-rstatus*
+}
+
+# 3.6.5 Time Zone Component
+
+component-vtimezone = element vtimezone {
+    element properties {
+        property-tzid &
+
+        property-last-mod? &
+        property-tzuurl?
+    },
+    element components {
+        (component-standard | component-daylight) &
+        component-standard* &
+        component-daylight*
+    }
+}
+
+component-standard = element standard {
+    type-tzprop
+}
+
+component-daylight = element daylight {
+    type-tzprop
+}
+
+type-tzprop = element properties {
+    property-dtstart &
+    property-tzoffsetto &
+    property-tzoffsetfrom &
+
+    property-rrule? &
+
+    property-comment* &
+    property-rdate* &
+    property-tzname*
+}
+
+# 3.6.6 Alarm Component
+
+component-valarm = element valarm {
+    audioprop | dispprop | emailprop
+}
+
+type-audioprop = element properties {
+    property-action &
+    property-trigger &
+
+    (property-duration, property-repeat)? &
+
+    property-attach?
+}
+
+type-dispprop = element properties {
+    property-action &
+    property-description &
+    property-trigger &
+    property-summary &
+
+    property-attendee+ &
+
+    (property-duration, property-repeat)? &
+
+    property-attach*
+}
+
+type-emailprop = element properties {
+    property-action &
+    property-description &
+    property-trigger &
+
+    (property-duration, property-repeat)?
+}
+
+# 3.7 Calendar Properties
+
+# 3.7.1 Calendar Scale
+
+property-calscale = element calscale {
+
+    element parameters { empty }?,
+
+    element text { "GREGORIAN" }
+}
+
+# 3.7.2 Method
+
+property-method = element method {
+
+    element parameters { empty }?,
+
+    value-text
+}
+
+# 3.7.3 Product Identifier
+
+property-prodid = element prodid {
+
+    element parameters { empty }?,
+
+    value-text
+}
+
+# 3.7.4 Version
+
+property-version = element version {
+
+    element parameters { empty }?,
+
+    element text { "2.0" }
+}
+
+# 3.8 Component Properties
+
+# 3.8.1 Descriptive Component Properties
+
+# 3.8.1.1 Attachment
+
+property-attach = element attach {
+
+    element parameters {
+        fmttypeparam? &
+        encodingparam?
+    }?,
+
+    value-uri | value-binary
+}
+
+# 3.8.1.2 Categories
+
+property-categories = element categories {
+
+    element parameters {
+        languageparam? &
+    }?,
+    value-text+
+}
+
+# 3.8.1.3 Classification
+
+property-class = element class {
+
+    element parameters { empty }?,
+
+    element text {
+        "PUBLIC" |
+        "PRIVATE" |
+        "CONFIDENTIAL"
+    }
+}
+
+# 3.8.1.4 Comment
+
+property-comment = element comment {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.1.5 Description
+
+property-description = element description {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.1.6 Geographic Position
+
+property-geo = element geo {
+
+    element parameters { empty }?,
+
+    element latitude  { xsd:float },
+    element longitude { xsd:float }
+}
+
+# 3.8.1.7 Location
+
+property-location = element location {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.1.8 Percent Complete
+
+property-percent = element percent-complete {
+
+    element parameters { empty }?,
+
+    value-integer
+}
+
+# 3.8.1.9 Priority
+
+property-priority = element priority {
+
+    element parameters { empty }?,
+
+    value-integer
+}
+
+# 3.8.1.10 Resources
+
+property-resources = element resources {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text+
+}
+
+# 3.8.1.11 Status
+
+property-status-event = element status {
+
+    element parameters { empty }?,
+
+    element text {
+        "TENTATIVE" |
+        "CONFIRMED" |
+        "CANCELLED"
+    }
+}
+
+property-status-todo = element status {
+
+    element parameters { empty }?,
+
+    element text {
+        "NEEDS-ACTION" |
+        "COMPLETED" |
+        "IN-PROCESS" |
+        "CANCELLED"
+    }
+}
+
+property-status-jour = element status {
+
+    element parameters { empty }?,
+
+    element text {
+        "DRAFT" |
+        "FINAL" |
+        "CANCELLED"
+    }
+}
+
+# 3.8.1.12 Summary
+
+property-summary = element summary {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.2 Date and Time Component Properties
+
+# 3.8.2.1 Date/Time Completed
+
+property-completed = element completed {
+
+    element parameters { empty }?,
+
+    value-date-time
+}
+
+# 3.8.2.2 Date/Time End
+
+property-dtend = element dtend {
+
+    element parameters {
+        tzidparam?
+    }?,
+
+    value-date-time |
+    value-date
+}
+
+# 3.8.2.3 Date/Time Due
+
+property-due = element due {
+
+    element parameters {
+        tzidparam?
+    }?,
+
+    value-date-time |
+    value-date
+}
+
+# 3.8.2.4 Date/Time Start
+
+property-dtstart = element dtstart {
+
+    element parameters {
+        tzidparam?
+    }?,
+
+    value-date-time |
+    value-date
+}
+
+# 3.8.2.5 Duration
+
+property-duration = element duration {
+
+    element parameters { empty }?,
+    value-duration
+}
+
+# 3.8.2.6 Free/Busy Time
+
+property-freebusy = element freebusy {
+
+    element parameters {
+        fbtypeparam?
+    }?,
+
+
+    value-period+
+}
+
+# 3.8.2.7 Time Transparency
+
+property-transp = element transp {
+
+    element parameters { empty }?,
+
+    element text {
+        "OPAQUE" |
+        "TRANSPARENT"
+    }
+}
+
+# 3.8.3 Time Zone Component Properties
+
+# 3.8.3.1 Time Zone Identifier
+
+property-tzid = element tzid {
+
+    element parameters { empty }?,
+
+    value-text
+}
+
+# 3.8.3.2 Time Zone Name
+
+property-tzname = element tzname {
+
+    element parameters {
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.3.3 Time Zone Offset From
+
+property-tzoffsetfrom = element tzoffsetfrom {
+
+    element parameters { empty }?,
+
+    value-utc-offset
+}
+
+# 3.8.3.4 Time Zone Offset To
+
+property-tzoffsetto = element tzoffsetto {
+
+    element parameters { empty }?,
+
+    value-utc-offset
+}
+
+# 3.8.3.5 Time Zone URL
+
+property-tzurl = element tzurl {
+
+    element parameters { empty }?,
+
+    value-uri
+}
+
+# 3.8.4 Relationship Component Properties
+
+# 3.8.4.1 Attendee
+
+property-attendee = element attendee {
+
+    element parameters {
+        cutypeparam? &
+        memberparam? &
+        roleparam? &
+        partstatparam? &
+        rsvpparam? &
+        deltoparam? &
+        delfromparam? &
+        sentbyparam? &
+        cnparam? &
+        dirparam? &
+        languageparam?
+    }?,
+
+    value-cal-address
+}
+
+# 3.8.4.2 Contact
+
+property-contact = element contact {
+
+    element parameters {
+        altrepparam? &
+        languageparam?
+    }?,
+
+    value-text
+}
+
+# 3.8.4.3 Organizer
+
+property-organizer = element organizer {
+
+    element parameters {
+        cnparam? &
+        dirparam? &
+        sentbyparam? &
+        languageparam?
+    }?,
+
+    value-cal-address
+}
+
+# 3.8.4.4 Recurrence ID
+
+property-recurid = element recurrence-id {
+
+    element parameters {
+        tzidparam? &
+        rangeparam?
+    }?,
+
+    value-date-time |
+    value-date
+}
+
+# 3.8.4.5 Related-To
+
+property-related = element related-to {
+
+    element parameters {
+        reltypeparam?
+    }?,
+    value-text
+}
+
+# 3.8.4.6 Uniform Resource Locator
+
+property-url = element url {
+
+    element parameters { empty }?,
+
+    value-uri
+}
+
+# 3.8.4.7 Unique Identifier
+
+property-uid = element uid {
+
+    element parameters { empty }?,
+
+    value-text
+}
+
+# 3.8.5 Recurrence Component Properties
+
+# 3.8.5.1 Exception Date/Times
+
+property-exdate = element exdate {
+
+    element parameters {
+        tzidparam?
+    }?,
+
+    value-date-time+ |
+    value-date+
+}
+
+# 3.8.5.2 Recurrence Date/Times
+
+property-rdate = element rdate {
+
+    element parameters {
+        tzidparam?
+    }?,
+
+    value-date-time+ |
+    value-date+ |
+    value-period+
+}
+
+# 3.8.5.3 Recurrence Rule
+
+property-rrule = element rrule {
+
+    element parameters { empty }?,
+
+    value-recur
+}
+
+# 3.8.6 Alarm Component Properties
+
+# 3.8.6.1 Action
+
+property-action = element action {
+
+    element parameters { empty }?,
+
+    element text {
+        "AUDIO" |
+        "DISPLAY" |
+        "EMAIL"
+    }
+}
+
+# 3.8.6.2 Repeat Count
+
+property-repeat = element repeat {
+
+    element parameters { empty }?,
+
+    value-integer
+}
+
+# 3.8.6.3 Trigger
+
+property-trigger = element trigger {
+
+    (
+        element parameters {
+            trigrelparam?
+        }?,
+
+        value-duration
+    ) |
+    (
+        element parameters { empty }?,
+
+        value-date-time
+    )
+}
+
+# 3.8.7 Change Management Component Properties
+
+# 3.8.7.1 Date/Time Created
+
+property-created = element created {
+
+    element parameters { empty }?,
+
+    value-date-time
+}
+
+# 3.8.7.2 Date/Time Stamp
+
+property-dtstamp = element dtstamp {
+
+    element parameters { empty }?,
+
+    value-date-time
+}
+
+# 3.8.7.3 Last Modified
+
+property-last-mod = element last-modified {
+
+    element parameters { empty }?,
+
+    value-date-time
+}
+
+# 3.8.7.4 Sequence Number
+
+property-seq = element sequence {
+
+    element parameters { empty }?,
+
+    value-integer
+}
+
+# 3.8.8 Miscellaneous Component Properties
+
+# 3.8.8.3 Request Status
+
+property-rstatus = element request-status {
+
+    element parameters {
+        languageparam?
+    }?,
+
+    element code { xsd:string },
+    element description { xsd:string },
+    element data { xsd:string }?
+}
+
diff --git a/schemas/ical/iCalendar.xsd b/schemas/ical/iCalendar.xsd
new file mode 100644
index 0000000..def79cb
--- /dev/null
+++ b/schemas/ical/iCalendar.xsd
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     WS-Calendar Version 1.0
+     Committee Specification Draft 04 / Public Review Draft 03
+     17 June 2011
+     Source: http://docs.oasis-open.org/ws-calendar/ws-calendar-spec/v1.0/csprd03/xsd/
+     Copyright (c) The Calendaring and Scheduling Consortium 2010-2011. All Rights Reserved.
+     Copyright (c) OASIS Open 2010-2011. All Rights Reserved. -->
+
+<!-- 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. -->
+
+<!-- edited with XMLSpy v2010 rel. 3 sp1 (x64) (http://www.altova.com) by Toby Considine (TC9) -->
+<!--non-normative, to support development of WS-Calendar - 2010/10/30. Refer to rfc5545 and xCal in the IETF for normative description-->
+<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">
+	<!-- ===================== Standard Extensions =======================  -->
+	<xs:include schemaLocation="iCalendar-link-extension.xsd"/>
+	<!-- ===================== 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"/>
+	<!-- =====================================================================
+       3.4 Calendar Components
+       ===================================================================== -->
+	<xs:include schemaLocation="iCalendar-props.xsd"/>
+	<xs:complexType name="BaseComponentType" abstract="true">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        This type is the basis for all components and provides a base class for
+        applications.
+        
+        Essentially it states that a component is a set of properties.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:sequence>
+			<xs:element name="properties" type="xcal:ArrayOfProperties" minOccurs="0"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="baseComponent" type="xcal:BaseComponentType" abstract="true"/>
+	<xs:element name="vevent" type="xcal:VeventType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:element name="vtodo" type="xcal:VtodoType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:element name="vjournal" type="xcal:VjournalType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:element name="vfreebusy" type="xcal:VfreebusyType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<xs:element name="vtimezone" type="xcal:VtimezoneType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+	<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"/>
+	<!-- 3.4 iCalendar Stream -->
+	<xs:complexType name="IcalendarType">
+		<xs:sequence>
+			<xs:element name="vcalendar" type="xcal:VcalendarType" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="icalendar" type="xcal:IcalendarType"/>
+	<!-- 3.6 Calendar Components -->
+	<xs:complexType name="VcalendarType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        This type is the basis for all components and provides a base class for
+        applications.
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType">
+				<xs:sequence>
+					<xs:element name="components" type="xcal:ArrayOfVcalendarContainedComponents"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="vcalendar" type="xcal:VcalendarType"/>
+	<xs:element name="vcalendarContainedComponent" type="xcal:VcalendarContainedComponentType" abstract="true"/>
+	<xs:complexType name="ArrayOfVcalendarContainedComponents">
+		<xs:sequence>
+			<xs:element ref="xcal:vcalendarContainedComponent" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:complexType name="VcalendarContainedComponentType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        This type is the basis for all components that can be contained within
+        a vcalendar component
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.6.1 Event Component -->
+	<xs:complexType name="VeventType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:EventTodoComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="EventTodoComponentType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Events and todos only contain alarms
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType">
+				<xs:sequence>
+					<xs:element name="components" type="xcal:ArrayOfEventTodoContainedComponents"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="ArrayOfEventTodoContainedComponents">
+		<xs:sequence>
+			<xs:choice minOccurs="0" maxOccurs="unbounded">
+				<xs:element ref="xcal:valarm"/>
+			</xs:choice>
+		</xs:sequence>
+	</xs:complexType>
+	<!-- 3.6.2 To-do Component -->
+	<xs:complexType name="VtodoType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:EventTodoComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.6.3 Journal Component -->
+	<xs:complexType name="VjournalType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Journal components contain no other components
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.6.4 Free/Busy Component -->
+	<xs:complexType name="VfreebusyType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Freebusy components contain no other components
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.6.5 timezone -->
+	<xs:complexType name="VtimezoneType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Timezones only contain daylight and standard
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:VcalendarContainedComponentType">
+				<xs:sequence>
+					<xs:element name="components" type="xcal:ArrayOfTimezoneContainedComponents"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="ArrayOfTimezoneContainedComponents">
+		<xs:sequence>
+			<xs:choice minOccurs="0" maxOccurs="unbounded">
+				<xs:element ref="xcal:standard"/>
+				<xs:element ref="xcal:daylight"/>
+			</xs:choice>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:complexType name="StandardType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Standard components contain no other components
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="DaylightType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Daylight components contain no other components
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- 3.6.6 Alarm Component -->
+	<xs:complexType name="ValarmType" mixed="false">
+		<xs:complexContent>
+			<xs:extension base="xcal:AlarmComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:complexType name="AlarmComponentType" mixed="false">
+		<xs:annotation>
+			<xs:documentation xml:lang="en">
+        Alarms contain no components
+      </xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="xcal:BaseComponentType"/>
+		</xs:complexContent>
+	</xs:complexType>
+</xs:schema>


commit c249a4b477a2e191f0622dd54e303787da563b1a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon Oct 31 00:25:08 2011 +0100

    initial commit

diff --git a/c++/.gitignore b/c++/.gitignore
new file mode 100644
index 0000000..51ea4cc
--- /dev/null
+++ b/c++/.gitignore
@@ -0,0 +1 @@
+bindings/*
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
new file mode 100644
index 0000000..77458cf
--- /dev/null
+++ b/c++/CMakeLists.txt
@@ -0,0 +1,30 @@
+project(kolabxmlbindings)
+
+make_directory(bindings)
+
+set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
+set( SCHEMAS  
+    ${SCHEMA_DIR}/base.xsd 
+    ${SCHEMA_DIR}/incidence.xsd 
+    ${SCHEMA_DIR}/event.xsd 
+    ${SCHEMA_DIR}/note.xsd )
+set( SCHEMA_SOURCEFILES  
+    bindings/base.cxx
+    bindings/incidence.cxx
+    bindings/event.cxx
+    bindings/note.cxx )
+set( XSDCXX  /usr/bin/xsdcxx)
+
+add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
+    COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD --output-dir bindings ${SCHEMAS}
+    COMMENT "Generating XSD bindings"
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    VERBATIM
+    )
+
+ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
+
+include_directories( ./ )
+add_library(kolabxml lib/kolabkcalconversion.cpp ${SCHEMA_SOURCEFILES})
+
+add_subdirectory(tests)
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
new file mode 100644
index 0000000..544d66c
--- /dev/null
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -0,0 +1,359 @@
+#include "kolabkcalconversion.h"
+
+#include "bindings/incidence.hxx"
+#include <kcalcore/recurrence.h>
+#include <QtCore/QBitArray>
+#include <QtCore/QVector>
+#include <vector>
+
+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
+}
+
+//setup a KolabXSD:Recurrence from a KCalCore recurrence
+KolabXSD::Recurrence fromKCal( KCalCore::Recurrence* recur )
+{
+    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;
+    }
+    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;
+    }
+    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)
+{
+
+}
+
+
+}
+}
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
new file mode 100644
index 0000000..bd46003
--- /dev/null
+++ b/c++/lib/kolabkcalconversion.h
@@ -0,0 +1,19 @@
+#ifndef KOLABKCALTOOLS_H
+#define KOLABKCALTOOLS_H
+
+#include <bindings/incidence.hxx>
+#include <kcalcore/recurrence.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 );
+        
+    };
+};
+
+#endif
\ No newline at end of file
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
new file mode 100644
index 0000000..b816f7a
--- /dev/null
+++ b/c++/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+FIND_PACKAGE(Qt4 REQUIRED)
+
+QT4_WRAP_CPP(HEADERS_MOC kcalconversiontest.h)
+
+#add_test("conversiontest" kcalconversiontest ${kolabproxy_shared_relative_SRCS} ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} kcalconversiontest.cpp)
+add_executable(kcalconversiontest kcalconversiontest.cpp )
+
+target_link_libraries(kcalconversiontest ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_KCALCORE_LIBS} kolabxml)
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
new file mode 100644
index 0000000..b88d835
--- /dev/null
+++ b/c++/tests/kcalconversiontest.cpp
@@ -0,0 +1,226 @@
+#include "kcalconversiontest.h"
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+#include <kcalcore/recurrence.h>
+#include <lib/kolabkcalconversion.h>
+
+
+void KCalConversionTest::testConversion_data()
+{
+    /*
+    QTest::addColumn<KCalCore::Recurrence>( "kcalrecurrence" );
+    QTest::addColumn<QString>( "result" );
+    
+    KCalCore::Recurrence recurrence;
+    recurrence.setYearly(2);
+    
+    QTest::newRow( "test1" ) << recurrence;
+    */
+}
+
+uint frequency(const KolabXSD::Recurrence &r) 
+{
+   
+    return 2;
+}
+    
+void KCalConversionTest::testConversion()
+{
+  /*  QFETCH(KCalCore::Recurrence, kcalrecurrence);
+    
+    KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
+    QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
+    */
+}
+
+#if 0
+class KCalConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+      
+    void testConversion_data()
+    {
+        QTest::addColumn<QString>( "kcalrecurrence" );
+        QTest::addColumn<QString>( "result" );
+        
+        QTest::newRow( "test1" );
+    }
+    
+    void testConversion()
+    {
+        
+    }
+      
+/*
+    void testContacts_data()
+    {
+      createContactsTestSet();
+    }
+
+    void testContacts()
+    {
+      QFETCH( QString, vcardFileName );
+      QFETCH( QString, mimeFileName );
+
+      KolabHandler *handler = KolabHandler::createHandler( "contact", Collection() );
+      QVERIFY( handler );
+
+      // mime -> vcard conversion
+      const Item kolabItem = readMimeFile( mimeFileName );
+      QVERIFY( kolabItem.hasPayload() );
+
+      Item::List vcardItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
+      QCOMPARE( vcardItems.size(), 1 );
+      QVERIFY( vcardItems.first().hasPayload<KABC::Addressee>() );
+      KABC::Addressee convertedAddressee = vcardItems.first().payload<KABC::Addressee>();
+
+      QFile vcardFile( vcardFileName );
+      QVERIFY( vcardFile.open( QFile::ReadOnly ) );
+      KABC::VCardConverter converter;
+      const KABC::Addressee realAddressee = converter.parseVCard( vcardFile.readAll() );
+
+      // fix up the converted addressee for comparisson
+      convertedAddressee.setName( realAddressee.name() ); // name() apparently is something strange
+      QVERIFY( !convertedAddressee.custom( "KOLAB", "CreationDate" ).isEmpty() );
+      convertedAddressee.removeCustom( "KOLAB", "CreationDate" ); // that's conversion time !?
+      QVERIFY( normalizePhoneNumbers( convertedAddressee, realAddressee ) ); // phone number ids are random
+      QVERIFY( normalizeAddresses( convertedAddressee, realAddressee ) ); // same here
+
+//       qDebug() << convertedAddressee.toString();
+//       qDebug() << realAddressee.toString();
+      QCOMPARE( realAddressee, convertedAddressee );
+
+
+      // and now the other way around
+      Item convertedKolabItem;
+      Item vcardItem( "text/directory" );
+      vcardItem.setPayload( realAddressee );
+      handler->toKolabFormat( vcardItem, convertedKolabItem );
+      QVERIFY( convertedKolabItem.hasPayload<KMime::Message::Ptr>() );
+
+      const KMime::Message::Ptr convertedMime = convertedKolabItem.payload<KMime::Message::Ptr>();
+      const KMime::Message::Ptr realMime = kolabItem.payload<KMime::Message::Ptr>();
+
+//       qDebug() << convertedMime->encodedContent();
+//       qDebug() << realMime->encodedContent();
+      QVERIFY( compareMimeMessage( convertedMime, realMime ) );
+
+      delete handler;
+    }
+
+    void testIncidences_data()
+    {
+      createIndidenceTestSet();
+    }
+
+    void testIncidences()
+    {
+      QFETCH( QString, type );
+      QFETCH( QString, icalFileName );
+      QFETCH( QString, mimeFileName );
+
+      KolabHandler *handler = KolabHandler::createHandler( type.toLatin1(), Collection() );
+      QVERIFY( handler );
+
+      // mime -> vcard conversion
+      const Item kolabItem = readMimeFile( mimeFileName );
+      QVERIFY( kolabItem.hasPayload() );
+
+      Item::List icalItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
+      QCOMPARE( icalItems.size(), 1 );
+      QVERIFY( icalItems.first().hasPayload<KCalCore::Incidence::Ptr>() );
+      KCalCore::Incidence::Ptr convertedIncidence = icalItems.first().payload<KCalCore::Incidence::Ptr>();
+
+      QFile icalFile( icalFileName );
+      QVERIFY( icalFile.open( QFile::ReadOnly ) );
+      KCalCore::ICalFormat format;
+      const KCalCore::Incidence::Ptr realIncidence( format.fromString( QString::fromUtf8( icalFile.readAll() ) ) );
+
+      // fix up the converted incidence for comparisson
+      foreach ( KCalCore::Attendee::Ptr a, convertedIncidence->attendees() )
+        a->setUid( QString() ); // contains random values
+      foreach ( KCalCore::Attendee::Ptr a, realIncidence->attendees() )
+        a->setUid( QString() ); // contains random values
+      if ( type == "task" ) {
+        QVERIFY( icalItems.first().hasPayload<KCalCore::Todo::Ptr>() );
+        KCalCore::Todo::Ptr todo = icalItems.first().payload<KCalCore::Todo::Ptr>();
+        if ( !todo->hasDueDate() && !todo->hasStartDate() )
+          convertedIncidence->setAllDay( realIncidence->allDay() ); // all day has no meaning if there are no start and due dates but may differ nevertheless
+      }
+      // recurrence objects are created on demand, but KCalCore::Incidence::operator==() doesn't take that into account
+      // so make sure both incidences have one
+      realIncidence->recurrence();
+      convertedIncidence->recurrence();
+
+      if ( *(realIncidence.data()) != *(convertedIncidence.data()) ) {
+        qDebug() << "REAL: " << format.toString( realIncidence );
+        qDebug() << "CONVERTED: " << format.toString( convertedIncidence );
+      }
+      QVERIFY( *(realIncidence.data()) ==  *(convertedIncidence.data()) );
+
+
+      // and now the other way around
+      Item convertedKolabItem;
+      Item icalItem;
+      switch ( realIncidence->type() ) {
+        case KCalCore::IncidenceBase::TypeEvent: icalItem.setMimeType( KCalCore::Event::eventMimeType() ); return;
+        case KCalCore::IncidenceBase::TypeTodo: icalItem.setMimeType( KCalCore::Todo::todoMimeType() ); return;
+        case KCalCore::IncidenceBase::TypeJournal: icalItem.setMimeType( KCalCore::Journal::journalMimeType() ); return;
+        default: QFAIL( "incidence type not supported" );
+      }
+      icalItem.setPayload( realIncidence );
+      handler->toKolabFormat( icalItem, convertedKolabItem );
+      QVERIFY( convertedKolabItem.hasPayload<KMime::Message::Ptr>() );
+
+      const KMime::Message::Ptr convertedMime = convertedKolabItem.payload<KMime::Message::Ptr>();
+      const KMime::Message::Ptr realMime = kolabItem.payload<KMime::Message::Ptr>();
+
+//       qDebug() << convertedMime->encodedContent();
+//       qDebug() << realMime->encodedContent();
+      QVERIFY( compareMimeMessage( convertedMime, realMime ) );
+
+      delete handler;
+    }
+
+    void benchmarkContactsLoading_data()
+    {
+      createContactsTestSet();
+    }
+
+    void benchmarkContactsLoading()
+    {
+      QFETCH( QString, vcardFileName );
+      QFETCH( QString, mimeFileName );
+
+      QBENCHMARK {
+        KolabHandler *handler = KolabHandler::createHandler( "contact", Collection() );
+        const Item kolabItem = readMimeFile( mimeFileName );
+        const Item::List vcardItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
+        delete handler;
+      }
+    }
+
+    void benchmarkIncidenceLoading_data()
+    {
+      createIndidenceTestSet();
+    }
+
+    void benchmarkIncidenceLoading()
+    {
+      QFETCH( QString, type );
+      QFETCH( QString, mimeFileName );
+
+      QBENCHMARK {
+        KolabHandler *handler = KolabHandler::createHandler( type.toLatin1(), Collection() );
+        const Item kolabItem = readMimeFile( mimeFileName );
+        const Item::List icalItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
+        delete handler;
+      }
+    }*/
+};
+#endif
+QTEST_MAIN( KCalConversionTest )
+
+#include "moc_kcalconversiontest.cxx"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
new file mode 100644
index 0000000..826147f
--- /dev/null
+++ b/c++/tests/kcalconversiontest.h
@@ -0,0 +1,17 @@
+#ifndef KCALCONVERSIONTEST_H
+#define KCALCONVERSIONTEST_H
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+
+class KCalConversionTest : public QObject
+{
+  Q_OBJECT
+  private slots:
+      
+    void testConversion_data();
+    void testConversion();
+
+};
+
+#endif
\ No newline at end of file





More information about the commits mailing list