3 commits - lib/ext lib/kolab_sync_data_calendar.php lib/kolab_sync_data_contacts.php lib/kolab_sync_data_email.php lib/kolab_sync_data_gal.php lib/kolab_sync_data.php lib/kolab_sync_data_tasks.php lib/kolab_sync_logger.php lib/kolab_sync.php

Aleksander Machniak machniak at kolabsys.com
Mon Aug 27 13:03:48 CEST 2012


 lib/ext/Syncroton/Command/GetAttachment.php            |   63 +---
 lib/ext/Syncroton/Command/Options.php                  |    2 
 lib/ext/Syncroton/Command/Provision.php                |    2 
 lib/ext/Syncroton/Command/Search.php                   |   14 -
 lib/ext/Syncroton/Command/SendMail.php                 |   21 +
 lib/ext/Syncroton/Command/SmartForward.php             |   22 +
 lib/ext/Syncroton/Command/SmartReply.php               |   21 +
 lib/ext/Syncroton/Command/Sync.php                     |   11 
 lib/ext/Syncroton/Data/Contacts.php                    |   51 ++-
 lib/ext/Syncroton/Data/Email.php                       |   61 ++--
 lib/ext/Syncroton/Exception/Status.php                 |  219 +++++++++++++++++
 lib/ext/Syncroton/Exception/Status/Autodiscover.php    |   32 ++
 lib/ext/Syncroton/Exception/Status/FolderCreate.php    |   46 +++
 lib/ext/Syncroton/Exception/Status/FolderDelete.php    |   42 +++
 lib/ext/Syncroton/Exception/Status/FolderSync.php      |   40 +++
 lib/ext/Syncroton/Exception/Status/FolderUpdate.php    |   46 +++
 lib/ext/Syncroton/Exception/Status/GetItemEstimate.php |   36 ++
 lib/ext/Syncroton/Exception/Status/ItemOperations.php  |   62 ++++
 lib/ext/Syncroton/Exception/Status/MeetingResponse.php |   36 ++
 lib/ext/Syncroton/Exception/Status/Sync.php            |   54 ++++
 lib/ext/Syncroton/Model/AEntry.php                     |  178 +++++++------
 lib/ext/Syncroton/Model/Contact.php                    |  175 +++++--------
 lib/ext/Syncroton/Model/Email.php                      |  124 +++------
 lib/ext/Syncroton/Model/EmailAttachment.php            |   48 ---
 lib/ext/Syncroton/Model/EmailBody.php                  |   15 -
 lib/ext/Syncroton/Model/EmailFlag.php                  |   45 +--
 lib/ext/Syncroton/Model/Event.php                      |  107 ++------
 lib/ext/Syncroton/Model/EventAttendee.php              |   14 -
 lib/ext/Syncroton/Model/EventException.php             |   32 +-
 lib/ext/Syncroton/Model/EventRecurrence.php            |   24 -
 lib/ext/Syncroton/Model/FileReference.php              |    4 
 lib/ext/Syncroton/Model/Folder.php                     |   36 --
 lib/ext/Syncroton/Model/GAL.php                        |   68 -----
 lib/ext/Syncroton/Model/GALPicture.php                 |   44 ---
 lib/ext/Syncroton/Model/SendMail.php                   |   33 ++
 lib/ext/Syncroton/Model/SmartForward.php               |   35 ++
 lib/ext/Syncroton/Model/SmartReply.php                 |   35 ++
 lib/ext/Syncroton/Model/StoreResponse.php              |   14 -
 lib/ext/Syncroton/Model/StoreResponseResult.php        |    8 
 lib/ext/Syncroton/Model/Task.php                       |   61 +---
 lib/ext/Syncroton/Model/TaskRecurrence.php             |   30 +-
 lib/ext/Syncroton/Server.php                           |   23 +
 lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php             |    3 
 lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php   |   18 -
 lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php  |   48 +++
 lib/kolab_sync.php                                     |   18 -
 lib/kolab_sync_data.php                                |   99 +++----
 lib/kolab_sync_data_calendar.php                       |  121 +++------
 lib/kolab_sync_data_contacts.php                       |  127 ++++-----
 lib/kolab_sync_data_email.php                          |   91 +++----
 lib/kolab_sync_data_gal.php                            |   28 +-
 lib/kolab_sync_data_tasks.php                          |   38 +-
 lib/kolab_sync_logger.php                              |  100 +++++++
 53 files changed, 1628 insertions(+), 1097 deletions(-)

New commits:
commit 318c72cba4884cedcb6008b8a9dee203bf4a18d3
Author: Aleksander Machniak <alec at alec.pl>
Date:   Mon Aug 27 08:24:41 2012 +0200

    Update Syncroton

diff --git a/lib/ext/Syncroton/Command/GetAttachment.php b/lib/ext/Syncroton/Command/GetAttachment.php
index c67da76..5bf745d 100644
--- a/lib/ext/Syncroton/Command/GetAttachment.php
+++ b/lib/ext/Syncroton/Command/GetAttachment.php
@@ -15,43 +15,14 @@
  * @package     Syncroton
  * @subpackage  Command
  */
- 
-class Syncroton_Command_GetAttachment
+class Syncroton_Command_GetAttachment extends Syncroton_Command_Wbxml
 {
-    /**
-     * informations about the currently device
-     *
-     * @var Syncroton_Model_Device
-     */
-    protected $_device;
-    
-    /**
-     * timestamp to use for all sync requests
-     *
-     * @var DateTime
-     */
-    protected $_syncTimeStamp;
-    
     /**
      *
      * @var string
      */
     protected $_attachmentName;
     
-    /**
-     * the constructor
-     *
-     * @param  mixed                   $requestBody
-     * @param  Syncroton_Model_Device  $device
-     * @param  string                  $policyKey
-     */
-    public function __construct($requestBody, Syncroton_Model_IDevice $device, $policyKey)
-    {
-        $this->_policyKey     = $policyKey;
-        $this->_device        = $device;
-        $this->_syncTimeStamp = new DateTime(null, new DateTimeZone('UTC'));
-    }
-    
     /**
      * process the XML file and add, change, delete or fetches data 
      *
@@ -59,7 +30,7 @@ class Syncroton_Command_GetAttachment
      */
     public function handle()
     {
-        $this->_attachmentName = $_GET['AttachmentName'];
+        $this->_attachmentName = $this->_requestParameters['attachmentName'];
     }
     
     /**
@@ -73,22 +44,24 @@ class Syncroton_Command_GetAttachment
         
         $attachment = $dataController->getFileReference($this->_attachmentName);
         
-        // cache for 3600 seconds
-        $maxAge = 3600;
-        $now = new DateTime(null, new DateTimeZone('UTC'));
-        header('Cache-Control: private, max-age=' . $maxAge);
-        header("Expires: " . gmdate('D, d M Y H:i:s', $now->modify("+{$maxAge} sec")->getTimestamp()) . " GMT");
-        
-        // overwrite Pragma header from session
-        header("Pragma: cache");
-        
-        #header('Content-Disposition: attachment; filename="' . $filename . '"');
-        header("Content-Type: " . $attachment->ContentType);
+        if (PHP_SAPI !== 'cli') {
+            // cache for 3600 seconds
+            $maxAge = 3600;
+            $now = new DateTime(null, new DateTimeZone('UTC'));
+            header('Cache-Control: private, max-age=' . $maxAge);
+            header("Expires: " . gmdate('D, d M Y H:i:s', $now->modify("+{$maxAge} sec")->getTimestamp()) . " GMT");
+            
+            // overwrite Pragma header from session
+            header("Pragma: cache");
+            
+            #header('Content-Disposition: attachment; filename="' . $filename . '"');
+            header("Content-Type: " . $attachment->contentType);
+        }
         
-        if (is_resource($attachment->Data)) {
-            fpassthru($attachment->Data);
+        if (is_resource($attachment->data)) {
+            fpassthru($attachment->data);
         } else {
-            echo $attachment->Data;
+            echo $attachment->data;
         }
     }
 }
diff --git a/lib/ext/Syncroton/Command/Options.php b/lib/ext/Syncroton/Command/Options.php
index 35a98e7..252899c 100644
--- a/lib/ext/Syncroton/Command/Options.php
+++ b/lib/ext/Syncroton/Command/Options.php
@@ -26,7 +26,7 @@ class Syncroton_Command_Options
     {
         // same header like Exchange 2xxx???
         header('MS-Server-ActiveSync:  14.00.0536.000');
-        header("MS-ASProtocolVersions: 12.0,12.1,14.0,14.1");
+        header("MS-ASProtocolVersions: 2.5,12.0,12.1,14.0,14.1");
         header("MS-ASProtocolCommands: CreateCollection,DeleteCollection,FolderCreate,FolderDelete,FolderSync,FolderUpdate,GetAttachment,GetHierarchy,GetItemEstimate,ItemOperations,MeetingResponse,MoveCollection,MoveItems,Provision,ResolveRecipients,Ping,SendMail,Search,Settings,SmartForward,SmartReply,Sync,ValidateCert");
     }    
 }
diff --git a/lib/ext/Syncroton/Command/Provision.php b/lib/ext/Syncroton/Command/Provision.php
index b4ddf41..c4e582b 100644
--- a/lib/ext/Syncroton/Command/Provision.php
+++ b/lib/ext/Syncroton/Command/Provision.php
@@ -160,7 +160,7 @@ class Syncroton_Command_Provision extends Syncroton_Command_Wbxml
         $policy->appendChild($this->_outputDom->createElementNS('uri:Provision', 'Status', 1));
         $policy->appendChild($this->_outputDom->createElementNS('uri:Provision', 'PolicyKey', $policykey));
 
-        $this->_device->policykey = null;
+        $this->_device->policykey = $policykey;
         $this->_deviceBackend->update($this->_device);
     }
 
diff --git a/lib/ext/Syncroton/Command/Search.php b/lib/ext/Syncroton/Command/Search.php
index 7febe29..ccef6ab 100644
--- a/lib/ext/Syncroton/Command/Search.php
+++ b/lib/ext/Syncroton/Command/Search.php
@@ -57,7 +57,7 @@ class Syncroton_Command_Search extends Syncroton_Command_Wbxml
         }
         
         $storeResponse = new Syncroton_Model_StoreResponse(array(
-           'Status' => self::STATUS_SUCCESS,
+           'status' => self::STATUS_SUCCESS,
         ));
         
         try {
@@ -70,7 +70,7 @@ class Syncroton_Command_Search extends Syncroton_Command_Wbxml
             $start = $options['range'][0];
             $limit = $options['range'][1] + 1;
             $total = count($results);
-            $storeResponse->Total = $total;
+            $storeResponse->total = $total;
 
             if ($total) {
                 if ($start > $total) {
@@ -84,18 +84,18 @@ class Syncroton_Command_Search extends Syncroton_Command_Wbxml
                     $results = array_slice($results, $start, $limit-$start);
                 }
 
-                $storeResponse->Range = array($start, $start + count($results) - 1);
+                $storeResponse->range = array($start, $start + count($results) - 1);
             }
 
             foreach ($results as $result) {
-                if (empty($result->Properties)) {
-                    $result->Properties = $dataController->getSearchEntry($result->LongId, $this->_store->options);
+                if (empty($result->properties)) {
+                    $result->properties = $dataController->getSearchEntry($result->longId, $this->_store->options);
                 }
 
-                $storeResponse->Result[] = $result;
+                $storeResponse->result[] = $result;
             }
         } catch (Exception $e) {
-            $storeResponse->Status = self::STATUS_SERVER_ERROR;
+            $storeResponse->status = self::STATUS_SERVER_ERROR;
         }
 
         $search = $this->_outputDom->documentElement;
diff --git a/lib/ext/Syncroton/Command/SendMail.php b/lib/ext/Syncroton/Command/SendMail.php
index 773e27f..d1875a2 100644
--- a/lib/ext/Syncroton/Command/SendMail.php
+++ b/lib/ext/Syncroton/Command/SendMail.php
@@ -18,7 +18,7 @@
 class Syncroton_Command_SendMail extends Syncroton_Command_Wbxml
 {
     protected $_defaultNameSpace    = 'uri:ComposeMail';
-    protected $_documentElement     = 'Sendmail';
+    protected $_documentElement     = 'SendMail';
 
     protected $_saveInSent;
     protected $_source;
@@ -47,7 +47,7 @@ class Syncroton_Command_SendMail extends Syncroton_Command_Wbxml
             
             if (isset ($xml->Source)) {
                 if ($xml->Source->LongId) {
-                    $this->_source = $xml->Source->LongId;
+                    $this->_source = (string)$xml->Source->LongId;
                 } else {
                     $this->_source = array(
                         'collectionId' => (string)$xml->Source->FolderId,
@@ -70,7 +70,20 @@ class Syncroton_Command_SendMail extends Syncroton_Command_Wbxml
     public function getResponse()
     {
         $dataController = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_EMAIL, $this->_device, $this->_syncTimeStamp);
-    
-        $dataController->sendEmail($this->_mime, $this->_saveInSent);        
+
+        try {
+            $dataController->sendEmail($this->_mime, $this->_saveInSent);
+        } catch (Syncroton_Exception_Status $ses) {
+            if ($this->_logger instanceof Zend_Log)
+                $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " Sending email failed: " . $ses->getMessage());
+
+            $response = new Syncroton_Model_SendMail(array(
+                'status' => $ses->getCode(),
+            ));
+
+            $response->appendXML($this->_outputDom->documentElement);
+
+            return $this->_outputDom;
+        }
     }
 }
diff --git a/lib/ext/Syncroton/Command/SmartForward.php b/lib/ext/Syncroton/Command/SmartForward.php
index e5ce2d1..aeedff4 100644
--- a/lib/ext/Syncroton/Command/SmartForward.php
+++ b/lib/ext/Syncroton/Command/SmartForward.php
@@ -15,19 +15,33 @@
  * @package     Syncroton
  * @subpackage  Command
  */
-class Syncroton_Command_SmartForward extends Syncroton_Command_SmartReply
+class Syncroton_Command_SmartForward extends Syncroton_Command_SendMail
 {
     protected $_defaultNameSpace    = 'uri:ComposeMail';
     protected $_documentElement     = 'SmartForward';
+
     /**
      * this function generates the response for the client
-     * 
+     *
      * @return void
      */
     public function getResponse()
     {
         $dataController = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_EMAIL, $this->_device, $this->_syncTimeStamp);
-    
-        $dataController->forwardEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+
+        try {
+            $dataController->forwardEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+        } catch (Syncroton_Exception_Status $ses) {
+            if ($this->_logger instanceof Zend_Log)
+                $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " Sending email failed: " . $ses->getMessage());
+
+            $response = new Syncroton_Model_SmartForward(array(
+                'status' => $ses->getCode(),
+            ));
+
+            $response->appendXML($this->_outputDom->documentElement);
+
+            return $this->_outputDom;
+        }
     }
 }
diff --git a/lib/ext/Syncroton/Command/SmartReply.php b/lib/ext/Syncroton/Command/SmartReply.php
index f17d16d..5778581 100644
--- a/lib/ext/Syncroton/Command/SmartReply.php
+++ b/lib/ext/Syncroton/Command/SmartReply.php
@@ -19,16 +19,29 @@ class Syncroton_Command_SmartReply extends Syncroton_Command_SendMail
 {
     protected $_defaultNameSpace    = 'uri:ComposeMail';
     protected $_documentElement     = 'SmartReply';
-    
+
     /**
      * this function generates the response for the client
-     * 
+     *
      * @return void
      */
     public function getResponse()
     {
         $dataController = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_EMAIL, $this->_device, $this->_syncTimeStamp);
-    
-        $dataController->replyEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+
+        try {
+            $dataController->replyEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+        } catch (Syncroton_Exception_Status $ses) {
+            if ($this->_logger instanceof Zend_Log)
+                $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " Sending email failed: " . $ses->getMessage());
+
+            $response = new Syncroton_Model_SmartReply(array(
+                'status' => $ses->getCode(),
+            ));
+
+            $response->appendXML($this->_outputDom->documentElement);
+
+            return $this->_outputDom;
+        }
     }
 }
diff --git a/lib/ext/Syncroton/Command/Sync.php b/lib/ext/Syncroton/Command/Sync.php
index ed39123..9173e30 100644
--- a/lib/ext/Syncroton/Command/Sync.php
+++ b/lib/ext/Syncroton/Command/Sync.php
@@ -534,6 +534,8 @@ class Syncroton_Command_Sync extends Syncroton_Command_Wbxml
                         } catch (Exception $e) {
                             if ($this->_logger instanceof Zend_Log) 
                                 $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " unable to convert entry to xml: " . $e->getMessage());
+                            if ($this->_logger instanceof Zend_Log) 
+                                $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " unable to convert entry to xml: " . $e->getTraceAsString());
                             $fetch->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'Status', self::STATUS_OBJECT_NOT_FOUND));
                         }
                     }
diff --git a/lib/ext/Syncroton/Data/Contacts.php b/lib/ext/Syncroton/Data/Contacts.php
index b592d49..1b8718a 100644
--- a/lib/ext/Syncroton/Data/Contacts.php
+++ b/lib/ext/Syncroton/Data/Contacts.php
@@ -28,7 +28,8 @@ class Syncroton_Data_Contacts extends Syncroton_Data_AData implements Syncroton_
         
         return new Syncroton_Model_GAL(array(
             'firstName' => $contact->firstName,
-            'lastName'  => $contact->lastName
+            'lastName'  => $contact->lastName,
+            'picture'   => new Syncroton_Model_GALPicture(array('status' => 1, 'data' => 'abc'))
         ));
     }
     
@@ -47,8 +48,8 @@ class Syncroton_Data_Contacts extends Syncroton_Data_AData implements Syncroton_
             
             if ($contact->firstName == $query) {
                 $found[] = new Syncroton_Model_StoreResponseResult(array(
-                    'LongId' => 'addressbookFolderId-' .  $serverId,
-                    'Properties' => $this->getSearchEntry('addressbookFolderId-' .  $serverId, $options)
+                    'longId' => 'addressbookFolderId-' .  $serverId,
+                    'properties' => $this->getSearchEntry('addressbookFolderId-' .  $serverId, $options)
                 ));
             }
         }
diff --git a/lib/ext/Syncroton/Data/Email.php b/lib/ext/Syncroton/Data/Email.php
index 96e7a19..9c84aae 100644
--- a/lib/ext/Syncroton/Data/Email.php
+++ b/lib/ext/Syncroton/Data/Email.php
@@ -2,7 +2,8 @@
 /**
  * Syncroton
  *
- * @package     Model
+ * @package     Syncroton
+ * @subpackage  Data
  * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
  * @copyright   Copyright (c) 2009-2012 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Lars Kneschke <l.kneschke at metaways.de>
@@ -13,14 +14,12 @@
  *
  * @package     Model
  */
-
 class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Data_IDataEmail
 {
     /**
      * used by unit tests only to simulated added folders
      */
-    public static $entries = array(
-    );
+    public static $entries = array();
     
     /**
      * (non-PHPdoc)
@@ -28,17 +27,22 @@ class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Dat
      */
     public function forwardEmail($source, $inputStream, $saveInSent, $replaceMime)
     {
+        if ($inputStream == 'triggerException') {
+            throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAILBOX_SERVER_OFFLINE);
+        }
+        
         // forward email
     }
     
