/**
  * generate FolderSync response
  *
  * @todo currently we support only the main folder which contains all contacts/tasks/events/notes per class
  * 
  * @param boolean $_keepSession keep session active(don't logout user) when true
  */
 public function getResponse($_keepSession = FALSE)
 {
     $folderSync = $this->_outputDom->documentElement;
     if ($this->_syncKey > '0' && $this->_controller->validateSyncKey($this->_device, $this->_syncKey, 'FolderSync') === false) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " INVALID synckey provided");
         $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Status', self::STATUS_INVALID_SYNC_KEY));
     } else {
         $adds = array();
         $deletes = array();
         $count = 0;
         if ($this->_syncKey == 0) {
             $this->_folderStateBackend->resetState($this->_device);
         }
         foreach ($this->_classes as $class) {
             $dataController = ActiveSync_Controller::dataFactory($class, $this->_device, $this->_syncTimeStamp);
             try {
                 $folders = $dataController->getSupportedFolders();
             } catch (Exception $e) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) {
                     Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . " failed to get folders for class {$class}. " . $e->getMessage());
                 }
                 if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) {
                     Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . " failed to get folders for class {$class}. " . $e->getTraceAsString());
                 }
                 continue;
             }
             if ($this->_syncKey == 0) {
                 foreach ($folders as $folderId => $folder) {
                     $adds[$class][$folderId] = $folder;
                     $count++;
                 }
             } else {
                 $allServerEntries = array_keys($folders);
                 $allClientEntries = $this->_folderStateBackend->getClientState($this->_device, $class);
                 // added entries
                 $serverDiff = array_diff($allServerEntries, $allClientEntries);
                 foreach ($serverDiff as $folderId) {
                     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " add {$class} {$folderId}");
                     }
                     $adds[$class][$folderId] = $folders[$folderId];
                     $count++;
                 }
                 // deleted entries
                 $serverDiff = array_diff($allClientEntries, $allServerEntries);
                 foreach ($serverDiff as $folderId) {
                     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " delete {$class} {$folderId}");
                     }
                     $deletes[$class][$folderId] = $folderId;
                     $count++;
                 }
             }
         }
         if ($count > 0) {
             $newSyncKey = $this->_syncKey + 1;
         } else {
             $newSyncKey = $this->_syncKey;
         }
         // create xml output
         $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Status', self::STATUS_SUCCESS));
         $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'SyncKey', $newSyncKey));
         $changes = $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Changes'));
         $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Count', $count));
         foreach ($adds as $class => $folders) {
             foreach ((array) $folders as $folder) {
                 $add = $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Add'));
                 $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ServerId', $folder['folderId']));
                 $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ParentId', $folder['parentId']));
                 $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'DisplayName', $folder['displayName']));
                 $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Type', $folder['type']));
                 $this->_addFolderState($class, $folder['folderId']);
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " {$class} => " . $folder['folderId']);
                 }
             }
         }
         foreach ($deletes as $class => $folders) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " {$class}");
             }
             foreach ((array) $folders as $folderId) {
                 $delete = $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Delete'));
                 $delete->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ServerId', $folderId));
                 $this->_deleteFolderState($class, $folderId);
             }
         }
         $this->_controller->updateSyncKey($this->_device, $newSyncKey, $this->_syncTimeStamp, 'FolderSync');
     }
     return $this->_outputDom;
 }