+    /**
+     * (non-PHPdoc)
+     * @see Syncroton_Data_AData::getFileReference()
+     */
     public function getFileReference($fileReference)
     {
         list($messageId, $partId) = explode('-', $fileReference, 2);
     
         // example code
-        //$file = $this->_imapBackend->getMessagePart($messageId, $partId);
-    
-        // example code
         return new Syncroton_Model_FileReference(array(
             'contentType' => 'text/plain',
             'data'        => 'Lars'
@@ -54,6 +58,10 @@ class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Dat
         // forward email
     }
     
+    /**
+     * (non-PHPdoc)
+     * @see Syncroton_Data_AData::updateEntry()
+     */
     public function updateEntry($_folderId, $_serverId, Syncroton_Model_IEntry $_entry)
     {
         // not used by email
@@ -65,6 +73,9 @@ class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Dat
      */
     public function sendEmail($inputStream, $saveInSent)
     {
+        if ($inputStream == 'triggerException') {
+            throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAILBOX_SERVER_OFFLINE);
+        }
         // send email
     }
     
diff --git a/lib/ext/Syncroton/Exception/Status.php b/lib/ext/Syncroton/Exception/Status.php
new file mode 100644
index 0000000..2a21ef3
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Exception for Status element
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status extends Syncroton_Exception
+{
+    // http://msdn.microsoft.com/en-us/library/ee218647%28v=exchg.80%29
+    const INVALID_CONTENT                    = 101;
+    const INVALID_WBXML                      = 102;
+    const INVALID_XML                        = 103;
+    const INVALID_DATE_TIME                  = 104;
+    const INVALID_COMBINATION_OF_IDS         = 105;
+    const INVALID_IDS                        = 106;
+    const INVALID_MIME                       = 107;
+    const DEVICE_MISSING_OR_INVALID          = 108;
+    const DEVICE_TYPE_MISSING_OR_INVALID     = 109;
+    const SERVER_ERROR                       = 110;
+    const SERVER_ERROR_RETRY_LATER           = 111;
+    const ACTIVE_DIRECTORY_ACCESS_DENIED     = 112;
+    const MAILBOX_QUOTA_EXCEEDED             = 113;
+    const MAILBOX_SERVER_OFFLINE             = 114;
+    const SEND_QUOTA_EXCEEDED                = 115;
+    const MESSAGE_RECIPIENT_UNRESOLVED       = 116;
+    const MESSAGE_REPLY_NOT_ALLOWED          = 117;
+    const MESSAGE_PREVIOUSLY_SENT            = 118;
+    const MESSAGE_HAS_NO_RECIPIENT           = 119;
+    const MAIL_SUBMISSION_FAILED             = 120;
+    const MESSAGE_REPLY_FAILED               = 121;
+    const ATTACHMENT_IS_TOO_LARGE            = 122;
+    const USER_HAS_NO_MAILBOX                = 123;
+    const USER_CANNOT_BE_ANONYMOUS           = 124;
+    const USER_PRINCIPAL_COULD_NOT_BE_FOUND  = 125;
+    const USER_DISABLED_FOR_SYNC             = 126;
+    const USER_ON_NEW_MAILBOX_CANNOT_SYNC    = 127;
+    const USER_ON_LEGACY_MAILBOX_CANNOT_SYNC = 128;
+    const DEVICE_IS_BLOCKED_FOR_THIS_USER    = 129;
+    const ACCESS_DENIED                      = 130;
+    const ACCOUNT_DISABLED                   = 131;
+    const SYNC_STATE_NOT_FOUND               = 132;
+    const SYNC_STATE_LOCKED                  = 133;
+    const SYNC_STATE_CORRUPT                 = 134;
+    const SYNC_STATE_ALREADY_EXISTS          = 135;
+    const SYNC_STATE_VERSION_INVALID         = 136;
+    const COMMAND_NOT_SUPPORTED              = 137;
+    const VERSION_NOT_SUPPORTED              = 138;
+    const DEVICE_NOT_FULLY_PROVISIONABLE     = 139;
+    const REMOTE_WIPE_REQUESTED              = 140;
+    const LEGACY_DEVICE_ON_STRICT_POLICY     = 141;
+    const DEVICE_NOT_PROVISIONED             = 142;
+    const POLICY_REFRESH                     = 143;
+    const INVALID_POLICY_KEY                 = 144;
+    const EXTERNALLY_MANAGED_DEVICES_NOT_ALLOWED = 145;
+    const NO_RECURRENCE_IN_CALENDAR          = 146;
+    const UNEXPECTED_ITEM_CLASS              = 147;
+    const REMOTE_SERVER_HAS_NO_SSL           = 148;
+    const INVALID_STORED_REQUEST             = 149;
+    const ITEM_NOT_FOUND                     = 150;
+    const TOO_MANY_FOLDERS                   = 151;
+    const NO_FOLDERS_FOUND                   = 152;
+    const ITEMS_LOST_AFTER_MOVE              = 153;
+    const FAILURE_IN_MOVE_OPERATION          = 154;
+    const MOVE_COMMAND_DISALLOWED            = 155;
+    const MOVE_COMMAND_INVALID_DESTINATION   = 156;
+    const AVAILABILITY_TO_MANY_RECIPIENTS    = 160;
+    const AVAILABILITY_DL_LIMIT_REACHED      = 161;
+    const AVAILABILITY_TRANSIENT_FAILURE     = 162;
+    const AVAILABILITY_FAILURE               = 163;
+    const BODY_PART_PREFERENCE_TYPE_NOT_SUPPORTED = 164;
+    const DEVICE_INFORMATION_REQUIRED        = 165;
+    const INVALID_ACCOUNT_ID                 = 166;
+    const ACCOUNT_SEND_DISABLED              = 167;
+    CONST IRM_FEATURE_DISABLED               = 168;
+    const IRM_TRANSIENT_ERROR                = 169;
+    const IRM_PERMANENT_ERROR                = 170;
+    const IRM_INVALID_TEMPLATE_ID            = 171;
+    const IRM_OPERATION_NOT_PERMITTED        = 172;
+    const NO_PICTURE                         = 173;
+    const PICTURE_TO_LARGE                   = 174;
+    const PICTURE_LIMIT_REACHED              = 175;
+    const BODY_PART_CONVERSATION_TOO_LARGE   = 176;
+    const MAXIMUM_DEVICES_REACHED            = 177;
+
+    /**
+     * Common error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_commonMessages = array(
+        self::INVALID_CONTENT                    => "Invalid request body",
+        self::INVALID_WBXML                      => "Invalid WBXML request",
+        self::INVALID_XML                        => "Invalid XML request",
+        self::INVALID_DATE_TIME                  => "Invalid datetime string",
+        self::INVALID_COMBINATION_OF_IDS         => "Invalid combination of parameters",
+        self::INVALID_IDS                        => "Invalid one or more IDs",
+        self::INVALID_MIME                       => "Invalid MIME content",
+        self::DEVICE_MISSING_OR_INVALID          => "Device ID invalid or missing",
+        self::DEVICE_TYPE_MISSING_OR_INVALID     => "Device type invalid or missing",
+        self::SERVER_ERROR                       => "Unknown server error",
+        self::SERVER_ERROR_RETRY_LATER           => "Unknown server error. Device should retry later",
+        self::ACTIVE_DIRECTORY_ACCESS_DENIED     => "No access to an object in the directory service",
+        self::MAILBOX_QUOTA_EXCEEDED             => "The mailbox quota size exceeded",
+        self::MAILBOX_SERVER_OFFLINE             => "The mailbox server is offline",
+        self::SEND_QUOTA_EXCEEDED                => "The request would exceed the send quota",
+        self::MESSAGE_RECIPIENT_UNRESOLVED       => "Recipient could not be resolved to an e-mail address",
+        self::MESSAGE_REPLY_NOT_ALLOWED          => "The mailbox server doesn't allow a reply of this message",
+        self::MESSAGE_PREVIOUSLY_SENT            => "The message was already sent in a previous request",
+        self::MESSAGE_HAS_NO_RECIPIENT           => "The message being sent contains no recipient",
+        self::MAIL_SUBMISSION_FAILED             => "The server failed to submit the message for delivery",
+        self::MESSAGE_REPLY_FAILED               => "The server failed to create a reply message",
+        self::ATTACHMENT_IS_TOO_LARGE            => "The attachment is too large",
+        self::USER_HAS_NO_MAILBOX                => "A mailbox could not be found for the user",
+        self::USER_CANNOT_BE_ANONYMOUS           => "The request was sent without credentials. Anonymous requests are not allowed",
+        self::USER_PRINCIPAL_COULD_NOT_BE_FOUND  => "The user was not found in the directory service",
+        self::USER_DISABLED_FOR_SYNC             => "This user is not allowed to use ActiveSync",
+        self::USER_ON_NEW_MAILBOX_CANNOT_SYNC    => "The server is configured to prevent users from syncing",
+        self::USER_ON_LEGACY_MAILBOX_CANNOT_SYNC => "The server is configured to prevent users on legacy servers from syncing",
+        self::DEVICE_IS_BLOCKED_FOR_THIS_USER    => "This device is not the allowed device",
+        self::ACCESS_DENIED                      => "The user is not allowed to perform that request",
+        self::ACCOUNT_DISABLED                   => "The user's account is disabled",
+        self::SYNC_STATE_NOT_FOUND               => "Missing data file that contains the state of the client",
+        self::SYNC_STATE_LOCKED                  => "Locked data file that contains the state of the client",
+        self::SYNC_STATE_CORRUPT                 => "Corrupted data file that contains the state of the client",
+        self::SYNC_STATE_ALREADY_EXISTS          => "The data file that contains the state of the client already exists",
+        self::SYNC_STATE_VERSION_INVALID         => "Version of the data file that contains the state of the client is invalid",
+        self::COMMAND_NOT_SUPPORTED              => "The command is not supported by this server",
+        self::VERSION_NOT_SUPPORTED              => "The command is not supported in the protocol version specified",
+        self::DEVICE_NOT_FULLY_PROVISIONABLE     => "The device uses a protocol version that cannot send all the policy settings the admin enabled",
+        self::REMOTE_WIPE_REQUESTED              => "A remote wipe was requested",
+        self::LEGACY_DEVICE_ON_STRICT_POLICY     => "A policy is in place but the device is not provisionable",
+        self::DEVICE_NOT_PROVISIONED             => "There is a policy in place",
+        self::POLICY_REFRESH                     => "The policy is configured to be refreshed every few hours",
+        self::INVALID_POLICY_KEY                 => "The device's policy key is invalid",
+        self::EXTERNALLY_MANAGED_DEVICES_NOT_ALLOWED => "The server doesn't allow externally managed devices to sync",
+        self::NO_RECURRENCE_IN_CALENDAR          => "The request tried to forward an occurrence of a meeting that has no recurrence",
+        self::UNEXPECTED_ITEM_CLASS              => "The request tried to operate on a type of items unknown to the server",
+        self::REMOTE_SERVER_HAS_NO_SSL           => "Remote server doesn't have SSL enabled",
+        self::INVALID_STORED_REQUEST             => "The stored result is invalid. The device should send the full request again",
+        self::ITEM_NOT_FOUND                     => "Item not found",
+        self::TOO_MANY_FOLDERS                   => "The mailbox contains too many folders",
+        self::NO_FOLDERS_FOUND                   => "The mailbox contains no folders",
+        self::ITEMS_LOST_AFTER_MOVE              => "Items lost after move",
+        self::FAILURE_IN_MOVE_OPERATION          => "The mailbox server returned an unknown error while moving items",
+        self::MOVE_COMMAND_DISALLOWED             => "An ItemOperations command request to move a conversation is missing the MoveAlways element",
+        self::MOVE_COMMAND_INVALID_DESTINATION   => "The destination folder for the move is invalid",
+        self::AVAILABILITY_TO_MANY_RECIPIENTS    => "The command has reached the maximum number of recipients that it can request availability for",
+        self::AVAILABILITY_DL_LIMIT_REACHED      => "The size of the distribution list is larger than the availability service is configured to process",
+        self::AVAILABILITY_TRANSIENT_FAILURE     => "Availability service request failed with a transient error",
+        self::AVAILABILITY_FAILURE               => "Availability service request failed with an error",
+        self::BODY_PART_PREFERENCE_TYPE_NOT_SUPPORTED => "The BodyPartPreference node has an unsupported Type element",
+        self::DEVICE_INFORMATION_REQUIRED        => "The required DeviceInformation element is missing in the Provision request",
+        self::INVALID_ACCOUNT_ID                 => "Invalid AccountId value",
+        self::ACCOUNT_SEND_DISABLED              => "The AccountId value specified in the request does not support sending e-mail",
+        self::IRM_FEATURE_DISABLED               => "The Information Rights Management feature is disabled",
+        self::IRM_TRANSIENT_ERROR                => "Information Rights Management encountered a transient error",
+        self::IRM_PERMANENT_ERROR                => "Information Rights Management encountered a permanent error",
+        self::IRM_INVALID_TEMPLATE_ID            => "The Template ID value is not valid",
+        self::IRM_OPERATION_NOT_PERMITTED        => "Information Rights Management does not support the specified operation",
+        self::NO_PICTURE                         => "The user does not have a contact photo",
+        self::PICTURE_TO_LARGE                   => "The contact photo exceeds the size limit set by the MaxSize element",
+        self::PICTURE_LIMIT_REACHED              => "The number of contact photos returned exceeds the size limit set by the MaxPictures element",
+        self::BODY_PART_CONVERSATION_TOO_LARGE   => "The conversation is too large to compute the body parts",
+        self::MAXIMUM_DEVICES_REACHED            => "The user's account has too many device partnerships",
+    );
+
+    /**
+     * Error messages assigned to class-specific error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array();
+
+
+    /**
+     * Constructor
+     */
+    function __construct()
+    {
+        $args = func_get_args();
+
+        if (isset($args[1])) {
+            $code    = $args[1];
+            $message = $args[0];
+        } elseif (is_int($args[0])) {
+            $code    = $args[0];
+            $message = null;
+        } else {
+            $message = $args[0];
+        }
+
+        if (!$code) {
+            $code = self::SERVER_ERROR;
+        }
+
+        if (!$message) {
+            if (isset($this->_errorMessages[$code])) {
+                $message = $this->_errorMessages[$code];
+            } elseif (isset($this->_commonMessages[$code])) {
+                $message = $this->_commonMessages[$code];
+            }
+        }
+
+        parent::__construct($message, $code);
+    }
+}
diff --git a/lib/ext/Syncroton/Exception/Status/Autodiscover.php b/lib/ext/Syncroton/Exception/Status/Autodiscover.php
new file mode 100644
index 0000000..de33bf3
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/Autodiscover.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in Autodiscover response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_Autodiscover extends Syncroton_Exception_Status
+{
+    const PROTOCOL_ERROR = 2;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::PROTOCOL_ERROR => "Protocol error",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/FolderCreate.php b/lib/ext/Syncroton/Exception/Status/FolderCreate.php
new file mode 100644
index 0000000..708e2e1
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/FolderCreate.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in FolderCreate response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_FolderCreate extends Syncroton_Exception_Status
+{
+    const FOLDER_EXISTS       = 2;
+    const SPECIAL_FOLDER      = 3;
+    const PARENT_NOT_FOUND    = 5;
+    const FOLDER_SERVER_ERROR = 6;
+    const INVALID_SYNCKEY     = 9;
+    const INVALID_REQUEST     = 10;
+    const UNKNOWN_ERROR       = 11;
+    const UNKNOWN_CODE        = 12;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::FOLDER_EXISTS       => "A folder that has this name already exists",
+        self::SPECIAL_FOLDER      => "The specified folder is a special system folder",
+        self::PARENT_NOT_FOUND    => "The specified parent folder was not found",
+        self::FOLDER_SERVER_ERROR => "An error occurred on the server",
+        self::INVALID_SYNCKEY     => "Synchronization key mismatch or invalid synchronization key",
+        self::INVALID_REQUEST     => "Malformed request",
+        self::UNKNOWN_ERROR       => "An unknown error occurred",
+        self::UNKNOWN_CODE        => "Unusual back-end issue",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/FolderDelete.php b/lib/ext/Syncroton/Exception/Status/FolderDelete.php
new file mode 100644
index 0000000..c8a3a4b
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/FolderDelete.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in FolderDelete response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_FolderDelete extends Syncroton_Exception_Status
+{
+    const SPECIAL_FOLDER      = 3;
+    const FOLDER_NOT_FOUND    = 4;
+    const FOLDER_SERVER_ERROR = 6;
+    const INVALID_SYNCKEY     = 9;
+    const INVALID_REQUEST     = 10;
+    const UNKNOWN_ERROR       = 11;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::SPECIAL_FOLDER      => "The specified folder is a special system folder",
+        self::FOLDER_NOT_FOUND    => "The specified folder doesn't exist",
+        self::FOLDER_SERVER_ERROR => "An error occurred on the server",
+        self::INVALID_SYNCKEY     => "Synchronization key mismatch or invalid synchronization key",
+        self::INVALID_REQUEST     => "Malformed request",
+        self::UNKNOWN_ERROR       => "An unknown error occurred",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/FolderSync.php b/lib/ext/Syncroton/Exception/Status/FolderSync.php
new file mode 100644
index 0000000..bcd2418
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/FolderSync.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in FolderSync response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_FolderSync extends Syncroton_Exception_Status
+{
+    const FOLDER_SERVER_ERROR = 6;
+    const INVALID_SYNCKEY     = 9;
+    const INVALID_REQUEST     = 10;
+    const UNKNOWN_ERROR       = 11;
+    const UNKNOWN_CODE        = 12;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::FOLDER_SERVER_ERROR => "An error occurred on the server",
+        self::INVALID_SYNCKEY     => "Synchronization key mismatch or invalid synchronization key",
+        self::INVALID_REQUEST     => "Malformed request",
+        self::UNKNOWN_ERROR       => "An unknown error occurred",
+        self::UNKNOWN_CODE        => "Unusual back-end issue",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/FolderUpdate.php b/lib/ext/Syncroton/Exception/Status/FolderUpdate.php
new file mode 100644
index 0000000..63c629c
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/FolderUpdate.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in FolderUpdate response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_FolderUpdate extends Syncroton_Exception_Status
+{
+    const FOLDER_EXISTS       = 2;
+    const SPECIAL_FOLDER      = 3;
+    const FOLDER_NOT_FOUND    = 4;
+    const PARENT_NOT_FOUND    = 5;
+    const FOLDER_SERVER_ERROR = 6;
+    const INVALID_SYNCKEY     = 9;
+    const INVALID_REQUEST     = 10;
+    const UNKNOWN_ERROR       = 11;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::FOLDER_EXISTS       => "A folder that has this name already exists or is a special folder",
+        self::SPECIAL_FOLDER      => "The specified folder is the Recipient information folder which cannot be updated",
+        self::FOLDER_NOT_FOUND    => "The specified folder doesn't exist",
+        self::PARENT_NOT_FOUND    => "The specified parent folder was not found",
+        self::FOLDER_SERVER_ERROR => "An error occurred on the server",
+        self::INVALID_SYNCKEY     => "Synchronization key mismatch or invalid synchronization key",
+        self::INVALID_REQUEST     => "Malformed request",
+        self::UNKNOWN_ERROR       => "An unknown error occurred",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/GetItemEstimate.php b/lib/ext/Syncroton/Exception/Status/GetItemEstimate.php
new file mode 100644
index 0000000..d4b5685
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/GetItemEstimate.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Exception for Status element in GetItemEstimate response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_GetItemEstimate extends Syncroton_Exception_Status
+{
+    const INVALID_COLLECTION   = 2;
+    const SYNCSTATE_NOT_PRIMED = 3;
+    const INVALID_SYNCKEY      = 4;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::INVALID_COLLECTION   => "A collection was invalid or one of the specified collection IDs was invalid",
+        self::SYNCSTATE_NOT_PRIMED => "The synchronization state has not been primed",
+        self::INVALID_SYNCKEY      => "The specified synchronization key was invalid",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/ItemOperations.php b/lib/ext/Syncroton/Exception/Status/ItemOperations.php
new file mode 100644
index 0000000..94aa1fe
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/ItemOperations.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Exception for Status element in ItemOperations response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_ItemOperations extends Syncroton_Exception_Status
+{
+    const PROTOCOL_ERROR         = 2;
+    const ITEM_SERVER_ERROR      = 3;
+    const DOCLIB_INVALID_URI     = 4;
+    const DOCLIB_ACCESS_DENIED   = 5;
+    const DOCLIB_NOT_FOUND       = 6;
+    const DOCLIB_CONN_FAILED     = 7;
+    const INVALID_BYTE_RANGE     = 8;
+    const UNKNOWN_STORE          = 9;
+    const FILE_EMPTY             = 10;
+    const DATA_TOO_LARGE         = 11;
+    const FILE_IO_ERROR          = 12;
+    const CONVERSION_ERROR       = 14;
+    const INVALID_ATTACHMENT     = 15;
+    const RESOURCE_ACCESS_DENIED = 16;
+    const PARTIAL_SUCCESS        = 17;
+    const CREDENTIALS_REQUIRED   = 18;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::PROTOCOL_ERROR         => "Protocol error - protocol violation/XML validation error",
+        self::ITEM_SERVER_ERROR      => "Server error",
+        self::DOCLIB_INVALID_URI     => "Document library access - The specified URI is bad",
+        self::DOCLIB_ACCESS_DENIED   => "Document library - Access denied",
+        self::DOCLIB_NOT_FOUND       => "Document library - The object was not found or access denied",
+        self::DOCLIB_CONN_FAILED     => "Document library - Failed to connect to the server",
+        self::INVALID_BYTE_RANGE     => "The byte-range is invalid or too large",
+        self::UNKNOWN_STORE          => "The store is unknown or unsupported",
+        self::FILE_EMPTY             => "The file is empty",
+        self::DATA_TOO_LARGE         => "The requested data size is too large",
+        self::FILE_IO_ERROR          => "Failed to download file because of input/output (I/O) failure",
+        self::CONVERSION_ERROR       => "Mailbox fetch provider - The item failed conversion",
+        self::INVALID_ATTACHMENT     => "Attachment fetch provider - Attachment or attachment ID is invalid",
+        self::RESOURCE_ACCESS_DENIED => "Access to the resource is denied",
+        self::PARTIAL_SUCCESS        => "Partial success; the command completed partially",
+        self::CREDENTIALS_REQUIRED   => "Credentials required",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/MeetingResponse.php b/lib/ext/Syncroton/Exception/Status/MeetingResponse.php
new file mode 100644
index 0000000..34eb6e0
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/MeetingResponse.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in MeetingResponse response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_MeetingResponse extends Syncroton_Exception_Status
+{
+    const INVALID_REQUEST       = 2;
+    const MEETING_SERVER_ERROR  = 3;
+    const MEETING_ERROR         = 4;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::INVALID_REQUEST       => "Invalid meeting request",
+        self::MEETING_SERVER_ERROR  => "An error occurred on the server mailbox",
+        self::MEETING_ERROR         => "An error occurred on the server",
+    );
+}
diff --git a/lib/ext/Syncroton/Exception/Status/Sync.php b/lib/ext/Syncroton/Exception/Status/Sync.php
new file mode 100644
index 0000000..12998c4
--- /dev/null
+++ b/lib/ext/Syncroton/Exception/Status/Sync.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * exception for Status element in Sync response
+ *
+ * @package     Syncroton
+ * @subpackage  Exception
+ */
+class Syncroton_Exception_Status_Sync extends Syncroton_Exception_Status
+{
+    const INVALID_SYNCKEY     = 3;
+    const PROTOCOL_ERROR      = 4;
+    const SYNC_SERVER_ERROR   = 5;
+    const INVALID_ITEM        = 6;
+    const OBJECT_CONFLICT     = 7;
+    const OBJECT_NOT_FOUND    = 8;
+    const SYNC_ERROR          = 9;
+    const HIERARCHY_CHANGED   = 12;
+    const INCOMPLETE_REQUEST  = 13;
+    const INVALID_INTERVAL    = 14;
+    const INVALID_REQUEST     = 15;
+    const SYNC_RETRY          = 16;
+
+    /**
+     * Error messages assigned to error codes
+     *
+     * @var array
+     */
+    protected $_errorMessages = array(
+        self::INVALID_SYNCKEY     => "Invalid synchronization key",
+        self::PROTOCOL_ERROR      => "Protocol error",
+        self::SYNC_SERVER_ERROR   => "Server error",
+        self::INVALID_ITEM        => "Error in client/server conversion",
+        self::OBJECT_CONFLICT     => "Conflict matching the client and server object",
+        self::OBJECT_NOT_FOUND    => "Object not found",
+        self::SYNC_ERROR          => "The Sync command cannot be completed",
+        self::HIERARCHY_CHANGED   => "The folder hierarchy has changed",
+        self::INCOMPLETE_REQUEST  => "The Sync command request is not complete",
+        self::INVALID_INTERVAL    => "Invalid Wait or HeartbeatInterval value",
+        self::INVALID_REQUEST     => "Too many collections are included in the Sync request",
+        self::SYNC_RETRY          => "Something on the server caused a retriable error",
+    );
+}
diff --git a/lib/ext/Syncroton/Model/AEntry.php b/lib/ext/Syncroton/Model/AEntry.php
index a6b7965..79cfb9a 100644
--- a/lib/ext/Syncroton/Model/AEntry.php
+++ b/lib/ext/Syncroton/Model/AEntry.php
@@ -163,10 +163,13 @@ abstract class Syncroton_Model_AEntry implements Syncroton_Model_IEntry, Iterato
      * @param unknown_type $_domParrent
      */
     protected function _addXMLNamespaces(DOMElement $_domParrent)
-    {
-        foreach($this->_properties as $namespace => $namespaceProperties) {
-            $_domParrent->ownerDocument->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:'.$namespace, 'uri:'.$namespace);
-        }
+    {
+        foreach($this->_properties as $namespace => $namespaceProperties) {
+            // don't add default namespace again
+            if($_domParrent->ownerDocument->documentElement->namespaceURI != 'uri:'.$namespace) {
+                $_domParrent->ownerDocument->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:'.$namespace, 'uri:'.$namespace);
+            }
+        }
     }
     
     protected function _appendXMLElement($element, $elementProperties, $value)
diff --git a/lib/ext/Syncroton/Model/Email.php b/lib/ext/Syncroton/Model/Email.php
index cfdefa9..2ef7da2 100644
--- a/lib/ext/Syncroton/Model/Email.php
+++ b/lib/ext/Syncroton/Model/Email.php
@@ -78,113 +78,4 @@ class Syncroton_Model_Email extends Syncroton_Model_AEntry
             'umUserNotes'           => array('type' => 'string'),
         ),
     );
-    
-    protected function _parseAirSyncBaseNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from AirSyncBase namespace
-        $children = $properties->children('uri:AirSyncBase');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Body':
-                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
-    
-                    break;
-    
-                default:
-                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-    
-                    switch ($properties['type']) {
-                        case 'datetime':
-                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
-    
-                            break;
-    
-                        case 'number':
-                            $this->$elementName = (int) $xmlElement;
-    
-                            break;
-                        default:
-                            $this->$elementName = (string) $xmlElement;
-    
-                            break;
-                    }
-            }
-        }
-    }
-    
-    protected function _parseEmailNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from AirSyncBase namespace
-        $children = $properties->children('uri:Email');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Body':
-                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
-    
-                    break;
-
-                case 'Flag':
-                    $this->$elementName = new Syncroton_Model_EmailFlag($xmlElement);
-                    break;
-
-                default:
-                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-    
-                    switch ($properties['type']) {
-                        case 'datetime':
-                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
-    
-                            break;
-    
-                        case 'number':
-                            $this->$elementName = (int) $xmlElement;
-    
-                            break;
-                        default:
-                            $this->$elementName = (string) $xmlElement;
-    
-                            break;
-                    }
-            }
-        }
-    }
-    
-    protected function _parseEmail2Namespace(SimpleXMLElement $properties)
-    {
-        // fetch data from AirSyncBase namespace
-        $children = $properties->children('uri:Email2');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Body':
-                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
-    
-                    break;
-    
-                default:
-                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-    
-                    switch ($properties['type']) {
-                        case 'datetime':
-                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
-    
-                            break;
-    
-                        case 'number':
-                            $this->$elementName = (int) $xmlElement;
-    
-                            break;
-                        default:
-                            $this->$elementName = (string) $xmlElement;
-    
-                            break;
-                    }
-            }
-        }
-    }
 }
diff --git a/lib/ext/Syncroton/Model/SendMail.php b/lib/ext/Syncroton/Model/SendMail.php
new file mode 100644
index 0000000..b11d9b9
--- /dev/null
+++ b/lib/ext/Syncroton/Model/SendMail.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Model
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab SYstems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Class to handle ActiveSync SendMail element
+ *
+ * @package    Syncroton
+ * @subpackage Model
+ */
+class Syncroton_Model_SendMail extends Syncroton_Model_AEntry
+{
+    protected $_properties = array(
+        'ComposeMail' => array(
+            'accountId'       => array('type' => 'string'),
+            'clientId'        => array('type' => 'string'),
+            'mime'            => array('type' => 'byteArray'),
+            'saveInSentItems' => array('type' => 'string'),
+            'status'          => array('type' => 'number'),
+        ),
+        'RightsManagement' => array(
+            'templateID'      => array('type' => 'string'),
+        )
+    );
+}
diff --git a/lib/ext/Syncroton/Model/SmartForward.php b/lib/ext/Syncroton/Model/SmartForward.php
new file mode 100644
index 0000000..40ae481
--- /dev/null
+++ b/lib/ext/Syncroton/Model/SmartForward.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Model
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 KolabSYstems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Class to handle ActiveSync SmartForward element
+ *
+ * @package    Syncroton
+ * @subpackage Model
+ */
+class Syncroton_Model_SmartForward extends Syncroton_Model_AEntry
+{
+    protected $_properties = array(
+        'ComposeMail' => array(
+            'accountId'       => array('type' => 'string'),
+            'clientId'        => array('type' => 'string'),
+            'mime'            => array('type' => 'byteArray'),
+            'replaceMime'     => array('type' => 'string'),
+            'saveInSentItems' => array('type' => 'string'),
+            'source'          => array('type' => 'container'), // or string
+            'status'          => array('type' => 'number'),
+        ),
+        'RightsManagement' => array(
+            'templateID'      => array('type' => 'string'),
+        )
+    );
+}
diff --git a/lib/ext/Syncroton/Model/SmartReply.php b/lib/ext/Syncroton/Model/SmartReply.php
new file mode 100644
index 0000000..b61cbc6
--- /dev/null
+++ b/lib/ext/Syncroton/Model/SmartReply.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Model
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2012 Kolab Systems AG (http://www.kolabsys.com)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ * @author      Aleksander Machniak <machniak at kolabsys.com>
+ */
+
+/**
+ * Class to handle ActiveSync SmartReply element
+ *
+ * @package    Syncroton
+ * @subpackage Model
+ */
+class Syncroton_Model_SmartReply extends Syncroton_Model_AEntry
+{
+    protected $_properties = array(
+        'ComposeMail' => array(
+            'accountId'       => array('type' => 'string'),
+            'clientId'        => array('type' => 'string'),
+            'mime'            => array('type' => 'byteArray'),
+            'replaceMime'     => array('type' => 'string'),
+            'saveInSentItems' => array('type' => 'string'),
+            'source'          => array('type' => 'container'), // or string
+            'status'          => array('type' => 'number'),
+        ),
+        'RightsManagement' => array(
+            'templateID'      => array('type' => 'string'),
+        )
+    );
+}
diff --git a/lib/ext/Syncroton/Model/StoreResponse.php b/lib/ext/Syncroton/Model/StoreResponse.php
index 35c030e..2708f0f 100644
--- a/lib/ext/Syncroton/Model/StoreResponse.php
+++ b/lib/ext/Syncroton/Model/StoreResponse.php
@@ -37,10 +37,10 @@ class Syncroton_Model_StoreResponse extends Syncroton_Model_AEntry
 
     protected $_properties = array(
         'Search' => array(
-            'Status'    => array('type' => 'number'),
-            'Result'    => array('type' => 'container', 'multiple' => true),
-            'Range'     => array('type' => 'string'),
-            'Total'     => array('type' => 'number'),
+            'status'    => array('type' => 'number'),
+            'result'    => array('type' => 'container', 'multiple' => true),
+            'range'     => array('type' => 'string'),
+            'total'     => array('type' => 'number'),
         )
     );
 
@@ -59,7 +59,7 @@ class Syncroton_Model_StoreResponse extends Syncroton_Model_AEntry
             $nameSpace = 'uri:' . $nameSpace;
 
             switch ($elementName) {
-                case 'Result':
+                case 'result':
                     foreach ($value as $result) {
                         $element = $_domParrent->ownerDocument->createElementNS($nameSpace, 'Result');
                         $result->appendXML($element);
@@ -67,13 +67,13 @@ class Syncroton_Model_StoreResponse extends Syncroton_Model_AEntry
                     }
                     break;
 
-                case 'Range':
+                case 'range':
                     if (is_array($value) && count($value) == 2) {
                         $value = implode('-', $value);
                     }
 
                 default:
-                    $element = $_domParrent->ownerDocument->createElementNS($nameSpace, $elementName);
+                    $element = $_domParrent->ownerDocument->createElementNS($nameSpace, ucfirst($elementName));
                     $element->appendChild($_domParrent->ownerDocument->createTextNode($value));
                     $_domParrent->appendChild($element);
             }
diff --git a/lib/ext/Syncroton/Model/StoreResponseResult.php b/lib/ext/Syncroton/Model/StoreResponseResult.php
index b79f863..292fed8 100644
--- a/lib/ext/Syncroton/Model/StoreResponseResult.php
+++ b/lib/ext/Syncroton/Model/StoreResponseResult.php
@@ -20,12 +20,12 @@ class Syncroton_Model_StoreResponseResult extends Syncroton_Model_AEntry
 
     protected $_properties = array(
         'AirSync' => array(
-            'Class'        => array('type' => 'string'),
-            'CollectionId' => array('type' => 'string'),
+            'class'        => array('type' => 'string'),
+            'collectionId' => array('type' => 'string'),
         ),
         'Search' => array(
-            'LongId'     => array('type' => 'string'),
-            'Properties' => array('type' => 'container'),
+            'longId'     => array('type' => 'string'),
+            'properties' => array('type' => 'container'),
         )
     );
 }
diff --git a/lib/ext/Syncroton/Server.php b/lib/ext/Syncroton/Server.php
index 862614c..a1f4f55 100644
--- a/lib/ext/Syncroton/Server.php
+++ b/lib/ext/Syncroton/Server.php
@@ -107,8 +107,12 @@ class Syncroton_Server
             try {
                 $decoder = new Syncroton_Wbxml_Decoder($this->_body);
                 $requestBody = $decoder->decode();
-                if ($this->_logger instanceof Zend_Log) 
-                    $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml request: " . $requestBody->saveXML());
+                if ($this->_logger instanceof Zend_Log) {
+                    $requestBody->formatOutput = true;
+                    // remove not important XML information
+                    $request_str = preg_replace('|(</*)([a-z0-9]+:)?([a-z0-9]+)[^>]*>|i', '\\1\\3>', $requestBody->saveXML());
+                    $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml request:\n" . trim($request_str));
+                }
             } catch(Syncroton_Wbxml_Exception_UnexpectedEndOfFile $e) {
                 $requestBody = NULL;
             }
@@ -162,8 +166,12 @@ class Syncroton_Server
         }
         
         if ($response instanceof DOMDocument) {
-            if ($this->_logger instanceof Zend_Log) 
-                $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml response: " . $response->saveXML());
+            if ($this->_logger instanceof Zend_Log) {
+                $response->formatOutput = true;
+                // remove not important XML information
+                $response_str = preg_replace('|(</*)([a-z0-9]+:)?([a-z0-9]+)[^>]*>|i', '\\1\\3>', $response->saveXML());
+                $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml response:\n" . trim($response_str));
+            }
         
             $outputStream = fopen("php://temp", 'r+');
         
@@ -275,7 +283,6 @@ class Syncroton_Server
             $deviceType = fread($stream, $deviceTypeLength);
             
             // @todo parse command parameters 
-            
             $result = array(
                 'protocolVersion' => $protocolVersion,
                 'command'         => $command,
@@ -283,7 +290,8 @@ class Syncroton_Server
                 'deviceType'      => $deviceType,
                 'saveInSent'      => null,
                 'collectionId'    => null,
-                'itemId'          => null
+                'itemId'          => null,
+                'attachmentName'  => null
             );
         } else {
             $result = array(
@@ -293,7 +301,8 @@ class Syncroton_Server
                 'deviceType'      => $request->getQuery('DeviceType'),
                 'saveInSent'      => $request->getQuery('SaveInSent'),
                 'collectionId'    => $request->getQuery('CollectionId'),
-                'itemId'          => $request->getQuery('ItemId')
+                'itemId'          => $request->getQuery('ItemId'),
+                'attachmentName'  => $request->getQuery('AttachmentName'),
             );
         }
         
diff --git a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
index 98d0466..fb4768e 100755
--- a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
+++ b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
@@ -40,7 +40,7 @@ class Syncroton_Wbxml_Dtd_ActiveSync
     const CODEPAGE_SETTINGS          = 18;
     const CODEPAGE_DOCUMENTLIBRARY   = 19;
     const CODEPAGE_ITEMOPERATIONS    = 20;
-    const CODEPAGE_COMPOSEEMAIL      = 21;
+    const CODEPAGE_COMPOSEMAIL       = 21;
     const CODEPAGE_EMAIL2            = 22;
     const CODEPAGE_NOTES             = 23;
     const CODEPAGE_RIGHTSMANAGEMENT  = 24;
diff --git a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php
new file mode 100644
index 0000000..58d5fb9
--- /dev/null
+++ b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage24.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Syncroton
+ *
+ * @package     Wbxml
+ * @subpackage  ActiveSync
+ * @license     http://www.tine20.org/licenses/lgpl.html LGPL Version 3
+ * @copyright   Copyright (c) 2012-2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Lars Kneschke <l.kneschke at metaways.de>
+ */
+
+/**
+ * class documentation
+ *
+ * @package     Wbxml
+ * @subpackage  ActiveSync
+ */
+ 
+class Syncroton_Wbxml_Dtd_ActiveSync_CodePage24 extends Syncroton_Wbxml_Dtd_ActiveSync_Abstract
+{
+    protected $_codePageNumber  = 24;
+    
+    protected $_codePageName    = 'RightsManagement';
+        
+    protected $_tags = array(     
+        'RightsManagementSupport'            => 0x05,
+        'RightsManagementTemplates'          => 0x06,
+        'RightsManagementTemplate'           => 0x07,
+        'RightsManagementLicense'            => 0x08,
+        'ReplyAllowed'                       => 0x09,
+        'EditAllowed'                        => 0x0a,
+        'ReplyAllAllowed'                    => 0x0b,
+        'ForwardAllowed'                     => 0x0c,
+        'ModifyRecipientsAllowed'            => 0x0d,
+        'ExtractAllowed'                     => 0x0e,
+        'PrintAllowed'                       => 0x0f,
+        'ExportAllowed'                      => 0x10,
+        'ProgrammaticAccessAllowed'          => 0x11,
+        'RMOwner'                            => 0x12,
+        'ContentExpiryDate'                  => 0x13,
+        'TemplateName'                       => 0x14,
+        'TemplateID'                         => 0x15,
+        'TemplateDescription'                => 0x16,
+        'ContentOwner'                       => 0x17,
+        'RemoveRightsManagementDistribution' => 0x18
+    );
+    
+}
\ No newline at end of file


commit 04edd25fb68993fcda0ce947aa0689dd3ea5496f
Author: Aleksander Machniak <alec at alec.pl>
Date:   Thu Aug 23 14:49:44 2012 +0200

    Added logger class

diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php
index 35f2f83..2fb9b61 100644
--- a/lib/kolab_sync.php
+++ b/lib/kolab_sync.php
@@ -53,22 +53,8 @@ class kolab_sync extends rcube
     public function startup()
     {
         // Initialize Syncroton Logger
-        $this->logger = new Zend_Log();
-
-        if ($this->config->get('activesync_debug')) {
-            $priority = Zend_Log::DEBUG;
-            $log_file = 'logs/console';
-        }
-        else {
-            $priority = Zend_Log::ERR; // Zend_Log::WARN
-            $log_file = 'logs/errors';
-        }
-
-        $writer = new Zend_Log_Writer_Stream($log_file);
-        $filter = new Zend_Log_Filter_Priority($priority);
-
-        $this->logger->addWriter($writer);
-        $this->logger->addFilter($filter);
+        $debug_mode   = $this->config->get('activesync_debug') ? kolab_sync_logger::DEBUG : kolab_sync_logger::WARN;
+        $this->logger = new kolab_sync_logger($debug_mode);
     }
 
 
diff --git a/lib/kolab_sync_logger.php b/lib/kolab_sync_logger.php
new file mode 100644
index 0000000..d7a3807
--- /dev/null
+++ b/lib/kolab_sync_logger.php
@@ -0,0 +1,100 @@
+<?php
+/*
+ +--------------------------------------------------------------------------+
+ | Kolab Sync (ActiveSync for Kolab)                                        |
+ |                                                                          |
+ | Copyright (C) 2011-2012, Kolab Systems AG                                |
+ |                                                                          |
+ | This program is free software: you can redistribute it and/or modify     |
+ | it under the terms of the GNU Affero General Public License as published |
+ | by the Free Software Foundation, either version 3 of the License, or     |
+ | (at your option) any later version.                                      |
+ |                                                                          |
+ | This program is distributed in the hope that it will be useful,          |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of           |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             |
+ | GNU Affero General Public License for more details.                      |
+ |                                                                          |
+ | You should have received a copy of the GNU Affero General Public License |
+ | along with this program. If not, see <http://www.gnu.org/licenses/>      |
+ +--------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak at kolabsys.com>                      |
+ +--------------------------------------------------------------------------+
+*/
+
+/**
+ * Class for logging messages into log file(s)
+ */
+class kolab_sync_logger extends Zend_Log
+{
+    private static $mode;
+
+    /**
+     * Constructor
+     */
+    function __construct($mode = null)
+    {
+        self::$mode = intval($mode);
+
+        $r = new ReflectionClass($this);
+        $this->_priorities = $r->getConstants();
+    }
+
+    public function __call($method, $params)
+    {
+        $method = strtoupper($method);
+        if ($this->_priorities[$method] <= self::$mode) {
+            $this->log(array_shift($params), $method);
+        }
+    }
+
+    /**
+     * Message logger
+     *
+     * @param string $message Log message
+     * @param int    $mode    Message severity
+     */
+    public function log($message, $method)
+    {
+        $rcube   = rcube::get_instance();
+        $logfile = $rcube->config->get('activesync_log_file');
+        $format  = $rcube->config->get('log_date_format', 'd-M-Y H:i:s O');
+        $mode    = $this->_priorities[$method];
+
+        // if log_file is configured all logs will go to it
+        // otherwise use separate file for info/debug and warning/error
+        if (!$logfile) {
+            switch ($mode) {
+            case self::DEBUG:
+            case self::INFO:
+            case self::NOTICE:
+                $file = 'console';
+                break;
+            default:
+                $file = 'errors';
+                break;
+            }
+
+            $logfile = dirname(__FILE__) . '/../logs/' . $file;
+        }
+
+        if (!is_string($message)) {
+            $message = var_export($message, true);
+        }
+
+        $date    = date($format);
+        $logline = sprintf("[%s]: [%s] %s\n", $date, $method, $message);
+
+        if ($fp = @fopen($logfile, 'a')) {
+            fwrite($fp, $logline);
+            fflush($fp);
+            fclose($fp);
+            return;
+        }
+
+        if ($mode <= self::WARN) {
+            // send error to PHPs error handler if write to file didn't succeed
+            trigger_error($message, E_USER_ERROR);
+        }
+    }
+}


commit 6772ebd0223eff2773c972fc9de22b3ba5e524c6
Author: Aleksander Machniak <alec at alec.pl>
Date:   Thu Aug 23 09:39:54 2012 +0200

    Update Syncroton, update code for API changes

diff --git a/lib/ext/Syncroton/Command/Sync.php b/lib/ext/Syncroton/Command/Sync.php
index e9fead9..ed39123 100644
--- a/lib/ext/Syncroton/Command/Sync.php
+++ b/lib/ext/Syncroton/Command/Sync.php
@@ -103,6 +103,8 @@ class Syncroton_Command_Sync extends Syncroton_Command_Wbxml
      */
     protected $_syncState;
     
+    protected $_maxWindowSize = 100;
+    
     /**
      * process the XML file and add, change, delete or fetches data 
      */
@@ -113,6 +115,10 @@ class Syncroton_Command_Sync extends Syncroton_Command_Wbxml
         
         $this->_globalWindowSize = isset($xml->WindowSize) ? (int)$xml->WindowSize : 100;
         
+        if ($this->_globalWindowSize > $this->_maxWindowSize) {
+            $this->_globalWindowSize = $this->_maxWindowSize;
+        }
+        
         foreach ($xml->Collections->Collection as $xmlCollection) {
             $collectionData = new Syncroton_Model_SyncCollection($xmlCollection);
             
@@ -468,13 +474,12 @@ class Syncroton_Command_Sync extends Syncroton_Command_Wbxml
                 }
                 
                 
-                
-                
                 if (!empty($clientModifications['added']) || !empty($clientModifications['changed']) || !empty($clientModifications['deleted']) ||
                     !empty($serverModifications['added']) || !empty($serverModifications['changed']) || !empty($serverModifications['deleted'])) {
                     $collectionData->syncState->counter++;
                 }
                 
+
                 // collection header
                 $collection = $collections->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'Collection'));
                 if (!empty($collectionData->folder->class)) {
diff --git a/lib/ext/Syncroton/Data/Contacts.php b/lib/ext/Syncroton/Data/Contacts.php
index 133ae00..b592d49 100644
--- a/lib/ext/Syncroton/Data/Contacts.php
+++ b/lib/ext/Syncroton/Data/Contacts.php
@@ -27,8 +27,8 @@ class Syncroton_Data_Contacts extends Syncroton_Data_AData implements Syncroton_
         $contact = $this->getEntry(new Syncroton_Model_SyncCollection(array('collectionId' => $collectionId)), $serverId);
         
         return new Syncroton_Model_GAL(array(
-            'FirstName' => $contact->FirstName,
-            'LastName'  => $contact->LastName
+            'firstName' => $contact->firstName,
+            'lastName'  => $contact->lastName
         ));
     }
     
@@ -45,7 +45,7 @@ class Syncroton_Data_Contacts extends Syncroton_Data_AData implements Syncroton_
         foreach ($serverIds as $serverId) {
             $contact = $this->getEntry(new Syncroton_Model_SyncCollection(array('collectionId' => 'addressbookFolderId')), $serverId);
             
-            if ($contact->FirstName == $query) {
+            if ($contact->firstName == $query) {
                 $found[] = new Syncroton_Model_StoreResponseResult(array(
                     'LongId' => 'addressbookFolderId-' .  $serverId,
                     'Properties' => $this->getSearchEntry('addressbookFolderId-' .  $serverId, $options)
@@ -89,44 +89,44 @@ class Syncroton_Data_Contacts extends Syncroton_Data_AData implements Syncroton_
             $testData = array(
                 'addressbookFolderId' => array(
                     'contact1' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Lars', 
-                        'LastName'  => 'Kneschke'
+                        'firstName' => 'Lars', 
+                        'lastName'  => 'Kneschke'
                     )),
                     'contact2' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Cornelius', 
-                        'LastName'  => 'Weiß'
+                        'firstName' => 'Cornelius', 
+                        'lastName'  => 'Weiß'
                     )),
                     'contact3' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Lars', 
-                        'LastName'  => 'Kneschke'
+                        'firstName' => 'Lars', 
+                        'lastName'  => 'Kneschke'
                     )),
                     'contact4' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Cornelius', 
-                        'LastName'  => 'Weiß'
+                        'firstName' => 'Cornelius', 
+                        'lastName'  => 'Weiß'
                     )),
                     'contact5' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Lars', 
-                        'LastName'  => 'Kneschke'
+                        'firstName' => 'Lars', 
+                        'lastName'  => 'Kneschke'
                     )),
                     'contact6' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Cornelius', 
-                        'LastName'  => 'Weiß'
+                        'firstName' => 'Cornelius', 
+                        'lastName'  => 'Weiß'
                     )),
                     'contact7' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Lars', 
-                        'LastName'  => 'Kneschke'
+                        'firstName' => 'Lars', 
+                        'lastName'  => 'Kneschke'
                     )),
                     'contact8' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Cornelius', 
-                        'LastName'  => 'Weiß'
+                        'firstName' => 'Cornelius', 
+                        'lastName'  => 'Weiß'
                     )),
                     'contact9' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Lars', 
-                        'LastName'  => 'Kneschke'
+                        'firstName' => 'Lars', 
+                        'lastName'  => 'Kneschke'
                     )),
                     'contact10' => new Syncroton_Model_Contact(array(
-                        'FirstName' => 'Cornelius', 
-                        'LastName'  => 'Weiß'
+                        'firstName' => 'Cornelius', 
+                        'lastName'  => 'Weiß'
                     ))
                 )
             );
diff --git a/lib/ext/Syncroton/Data/Email.php b/lib/ext/Syncroton/Data/Email.php
index 9765a7b..96e7a19 100644
--- a/lib/ext/Syncroton/Data/Email.php
+++ b/lib/ext/Syncroton/Data/Email.php
@@ -40,8 +40,8 @@ class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Dat
     
         // example code
         return new Syncroton_Model_FileReference(array(
-            'ContentType' => 'text/plain',
-            'Data'        => 'Lars'
+            'contentType' => 'text/plain',
+            'data'        => 'Lars'
         ));
     }
     
@@ -100,25 +100,25 @@ class Syncroton_Data_Email extends Syncroton_Data_AData implements Syncroton_Dat
             $testData = array(
                 'emailInboxFolderId' => array(
                     'email1' => new Syncroton_Model_Email(array(
-                        'AccountId'    => 'FooBar',
-                        'Attachments'  => array(
+                        'accountId'    => 'FooBar',
+                        'attachments'  => array(
                             new Syncroton_Model_EmailAttachment(array(
-                                'FileReference' => '12345abcd',
-                                'UmAttOrder'    => 1
+                                'fileReference' => '12345abcd',
+                                'umAttOrder'    => 1
                             ))
                         ),
-                        'Categories'   => array('123', '456'),
-                        'Cc'           => 'l.kneschke at metaways.de',
-                        'DateReceived' => new DateTime('2012-03-21 14:00:00', new DateTimeZone('UTC')), 
-                        'From'         => 'k.kneschke at metaways.de',
-                        'Subject'      => 'Test Subject',
-                        'To'           => 'j.kneschke at metaways.de',
-                        'Read'         => 1,
-                        'Body'         => new Syncroton_Model_EmailBody(array(
-                            'Type'              => Syncroton_Model_EmailBody::TYPE_PLAINTEXT, 
-                            'Data'              => 'Hello!', 
-                            'Truncated'         => true, 
-                            'EstimatedDataSize' => 600
+                        'categories'   => array('123', '456'),
+                        'cc'           => 'l.kneschke at metaways.de',
+                        'dateReceived' => new DateTime('2012-03-21 14:00:00', new DateTimeZone('UTC')), 
+                        'from'         => 'k.kneschke at metaways.de',
+                        'subject'      => 'Test Subject',
+                        'to'           => 'j.kneschke at metaways.de',
+                        'read'         => 1,
+                        'body'         => new Syncroton_Model_EmailBody(array(
+                            'type'              => Syncroton_Model_EmailBody::TYPE_PLAINTEXT, 
+                            'data'              => 'Hello!', 
+                            'truncated'         => true, 
+                            'estimatedDataSize' => 600
                         ))
                     )),
                 )
diff --git a/lib/ext/Syncroton/Model/AEntry.php b/lib/ext/Syncroton/Model/AEntry.php
index 6950563..a6b7965 100644
--- a/lib/ext/Syncroton/Model/AEntry.php
+++ b/lib/ext/Syncroton/Model/AEntry.php
@@ -62,21 +62,25 @@ abstract class Syncroton_Model_AEntry implements Syncroton_Model_IEntry, Iterato
                 #$value = $this->removeControlChars($value);
             }
             
-            $element = $_domParrent->ownerDocument->createElementNS($nameSpace, ucfirst($elementName));
-            
-            if (is_array($value)) {
+            if (isset($elementProperties['childElement'])) {
+                $element = $_domParrent->ownerDocument->createElementNS($nameSpace, ucfirst($elementName));
                 foreach($value as $subValue) {
-                    $subElement = $_domParrent->ownerDocument->createElementNS($nameSpace, $elementProperties['childName']);
+                    $subElement = $_domParrent->ownerDocument->createElementNS($nameSpace, ucfirst($elementProperties['childElement']));
                     
-                    $this->_appendXMLElement($subElement, array(), $subValue);
+                    $this->_appendXMLElement($subElement, $elementProperties, $subValue);
                     
                     $element->appendChild($subElement);
+                    
                 }
+                $_domParrent->appendChild($element);
             } else {
+                $element = $_domParrent->ownerDocument->createElementNS($nameSpace, ucfirst($elementName));
+                
                 $this->_appendXMLElement($element, $elementProperties, $value);
+                
+                $_domParrent->appendChild($element);
             }
             
-            $_domParrent->appendChild($element);
         }
     }
     
@@ -127,37 +131,32 @@ abstract class Syncroton_Model_AEntry implements Syncroton_Model_IEntry, Iterato
             }
         }
     }
-
-    /**
-     * set properties from SimpleXMLElement object
-     *
-     * @param SimpleXMLElement $xmlCollection
-     * @throws InvalidArgumentException
-     */
-    public function setFromSimpleXMLElement(SimpleXMLElement $properties)
-    {
+    
+    /**
+     * set properties from SimpleXMLElement object
+     *
+     * @param SimpleXMLElement $xmlCollection
+     * @throws InvalidArgumentException
+     */
+    public function setFromSimpleXMLElement(SimpleXMLElement $properties)
+    {
         if (!in_array($properties->getName(), (array) $this->_xmlBaseElement)) {
-            throw new InvalidArgumentException('Unexpected element name: ' . $properties->getName());
-        }
-
-        $this->_elements = array();
-
+            throw new InvalidArgumentException('Unexpected element name: ' . $properties->getName());
+        }
+    
+        $this->_elements = array();
+    
         foreach (array_keys($this->_properties) as $namespace) {
             if ($namespace == 'Internal') {
                 continue;
             }
-
-            $functionName = '_parse' . $namespace . 'Namespace';
-            if (method_exists($this, $functionName)) {
-                $this->$functionName($properties);
-            } else {
-                $this->_parseNamespace($properties, $namespace);
-            }
-        }
-
-        return;
+            
+            $this->_parseNamespace($namespace, $properties);
+        }
+    
+        return;
     }
-
+    
     /**
      * add needed xml namespaces to DomDocument
      * 
@@ -205,55 +204,69 @@ abstract class Syncroton_Model_AEntry implements Syncroton_Model_IEntry, Iterato
             }
         }
         
-        throw new InvalidArgumentException("$element is no valid property of this object");
-    }
-
-    protected function _parseElement(SimpleXMLElement $xmlElement)
-    {
-        list($namespace, $properties) = $this->_getElementProperties($xmlElement->getName());
-
-        switch ($properties['type']) {
-            case 'datetime':
-                $value = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
-                break;
-
-            case 'number':
-                $value = (int) $xmlElement;
-                break;
-
-            default:
-                $value = (string) $xmlElement;
-        }
-
-        return $value;
+        throw new InvalidArgumentException("$element is no valid property of " . get_class($this));
     }
-
-    protected function _parseNamespace(SimpleXMLElement $properties, $namespace)
-    {
-        $children = $properties->children('uri:' . $namespace);
-
-        foreach ($children as $elementName => $xmlElement) {
-            $this->$elementName = $this->_parseElement($xmlElement);
-        }
-    }
-
-    protected function _parseAirSyncBaseNamespace(SimpleXMLElement $properties)
+    
+    protected function _parseNamespace($nameSpace, SimpleXMLElement $properties)
     {
-        // fetch data from AirSyncBase namespace
-        $children = $properties->children('uri:AirSyncBase');
-
+        // fetch data from Contacts namespace
+        $children = $properties->children("uri:$nameSpace");
+        
         foreach ($children as $elementName => $xmlElement) {
-            switch ($elementName) {
-                case 'Body':
-                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
+            $elementName = lcfirst($elementName);
+            
+            if (!isset($this->_properties[$nameSpace][$elementName])) {
+                continue;
+            }
+            
+            list (, $elementProperties) = $this->_getElementProperties($elementName);
+            
+            switch ($elementProperties['type']) {
+                case 'container':
+                    if (isset($elementProperties['childElement'])) {
+                        $property = array();
+                        
+                        $childElement = ucfirst($elementProperties['childElement']);
+                        
+                        foreach ($xmlElement->$childElement as $subXmlElement) {
+                            if (isset($elementProperties['class'])) {
+                                $property[] = new $elementProperties['class']($subXmlElement);
+                            } else {
+                                $property[] = (string) $subXmlElement;
+                            }
+                        }
+                    } else {
+                        $subClassName = isset($elementProperties['class']) ? $elementProperties['class'] : get_class($this) . ucfirst($elementName);
+                        
+                        $property = new $subClassName($xmlElement);
+                    }
+                    
                     break;
-
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
+                    
+                case 'datetime':
+                    $property = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
+    
+                    break;
+    
+                case 'number':
+                    $property = (int) $xmlElement;
+    
+                    break;
+                    
+                default:
+                    $property = (string) $xmlElement;
+    
+                    break;
             }
-        }
+            
+            if (isset($elementProperties['encoding']) && $elementProperties['encoding'] == 'base64') {
+                $property = base64_decode($property);
+            }
+            
+            $this->$elementName = $property;
+        }
     }
-
+    
     public function &__get($name)
     {
         $this->_getElementProperties($name);
@@ -263,12 +276,12 @@ abstract class Syncroton_Model_AEntry implements Syncroton_Model_IEntry, Iterato
     
     public function __set($name, $value)
     {
-        list ($namespace, $properties) = $this->_getElementProperties($name);
-    
+        list ($nameSpace, $properties) = $this->_getElementProperties($name);
+        
         if ($properties['type'] == 'datetime' && !$value instanceof DateTime) {
             throw new InvalidArgumentException("value for $name must be an instance of DateTime");
         }
-    
+        
         $this->_elements[$name] = $value;
     }
     
diff --git a/lib/ext/Syncroton/Model/Contact.php b/lib/ext/Syncroton/Model/Contact.php
index c81fcfd..047628f 100644
--- a/lib/ext/Syncroton/Model/Contact.php
+++ b/lib/ext/Syncroton/Model/Contact.php
@@ -30,119 +30,74 @@ class Syncroton_Model_Contact extends Syncroton_Model_AEntry
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'Body'                   => array('type' => 'container')
+            'body'                   => array('type' => 'container', 'class' => 'Syncroton_Model_EmailBody')
         ),
         'Contacts' => array(
-            'Alias'                  => array('type' => 'string'),
-            'Anniversary'            => array('type' => 'datetime'),
-            'AssistantName'          => array('type' => 'string'),
-            'AssistantPhoneNumber'   => array('type' => 'string'),
-            'Birthday'               => array('type' => 'datetime'),
-            //'BodySize'              => 0x0a,
-            //'BodyTruncated'         => 0x0b,
-            'Business2PhoneNumber'   => array('type' => 'string'),
-            'BusinessAddressCity'    => array('type' => 'string'),
-            'BusinessAddressCountry' => array('type' => 'string'),
-            'BusinessAddressPostalCode' => array('type' => 'string'),
-            'BusinessAddressState'   => array('type' => 'string'),
-            'BusinessAddressStreet'  => array('type' => 'string'),
-            'BusinessFaxNumber'      => array('type' => 'string'),
-            'BusinessPhoneNumber'    => array('type' => 'string'),
-            'CarPhoneNumber'         => array('type' => 'string'),
-            'Categories'             => array('type' => 'container', 'childName' => 'Category'),
-            //'Category'              => array('type' => 'string'),
-            'Children'               => array('type' => 'container', 'childName' => 'Child'),
-            //'Child'                 => array('type' => 'string'),
-            'CompanyName'            => array('type' => 'string'),
-            'Department'             => array('type' => 'string'),
-            'Email1Address'          => array('type' => 'string'),
-            'Email2Address'          => array('type' => 'string'),
-            'Email3Address'          => array('type' => 'string'),
-            'FileAs'                 => array('type' => 'string'),
-            'FirstName'              => array('type' => 'string'),
-            'Home2PhoneNumber'       => array('type' => 'string'),
-            'HomeAddressCity'        => array('type' => 'string'),
-            'HomeAddressCountry'     => array('type' => 'string'),
-            'HomeAddressPostalCode'  => array('type' => 'string'),
-            'HomeAddressState'       => array('type' => 'string'),
-            'HomeAddressStreet'      => array('type' => 'string'),
-            'HomeFaxNumber'          => array('type' => 'string'),
-            'HomePhoneNumber'        => array('type' => 'string'),
-            'JobTitle'               => array('type' => 'string'),
-            'LastName'               => array('type' => 'string'),
-            'MiddleName'             => array('type' => 'string'),
-            'MobilePhoneNumber'      => array('type' => 'string'),
-            'OfficeLocation'         => array('type' => 'string'),
-            'OtherAddressCity'       => array('type' => 'string'),
-            'OtherAddressCountry'    => array('type' => 'string'),
-            'OtherAddressPostalCode' => array('type' => 'string'),
-            'OtherAddressState'      => array('type' => 'string'),
-            'OtherAddressStreet'     => array('type' => 'string'),
-            'PagerNumber'            => array('type' => 'string'),
-            'Picture'                => array('type' => 'string', 'encoding' => 'base64'),
-            'RadioPhoneNumber'       => array('type' => 'string'),
-            'Rtf'                    => array('type' => 'string'),
-            'Spouse'                 => array('type' => 'string'),
-            'Suffix'                 => array('type' => 'string'),
-            'Title'                  => array('type' => 'string'),
-            'WebPage'                => array('type' => 'string'),
-            'WeightedRank'           => array('type' => 'string'),
-            'YomiCompanyName'        => array('type' => 'string'),
-            'YomiFirstName'          => array('type' => 'string'),
-            'YomiLastName'           => array('type' => 'string'),
+            'alias'                  => array('type' => 'string'),
+            'anniversary'            => array('type' => 'datetime'),
+            'assistantName'          => array('type' => 'string'),
+            'assistantPhoneNumber'   => array('type' => 'string'),
+            'birthday'               => array('type' => 'datetime'),
+            'business2PhoneNumber'   => array('type' => 'string'),
+            'businessAddressCity'    => array('type' => 'string'),
+            'businessAddressCountry' => array('type' => 'string'),
+            'businessAddressPostalCode' => array('type' => 'string'),
+            'businessAddressState'   => array('type' => 'string'),
+            'businessAddressStreet'  => array('type' => 'string'),
+            'businessFaxNumber'      => array('type' => 'string'),
+            'businessPhoneNumber'    => array('type' => 'string'),
+            'carPhoneNumber'         => array('type' => 'string'),
+            'categories'             => array('type' => 'container', 'childElement' => 'category'),
+            'children'               => array('type' => 'container', 'childElement' => 'child'),
+            'companyName'            => array('type' => 'string'),
+            'department'             => array('type' => 'string'),
+            'email1Address'          => array('type' => 'string'),
+            'email2Address'          => array('type' => 'string'),
+            'email3Address'          => array('type' => 'string'),
+            'fileAs'                 => array('type' => 'string'),
+            'firstName'              => array('type' => 'string'),
+            'home2PhoneNumber'       => array('type' => 'string'),
+            'homeAddressCity'        => array('type' => 'string'),
+            'homeAddressCountry'     => array('type' => 'string'),
+            'homeAddressPostalCode'  => array('type' => 'string'),
+            'homeAddressState'       => array('type' => 'string'),
+            'homeAddressStreet'      => array('type' => 'string'),
+            'homeFaxNumber'          => array('type' => 'string'),
+            'homePhoneNumber'        => array('type' => 'string'),
+            'jobTitle'               => array('type' => 'string'),
+            'lastName'               => array('type' => 'string'),
+            'middleName'             => array('type' => 'string'),
+            'mobilePhoneNumber'      => array('type' => 'string'),
+            'officeLocation'         => array('type' => 'string'),
+            'otherAddressCity'       => array('type' => 'string'),
+            'otherAddressCountry'    => array('type' => 'string'),
+            'otherAddressPostalCode' => array('type' => 'string'),
+            'otherAddressState'      => array('type' => 'string'),
+            'otherAddressStreet'     => array('type' => 'string'),
+            'pagerNumber'            => array('type' => 'string'),
+            'picture'                => array('type' => 'string', 'encoding' => 'base64'),
+            'padioPhoneNumber'       => array('type' => 'string'),
+            'rtf'                    => array('type' => 'string'),
+            'spouse'                 => array('type' => 'string'),
+            'suffix'                 => array('type' => 'string'),
+            'title'                  => array('type' => 'string'),
+            'webPage'                => array('type' => 'string'),
+            'weightedRank'           => array('type' => 'string'),
+            'yomiCompanyName'        => array('type' => 'string'),
+            'yomiFirstName'          => array('type' => 'string'),
+            'yomiLastName'           => array('type' => 'string'),
         ),
         'Contacts2' => array(
-            'AccountName'            => array('type' => 'string'),
-            'CompanyMainPhone'       => array('type' => 'string'),
-            'CustomerId'             => array('type' => 'string'),
-            'GovernmentId'           => array('type' => 'string'),
-            'IMAddress'              => array('type' => 'string'),
-            'IMAddress2'             => array('type' => 'string'),
-            'IMAddress3'             => array('type' => 'string'),
-            'ManagerName'            => array('type' => 'string'),
-            'MMS'                    => array('type' => 'string'),
-            'NickName'               => array('type' => 'string'),
+            'accountName'            => array('type' => 'string'),
+            'companyMainPhone'       => array('type' => 'string'),
+            'customerId'             => array('type' => 'string'),
+            'governmentId'           => array('type' => 'string'),
+            'iMAddress'              => array('type' => 'string'),
+            'iMAddress2'             => array('type' => 'string'),
+            'iMAddress3'             => array('type' => 'string'),
+            'managerName'            => array('type' => 'string'),
+            'mMS'                    => array('type' => 'string'),
+            'nickName'               => array('type' => 'string'),
         )
     );
-    
-    protected function _parseContactsNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from Contacts namespace
-        $children = $properties->children('uri:Contacts');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Categories':
-                    $categories = array();
-                    
-                    foreach ($xmlElement->Category as $category) {
-                        $categories[] = (string) $category;
-                    }
-                    
-                    $this->$elementName = $categories;
-                    
-                    break;
-                    
-                case 'Children':
-                    $children = array();
-                    
-                    foreach ($xmlElement->Child as $child) {
-                        $children[] = (string) $child;
-                    }
-                    
-                    $this->$elementName = $children;
-                    
-                    break;
-                    
-                case 'Picture':
-                    $this->$elementName = base64_decode((string) $xmlElement);
-                    
-                    break;
-                    
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
-            }
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/Email.php b/lib/ext/Syncroton/Model/Email.php
index 5a982ca..cfdefa9 100644
--- a/lib/ext/Syncroton/Model/Email.php
+++ b/lib/ext/Syncroton/Model/Email.php
@@ -20,79 +20,100 @@
  * @property    array    To
  * @property    int      Read
  */
-
 class Syncroton_Model_Email extends Syncroton_Model_AEntry
 {
     protected $_xmlBaseElement = 'ApplicationData';
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'Attachments'             => array('type' => 'container', 'childName' => 'Attachment'),
-            'ContentType'             => array('type' => 'string'),
-            'Body'                    => array('type' => 'container'),
-            'NativeBodyType'          => array('type' => 'number'),
+            'attachments'             => array('type' => 'container', 'childElement' => 'attachment', 'class' => 'Syncroton_Model_EmailAttachment'),
+            'contentType'             => array('type' => 'string'),
+            'body'                    => array('type' => 'container', 'class' => 'Syncroton_Model_EmailBody'),
+            'nativeBodyType'          => array('type' => 'number'),
         ),
         'Email' => array(
-            'BusyStatus'              => array('type' => 'number'),
-            'Categories'              => array('type' => 'container', 'childName' => 'Category'),
-            'Cc'                      => array('type' => 'string'),
-            'CompleteTime'            => array('type' => 'datetime'),
-            'ContentClass'            => array('type' => 'string'),
-            'DateReceived'            => array('type' => 'datetime'),
-            #'DayOfMonth'              => array('type' => 'number'),
-            #'DayOfWeek'               => array('type' => 'number'),
-            'DisallowNewTimeProposal' => array('type' => 'number'),
-            'DisplayTo'               => array('type' => 'string'),
-            'DTStamp'                 => array('type' => 'datetime'),
-            'EndTime'                 => array('type' => 'datetime'),
-            'Flag'                    => array('type' => 'container'),
-            'From'                    => array('type' => 'string'),
-            'GlobalObjId'             => array('type' => 'string'),
-            'Importance'              => array('type' => 'number'),
-            'InstanceType'            => array('type' => 'number'),
-            'InternetCPID'            => array('type' => 'string'),
-            #'Interval'                => array('type' => 'number'),
-            'Location'                => array('type' => 'string'),
-            'MeetingRequest'          => array('type' => 'container'),
-            'MessageClass'            => array('type' => 'string'),
-            #'MonthOfYear'             => array('type' => 'number'),
-            #'Occurrences'             => array('type' => 'number'),
-            'Organizer'               => array('type' => 'string'),
-            'Read'                    => array('type' => 'number'),
-            #'Recurrence'              => array('type' => 'container'),
-            #'RecurrenceId'            => array('type' => 'datetime'),
-            'Recurrences'             => array('type' => 'container'),
-            'Reminder'                => array('type' => 'number'),
-            'ReplyTo'                 => array('type' => 'string'),
-            'ResponseRequested'       => array('type' => 'number'),
-            'Sensitivity'             => array('type' => 'number'),
-            'StartTime'               => array('type' => 'datetime'),
-            'Status'                  => array('type' => 'number'),
-            'Subject'                 => array('type' => 'string'),
-            'ThreadTopic'             => array('type' => 'string'),
-            'TimeZone'                => array('type' => 'timezone'),
-            'To'                      => array('type' => 'string'),
-            #'Type'                    => array('type' => 'number'),
-            #'Until'                   => array('type' => 'datetime'),
-            #'WeekOfMonth'             => array('type' => 'number'),
+            'busyStatus'              => array('type' => 'number'),
+            'categories'              => array('type' => 'container', 'childElement' => 'category'),
+            'cc'                      => array('type' => 'string'),
+            'completeTime'            => array('type' => 'datetime'),
+            'contentClass'            => array('type' => 'string'),
+            'dateReceived'            => array('type' => 'datetime'),
+            'disallowNewTimeProposal' => array('type' => 'number'),
+            'displayTo'               => array('type' => 'string'),
+            'dTStamp'                 => array('type' => 'datetime'),
+            'endTime'                 => array('type' => 'datetime'),
+            'flag'                    => array('type' => 'container'),
+            'from'                    => array('type' => 'string'),
+            'globalObjId'             => array('type' => 'string'),
+            'importance'              => array('type' => 'number'),
+            'instanceType'            => array('type' => 'number'),
+            'internetCPID'            => array('type' => 'string'),
+            'location'                => array('type' => 'string'),
+            'meetingRequest'          => array('type' => 'container', 'class' => 'Syncroton_Model_EmailMeetingRequest'),
+            'messageClass'            => array('type' => 'string'),
+            'organizer'               => array('type' => 'string'),
+            'read'                    => array('type' => 'number'),
+            'recurrences'             => array('type' => 'container'),
+            'reminder'                => array('type' => 'number'),
+            'replyTo'                 => array('type' => 'string'),
+            'responseRequested'       => array('type' => 'number'),
+            'sensitivity'             => array('type' => 'number'),
+            'startTime'               => array('type' => 'datetime'),
+            'status'                  => array('type' => 'number'),
+            'subject'                 => array('type' => 'string'),
+            'threadTopic'             => array('type' => 'string'),
+            'timeZone'                => array('type' => 'timezone'),
+            'to'                      => array('type' => 'string'),
         ),
         'Email2' => array(
-            'AccountId'             => array('type' => 'string'),
-            #'CalendarType'          => array('type' => 'number'),
-            'ConversationId'        => array('type' => 'byteArray'), // @todo handle this
-            'ConversationIndex'     => array('type' => 'byteArray'), // @todo handle this
-            #'FirstDayOfWeek'        => array('type' => 'number'),
-            #'IsLeapMonth'           => array('type' => 'number'),
-            'LastVerbExecuted'      => array('type' => 'number'),
-            'LastVerbExecutionTime' => array('type' => 'datetime'),
-            'MeetingMessageType'    => array('type' => 'number'),
-            'ReceivedAsBcc'         => array('type' => 'number'),
-            'Sender'                => array('type' => 'string'),
-            'UmCallerID'            => array('type' => 'string'),
-            'UmUserNotes'           => array('type' => 'string'),
+            'accountId'             => array('type' => 'string'),
+            'conversationId'        => array('type' => 'byteArray'), // @todo handle this
+            'conversationIndex'     => array('type' => 'byteArray'), // @todo handle this
+            'lastVerbExecuted'      => array('type' => 'number'),
+            'lastVerbExecutionTime' => array('type' => 'datetime'),
+            'meetingMessageType'    => array('type' => 'number'),
+            'receivedAsBcc'         => array('type' => 'number'),
+            'sender'                => array('type' => 'string'),
+            'umCallerID'            => array('type' => 'string'),
+            'umUserNotes'           => array('type' => 'string'),
         ),
     );
-
+    
+    protected function _parseAirSyncBaseNamespace(SimpleXMLElement $properties)
+    {
+        // fetch data from AirSyncBase namespace
+        $children = $properties->children('uri:AirSyncBase');
+    
+        foreach ($children as $elementName => $xmlElement) {
+    
+            switch ($elementName) {
+                case 'Body':
+                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
+    
+                    break;
+    
+                default:
+                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
+    
+                    switch ($properties['type']) {
+                        case 'datetime':
+                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
+    
+                            break;
+    
+                        case 'number':
+                            $this->$elementName = (int) $xmlElement;
+    
+                            break;
+                        default:
+                            $this->$elementName = (string) $xmlElement;
+    
+                            break;
+                    }
+            }
+        }
+    }
+    
     protected function _parseEmailNamespace(SimpleXMLElement $properties)
     {
         // fetch data from AirSyncBase namespace
@@ -101,13 +122,69 @@ class Syncroton_Model_Email extends Syncroton_Model_AEntry
         foreach ($children as $elementName => $xmlElement) {
     
             switch ($elementName) {
+                case 'Body':
+                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
+    
+                    break;
+
                 case 'Flag':
                     $this->$elementName = new Syncroton_Model_EmailFlag($xmlElement);
                     break;
 
                 default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
+                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
+    
+                    switch ($properties['type']) {
+                        case 'datetime':
+                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
+    
+                            break;
+    
+                        case 'number':
+                            $this->$elementName = (int) $xmlElement;
+    
+                            break;
+                        default:
+                            $this->$elementName = (string) $xmlElement;
+    
+                            break;
+                    }
             }
         }
     }
+    
+    protected function _parseEmail2Namespace(SimpleXMLElement $properties)
+    {
+        // fetch data from AirSyncBase namespace
+        $children = $properties->children('uri:Email2');
+    
+        foreach ($children as $elementName => $xmlElement) {
+    
+            switch ($elementName) {
+                case 'Body':
+                    $this->$elementName = new Syncroton_Model_EmailBody($xmlElement);
+    
+                    break;
+    
+                default:
+                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
+    
+                    switch ($properties['type']) {
+                        case 'datetime':
+                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
+    
+                            break;
+    
+                        case 'number':
+                            $this->$elementName = (int) $xmlElement;
+    
+                            break;
+                        default:
+                            $this->$elementName = (string) $xmlElement;
+    
+                            break;
+                    }
+            }
+        }
+    }
 }
diff --git a/lib/ext/Syncroton/Model/EmailAttachment.php b/lib/ext/Syncroton/Model/EmailAttachment.php
index 4022166..59f0360 100644
--- a/lib/ext/Syncroton/Model/EmailAttachment.php
+++ b/lib/ext/Syncroton/Model/EmailAttachment.php
@@ -25,47 +25,17 @@ class Syncroton_Model_EmailAttachment extends Syncroton_Model_AEntry
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'ContentId'               => array('type' => 'string'),
-            'ContentLocation'         => array('type' => 'string'),
-            'DisplayName'             => array('type' => 'string'),
-            'EstimatedDataSize'       => array('type' => 'string'),
-            'FileReference'           => array('type' => 'string'),
-            'IsInline'                => array('type' => 'number'),
-            'Method'                  => array('type' => 'string'),
+            'contentId'               => array('type' => 'string'),
+            'contentLocation'         => array('type' => 'string'),
+            'displayName'             => array('type' => 'string'),
+            'estimatedDataSize'       => array('type' => 'string'),
+            'fileReference'           => array('type' => 'string'),
+            'isInline'                => array('type' => 'number'),
+            'method'                  => array('type' => 'string'),
         ),
         'Email2' => array(
-            'UmAttDuration'         => array('type' => 'number'),
-            'UmAttOrder'            => array('type' => 'number'),
+            'umAttDuration'         => array('type' => 'number'),
+            'umAttOrder'            => array('type' => 'number'),
         ),
     );
-    
-    protected function _parseAirSyncBaseNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from Email namespace
-        $children = $properties->children('uri:AirSyncBase');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Attachments':
-                    $attachments = array();
-                    
-                    foreach ($xmlElement->$elementName as $attachment) {
-                        $attachments[] = new Syncroton_Model_EmailAttachment($attachment);
-                    }
-                    
-                    $this->$elementName = $attachments;
-                    
-                    break;
-                    
-                case 'Recurrence':
-                    $this->$elementName = new Syncroton_Model_TaskRecurrence($xmlElement);
-                    
-                    break;
-                    
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/EmailBody.php b/lib/ext/Syncroton/Model/EmailBody.php
index 474d3ba..92a886b 100644
--- a/lib/ext/Syncroton/Model/EmailBody.php
+++ b/lib/ext/Syncroton/Model/EmailBody.php
@@ -29,15 +29,14 @@ class Syncroton_Model_EmailBody extends Syncroton_Model_AEntry
     
     protected $_xmlBaseElement = 'Body';
     
-    // @todo handle body
     protected $_properties = array(
         'AirSyncBase' => array(
-            'Type'              => array('type' => 'string'),
-            'EstimatedDataSize' => array('type' => 'string'),
-            'Data'              => array('type' => 'string'),
-            'Truncated'         => array('type' => 'number'),
-            'Part'              => array('type' => 'number'),
-            'Preview'           => array('type' => 'string'),
+            'type'              => array('type' => 'string'),
+            'estimatedDataSize' => array('type' => 'string'),
+            'data'              => array('type' => 'string'),
+            'truncated'         => array('type' => 'number'),
+            'part'              => array('type' => 'number'),
+            'preview'           => array('type' => 'string'),
         ),
     );
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/EmailFlag.php b/lib/ext/Syncroton/Model/EmailFlag.php
index 2d8d518..c284987 100644
--- a/lib/ext/Syncroton/Model/EmailFlag.php
+++ b/lib/ext/Syncroton/Model/EmailFlag.php
@@ -38,40 +38,21 @@ class Syncroton_Model_EmailFlag extends Syncroton_Model_AEntry
 
     protected $_properties = array(
         'Email' => array(
-            'CompleteTime'       => array('type' => 'datetime'),
-            'FlagType'           => array('type' => 'string'),
-             // Android bug http://code.google.com/p/android/issues/detail?id=36113
-            'FlagStatus'         => array('type' => 'number'),
-            'Status'             => array('type' => 'number'),
+            'completeTime'       => array('type' => 'datetime'),
+            'flagType'           => array('type' => 'string'),
+            'status'             => array('type' => 'number'),
         ),
         'Tasks' => array(
-            'DateCompleted'      => array('type' => 'datetime'),
-            'DueDate'            => array('type' => 'datetime'),
-            'OrdinalDate'        => array('type' => 'datetime'),
-            'ReminderSet'        => array('type' => 'number'),
-            'ReminderTime'       => array('type' => 'datetime'),
-            'StartDate'          => array('type' => 'datetime'),
-            'Subject'            => array('type' => 'string'),
-            'SubOrdinalDate'     => array('type' => 'string'),
-            'UtcStartDate'       => array('type' => 'datetime'),
-            'UtcDueDate'         => array('type' => 'datetime'),
+            'dateCompleted'      => array('type' => 'datetime'),
+            'dueDate'            => array('type' => 'datetime'),
+            'ordinalDate'        => array('type' => 'datetime'),
+            'reminderSet'        => array('type' => 'number'),
+            'reminderTime'       => array('type' => 'datetime'),
+            'startDate'          => array('type' => 'datetime'),
+            'subject'            => array('type' => 'string'),
+            'subOrdinalDate'     => array('type' => 'string'),
+            'utcStartDate'       => array('type' => 'datetime'),
+            'utcDueDate'         => array('type' => 'datetime'),
         ),
     );
-
-    protected function _parseEmailNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from AirSyncBase namespace
-        $children = $properties->children('uri:Email');
-
-        foreach ($children as $elementName => $xmlElement) {
-            switch ($elementName) {
-                case 'FlagStatus':
-                    // Android bug http://code.google.com/p/android/issues/detail?id=36113
-                    $elementName = 'Status';
-
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
-            }
-        }
-    }
 }
diff --git a/lib/ext/Syncroton/Model/Event.php b/lib/ext/Syncroton/Model/Event.php
index b0176b6..02307e0 100644
--- a/lib/ext/Syncroton/Model/Event.php
+++ b/lib/ext/Syncroton/Model/Event.php
@@ -35,88 +35,33 @@ class Syncroton_Model_Event extends Syncroton_Model_AEntry
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'Body'                   => array('type' => 'container')
+            'body'                      => array('type' => 'container', 'class' => 'Syncroton_Model_EmailBody')
         ),
         'Calendar' => array(
-            'AllDayEvent'             => array('type' => 'number'),
-            'AppointmentReplyTime'    => array('type' => 'datetime'),
-            'Attendees'               => array('type' => 'container', 'childName' => 'Attendee'),
-            //'Body'                    => 0x0b,
-            //'BodyTruncated'           => 0x0c,
-            'BusyStatus'              => array('type' => 'number'),
-            'Categories'              => array('type' => 'container', 'childName' => 'Category'),
-            'DisallowNewTimeProposal' => array('type' => 'number'),
-            'DtStamp'                 => array('type' => 'datetime'),
-            'EndTime'                 => array('type' => 'datetime'),
-            'Exceptions'              => array('type' => 'container', 'childName' => 'Exception'),
-            'Location'                => array('type' => 'string'),
-            'MeetingStatus'           => array('type' => 'number'),
-            'OnlineMeetingConfLink'   => array('type' => 'string'),
-            'OnlineMeetingExternalLink' => array('type' => 'string'),
-            'OrganizerEmail'          => array('type' => 'string'),
-            'OrganizerName'           => array('type' => 'string'),
-            'Recurrence'              => array('type' => 'container'),
-            'Reminder'                => array('type' => 'number'),
-            'ResponseRequested'       => array('type' => 'number'),
-            'ResponseType'            => array('type' => 'number'),
-            //'Rtf'                     => 0x10,
-            'Sensitivity'             => array('type' => 'number'),
-            'StartTime'               => array('type' => 'datetime'),
-            'Subject'                 => array('type' => 'string'),
-            'Timezone'                => array('type' => 'timezone'),
-            'UID'                     => array('type' => 'string'),
+            'allDayEvent'               => array('type' => 'number'),
+            'appointmentReplyTime'      => array('type' => 'datetime'),
+            'attendees'                 => array('type' => 'container', 'childElement' => 'attendee', 'class' => 'Syncroton_Model_EventAttendee'),
+            'busyStatus'                => array('type' => 'number'),
+            'categories'                => array('type' => 'container', 'childElement' => 'category'),
+            'disallowNewTimeProposal'   => array('type' => 'number'),
+            'dtStamp'                   => array('type' => 'datetime'),
+            'endTime'                   => array('type' => 'datetime'),
+            'exceptions'                => array('type' => 'container', 'childElement' => 'exception', 'class' => 'Syncroton_Model_EventException'),
+            'location'                  => array('type' => 'string'),
+            'meetingStatus'             => array('type' => 'number'),
+            'onlineMeetingConfLink'     => array('type' => 'string'),
+            'onlineMeetingExternalLink' => array('type' => 'string'),
+            'organizerEmail'            => array('type' => 'string'),
+            'organizerName'             => array('type' => 'string'),
+            'recurrence'                => array('type' => 'container'),
+            'reminder'                  => array('type' => 'number'),
+            'responseRequested'         => array('type' => 'number'),
+            'responseType'              => array('type' => 'number'),
+            'sensitivity'               => array('type' => 'number'),
+            'startTime'                 => array('type' => 'datetime'),
+            'subject'                   => array('type' => 'string'),
+            'timezone'                  => array('type' => 'timezone'),
+            'uID'                       => array('type' => 'string'),
         )
     );
-    
-    protected function _parseCalendarNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from Contacts namespace
-        $children = $properties->children('uri:Calendar');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Attendees':
-                    $attendees = array();
-                    
-                    foreach ($xmlElement->Attendee as $attendee) {
-                        $attendees[] = new Syncroton_Model_EventAttendee($attendee);
-                    }
-                    
-                    $this->$elementName = $attendees;
-                    
-                    break;
-                    
-                case 'Categories':
-                    $categories = array();
-                    
-                    foreach ($xmlElement->$elementName as $category) {
-                        $categories[] = (string) $category;
-                    }
-                    
-                    $this->$elementName = $categories;
-                    
-                    break;
-                    
-                case 'Exceptions':
-                    $exceptions = array();
-                    
-                    foreach ($xmlElement->Exception as $exception) {
-                        $exceptions[] = new Syncroton_Model_EventException($exception);
-                    }
-                    
-                    $this->$elementName = $exceptions;
-                    
-                    break;
-                    
-                case 'Recurrence':
-                    $this->$elementName = new Syncroton_Model_EventRecurrence($xmlElement);
-                    
-                    break;
-                    
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
-            }
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/EventAttendee.php b/lib/ext/Syncroton/Model/EventAttendee.php
index 097feb1..a439650 100644
--- a/lib/ext/Syncroton/Model/EventAttendee.php
+++ b/lib/ext/Syncroton/Model/EventAttendee.php
@@ -22,6 +22,8 @@
 
 class Syncroton_Model_EventAttendee extends Syncroton_Model_AEntry
 {
+    protected $_xmlBaseElement = 'Attendee';
+    
     /**
      * attendee status
      */
@@ -37,15 +39,13 @@ class Syncroton_Model_EventAttendee extends Syncroton_Model_AEntry
     const ATTENDEE_TYPE_REQUIRED = 1;
     const ATTENDEE_TYPE_OPTIONAL = 2;
     const ATTENDEE_TYPE_RESOURCE = 3;
-
-    protected $_xmlBaseElement = 'Attendee';
     
     protected $_properties = array(
         'Calendar' => array(
-            'AttendeeStatus'          => array('type' => 'number'),
-            'AttendeeType'            => array('type' => 'number'),
-            'Email'                   => array('type' => 'string'),
-            'Name'                    => array('type' => 'string'),
+            'attendeeStatus'          => array('type' => 'number'),
+            'attendeeType'            => array('type' => 'number'),
+            'email'                   => array('type' => 'string'),
+            'name'                    => array('type' => 'string'),
         )
     );
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/EventException.php b/lib/ext/Syncroton/Model/EventException.php
index 7ab97d7..400c397 100644
--- a/lib/ext/Syncroton/Model/EventException.php
+++ b/lib/ext/Syncroton/Model/EventException.php
@@ -28,22 +28,22 @@ class Syncroton_Model_EventException extends Syncroton_Model_Event
     
     protected $_properties = array(
         'Calendar' => array(
-            'AllDayEvent'             => array('type' => 'number'),
-            'AppointmentReplyTime'    => array('type' => 'datetime'),
-            'Attendees'               => array('type' => 'container'),
-            'BusyStatus'              => array('type' => 'number'),
-            'Categories'              => array('type' => 'container'),
-            'Deleted'                 => array('type' => 'number'),
-            'DtStamp'                 => array('type' => 'datetime'),
-            'EndTime'                 => array('type' => 'datetime'),
-            'ExceptionStartTime'      => array('type' => 'datetime'),
-            'Location'                => array('type' => 'string'),
-            'MeetingStatus'           => array('type' => 'number'),
-            'Reminder'                => array('type' => 'number'),
-            'ResponseType'            => array('type' => 'number'),
-            'Sensitivity'             => array('type' => 'number'),
-            'StartTime'               => array('type' => 'datetime'),
-            'Subject'                 => array('type' => 'string'),
+            'allDayEvent'             => array('type' => 'number'),
+            'appointmentReplyTime'    => array('type' => 'datetime'),
+            'attendees'               => array('type' => 'container', 'childElement' => 'attendee', 'class' => 'Syncroton_Model_EventAttendee'),
+            'busyStatus'              => array('type' => 'number'),
+            'categories'              => array('type' => 'container', 'childElement' => 'category'),
+            'deleted'                 => array('type' => 'number'),
+            'dtStamp'                 => array('type' => 'datetime'),
+            'endTime'                 => array('type' => 'datetime'),
+            'exceptionStartTime'      => array('type' => 'datetime'),
+            'location'                => array('type' => 'string'),
+            'meetingStatus'           => array('type' => 'number'),
+            'reminder'                => array('type' => 'number'),
+            'responseType'            => array('type' => 'number'),
+            'sensitivity'             => array('type' => 'number'),
+            'startTime'               => array('type' => 'datetime'),
+            'subject'                 => array('type' => 'string'),
         )
     );    
 }
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/EventRecurrence.php b/lib/ext/Syncroton/Model/EventRecurrence.php
index 5d7c021..367a2bc 100644
--- a/lib/ext/Syncroton/Model/EventRecurrence.php
+++ b/lib/ext/Syncroton/Model/EventRecurrence.php
@@ -54,17 +54,17 @@ class Syncroton_Model_EventRecurrence extends Syncroton_Model_AEntry
     
     protected $_properties = array(
         'Calendar' => array(
-            'CalendarType'            => array('type' => 'number'),
-            'DayOfMonth'              => array('type' => 'number'),
-            'DayOfWeek'               => array('type' => 'number'),
-            'FirstDayOfWeek'          => array('type' => 'number'),
-            'Interval'                => array('type' => 'number'),
-            'IsLeapMonth'             => array('type' => 'number'),
-            'MonthOfYear'             => array('type' => 'number'),
-            'Occurrences'             => array('type' => 'number'),
-            'Type'                    => array('type' => 'number'),
-            'Until'                   => array('type' => 'datetime'),
-            'WeekOfMonth'             => array('type' => 'number'),
+            'calendarType'            => array('type' => 'number'),
+            'dayOfMonth'              => array('type' => 'number'),
+            'dayOfWeek'               => array('type' => 'number'),
+            'firstDayOfWeek'          => array('type' => 'number'),
+            'interval'                => array('type' => 'number'),
+            'isLeapMonth'             => array('type' => 'number'),
+            'monthOfYear'             => array('type' => 'number'),
+            'occurrences'             => array('type' => 'number'),
+            'type'                    => array('type' => 'number'),
+            'until'                   => array('type' => 'datetime'),
+            'weekOfMonth'             => array('type' => 'number'),
         )
     );
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/FileReference.php b/lib/ext/Syncroton/Model/FileReference.php
index 6c2e67d..3aa00cb 100644
--- a/lib/ext/Syncroton/Model/FileReference.php
+++ b/lib/ext/Syncroton/Model/FileReference.php
@@ -22,10 +22,10 @@ class Syncroton_Model_FileReference extends Syncroton_Model_AEntry
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'ContentType' => array('type' => 'string'),
+            'contentType' => array('type' => 'string'),
         ),
         'ItemOperations' => array(
-            'Data'        => array('type' => 'string', 'encoding' => 'base64'),
+            'data'        => array('type' => 'string', 'encoding' => 'base64'),
         )
     );
         
diff --git a/lib/ext/Syncroton/Model/Folder.php b/lib/ext/Syncroton/Model/Folder.php
index 50cb189..33412cf 100644
--- a/lib/ext/Syncroton/Model/Folder.php
+++ b/lib/ext/Syncroton/Model/Folder.php
@@ -34,40 +34,4 @@ class Syncroton_Model_Folder extends Syncroton_Model_AEntry implements Syncroton
             'lastfiltertype' => array('type' => 'number')
         ),
     );
-    
-    protected function _parseFolderHierarchyNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from Contacts namespace
-        $children = $properties->children('uri:FolderHierarchy');
-    
-        foreach ($children as $elementName => $xmlElement) {
-            $elementName = lcfirst($elementName);
-            
-            if (!isset($this->_properties['FolderHierarchy'][$elementName])) {
-                continue;
-            }
-            
-            switch ($elementName) {
-                default:
-                    list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-    
-                    switch ($elementProperties['type']) {
-                        case 'datetime':
-                            $this->$elementName = new DateTime((string) $xmlElement, new DateTimeZone('UTC'));
-    
-                            break;
-    
-                        case 'number':
-                            $this->$elementName = (int) $xmlElement;
-    
-                            break;
-                        default:
-                            $this->$elementName = (string) $xmlElement;
-    
-                            break;
-                    }
-            }
-        }
-    }
 }
-
diff --git a/lib/ext/Syncroton/Model/GAL.php b/lib/ext/Syncroton/Model/GAL.php
index 292540b..31af916 100644
--- a/lib/ext/Syncroton/Model/GAL.php
+++ b/lib/ext/Syncroton/Model/GAL.php
@@ -35,63 +35,17 @@ class Syncroton_Model_GAL extends Syncroton_Model_AEntry
 
     protected $_properties = array(
         'GAL' => array(
-            'Alias'         => array('type' => 'string'),
-            'Company'       => array('type' => 'string'),
-            'DisplayName'   => array('type' => 'string'),
-            'EmailAddress'  => array('type' => 'string'),
-            'FirstName'     => array('type' => 'string'),
-            'LastName'      => array('type' => 'string'),
-            'MobilePhone'   => array('type' => 'string'),
-            'Office'        => array('type' => 'string'),
-            'Phone'         => array('type' => 'string'),
-            'Picture'       => array('type' => 'composite'),
-            'Title'         => array('type' => 'string'),
+            'alias'         => array('type' => 'string'),
+            'company'       => array('type' => 'string'),
+            'displayName'   => array('type' => 'string'),
+            'emailAddress'  => array('type' => 'string'),
+            'firstName'     => array('type' => 'string'),
+            'lastName'      => array('type' => 'string'),
+            'mobilePhone'   => array('type' => 'string'),
+            'office'        => array('type' => 'string'),
+            'phone'         => array('type' => 'string'),
+            'picture'       => array('type' => 'container'),
+            'title'         => array('type' => 'string'),
         )
     );
-
-    public function appendXML(DOMElement $_domParrent)
-    {
-        $this->_addXMLNamespaces($_domParrent);
-
-        foreach($this->_elements as $elementName => $value) {
-            // skip empty values
-            if($value === null || $value === '' || (is_array($value) && empty($value))) {
-                continue;
-            }
-
-            list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-
-            $nameSpace = 'uri:' . $nameSpace;
-
-            // strip off any non printable control characters
-/*
-            if (!ctype_print($value)) {
-                $value = $this->removeControlChars($value);
-            }
-*/
-            switch ($elementName) {
-                case 'Picture':
-                    $element = $_domParrent->ownerDocument->createElementNS($nameSpace, $elementName);
-                    $value->appendXML($element);
-                    $_domParrent->appendChild($element);
-                    break;
-
-                default:
-                    $element = $_domParrent->ownerDocument->createElementNS($nameSpace, $elementName);
-
-                    if (isset($elementProperties['encoding']) && $elementProperties['encoding'] == 'base64') {
-                        if (is_resource($value)) {
-                            stream_filter_append($value, 'convert.base64-encode');
-                            $value = stream_get_contents($value);
-                        } else {
-                            $value = base64_encode($value);
-                        }
-                    }
-
-                    $element->appendChild($_domParrent->ownerDocument->createTextNode($value));
-
-                    $_domParrent->appendChild($element);
-            }
-        }
-    }
 }
diff --git a/lib/ext/Syncroton/Model/GALPicture.php b/lib/ext/Syncroton/Model/GALPicture.php
index d99cdaf..d7a208a 100644
--- a/lib/ext/Syncroton/Model/GALPicture.php
+++ b/lib/ext/Syncroton/Model/GALPicture.php
@@ -31,50 +31,10 @@ class Syncroton_Model_GALPicture extends Syncroton_Model_AEntry
 
     protected $_properties = array(
         'AirSync' => array(
-            'Status'       => array('type' => 'number'),
+            'status'       => array('type' => 'number'),
         ),
         'GAL' => array(
-            'Data'         => array('type' => 'byteArray'),
+            'data'         => array('type' => 'byteArray'),
         ),
     );
-
-    public function appendXML(DOMElement $_domParrent)
-    {
-        $this->_addXMLNamespaces($_domParrent);
-
-        foreach($this->_elements as $elementName => $value) {
-            // skip empty values
-            if($value === null || $value === '' || (is_array($value) && empty($value))) {
-                continue;
-            }
-
-            list ($nameSpace, $elementProperties) = $this->_getElementProperties($elementName);
-
-            $nameSpace = 'uri:' . $nameSpace;
-
-            // strip off any non printable control characters
-/*
-            if (!ctype_print($value)) {
-                $value = $this->removeControlChars($value);
-            }
-*/
-            switch ($elementName) {
-                default:
-                    $element = $_domParrent->ownerDocument->createElementNS($nameSpace, $elementName);
-
-                    if (isset($elementProperties['encoding']) && $elementProperties['encoding'] == 'base64') {
-                        if (is_resource($value)) {
-                            stream_filter_append($value, 'convert.base64-encode');
-                            $value = stream_get_contents($value);
-                        } else {
-                            $value = base64_encode($value);
-                        }
-                    }
-
-                    $element->appendChild($_domParrent->ownerDocument->createTextNode($value));
-
-                    $_domParrent->appendChild($element);
-            }
-        }
-    }
 }
diff --git a/lib/ext/Syncroton/Model/StoreResponse.php b/lib/ext/Syncroton/Model/StoreResponse.php
index cd1770f..35c030e 100644
--- a/lib/ext/Syncroton/Model/StoreResponse.php
+++ b/lib/ext/Syncroton/Model/StoreResponse.php
@@ -38,7 +38,7 @@ class Syncroton_Model_StoreResponse extends Syncroton_Model_AEntry
     protected $_properties = array(
         'Search' => array(
             'Status'    => array('type' => 'number'),
-            'Result'    => array('type' => 'container'),
+            'Result'    => array('type' => 'container', 'multiple' => true),
             'Range'     => array('type' => 'string'),
             'Total'     => array('type' => 'number'),
         )
diff --git a/lib/ext/Syncroton/Model/Task.php b/lib/ext/Syncroton/Model/Task.php
index c824508..c4e032f 100644
--- a/lib/ext/Syncroton/Model/Task.php
+++ b/lib/ext/Syncroton/Model/Task.php
@@ -9,7 +9,7 @@
  */
 
 /**
- * class to handle ActiveSync event
+ * class to handle ActiveSync task
  *
  * @package     Model
  * @property    string  class
@@ -19,59 +19,28 @@
  * @property    string  syncKey
  * @property    int     windowSize
  */
-
 class Syncroton_Model_Task extends Syncroton_Model_AEntry
 {
     protected $_xmlBaseElement = 'ApplicationData';
     
     protected $_properties = array(
         'AirSyncBase' => array(
-            'Body'                   => array('type' => 'container')
+            'body'                   => array('type' => 'container', 'class' => 'Syncroton_Model_EmailBody')
         ),
         'Tasks' => array(
-            'Categories'              => array('type' => 'container', 'childName' => 'Category'),
-            'Complete'                => array('type' => 'number'),
-            'DateCompleted'           => array('type' => 'datetime'),
-            'DueDate'                 => array('type' => 'datetime'),
-            'Importance'              => array('type' => 'number'),
-            'Recurrence'              => array('type' => 'container'),
-            'ReminderSet'             => array('type' => 'number'),
-            'ReminderTime'            => array('type' => 'datetime'),
-            'Sensitivity'             => array('type' => 'number'),
-            'StartDate'               => array('type' => 'datetime'),
-            'Subject'                 => array('type' => 'string'),
-            'UtcDueDate'              => array('type' => 'datetime'),
-            'UtcStartDate'            => array('type' => 'datetime'),
+            'categories'              => array('type' => 'container', 'childElement' => 'category'),
+            'complete'                => array('type' => 'number'),
+            'dateCompleted'           => array('type' => 'datetime'),
+            'dueDate'                 => array('type' => 'datetime'),
+            'importance'              => array('type' => 'number'),
+            'recurrence'              => array('type' => 'container'),
+            'reminderSet'             => array('type' => 'number'),
+            'reminderTime'            => array('type' => 'datetime'),
+            'sensitivity'             => array('type' => 'number'),
+            'startDate'               => array('type' => 'datetime'),
+            'subject'                 => array('type' => 'string'),
+            'utcDueDate'              => array('type' => 'datetime'),
+            'utcStartDate'            => array('type' => 'datetime'),
         )
     );
-    
-    protected function _parseTasksNamespace(SimpleXMLElement $properties)
-    {
-        // fetch data from Contacts namespace
-        $children = $properties->children('uri:Tasks');
-    
-        foreach ($children as $elementName => $xmlElement) {
-    
-            switch ($elementName) {
-                case 'Categories':
-                    $categories = array();
-                    
-                    foreach ($xmlElement->$elementName as $category) {
-                        $categories[] = (string) $category;
-                    }
-                    
-                    $this->$elementName = $categories;
-                    
-                    break;
-                    
-                case 'Recurrence':
-                    $this->$elementName = new Syncroton_Model_TaskRecurrence($xmlElement);
-                    
-                    break;
-                    
-                default:
-                    $this->$elementName = $this->_parseElement($xmlElement);
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Model/TaskRecurrence.php b/lib/ext/Syncroton/Model/TaskRecurrence.php
index 1a6b712..eb0b4b0 100644
--- a/lib/ext/Syncroton/Model/TaskRecurrence.php
+++ b/lib/ext/Syncroton/Model/TaskRecurrence.php
@@ -47,20 +47,20 @@ class Syncroton_Model_TaskRecurrence extends Syncroton_Model_AEntry
         
     protected $_properties = array(
         'Tasks' => array(
-            'CalendarType'            => array('type' => 'number'),
-            'DayOfMonth'              => array('type' => 'number'),
-            'DayOfWeek'               => array('type' => 'number'),
-            'DeadOccur'               => array('type' => 'number'),
-            'FirstDayOfWeek'          => array('type' => 'number'),
-            'Interval'                => array('type' => 'number'),
-            'IsLeapMonth'             => array('type' => 'number'),
-            'MonthOfYear'             => array('type' => 'number'),
-            'Occurrences'             => array('type' => 'number'),
-            'Regenerate'              => array('type' => 'number'),
-            'Start'                   => array('type' => 'datetime'),
-            'Type'                    => array('type' => 'number'),
-            'Until'                   => array('type' => 'datetime'),
-            'WeekOfMonth'             => array('type' => 'number'),
+            'calendarType'            => array('type' => 'number'),
+            'dayOfMonth'              => array('type' => 'number'),
+            'dayOfWeek'               => array('type' => 'number'),
+            'deadOccur'               => array('type' => 'number'),
+            'firstDayOfWeek'          => array('type' => 'number'),
+            'interval'                => array('type' => 'number'),
+            'isLeapMonth'             => array('type' => 'number'),
+            'monthOfYear'             => array('type' => 'number'),
+            'occurrences'             => array('type' => 'number'),
+            'regenerate'              => array('type' => 'number'),
+            'start'                   => array('type' => 'datetime'),
+            'type'                    => array('type' => 'number'),
+            'until'                   => array('type' => 'datetime'),
+            'weekOfMonth'             => array('type' => 'number'),
         )
     );
-}
+}
\ No newline at end of file
diff --git a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
index 3e4e11e..98d0466 100755
--- a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
+++ b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync.php
@@ -43,6 +43,7 @@ class Syncroton_Wbxml_Dtd_ActiveSync
     const CODEPAGE_COMPOSEEMAIL      = 21;
     const CODEPAGE_EMAIL2            = 22;
     const CODEPAGE_NOTES             = 23;
+    const CODEPAGE_RIGHTSMANAGEMENT  = 24;
     
     /**
      * variable to hold currently active codepage
diff --git a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php
index c772a0d..bca834c 100644
--- a/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php
+++ b/lib/ext/Syncroton/Wbxml/Dtd/ActiveSync/CodePage2.php
@@ -59,14 +59,14 @@ class Syncroton_Wbxml_Dtd_ActiveSync_CodePage2 extends Syncroton_Wbxml_Dtd_Activ
         'ResponseRequested'     => 0x26,
         'Recurrences'           => 0x27,
         'Recurrence'            => 0x28,
-        'Type'       => 0x29,
-        'Until'      => 0x2a,
-        'Occurrences'  => 0x2b,
-        'Interval'     => 0x2c,
-        'DayOfWeek'    => 0x2d,
-        'DayOfMonth'   => 0x2e,
-        'WeekOfMonth'  => 0x2f,
-        'MonthOfYear'  => 0x30,
+        'Type'                  => 0x29,
+        'Until'                 => 0x2a,
+        'Occurrences'           => 0x2b,
+        'Interval'              => 0x2c,
+        'DayOfWeek'             => 0x2d,
+        'DayOfMonth'            => 0x2e,
+        'WeekOfMonth'           => 0x2f,
+        'MonthOfYear'           => 0x30,
         'StartTime'               => 0x31,
         'Sensitivity'             => 0x32,
         'TimeZone'                => 0x33,
@@ -77,7 +77,7 @@ class Syncroton_Wbxml_Dtd_ActiveSync_CodePage2 extends Syncroton_Wbxml_Dtd_Activ
         'MIMESize'                => 0x38,
         'InternetCPID'            => 0x39,
         'Flag'                    => 0x3a,
-        'FlagStatus'              => 0x3b,
+        'Status'                  => 0x3b,
         'ContentClass'            => 0x3c,
         'FlagType'                => 0x3d,
         'CompleteTime'            => 0x3e,
diff --git a/lib/kolab_sync_data.php b/lib/kolab_sync_data.php
index 60db0cb..53b512a 100644
--- a/lib/kolab_sync_data.php
+++ b/lib/kolab_sync_data.php
@@ -708,23 +708,6 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
     abstract function toKolab(Syncroton_Model_IEntry $data, $folderId, $entry = null);
 
     /**
-     * Removes control chars from string which are not allowed in ActiveSync
-     *
-     * @param string $value Text
-     *
-     * @return string Text
-     * @deprecated
-     */
-    public static function quote($value)
-    {
-        if ($value && !ctype_print($value)) {
-            $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', null, $value);
-        }
-
-        return $value;
-    }
-
-    /**
      * Extracts data from kolab data array
      */
     protected function getKolabDataItem($data, $name)
@@ -906,11 +889,11 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
         }
 
         if (!empty($value)) {
-            $params['Data'] = $value;
+            $params['data'] = $value;
         }
 
         if (!isset($params['Type'])) {
-            $params['Type'] = 1;
+            $params['type'] = 1;
         }
 
         return new Syncroton_Model_EmailBody($params);
@@ -923,8 +906,8 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
      */
     protected function getBody($data)
     {
-        if ($data && $data->Data) {
-            return $data->Data;
+        if ($data && $data->data) {
+            return $data->data;
         }
     }
 
@@ -974,12 +957,12 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
         // required fields
         switch($r['FREQ']) {
         case 'DAILY':
-            $recurrence['Type'] = self::RECUR_TYPE_DAILY;
+            $recurrence['type'] = self::RECUR_TYPE_DAILY;
             break;
 
         case 'WEEKLY':
-            $recurrence['Type'] = self::RECUR_TYPE_WEEKLY;
-            $recurrence['DayOfWeek'] = $this->day2bitmask($r['BYDAY']);
+            $recurrence['type'] = self::RECUR_TYPE_WEEKLY;
+            $recurrence['dayOfWeek'] = $this->day2bitmask($r['BYDAY']);
             break;
 
         case 'MONTHLY':
@@ -987,16 +970,16 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
                 // @TODO: ActiveSync doesn't support multi-valued month days,
                 // should we replicate the recurrence element for each day of month?
                 $month_day = array_shift(explode(',', $r['BYMONTHDAY']));
-                $recurrence['Type'] = self::RECUR_TYPE_MONTHLY;
-                $recurrence['DayOfMonth'] = $month_day;
+                $recurrence['type'] = self::RECUR_TYPE_MONTHLY;
+                $recurrence['dayOfMonth'] = $month_day;
             }
             else {
                 $week = (int) substr($r['BYDAY'], 0, -2);
                 $week = ($week == -1) ? 5 : $week;
                 $day  = substr($r['BYDAY'], -2);
-                $recurrence['Type'] = self::RECUR_TYPE_MONTHLY_DAYN;
-                $recurrence['WeekOfMonth'] = $week;
-                $recurrence['DayOfWeek'] = $this->day2bitmask($day);
+                $recurrence['type'] = self::RECUR_TYPE_MONTHLY_DAYN;
+                $recurrence['weekOfMonth'] = $week;
+                $recurrence['dayOfWeek'] = $this->day2bitmask($day);
             }
             break;
 
@@ -1009,34 +992,34 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
                 $week = (int) substr($r['BYDAY'], 0, -2);
                 $week = ($week == -1) ? 5 : $week;
                 $day  = substr($r['BYDAY'], -2);
-                $recurrence['Type'] = self::RECUR_TYPE_YEARLY_DAYN;
-                $recurrence['WeekOfMonth'] = $week;
-                $recurrence['DayOfWeek'] = $this->day2bitmask($day);
-                $recurrence['MonthOfYear'] = $month;
+                $recurrence['type'] = self::RECUR_TYPE_YEARLY_DAYN;
+                $recurrence['weekOfMonth'] = $week;
+                $recurrence['dayOfWeek'] = $this->day2bitmask($day);
+                $recurrence['monthOfYear'] = $month;
             }
             else if (!empty($r['BYMONTHDAY'])) {
                 // @TODO: ActiveSync doesn't support multi-valued month days,
                 // should we replicate the recurrence element for each day of month?
                 $month_day = array_shift(explode(',', $r['BYMONTHDAY']));
-                $recurrence['Type'] = self::RECUR_TYPE_YEARLY;
-                $recurrence['DayOfMonth'] = $month_day;
-                $recurrence['MonthOfYear'] = $month;
+                $recurrence['type'] = self::RECUR_TYPE_YEARLY;
+                $recurrence['dayOfMonth'] = $month_day;
+                $recurrence['monthOfYear'] = $month;
             }
             else {
-                $recurrence['Type'] = self::RECUR_TYPE_YEARLY;
-                $recurrence['MonthOfYear'] = $month;
+                $recurrence['type'] = self::RECUR_TYPE_YEARLY;
+                $recurrence['monthOfYear'] = $month;
             }
             break;
         }
 
         // required field
-        $recurrence['Interval'] = $r['INTERVAL'] ? $r['INTERVAL'] : 1;
+        $recurrence['interval'] = $r['INTERVAL'] ? $r['INTERVAL'] : 1;
 
         if (!empty($r['UNTIL'])) {
-            $recurrence['Until'] = $this->date_from_kolab($r['UNTIL']);
+            $recurrence['until'] = $this->date_from_kolab($r['UNTIL']);
         }
         else if (!empty($r['COUNT'])) {
-            $recurrence['Occurrences'] = $r['COUNT'];
+            $recurrence['occurrences'] = $r['COUNT'];
         }
 
         $class = 'Syncroton_Model_' . $type . 'Recurrence';
@@ -1049,11 +1032,11 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
      */
     protected function recurrence_to_kolab($data, $timezone = null)
     {
-        if (!isset($data->Recurrence) || isset($data->Recurrence->Type)) {
+        if (!isset($data->recurrence) || isset($data->recurrence->type)) {
             return null;
         }
 
-        $type = $data->Recurrence->Type;
+        $type = $data->recurrence->type;
 
         $rrule['FREQ'] = array_search($type, $this->recurTypeMap);
 
@@ -1062,16 +1045,16 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
             break;
 
         case self::RECUR_TYPE_WEEKLY:
-            $rrule['BYDAY'] = $this->bitmask2day($data->Recurrence->DayOfWeek);
+            $rrule['BYDAY'] = $this->bitmask2day($data->recurrence->dayOfWeek);
             break;
 
         case self::RECUR_TYPE_MONTHLY:
-            $rrule['BYMONTHDAY'] = $data->Recurrence->DayOfMonth;
+            $rrule['BYMONTHDAY'] = $data->recurrence->dayOfMonth;
             break;
 
         case self::RECUR_TYPE_MONTHLY_DAYN:
-            $week = $data->Recurrence->WeekOfMonth;
-            $day  = $data->Recurrence->DayOfWeek;
+            $week = $data->recurrence->weekOfMonth;
+            $day  = $data->recurrence->dayOfWeek;
             $byDay  = $week == 5 ? -1 : $week;
             $byDay .= $this->bitmask2day($day);
 
@@ -1079,15 +1062,15 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
             break;
 
         case self::RECUR_TYPE_YEARLY:
-            $rrule['BYMONTH']    = $data->Recurrence->MonthOfYear;
-            $rrule['BYMONTHDAY'] = $data->Recurrence->DayOfMonth;
+            $rrule['BYMONTH']    = $data->recurrence->monthOfYear;
+            $rrule['BYMONTHDAY'] = $data->recurrence->dayOfMonth;
             break;
 
         case self::RECUR_TYPE_YEARLY_DAYN:
-            $rrule['BYMONTH'] = $data->Recurrence->MonthOfYear;
+            $rrule['BYMONTH'] = $data->recurrence->monthOfYear;
 
-            $week = $data->Recurrence->WeekOfMonth;
-            $day  = $data->Recurrence->DayOfWeek;
+            $week = $data->recurrence->weekOfMonth;
+            $day  = $data->recurrence->dayOfWeek;
             $byDay  = $week == 5 ? -1 : $week;
             $byDay .= $this->bitmask2day($day);
 
@@ -1095,16 +1078,16 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
             break;
         }
 
-        $rrule['INTERVAL'] = isset($data->Recurrence->Interval) ? $data->Recurrence->Interval : 1;
+        $rrule['INTERVAL'] = isset($data->recurrence->interval) ? $data->recurrence->interval : 1;
 
-        if (isset($data->Recurrence->Until)) {
+        if (isset($data->recurrence->until)) {
             if ($timezone) {
-                $data->Recurrence->Until->setTimezone($timezone);
+                $data->recurrence->until->setTimezone($timezone);
             }
-            $rrule['UNTIL'] = $data->Recurrence->Until;
+            $rrule['UNTIL'] = $data->recurrence->until;
         }
-        else if (!empty($data->Recurrence->Occurrences)) {
-            $rrule['COUNT'] = $data->Recurrence->Occurrences;
+        else if (!empty($data->recurrence->occurrences)) {
+            $rrule['COUNT'] = $data->recurrence->occurrences;
         }
 
         return $rrule;
diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php
index 26e7975..19ab083 100644
--- a/lib/kolab_sync_data_calendar.php
+++ b/lib/kolab_sync_data_calendar.php
@@ -32,47 +32,28 @@ class kolab_sync_data_calendar extends kolab_sync_data
      * Mapping from ActiveSync Calendar namespace fields
      */
     protected $mapping = array(
-        'AllDayEvent'             => 'allday',
-        //'Attendee'                => 'attendee',      // Attendees member
-        //'Attendees'               => 'attendees',
-        //'AttendeeStatus'          => 'attendeestatus', // Attendee member
-        //'AttendeeType'            => 'attendeetype',  // Attendee member
-        'Body'                    => 'description',
-        //'BodyTruncated'           => 'bodytruncated',
-        'BusyStatus'              => 'free_busy',
-        //'Categories'              => 'categories',
-        //'Category'                => 'category',      // Categories member
-        //'DayOfMonth'              => 'dayofmonth',    // Recurrence member
-        //'DayOfWeek'               => 'dayofweek',     // Recurrence member
-        //'Deleted'                 => 'deleted',       // Exception member
-        'DtStamp'                 => 'changed',
-        //'Email'                   => 'email',         // Attendee member
-        'EndTime'                 => 'end',
-        //'Exception'               => 'exception',     // recurrence pattern exception, Exceptions member
-        //'Exceptions'              => 'exceptions',
-        //'ExceptionStartTime'      => 'exceptionstarttime', // Exception member
-        //'FirstDayOfWeek'          => 'firstdayofweek', // Recurrence member
-        //'Interval'                => 'interval',      // Recurrence member
-        //'IsLeapMonth'             => 'isleapmonth',   // Recurrence member
-        'Location'                => 'location',
-        //'MeetingStatus'           => 'meetingstatus',
-        //'MonthOfYear'             => 'monthofyear',   // Recurrence member
-        //'Name'                    => 'name',          // Attendee member
-        //'Occurrences'             => 'occurences',    // Recurrence member
-        //'OrganizerEmail'          => 'organizeremail',
-        //'OrganizerName'           => 'organizername',
-        //'Recurrence'              => 'recurrence',
-        //'Reminder'                => 'reminder',
-        //'ResponseRequested'       => 'responserequested',
-        //'ResponseType'          => 'responsetype',
-        'Sensitivity'             => 'sensitivity',
-        'StartTime'               => 'start',
-        'Subject'                 => 'title',
-        //'Timezone'                => 'timezone',
-        //'Type'                    => 'type',      // Recurrence member
-        'UID'                     => 'uid',
-        //'Until'                   => 'until',     // Recurrence member
-        //'WeekOfMonth'             => 'weekofmonth', // Recurrence member
+        'allDayEvent'             => 'allday',
+        //'attendees'               => 'attendees',
+        'body'                    => 'description',
+        //'bodyTruncated'           => 'bodytruncated',
+        'busyStatus'              => 'free_busy',
+        //'categories'              => 'categories',
+        'dtStamp'                 => 'changed',
+        'endTime'                 => 'end',
+        //'exceptions'              => 'exceptions',
+        'location'                => 'location',
+        //'meetingStatus'           => 'meetingstatus',
+        //'organizerEmail'          => 'organizeremail',
+        //'organizerName'           => 'organizername',
+        //'recurrence'              => 'recurrence',
+        //'reminder'                => 'reminder',
+        //'responseRequested'       => 'responserequested',
+        //'responseType'          => 'responsetype',
+        'sensitivity'             => 'sensitivity',
+        'startTime'               => 'start',
+        'subject'                 => 'title',
+        //'timezone'                => 'timezone',
+        'uID'                     => 'uid',
     );
 
     /**
@@ -209,7 +190,7 @@ class kolab_sync_data_calendar extends kolab_sync_data
                 $tzc = kolab_sync_timezone_converter::getInstance();
 
                 if ($tz_name = $tzc->encodeTimezone($tz_name)) {
-                    $result['Timezone'] = $tz_name;
+                    $result['timezone'] = $tz_name;
                 }
             }
         }
@@ -259,12 +240,12 @@ class kolab_sync_data_calendar extends kolab_sync_data
 
         // Event reminder time
         if ($config['ALARMS'] && ($minutes = $this->from_kolab_alarm($event['alarms']))) {
-            $result['Reminder'] = $minutes;
+            $result['reminder'] = $minutes;
         }
 
         // Categories, Roundcube Calendar plugin supports only one category at a time
         if (!empty($event['categories'])) {
-            $result['Categories'] = (array) $event['categories'];
+            $result['categories'] = (array) $event['categories'];
         }
 
         // Organizer
@@ -272,11 +253,11 @@ class kolab_sync_data_calendar extends kolab_sync_data
             foreach ($event['attendees'] as $idx => $attendee) {
                 if ($attendee['role'] == 'ORGANIZER') {
                     $organizer = $attendee;
-                    if ($name = self::quote($attendee['name'])) {
-                        $result['OrganizerName'] = $name;
+                    if ($name = $attendee['name']) {
+                        $result['organizerName'] = $name;
                     }
-                    if ($email = self::quote($attendee['email'])) {
-                        $result['OrganizerEmail'] = $email;
+                    if ($email = $attendee['email']) {
+                        $result['organizerEmail'] = $email;
                     }
 
                     unset($event['attendees'][$idx]);
@@ -287,27 +268,27 @@ class kolab_sync_data_calendar extends kolab_sync_data
 
         // Attendees
         if (!empty($event['attendees'])) {
-            $result['Attendees'] = array();
+            $result['attendees'] = array();
 
             foreach ($event['attendees'] as $idx => $attendee) {
                 $att = array();
 
                 if ($attendee['name']) {
-                    $att['Name'] = $name;
+                    $att['name'] = $name;
                 }
                 if ($attendee['email']) {
-                    $att['Email'] = $email;
+                    $att['email'] = $email;
                 }
 
                 if ($this->asversion >= 12) {
                     $type   = isset($attendee['role'])   ? $this->attendeeTypeMap[$attendee['role']] : null;
                     $status = isset($attendee['status']) ? $this->attendeeStatusMap[$attende['status']] : null;
 
-                    $att['AttendeeType']   = $type ? $type : self::ATTENDEE_TYPE_REQUIRED;
-                    $att['AttendeeStatus'] = $status ? $status : self::ATTENDEE_STATUS_UNKNOWN;
+                    $att['attendeeType']   = $type ? $type : self::ATTENDEE_TYPE_REQUIRED;
+                    $att['attendeeStatus'] = $status ? $status : self::ATTENDEE_STATUS_UNKNOWN;
                 }
 
-                $result['Attendees'][] = new Syncroton_Model_EventAttendee($att);
+                $result['attendees'][] = new Syncroton_Model_EventAttendee($att);
             }
 /*
             // set own status
@@ -320,10 +301,10 @@ class kolab_sync_data_calendar extends kolab_sync_data
         }
 
         // Event meeting status
-        $result['MeetingStatus'] = intval(!empty($result['Attendees']));
+        $result['meetingStatus'] = intval(!empty($result['attendees']));
 
         // Recurrence
-        $result['Recurrence'] = $this->recurrence_from_kolab($event);
+        $result['recurrence'] = $this->recurrence_from_kolab($event);
 
         return new Syncroton_Model_Event($result);
     }
@@ -346,7 +327,7 @@ class kolab_sync_data_calendar extends kolab_sync_data
         $event['allday'] = 0;
 
         // Timezone
-        if (isset($data->Timezone)) {
+        if (isset($data->timezone)) {
             $tzc      = kolab_sync_timezone_converter::getInstance();
             $expected = kolab_format::$timezone->getName();
 
@@ -354,7 +335,7 @@ class kolab_sync_data_calendar extends kolab_sync_data
                 $expected = $event['start']->getTimezone()->getName();
             }
 
-            $timezone = $tzc->getTimezone($data->Timezone, $expected);
+            $timezone = $tzc->getTimezone($data->timezone, $expected);
             try {
                 $timezone = new DateTimeZone($timezone);
             }
@@ -381,7 +362,7 @@ class kolab_sync_data_calendar extends kolab_sync_data
                     $value->setTimezone($timezone);
                 }
                 // In ActiveSync all-day event ends on 00:00:00 next day
-                if ($value && $data->AllDayEvent && $name == 'end') {
+                if ($value && $data->allDayEvent && $name == 'end') {
                     $value->modify('-1 second');
                 }
 
@@ -412,22 +393,22 @@ class kolab_sync_data_calendar extends kolab_sync_data
         // Reminder
         // @TODO: should alarms be used when importing event from phone?
         if ($config['ALARMS']) {
-            $event['alarms'] = $this->to_kolab_alarm($data->Reminder, $event);
+            $event['alarms'] = $this->to_kolab_alarm($data->reminder, $event);
         }
 
         $event['attendees']  = array();
         $event['categories'] = array();
 
         // Categories
-        if (isset($data->Categories)) {
-            foreach ($data->Categories as $category) {
+        if (isset($data->categories)) {
+            foreach ($data->categories as $category) {
                 $event['categories'][] = $category;
             }
         }
 
         // Organizer
-        $name  = $data->OrganizerName;
-        $email = $data->OrganizerEmail;
+        $name  = $data->organizerName;
+        $email = $data->organizerEmail;
         if ($name || $email) {
             $event['attendees'][] = array(
                 'role'  => 'ORGANIZER',
@@ -437,11 +418,11 @@ class kolab_sync_data_calendar extends kolab_sync_data
         }
 
         // Attendees
-        if (isset($data->Attendees)) {
-            foreach ($data->Attendees as $attendee) {
+        if (isset($data->attendees)) {
+            foreach ($data->attendees as $attendee) {
                 $role = false;
-                if (isset($attendee->AttendeeType)) {
-                    $role = array_search($attendee->AttendeeType, $this->attendeeTypeMap);
+                if (isset($attendee->attendeeType)) {
+                    $role = array_search($attendee->attendeeType, $this->attendeeTypeMap);
                 }
                 if ($role === false) {
                     $role = array_search(self::ATTENDEE_TYPE_REQUIRED, $this->attendeeTypeMap);
@@ -451,8 +432,8 @@ class kolab_sync_data_calendar extends kolab_sync_data
 
                 $event['attendees'][] = array(
                     'role'  => $role,
-                    'name'  => $attendee->Name,
-                    'email' => $attendee->Email,
+                    'name'  => $attendee->name,
+                    'email' => $attendee->email,
                 );
             }
         }
diff --git a/lib/kolab_sync_data_contacts.php b/lib/kolab_sync_data_contacts.php
index 58adf36..8d379c7 100644
--- a/lib/kolab_sync_data_contacts.php
+++ b/lib/kolab_sync_data_contacts.php
@@ -32,73 +32,68 @@ class kolab_sync_data_contacts extends kolab_sync_data
      * Mapping from ActiveSync Contacts namespace fields
      */
     protected $mapping = array(
-        'Anniversary'           => 'anniversary',
-        'AssistantName'         => 'assistant:0',
-        //'AssistnamePhoneNumber' => 'assistnamephonenumber',
-        'Birthday'              => 'birthday',
-        'Body'                  => 'notes',
-        //'BodySize'              => 'bodysize',
-        //'BodyTruncated'         => 'bodytruncated',
-        //'Business2PhoneNumber'  => 'business2phonenumber',
-        'BusinessAddressCity'          => 'address.work.locality',
-        'BusinessAddressCountry'       => 'address.work.country',
-        'BusinessAddressPostalCode'    => 'address.work.code',
-        'BusinessAddressState'         => 'address.work.region',
-        'BusinessAddressStreet'        => 'address.work.street',
-        'BusinessFaxNumber'     => 'phone.workfax.number',
-        'BusinessPhoneNumber'   => 'phone.work.number',
-        'CarPhoneNumber'        => 'phone.car.number',
-        //'Categories'            => 'categories',
-        //'Category'              => 'category',
-        'Children'              => 'children',
-        //'Child'                 => 'child',
-        'CompanyName'           => 'organization',
-        'Department'            => 'department',
-        'Email1Address'         => 'email:0',
-        'Email2Address'         => 'email:1',
-        'Email3Address'         => 'email:2',
-        //'FileAs'                => 'fileas', //@TODO: ?
-        'FirstName'             => 'firstname',
-        //'Home2PhoneNumber'      => 'home2phonenumber',
-        'HomeAddressCity'       => 'address.home.locality',
-        'HomeAddressCountry'    => 'address.home.country',
-        'HomeAddressPostalCode' => 'address.home.code',
-        'HomeAddressState'      => 'address.home.region',
-        'HomeAddressStreet'     => 'address.home.street',
-        'HomeFaxNumber'         => 'phone.homefax.number',
-        'HomePhoneNumber'       => 'phone.home.number',
-        'JobTitle'              => 'jobtitle',
-        'LastName'              => 'surname',
-        'MiddleName'            => 'middlename',
-        'MobilePhoneNumber'     => 'phone.mobile.number',
-        //'OfficeLocation'        => 'officelocation',
-        'OtherAddressCity'      => 'address.office.locality',
-        'OtherAddressCountry'   => 'address.office.country',
-        'OtherAddressPostalCode' => 'address.office.code',
-        'OtherAddressState'     => 'address.office.region',
-        'OtherAddressStreet'    => 'address.office.street',
-        'PagerNumber'           => 'phone.pager.number',
-        //'RadioPhoneNumber'      => 'radiophonenumber',
-        'Spouse'                => 'spouse',
-        'Suffix'                => 'suffix',
-        'Title'                 => 'prefix',
-        'WebPage'               => 'website.homepage.url',
-        //'YomiCompanyName'       => 'yomicompanyname',
-        //'YomiFirstName'         => 'yomifirstname',
-        //'YomiLastName'          => 'yomilastname',
-        //'Rtf'                   => 'rtf',
-        'Picture'               => 'photo',
+        'anniversary'           => 'anniversary',
+        'assistantName'         => 'assistant:0',
+        //'assistantPhoneNumber' => 'assistantphonenumber',
+        'birthday'              => 'birthday',
+        'body'                  => 'notes',
+        'businessAddressCity'          => 'address.work.locality',
+        'businessAddressCountry'       => 'address.work.country',
+        'businessAddressPostalCode'    => 'address.work.code',
+        'businessAddressState'         => 'address.work.region',
+        'businessAddressStreet'        => 'address.work.street',
+        'businessFaxNumber'     => 'phone.workfax.number',
+        'businessPhoneNumber'   => 'phone.work.number',
+        'carPhoneNumber'        => 'phone.car.number',
+        //'categories'            => 'categories',
+        'children'              => 'children',
+        'companyName'           => 'organization',
+        'department'            => 'department',
+        'email1Address'         => 'email:0',
+        'email2Address'         => 'email:1',
+        'email3Address'         => 'email:2',
+        //'fileAs'                => 'fileas', //@TODO: ?
+        'firstName'             => 'firstname',
+        //'home2PhoneNumber'      => 'home2phonenumber',
+        'homeAddressCity'       => 'address.home.locality',
+        'homeAddressCountry'    => 'address.home.country',
+        'homeAddressPostalCode' => 'address.home.code',
+        'homeAddressState'      => 'address.home.region',
+        'homeAddressStreet'     => 'address.home.street',
+        'homeFaxNumber'         => 'phone.homefax.number',
+        'homePhoneNumber'       => 'phone.home.number',
+        'jobTitle'              => 'jobtitle',
+        'lastName'              => 'surname',
+        'middleName'            => 'middlename',
+        'mobilePhoneNumber'     => 'phone.mobile.number',
+        //'officeLocation'        => 'officelocation',
+        'otherAddressCity'      => 'address.office.locality',
+        'otherAddressCountry'   => 'address.office.country',
+        'otherAddressPostalCode' => 'address.office.code',
+        'otherAddressState'     => 'address.office.region',
+        'otherAddressStreet'    => 'address.office.street',
+        'pagerNumber'           => 'phone.pager.number',
+        'picture'               => 'photo',
+        //'radioPhoneNumber'      => 'radiophonenumber',
+        //'rtf'                   => 'rtf',
+        'spouse'                => 'spouse',
+        'suffix'                => 'suffix',
+        'title'                 => 'prefix',
+        'webPage'               => 'website.homepage.url',
+        //'yomiCompanyName'       => 'yomicompanyname',
+        //'yomiFirstName'         => 'yomifirstname',
+        //'yomiLastName'          => 'yomilastname',
         // Mapping from ActiveSync Contacts2 namespace fields
-        //'CustomerId'            => 'customerid',
-        //'GovernmentId'          => 'governmentid',
-        'IMAddress'             => 'im:0',
-        'IMAddress2'            => 'im:1',
-        'IMAddress3'            => 'im:2',
-        'ManagerName'           => 'manager:0',
-        //'CompanyMainPhone'      => 'companymainphone',
-        //'AccountName'           => 'accountname',
-        'NickName'              => 'nickname',
-        //'MMS'                   => 'mms',
+        //'accountName'           => 'accountname',
+        //'companyMainPhone'      => 'companymainphone',
+        //'customerId'            => 'customerid',
+        //'governmentId'          => 'governmentid',
+        'iMAddress'             => 'im:0',
+        'iMAddress2'            => 'im:1',
+        'iMAddress3'            => 'im:2',
+        'managerName'           => 'manager:0',
+        //'mMS'                   => 'mms',
+        'nickName'              => 'nickname',
     );
 
     /**
diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php
index 311ef70..6b6778d 100644
--- a/lib/kolab_sync_data_email.php
+++ b/lib/kolab_sync_data_email.php
@@ -34,21 +34,20 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
      * Mapping from ActiveSync Email namespace fields
      */
     protected $mapping = array(
-        'Cc'                    => 'cc',
-        //'ContentClass'          => 'contentclass',
-        'DateReceived'          => 'internaldate',
-        //'DisplayTo'             => 'displayto', //?
-        //'Flag'                  => 'flag',
-        //'FlagType'              => 'flagtype', // child of Flag element
-        'From'                  => 'from',
-        //'Importance'            => 'importance',
-        'InternetCPID'          => 'charset',
-        //'MessageClass'          => 'messageclass',
-        'ReplyTo'               => 'replyto',
-        //'Read'                  => 'read',
-        'Subject'               => 'subject',
-        //'ThreadTopic'           => 'threadtopic',
-        'To'                    => 'to',
+        'cc'                    => 'cc',
+        //'contentClass'          => 'contentclass',
+        'dateReceived'          => 'internaldate',
+        //'displayTo'             => 'displayto', //?
+        //'flag'                  => 'flag',
+        'from'                  => 'from',
+        //'importance'            => 'importance',
+        'internetCPID'          => 'charset',
+        //'messageClass'          => 'messageclass',
+        'replyTo'               => 'replyto',
+        //'read'                  => 'read',
+        'subject'               => 'subject',
+        //'threadTopic'           => 'threadtopic',
+        'to'                    => 'to',
     );
 
     /**
@@ -162,14 +161,14 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
 //        $result['ConversationIndex'] = 'CA2CFA8A23';
 
         // Read flag
-        $result['Read'] = intval(!empty($headers->flags['SEEN']));
+        $result['read'] = intval(!empty($headers->flags['SEEN']));
 
         // Flagged message
         if (!empty($headers->flags['FLAGGED'])) {
             // Use FollowUp flag which is used in Android when message is marked with a star
-            $result['Flag'] = new Syncroton_Model_EmailFlag(array(
-                'FlagType' => 'FollowUp',
-                'Status' => Syncroton_Model_EmailFlag::STATUS_ACTIVE,
+            $result['flag'] = new Syncroton_Model_EmailFlag(array(
+                'flagType' => 'FollowUp',
+                'status' => Syncroton_Model_EmailFlag::STATUS_ACTIVE,
             ));
         }
 
@@ -179,7 +178,7 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
                 $result['importance'] = 2; // High
             }
             else if ($headers->priority > 3) {
-                 $result['Importance'] = 0; // Low
+                 $result['importance'] = 0; // Low
             }
         }
 
@@ -271,24 +270,24 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
         }
 
         $body_params = array(
-            'Type'      => $airSyncBaseType,
-            'Truncated' => $isTruncacted,
+            'type'      => $airSyncBaseType,
+            'truncated' => $isTruncacted,
         );
         if ($isTruncated) {
-            $body_params['EstimatedDataSize'] = $real_length;
+            $body_params['estimatedDataSize'] = $real_length;
         }
 
-        $result['Body']           = $this->setBody($messageBody, $body_params);
-        $result['NativeBodyType'] = intval($message->has_html_part(false));
+        $result['body']           = $this->setBody($messageBody, $body_params);
+        $result['nativeBodyType'] = intval($message->has_html_part(false));
 
         // Message class
-        $result['MessageClass'] = 'IPM.Note' . ($airSyncBaseType == Syncroton_Command_Sync::MIMESUPPORT_SEND_MIME ? '.SMIME' : '');
-        $result['ContentClass'] = 'urn:content-classes:message';
+        $result['messageClass'] = 'IPM.Note' . ($airSyncBaseType == Syncroton_Command_Sync::MIMESUPPORT_SEND_MIME ? '.SMIME' : '');
+        $result['contentClass'] = 'urn:content-classes:message';
 
         // attachments
         $attachments = array_merge($message->attachments, $message->inline_parts);
         if (!empty($attachments)) {
-            $result['Attachments'] = array();
+            $result['attachments'] = array();
 
             foreach ($attachments as $attachment) {
                 $att = array();
@@ -298,23 +297,23 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
                     $filename = 'HTML Part';
                 }
 
-                $att['DisplayName']   = $filename;
-                $att['FileReference'] = $serverId . '::' . $attachment->mime_id;
-                $att['Method']        = 1;
-                $att['EstimatedDataSize'] = $attachment->size;
+                $att['displayName']   = $filename;
+                $att['fileReference'] = $serverId . '::' . $attachment->mime_id;
+                $att['method']        = 1;
+                $att['estimatedDataSize'] = $attachment->size;
 
                 if (!empty($attachment->content_id)) {
-                    $att['ContentId'] = $attachment->content_id;
+                    $att['contentId'] = $attachment->content_id;
                 }
                 if (!empty($attachment->content_location)) {
-                    $att['ContentLocation'] = $attachment->content_location;
+                    $att['contentLocation'] = $attachment->content_location;
                 }
 
                 if (in_array($attachment, $message->inline_parts)) {
-                    $att['IsInline'] = 1;
+                    $att['isInline'] = 1;
                 }
 
-                $result['Attachments'][] = new Syncroton_Model_EmailAttachment($att);
+                $result['attachments'][] = new Syncroton_Model_EmailAttachment($att);
             }
         }
 
@@ -456,20 +455,20 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
         $is_flagged = !empty($message->headers->flags['FLAGGED']);
 
         // Read status change
-        if (isset($entry->Read)) {
+        if (isset($entry->read)) {
             // here we update only Read flag
-            $flag = (((int)$entry->Read != 1) ? 'UN' : '') . 'SEEN';
+            $flag = (((int)$entry->read != 1) ? 'UN' : '') . 'SEEN';
             $this->storage->set_flag($msg['uid'], $flag, $msg['foldername']);
         }
 
         // Flag change
-        if (empty($entry->Flag)) {
+        if (empty($entry->flag)) {
             if ($is_flagged) {
                 $this->storage->set_flag($msg['uid'], 'UNFLAGGED', $msg['foldername']);
             }
         }
-        else if (!$is_flagged && !empty($entry->Flag)) {
-            if ($entry->Flag->FlagType && preg_match('/^follow\s*up/i', $entry->Flag->FlagType)) {
+        else if (!$is_flagged && !empty($entry->flag)) {
+            if ($entry->flag->flagType && preg_match('/^follow\s*up/i', $entry->flag->flagType)) {
                 $this->storage->set_flag($msg['uid'], 'FLAGGED', $msg['foldername']);
             }
         }
@@ -740,9 +739,9 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
             $uids = $search->get();
             foreach ($uids as $idx => $uid) {
                 $uids[$idx] = new Syncroton_Model_StoreResponseResult(array(
-                    'LongId'       => $this->createMessageId($folderid, $uid),
-                    'CollectionId' => $folderid,
-                    'Class'        => 'Email',
+                    'longId'       => $this->createMessageId($folderid, $uid),
+                    'collectionId' => $folderid,
+                    'class'        => 'Email',
                 ));
             }
             $result = array_merge($result, $uids);
@@ -853,8 +852,8 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
         $content_type = $part->mimetype;
 
         return new Syncroton_Model_FileReference(array(
-            'ContentType' => $content_type,
-            'Data'        => $body,
+            'contentType' => $content_type,
+            'data'        => $body,
         ));
     }
 
diff --git a/lib/kolab_sync_data_gal.php b/lib/kolab_sync_data_gal.php
index e830790..d7bb2e8 100644
--- a/lib/kolab_sync_data_gal.php
+++ b/lib/kolab_sync_data_gal.php
@@ -48,17 +48,17 @@ class kolab_sync_data_gal extends kolab_sync_data implements Syncroton_Data_IDat
      * Mapping from ActiveSync Contacts namespace fields
      */
     protected $mapping = array(
-        'Alias'         => 'nickname',
-        'Company'       => 'organization',
-        'DisplayName'   => 'name',
-        'EmailAddress'  => 'email',
-        'FirstName'     => 'firstname',
-        'LastName'      => 'surname',
-        'MobilePhone'   => 'phone.mobile',
-        'Office'        => 'office',
-        'Phone'         => 'phone',
-        'Title'         => 'jobtitle',
-        'Picture'       => 'photo',
+        'alias'         => 'nickname',
+        'company'       => 'organization',
+        'displayName'   => 'name',
+        'emailAddress'  => 'email',
+        'firstName'     => 'firstname',
+        'lastName'      => 'surname',
+        'mobilePhone'   => 'phone.mobile',
+        'office'        => 'office',
+        'picture'       => 'photo',
+        'phone'         => 'phone',
+        'title'         => 'jobtitle',
     );
 
     /**
@@ -158,8 +158,8 @@ class kolab_sync_data_gal extends kolab_sync_data implements Syncroton_Data_IDat
                 }
 
                 $value = new Syncroton_Model_GALPicture(array(
-                    'Data'   => $value, // binary
-                    'Status' => Syncroton_Model_GALPicture::STATUS_SUCCESS,
+                    'data'   => $value, // binary
+                    'status' => Syncroton_Model_GALPicture::STATUS_SUCCESS,
                 ));
 
                 break;
@@ -238,7 +238,7 @@ class kolab_sync_data_gal extends kolab_sync_data implements Syncroton_Data_IDat
         foreach ($records as $idx => $rec) {
             $longId = $rec['ID'];
             $result[] = new Syncroton_Model_StoreResponseResult(array(
-                'LongId'       => $longId,
+                'longId'       => $longId,
             ));
 
             $this->result[$longId] = $rec;
diff --git a/lib/kolab_sync_data_tasks.php b/lib/kolab_sync_data_tasks.php
index be94f59..318dc5b 100644
--- a/lib/kolab_sync_data_tasks.php
+++ b/lib/kolab_sync_data_tasks.php
@@ -32,20 +32,20 @@ class kolab_sync_data_tasks extends kolab_sync_data
      * Mapping from ActiveSync Calendar namespace fields
      */
     protected $mapping = array(
-        'Body'            => 'description',
-        'Categories'      => 'categories',
-        //'Complete'      => 'complete', // handled separately
-        'DateCompleted'   => 'changed',
-        'DueDate'         => 'due',
-        'Importance'      => 'priority',
-        //'Recurrence'      => 'recurrence',
-        //'ReminderSet'     => 'reminderset',
-        //'ReminderTime'    => 'remindertime',
-        'Sensitivity'     => 'sensitivity',
-        'StartDate'       => 'start',
-        'Subject'         => 'title',
-        'UtcDueDate'      => 'due',
-        'UtcStartDate'    => 'start',
+        'body'            => 'description',
+        'categories'      => 'categories',
+        //'complete'      => 'complete', // handled separately
+        'dateCompleted'   => 'changed',
+        'dueDate'         => 'due',
+        'importance'      => 'priority',
+        //'recurrence'      => 'recurrence',
+        //'reminderSet'     => 'reminderset',
+        //'reminderTime'    => 'remindertime',
+        'sensitivity'     => 'sensitivity',
+        'startDate'       => 'start',
+        'subject'         => 'title',
+        'utcDueDate'      => 'due',
+        'utcStartDate'    => 'start',
     );
 
     /**
@@ -110,7 +110,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
         $result = array();
 
         // Completion status (required)
-        $result['Complete'] = intval(!empty($task['status']) && $task['status'] == 'COMPLETED');
+        $result['complete'] = intval(!empty($task['status']) && $task['status'] == 'COMPLETED');
 
         // Calendar namespace fields
         foreach ($this->mapping as $key => $name) {
@@ -125,7 +125,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
                 break;
 
             case 'changed':
-                $value = $result['Complete'] ? self::date_from_kolab($value) : null;
+                $value = $result['complete'] ? self::date_from_kolab($value) : null;
                 break;
 
             case 'description':
@@ -142,7 +142,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
                 // but Kolab uses ten levels:
                 // 0 - unknown and 1-9 where 1 is the highest
                 if ($value) {
-                    $result['Importance'] = $value > 5 ? 2 : 0;
+                    $result['importance'] = $value > 5 ? 2 : 0;
                 }
                 break;
             }
@@ -155,7 +155,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
         }
 
         // Recurrence
-        $result['Recurrence'] = $this->recurrence_from_kolab($task, 'Task');
+        $result['recurrence'] = $this->recurrence_from_kolab($task, 'Task');
 
         return new Syncroton_Model_Task($result);
     }
@@ -210,7 +210,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
             $this->setKolabDataItem($task, $name, $value);
         }
 
-        if (!empty($data->Complete)) {
+        if (!empty($data->complete)) {
             $task['status']   = 'COMPLETED';
             $task['complete'] = 100;
         }





More information about the commits mailing list