diff --git a/src/app/Console/Commands/Wallet/BalancesCommand.php b/src/app/Console/Commands/Wallet/BalancesCommand.php
index e8f7bd81..2f9667b2 100644
--- a/src/app/Console/Commands/Wallet/BalancesCommand.php
+++ b/src/app/Console/Commands/Wallet/BalancesCommand.php
@@ -1,82 +1,84 @@
 <?php
 
 namespace App\Console\Commands\Wallet;
 
 use App\Transaction;
 use App\Wallet;
 use Illuminate\Console\Command;
 use Illuminate\Support\Facades\DB;
 
 class BalancesCommand extends Command
 {
     /**
      * The name and signature of the console command.
      *
      * @var string
      */
     protected $signature = 'wallet:balances {--skip-zeros} {--negative} {--invalid}';
 
     /**
      * The console command description.
      *
      * @var string
      */
     protected $description = 'Show the balance on wallets';
 
     /**
      * Execute the console command.
      *
      * @return mixed
      */
     public function handle()
     {
         $skip_zeros = $this->option('skip-zeros');
         $negative = $this->option('negative');
         $invalid = $this->option('invalid');
 
         $wallets = Wallet::select('wallets.*', 'users.email')
             ->join('users', 'users.id', '=', 'wallets.user_id')
             ->withEnvTenantContext('users')
             ->whereNull('users.deleted_at')
             ->orderBy('balance');
 
         if ($invalid) {
             $balances = Transaction::select(DB::raw('sum(amount) as summary, object_id as wallet_id'))
                 ->where('object_type', Wallet::class)
                 ->groupBy('wallet_id');
 
             $wallets->addSelect('balances.summary')
                 ->leftJoinSub($balances, 'balances', function ($join) {
                     $join->on('wallets.id', '=', 'balances.wallet_id');
                 })
-                ->whereRaw('(balances.summary != wallets.balance or (balances.summary is null and wallets.balance != 0))');
+                ->whereRaw(
+                    '(balances.summary != wallets.balance or (balances.summary is null and wallets.balance != 0))'
+                );
 
             if ($negative) {
                 $wallets->where('balances.summary', '<', 0);
             } elseif ($skip_zeros) {
                 $wallets->whereRaw('balances.summary != 0 and balances.summary is not null');
             }
         } else {
             if ($negative) {
                 $wallets->where('wallets.balance', '<', 0);
             } elseif ($skip_zeros) {
                 $wallets->whereNot('wallets.balance', 0);
             }
         }
 
         $wallets->cursor()->each(
             function (Wallet $wallet) use ($invalid) {
                 $balance = $wallet->balance;
                 $summary = $wallet->summary ?? 0;
                 $email = $wallet->email; // @phpstan-ignore-line
 
                 if ($invalid) {
                     $this->info(sprintf("%s: %8s %8s (%s)", $wallet->id, $balance, $summary, $email));
                     return;
                 }
 
                 $this->info(sprintf("%s: %8s (%s)", $wallet->id, $balance, $email));
             }
         );
     }
 }
diff --git a/src/app/Console/Commands/Wallet/EntitlementsCommand.php b/src/app/Console/Commands/Wallet/EntitlementsCommand.php
index 13da2cef..2bac9a71 100644
--- a/src/app/Console/Commands/Wallet/EntitlementsCommand.php
+++ b/src/app/Console/Commands/Wallet/EntitlementsCommand.php
@@ -1,79 +1,81 @@
 <?php
 
 namespace App\Console\Commands\Wallet;
 
 use App\Console\Command;
 
 class EntitlementsCommand extends Command
 {
     /**
      * The name and signature of the console command.
      *
      * @var string
      */
     protected $signature = 'wallet:entitlements {wallet} {--details}';
 
     /**
      * The console command description.
      *
      * @var string
      */
     protected $description = "List a wallet's entitlements.";
 
     /**
      * Execute the console command.
      *
      * @return mixed
      */
     public function handle()
     {
         $wallet = $this->getWallet($this->argument('wallet'));
 
         if (!$wallet) {
             $this->error("Wallet not found.");
             return 1;
         }
 
         $details = $this->option('details');
 
         $discount = $wallet->getDiscountRate();
 
         $entitlements = $wallet->entitlements()
             ->select('skus.title', 'entitlements.*')
             ->join('skus', 'skus.id', '=', 'entitlements.sku_id')
             ->orderBy('entitleable_type')
             ->orderBy('entitleable_id')
             ->orderBy('sku_id')
             ->orderBy('created_at')
             ->get();
 
         foreach ($entitlements as $entitlement) {
             // sanity check, deleted entitleable?
             if (!$entitlement->entitleable) {
-                $this->info("{$entitlement->id}: DELETED {$entitlement->entitleable_type} {$entitlement->entitleable_id}");
+                $this->info(
+                    "{$entitlement->id}: DELETED {$entitlement->entitleable_type} {$entitlement->entitleable_id}"
+                );
                 continue;
             }
 
             $title = $entitlement->title; // @phpstan-ignore-line
             $cost = $wallet->money((int) ($entitlement->cost * $discount));
             $entitleableTitle = $entitlement->entitleable->toString();
             $add = '';
 
             if ($details) {
                 $add = sprintf(
                     "(created: %s, updated: %s",
                     $entitlement->created_at->toDateString(),
                     $entitlement->updated_at->toDateString()
                 );
 
                 if ($discount) {
                     $add .= sprintf(", cost: %s", $wallet->money($entitlement->cost));
                 }
 
                 $add .= ")";
             }
 
             $this->info("{$entitlement->id}: {$entitleableTitle} ({$title}) {$cost}{$add}");
         }
     }
 }
diff --git a/src/tests/Infrastructure/ActivesyncTest.php b/src/tests/Infrastructure/ActivesyncTest.php
index 688bc0dd..3b65e71d 100644
--- a/src/tests/Infrastructure/ActivesyncTest.php
+++ b/src/tests/Infrastructure/ActivesyncTest.php
@@ -1,1665 +1,1667 @@
 <?php
 
 namespace Tests\Infrastructure;
 
 use App\Backends\Roundcube;
 use Tests\TestCase;
 use Illuminate\Support\Str;
 
+// @codingStandardsIgnoreStart
 class ActivesyncTest extends TestCase
 {
     private static ?\GuzzleHttp\Client $client = null;
     private static ?\App\User $user = null;
     private static ?string $deviceId = null;
     private static ?string $deviceId2 = null;
 
     private static function toWbxml($xml)
     {
         $outputStream = fopen("php://temp", 'r+');
         $encoder = new \Syncroton_Wbxml_Encoder($outputStream, 'UTF-8', 3);
         $dom = new \DOMDocument();
         $dom->loadXML($xml);
         $encoder->encode($dom);
         rewind($outputStream);
         return stream_get_contents($outputStream);
     }
 
     private static function fromWbxml($binary)
     {
         $stream = fopen('php://memory', 'r+');
         fwrite($stream, $binary);
         rewind($stream);
         $decoder = new \Syncroton_Wbxml_Decoder($stream);
         return $decoder->decode();
     }
 
     private function request($request, $cmd, $deviceId = null)
     {
         $user = self::$user;
         if (!$deviceId) {
             $deviceId = self::$deviceId;
         }
         $body = self::toWbxml($request);
         return self::$client->request(
             'POST',
             "?Cmd={$cmd}&User={$user->email}&DeviceId={$deviceId}&DeviceType=WindowsOutlook15",
             [
                 'headers' => [
                     "Content-Type" => "application/vnd.ms-sync.wbxml",
                     'MS-ASProtocolVersion' => "14.0"
                 ],
                 'body' => $body
             ]
         );
     }
 
     private function xpath($dom)
     {
         $xpath = new \DOMXpath($dom);
         $xpath->registerNamespace("ns", $dom->documentElement->namespaceURI);
         $xpath->registerNamespace("Tasks", "uri:Tasks");
         $xpath->registerNamespace("Calendar", "uri:Calendar");
         $xpath->registerNamespace("Email", "uri:Email");
         $xpath->registerNamespace("Email2", "uri:Email2");
         return $xpath;
     }
 
 
     /**
      * {@inheritDoc}
      */
     public function setUp(): void
     {
         parent::setUp();
 
         if (!self::$deviceId) {
             // By always creating a new device we force syncroton to initialize.
             // Otherwise we work against uninitialized metadata (subscription states),
             // because the account has been removed, but syncroton doesn't reinitalize the metadata for known devices.
             self::$deviceId = (string) Str::uuid();
             self::$deviceId2 = (string) Str::uuid();
         }
 
         $deviceId = self::$deviceId;
         \config(['imap.default_folders' => [
             'Drafts' => [
                 'metadata' => [
                     '/private/vendor/kolab/folder-type' => 'mail.drafts',
                     '/private/vendor/kolab/activesync' => "{\"FOLDER\":{\"{$deviceId}\":{\"S\":1}}}"
                 ],
             ],
             'Calendar' => [
                 'metadata' => [
                     '/private/vendor/kolab/folder-type' => 'event.default',
                     '/private/vendor/kolab/activesync' => "{\"FOLDER\":{\"{$deviceId}\":{\"S\":1}}}"
                 ],
             ],
             'Tasks' => [
                 'metadata' => [
                     '/private/vendor/kolab/folder-type' => 'task.default',
                     '/private/vendor/kolab/activesync' => "{\"FOLDER\":{\"{$deviceId}\":{\"S\":1}}}"
                 ],
             ],
             'Contacts' => [
                 'metadata' => [
                     '/private/vendor/kolab/folder-type' => 'contact.default',
                     '/private/vendor/kolab/activesync' => "{\"FOLDER\":{\"{$deviceId}\":{\"S\":1}}}"
                 ],
             ],
         ]]);
 
         if (!self::$user) {
             self::$user = $this->getTestUser('activesynctest@kolab.org', ['password' => 'simple123'], true);
             //FIXME this shouldn't be required, but it seems to be.
             Roundcube::dbh()->table('kolab_cache_task')->truncate();
             Roundcube::dbh()->table('syncroton_folder')->truncate();
             // Roundcube::dbh()->table('syncroton_content')->truncate();
             // Roundcube::dbh()->table('syncroton_device')->truncate();
         }
         if (!self::$client) {
             self::$client = new \GuzzleHttp\Client([
                     'http_errors' => false, // No exceptions
                     'base_uri' => \config("services.activesync.uri"),
                     'verify' => false,
                     'auth' => [self::$user->email, 'simple123'],
                     'connect_timeout' => 10,
                     'timeout' => 10,
                     'headers' => [
                         "Content-Type" => "application/xml; charset=utf-8",
                         "Depth" => "1",
                     ]
             ]);
         }
     }
 
     public function testOptions()
     {
         $response = self::$client->request('OPTIONS', '');
         $this->assertEquals(200, $response->getStatusCode());
         $this->assertStringContainsString('14', $response->getHeader('MS-Server-ActiveSync')[0]);
         $this->assertStringContainsString('14.1', $response->getHeader('MS-ASProtocolVersions')[0]);
         $this->assertStringContainsString('FolderSync', $response->getHeader('MS-ASProtocolCommands')[0]);
     }
 
     public function testPartialCommand()
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <FolderSync xmlns="uri:FolderHierarchy">
             <SyncKey>0</SyncKey>
         </FolderSync>
         EOF;
 
         $body = self::toWbxml($request);
         $deviceId = self::$deviceId;
         $user = self::$user;
         $response =  self::$client->request(
             'POST',
             "?Cmd=FolderSync&User={$user->email}&DeviceId={$deviceId}&DeviceType=WindowsOutlook15",
             [
                 'headers' => [
                     "Content-Type" => "application/vnd.ms-sync.wbxml",
                     'MS-ASProtocolVersion' => "14.0"
                 ],
                 //Truncated body
                 'body' => substr($body, 0, strlen($body) / 2)
             ]
         );
 
         $this->assertEquals(500, $response->getStatusCode());
     }
 
     public function testList()
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <FolderSync xmlns="uri:FolderHierarchy">
             <SyncKey>0</SyncKey>
         </FolderSync>
         EOF;
 
         $response = $this->request($request, 'FolderSync');
         $this->assertEquals(200, $response->getStatusCode());
         $dom = self::fromWbxml($response->getBody());
         $xml = $dom->saveXML();
 
         $this->assertStringContainsString('INBOX', $xml);
         // The hash is based on the name, so it's always the same
         $inboxId = '38b950ebd62cd9a66929c89615d0fc04';
         $this->assertStringContainsString($inboxId, $xml);
         $this->assertStringContainsString('Drafts', $xml);
         $this->assertStringContainsString('Calendar', $xml);
         $this->assertStringContainsString('Tasks', $xml);
         $this->assertStringContainsString('Contacts', $xml);
 
         // Find the inbox for the next step
         // $collectionIds = $dom->getElementsByTagName('ServerId');
         // $inboxId = $collectionIds[0]->nodeValue;
 
         return $inboxId;
     }
 
     /**
     * @depends testList
     */
     public function testInitialSync($inboxId)
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$inboxId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Email", $collection->childNodes->item(0)->nodeValue);
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(1)->nodeValue);
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
         return $inboxId;
     }
 
     /**
     * @depends testInitialSync
     */
     public function testAdd($inboxId)
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$inboxId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
         // We expect an empty response without a change
         $this->assertEquals(0, $response->getBody()->getSize());
     }
 
     /**
     * @depends testList
     */
     public function testSyncTasks()
     {
         $tasksId = "90335880f65deff6e521acea2b71a773";
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         return $tasksId;
     }
 
     /**
     * @depends testSyncTasks
     */
     public function testAddTask($tasksId)
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId1</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task1</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Tasks", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("2", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         $this->assertEquals("clientId1", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
         return [
             'collectionId' => $tasksId,
             'serverId1' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue
         ];
     }
 
     /**
     * Re-issuing the same command should not result in the sync key being invalidated.
     *
     * @depends testAddTask
     */
     public function testReAddTask($result)
     {
         $tasksId = $result['collectionId'];
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId1</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task1</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Tasks", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("2", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         $this->assertEquals("clientId1", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
         return [
             'collectionId' => $tasksId,
             'serverId1' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue
         ];
     }
 
     /**
     * Make sure we can continue with the sync after the previous hickup, also include a modification.
     *
     * @depends testAddTask
     */
     public function testAddTaskContinued($result)
     {
         $tasksId = $result['collectionId'];
         $serverId = $result['serverId1'];
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId2</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task2</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                         <Add>
                             <ClientId>clientId3</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task3</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                         <Change>
                             <ServerId>{$serverId}</ServerId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task4</Subject>
                             </ApplicationData>
                         </Change>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Tasks", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("3", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(2, $add->length);
         $this->assertEquals("clientId2", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals("clientId3", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(1)->nodeValue);
         $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
 
         // The server does not have to inform about a successful change
         $change = $xpath->query("//ns:Responses/ns:Change");
         $this->assertEquals(0, $change->length);
 
         return [
             'collectionId' => $tasksId,
             'serverId1' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue,
             'serverId2' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(1)->nodeValue
         ];
     }
 
     /**
     * Perform another duplicate request.
     *
     * @depends testAddTaskContinued
     */
     public function testAddTaskContinuedAgain($result)
     {
         $tasksId = $result['collectionId'];
         $serverId = $result['serverId1'];
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId2</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task2</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                         <Add>
                             <ClientId>clientId3</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task3</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                         <Change>
                             <ServerId>{$serverId}</ServerId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task4</Subject>
                             </ApplicationData>
                         </Change>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Tasks", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("3", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         print($dom->saveXML());
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(2, $add->length);
 
         $this->assertEquals("clientId2", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals(
             $result['serverId1'],
             $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue
         );
 
         $this->assertEquals("clientId3", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(1)->nodeValue);
         $this->assertEquals(
             $result['serverId2'],
             $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(1)->nodeValue
         );
 
         // The server does not have to inform about a successful change
         $change = $xpath->query("//ns:Responses/ns:Change");
         $this->assertEquals(0, $change->length);
 
         $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
 
         return [
             'collectionId' => $tasksId,
             'serverId2' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(1)->nodeValue
         ];
     }
 
     /**
     * Test a sync key that shouldn't exist yet.
     * @depends testSyncTasks
     */
     public function testInvalidSyncKey($tasksId)
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>4</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId999</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task1</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("3", $status[0]->nodeValue);
         //After this we have to start from scratch
     }
 
     /**
     * Test fetching changes with a second device
     * @depends testAddTaskContinuedAgain
     */
     public function testFetchTasks($result)
     {
         $tasksId = $result['collectionId'];
         $serverId = $result['serverId2'];
         // Initialize the second device
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <FolderSync xmlns="uri:FolderHierarchy">
             <SyncKey>0</SyncKey>
         </FolderSync>
         EOF;
 
         $response = $this->request($request, 'FolderSync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <MIMESupport>2</MIMESupport>
                         <MIMETruncation>8</MIMETruncation>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>4</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
 
         // Fetch the content
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Commands/ns:Add");
         $this->assertEquals(3, $add->length);
 
 
         //Resend the same command
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Commands/ns:Add");
         $this->assertEquals(3, $add->length);
 
         // Add another entry, delete an entry, with the original device (we have to init first again)
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <MIMESupport>2</MIMESupport>
                         <MIMETruncation>8</MIMETruncation>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>4</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId4</ClientId>
                             <ApplicationData>
                                 <Subject xmlns="uri:Tasks">task4</Subject>
                                 <Complete xmlns="uri:Tasks">0</Complete>
                                 <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate>
                                 <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate>
                             </ApplicationData>
                         </Add>
                         <Delete>
                             <ServerId>{$serverId}</ServerId>
                         </Delete>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
         $dom = self::fromWbxml($response->getBody());
 
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         // Delete does not have to be confirmed according to spec
         $delete = $xpath->query("//ns:Responses/ns:Delete");
         $this->assertEquals(0, $delete->length);
 
         // And fetch the changes
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         // print("=====\n");
         // print($dom->saveXML());
         // print("=====\n");
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Commands/ns:Add");
         $this->assertEquals(1, $add->length);
         $delete = $xpath->query("//ns:Commands/ns:Delete");
         $this->assertEquals(1, $delete->length);
 
         // and finally refetch the same changes
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync', self::$deviceId2);
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         // print("=====\n");
         // print($dom->saveXML());
         // print("=====\n");
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Commands/ns:Add");
         $this->assertEquals(1, $add->length);
         //FIXME we currently miss deletions.
         $delete = $xpath->query("//ns:Commands/ns:Delete");
         $this->assertEquals(0, $delete->length);
     }
 
     /**
     * @depends testList
     */
     public function testSyncCalendar()
     {
         $tasksId = "cca1b81c734abbcd669bea90d23e08ae";
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         return $tasksId;
     }
 
     /**
     * @depends testSyncCalendar
     */
     public function testAddEvent($tasksId)
     {
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId1</ClientId>
                             <ApplicationData>
                                 <StartTime xmlns="uri:Calendar">20230719T200032Z</StartTime>
                                 <BusyStatus xmlns="uri:Calendar">2</BusyStatus>
                                 <DtStamp xmlns="uri:Calendar">20230719T194232Z</DtStamp>
                                 <EndTime xmlns="uri:Calendar">20230719T203032Z</EndTime>
                                 <UID xmlns="uri:Calendar">046f2e01-e8d0-47c6-a607-ba360251761d</UID>
                                 <OrganizerEmail xmlns="uri:Calendar">activesynctest@kolab.org</OrganizerEmail>
                                 <MeetingStatus xmlns="uri:Calendar">0</MeetingStatus>
                                 <ResponseRequested xmlns="uri:Calendar">0</ResponseRequested>
                             </ApplicationData>
                         </Add>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Calendar", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("2", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         $this->assertEquals("clientId1", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals("1", $xpath->query("//ns:Responses/ns:Add/ns:Status")->item(0)->nodeValue);
         // $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
         return [
             'collectionId' => $tasksId,
             'serverId1' => $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue
         ];
     }
 
     /**
     * @depends testAddEvent
     */
     public function testReaddEvent($result)
     {
         $tasksId = $result['collectionId'];
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>2</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Add>
                             <ClientId>clientId1</ClientId>
                             <ApplicationData>
                                 <StartTime xmlns="uri:Calendar">20230719T200032Z</StartTime>
                                 <BusyStatus xmlns="uri:Calendar">2</BusyStatus>
                                 <DtStamp xmlns="uri:Calendar">20230719T194232Z</DtStamp>
                                 <EndTime xmlns="uri:Calendar">20230719T203032Z</EndTime>
                                 <UID xmlns="uri:Calendar">046f2e01-e8d0-47c6-a607-ba360251761d</UID>
                                 <OrganizerEmail xmlns="uri:Calendar">activesynctest@kolab.org</OrganizerEmail>
                                 <MeetingStatus xmlns="uri:Calendar">0</MeetingStatus>
                                 <ResponseRequested xmlns="uri:Calendar">0</ResponseRequested>
                             </ApplicationData>
                         </Add>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         $collections = $dom->getElementsByTagName('Collection');
         $this->assertEquals(1, $collections->length);
         $collection = $collections->item(0);
         $this->assertEquals("Class", $collection->childNodes->item(0)->nodeName);
         $this->assertEquals("Calendar", $collection->childNodes->item(0)->nodeValue);
 
         $this->assertEquals("SyncKey", $collection->childNodes->item(1)->nodeName);
         $this->assertEquals("3", $collection->childNodes->item(1)->nodeValue);
 
         $this->assertEquals("Status", $collection->childNodes->item(3)->nodeName);
         $this->assertEquals("1", $collection->childNodes->item(3)->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         $this->assertEquals("clientId1", $xpath->query("//ns:Responses/ns:Add/ns:ClientId")->item(0)->nodeValue);
         $this->assertEquals("5", $xpath->query("//ns:Responses/ns:Add/ns:Status")->item(0)->nodeValue);
         $this->assertEquals(0, $xpath->query("//ns:Commands")->length);
 
         return $result;
     }
 
     /**
     * @depends testReaddEvent
     */
     public function testDeleteEvent($result)
     {
         $tasksId = $result['collectionId'];
         $serverId = $result['serverId1'];
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks">
             <Collections>
                 <Collection>
                     <SyncKey>3</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <Commands>
                         <Delete>
                             <ServerId>{$serverId}</ServerId>
                         </Delete>
                     </Commands>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
         return $tasksId;
     }
 
     /**
     * @depends testDeleteEvent
     */
     public function testMeetingResponse($tasksId)
     {
         $inboxId = '38b950ebd62cd9a66929c89615d0fc04';
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$inboxId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         //Add the invitation to inbox
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:Syncroton="uri:Syncroton" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Email="uri:Email" xmlns:Email2="uri:Email2" xmlns:Tasks="uri:Tasks" xmlns:Calendar="uri:Calendar">
         <Collections>
             <Collection xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase">
             <SyncKey>1</SyncKey>
             <CollectionId>{$inboxId}</CollectionId>
             <Commands xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase">
                 <Add xmlns:default="uri:Email" xmlns:default1="uri:AirSyncBase">
                     <ClientId>clientid1</ClientId>
                     <ApplicationData>
                         <Email:DateReceived xmlns="uri:Email">2023-07-24T06:53:57.000Z</Email:DateReceived>
                         <Email:From xmlns="uri:Email">"Doe, John" &lt;doe@kolab1.mkpf.ch&gt;</Email:From>
                         <Email:InternetCPID xmlns="uri:Email">65001</Email:InternetCPID>
                         <Email:Subject xmlns="uri:Email">You've been invited to "event1"</Email:Subject>
                         <Email:To xmlns="uri:Email">admin@kolab1.mkpf.ch</Email:To>
                         <Email:Read xmlns="uri:Email">1</Email:Read>
                         <Email:Flag xmlns="uri:Email"/>
                         <AirSyncBase:Body xmlns="uri:AirSyncBase">
                         <AirSyncBase:Type>4</AirSyncBase:Type>
                         <AirSyncBase:Data>MIME-Version: 1.0&#13;
         From: "Doe, John" &lt;doe@kolab1.mkpf.ch&gt;&#13;
         Date: Mon, 24 Jul 2023 08:53:55 +0200&#13;
         Message-ID: &lt;9cd8885d1339b976c7cb15db086e7bbc@kolab1.mkpf.ch&gt;&#13;
         To: admin@kolab1.mkpf.ch&#13;
         Subject: You've been invited to "event1"&#13;
         Content-Type: multipart/alternative;&#13;
             boundary="=_a32392e5fc9266e3eeba97347cbfc147"&#13;
         &#13;
         --=_a32392e5fc9266e3eeba97347cbfc147&#13;
         Content-Transfer-Encoding: quoted-printable&#13;
         Content-Type: text/plain; charset=UTF-8;&#13;
         format=flowed&#13;
         &#13;
         *event1*&#13;
         &#13;
         When: 2023-07-24 11:00 - 11:30 (Europe/Vaduz)&#13;
         &#13;
         Invitees: Doe, John &lt;doe@kolab1.mkpf.ch&gt;,&#13;
         admin@kolab1.mkpf.ch&#13;
         &#13;
         Please find attached an iCalendar file with all the event details which you=&#13;
         =20&#13;
         can import to your calendar application.&#13;
         --=_a32392e5fc9266e3eeba97347cbfc147&#13;
         Content-Transfer-Encoding: 8bit&#13;
         Content-Type: text/calendar; charset=UTF-8; method=REQUEST;&#13;
         name=event.ics&#13;
         &#13;
         BEGIN:VCALENDAR&#13;
         VERSION:2.0&#13;
         PRODID:-//Roundcube 1.5.3//Sabre VObject 4.5.3//EN&#13;
         CALSCALE:GREGORIAN&#13;
         METHOD:REQUEST&#13;
         BEGIN:VTIMEZONE&#13;
         TZID:Europe/Vaduz&#13;
         BEGIN:STANDARD&#13;
         DTSTART:20221030T010000&#13;
         TZOFFSETFROM:+0200&#13;
         TZOFFSETTO:+0100&#13;
         TZNAME:CET&#13;
         END:STANDARD&#13;
         BEGIN:STANDARD&#13;
         DTSTART:20231029T010000&#13;
         TZOFFSETFROM:+0200&#13;
         TZOFFSETTO:+0100&#13;
         TZNAME:CET&#13;
         END:STANDARD&#13;
         BEGIN:DAYLIGHT&#13;
         DTSTART:20230326T010000&#13;
         TZOFFSETFROM:+0100&#13;
         TZOFFSETTO:+0200&#13;
         TZNAME:CEST&#13;
         END:DAYLIGHT&#13;
         END:VTIMEZONE&#13;
         BEGIN:VEVENT&#13;
         UID:CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2&#13;
         DTSTAMP:20230724T065355Z&#13;
         CREATED:20230724T065354Z&#13;
         LAST-MODIFIED:20230724T065354Z&#13;
         DTSTART;TZID=Europe/Vaduz:20230724T110000&#13;
         DTEND;TZID=Europe/Vaduz:20230724T113000&#13;
         SUMMARY:event1&#13;
         SEQUENCE:0&#13;
         TRANSP:OPAQUE&#13;
         ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVIDUAL;RSVP=&#13;
         TRUE:mailto:admin@kolab1.mkpf.ch&#13;
         ORGANIZER;CN="Doe, John":mailto:doe@kolab1.mkpf.ch&#13;
         END:VEVENT&#13;
         END:VCALENDAR&#13;
         &#13;
         --=_a32392e5fc9266e3eeba97347cbfc147--&#13;
                         </AirSyncBase:Data>
                         </AirSyncBase:Body>
                         <AirSyncBase:NativeBodyType xmlns="uri:AirSyncBase">1</AirSyncBase:NativeBodyType>
                         <Email:MessageClass xmlns="uri:Email">IPM.Note</Email:MessageClass>
                         <Email:ContentClass xmlns="uri:Email">urn:content-classes:message</Email:ContentClass>
                     </ApplicationData>
                 </Add>
             </Commands>
             </Collection>
         </Collections>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $status = $dom->getElementsByTagName('Status');
         $this->assertEquals("1", $status[0]->nodeValue);
 
         $xpath = $this->xpath($dom);
         $add = $xpath->query("//ns:Responses/ns:Add");
         $this->assertEquals(1, $add->length);
         $this->assertEquals("1", $xpath->query("//ns:Responses/ns:Add/ns:Status")->item(0)->nodeValue);
         $serverId = $xpath->query("//ns:Responses/ns:Add/ns:ServerId")->item(0)->nodeValue;
 
 
         //List the MeetingRequest
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$inboxId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$inboxId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>1</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals('IPM.Schedule.Meeting.Request', $xpath->query("//ns:Add/ns:ApplicationData/Email:MessageClass")->item(0)->nodeValue);
         $this->assertEquals('urn:content-classes:calendarmessage', $xpath->query("//ns:Add/ns:ApplicationData/Email:ContentClass")->item(0)->nodeValue);
         $this->assertEquals('BAAAAIIA4AB0xbcQGoLgCAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAHZDYWwtVWlkAQAAAENDNTQxOTFGNjU2REZCQjI5NEJFMEFDMThFNzA5MzE1LTUyOUNCQkRENDdBQ0REQzIA', $xpath->query("//ns:Add/ns:ApplicationData/Email:MeetingRequest/Email:GlobalObjId")->item(0)->nodeValue);
         $this->assertEquals('1', $xpath->query("//ns:Add/ns:ApplicationData/Email:MeetingRequest/Email2:MeetingMessageType")->item(0)->nodeValue);
 
         //Send a meeting response to accept
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <MeetingResponse xmlns="uri:MeetingResponse">
         <Request>
             <CollectionId>{$inboxId}</CollectionId>
             <UserResponse>1</UserResponse>
             <RequestId>$serverId</RequestId>
         </Request>
         </MeetingResponse>
         EOF;
         $response = $this->request($request, 'MeetingResponse');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals("1", $xpath->query("//ns:MeetingResponse/ns:Result/ns:Status")->item(0)->nodeValue);
         $this->assertStringContainsString("CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2", $xpath->query("//ns:MeetingResponse/ns:Result/ns:CalendarId")->item(0)->nodeValue);
 
 
         //Fetch the event and validate
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>1</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals("CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2", $xpath->query("//ns:Add/ns:ApplicationData/Calendar:UID")->item(0)->nodeValue);
         $this->assertEquals('activesynctest@kolab.org', $xpath->query("//ns:Add/ns:ApplicationData/Calendar:Attendees/Calendar:Attendee/Calendar:Email")->item(0)->nodeValue);
         $this->assertEquals('3', $xpath->query("//ns:Add/ns:ApplicationData/Calendar:Attendees/Calendar:Attendee/Calendar:AttendeeStatus")->item(0)->nodeValue);
         $serverId = $xpath->query("//ns:Add/ns:ServerId")->item(0)->nodeValue;
 
         $add = $xpath->query("//ns:Add");
         $this->assertEquals(1, $add->length);
 
 
         //Send a dummy event with an invalid attendeestatus (just like outlook does)
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Calendar="uri:Calendar">
         <Collections>
             <Collection>
             <SyncKey>2</SyncKey>
             <CollectionId>{$tasksId}</CollectionId>
             <DeletesAsMoves>0</DeletesAsMoves>
             <GetChanges>0</GetChanges>
             <WindowSize>512</WindowSize>
             <Options>
                 <FilterType>0</FilterType>
                 <BodyPreference xmlns="uri:AirSyncBase">
                 <Type>1</Type>
                 <AllOrNone>1</AllOrNone>
                 </BodyPreference>
             </Options>
             <Commands>
                 <Add>
                 <Class>Calendar</Class>
                 <ClientId>{B94F1272-ED5F-4613-90D6-731491596147}</ClientId>
                 <ApplicationData>
                     <Timezone xmlns="uri:Calendar">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Timezone>
                     <DtStamp xmlns="uri:Calendar">20230724T173929Z</DtStamp>
                     <StartTime xmlns="uri:Calendar">20230724T090000Z</StartTime>
                     <Subject xmlns="uri:Calendar">event1</Subject>
                     <UID xmlns="uri:Calendar">CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2</UID>
                     <OrganizerName xmlns="uri:Calendar">doe@kolab1.mkpf.ch</OrganizerName>
                     <OrganizerEmail xmlns="uri:Calendar">doe@kolab1.mkpf.ch</OrganizerEmail>
                     <Attendees xmlns="uri:Calendar">
                     <Attendee>
                         <Email>activesynctest@kolab.org</Email>
                         <Name>activesynctest@kolab.org</Name>
                         <AttendeeStatus>0</AttendeeStatus>
                         <AttendeeType>1</AttendeeType>
                     </Attendee>
                     </Attendees>
                     <EndTime xmlns="uri:Calendar">20230724T093000Z</EndTime>
                     <Sensitivity xmlns="uri:Calendar">0</Sensitivity>
                     <BusyStatus xmlns="uri:Calendar">2</BusyStatus>
                     <AllDayEvent xmlns="uri:Calendar">0</AllDayEvent>
                     <Reminder xmlns="uri:Calendar">15</Reminder>
                     <MeetingStatus xmlns="uri:Calendar">3</MeetingStatus>
                     <ResponseRequested xmlns="uri:Calendar">1</ResponseRequested>
                     <DisallowNewTimeProposal xmlns="uri:Calendar">0</DisallowNewTimeProposal>
                 </ApplicationData>
                 </Add>
             </Commands>
             </Collection>
         </Collections>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals("5", $xpath->query("//ns:Add/ns:Status")->item(0)->nodeValue);
 
 
         //Fetch the event and validate again
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>0</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>0</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
 
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase">
             <Collections>
                 <Collection>
                     <SyncKey>1</SyncKey>
                     <CollectionId>{$tasksId}</CollectionId>
                     <DeletesAsMoves>0</DeletesAsMoves>
                     <GetChanges>1</GetChanges>
                     <WindowSize>512</WindowSize>
                     <Options>
                         <FilterType>0</FilterType>
                         <BodyPreference xmlns="uri:AirSyncBase">
                             <Type>1</Type>
                             <AllOrNone>1</AllOrNone>
                         </BodyPreference>
                     </Options>
                 </Collection>
             </Collections>
             <WindowSize>16</WindowSize>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals("CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2", $xpath->query("//ns:Add/ns:ApplicationData/Calendar:UID")->item(0)->nodeValue);
         $this->assertEquals('activesynctest@kolab.org', $xpath->query("//ns:Add/ns:ApplicationData/Calendar:Attendees/Calendar:Attendee/Calendar:Email")->item(0)->nodeValue);
         $this->assertEquals('3', $xpath->query("//ns:Add/ns:ApplicationData/Calendar:Attendees/Calendar:Attendee/Calendar:AttendeeStatus")->item(0)->nodeValue);
 
 
         //Send a dummy event to change to tentative (just like outlook does
         $request = <<<EOF
         <?xml version="1.0" encoding="utf-8"?>
         <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
         <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Calendar="uri:Calendar">
         <Collections>
             <Collection>
             <SyncKey>2</SyncKey>
             <CollectionId>{$tasksId}</CollectionId>
             <DeletesAsMoves>0</DeletesAsMoves>
             <GetChanges>0</GetChanges>
             <WindowSize>512</WindowSize>
             <Options>
                 <FilterType>0</FilterType>
                 <BodyPreference xmlns="uri:AirSyncBase">
                 <Type>1</Type>
                 <AllOrNone>1</AllOrNone>
                 </BodyPreference>
             </Options>
             <Commands>
                 <Change>
                 <Class>Calendar</Class>
                 <ServerId>{$serverId}</ServerId>
                 <ApplicationData>
                     <Timezone xmlns="uri:Calendar">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Timezone>
                     <DtStamp xmlns="uri:Calendar">20230724T173929Z</DtStamp>
                     <StartTime xmlns="uri:Calendar">20230724T090000Z</StartTime>
                     <Subject xmlns="uri:Calendar">event1</Subject>
                     <UID xmlns="uri:Calendar">CC54191F656DFBB294BE0AC18E709315-529CBBDD47ACDDC2</UID>
                     <OrganizerName xmlns="uri:Calendar">doe@kolab1.mkpf.ch</OrganizerName>
                     <OrganizerEmail xmlns="uri:Calendar">doe@kolab1.mkpf.ch</OrganizerEmail>
                     <Attendees xmlns="uri:Calendar">
                     <Attendee>
                         <Email>activesynctest@kolab.org</Email>
                         <Name>activesynctest@kolab.org</Name>
                         <AttendeeStatus>0</AttendeeStatus>
                         <AttendeeType>1</AttendeeType>
                     </Attendee>
                     </Attendees>
                     <EndTime xmlns="uri:Calendar">20230724T093000Z</EndTime>
                     <Sensitivity xmlns="uri:Calendar">0</Sensitivity>
                     <BusyStatus xmlns="uri:Calendar">1</BusyStatus>
                     <AllDayEvent xmlns="uri:Calendar">0</AllDayEvent>
                     <Reminder xmlns="uri:Calendar">15</Reminder>
                     <MeetingStatus xmlns="uri:Calendar">3</MeetingStatus>
                     <ResponseRequested xmlns="uri:Calendar">1</ResponseRequested>
                     <DisallowNewTimeProposal xmlns="uri:Calendar">0</DisallowNewTimeProposal>
                 </ApplicationData>
                 </Change>
             </Commands>
             </Collection>
         </Collections>
         </Sync>
         EOF;
         $response = $this->request($request, 'Sync');
         $this->assertEquals(200, $response->getStatusCode());
 
         $dom = self::fromWbxml($response->getBody());
         print($dom->saveXML());
         $xpath = $this->xpath($dom);
 
         $this->assertEquals("1", $xpath->query("//ns:Collection/ns:Status")->item(0)->nodeValue);
     }
 
     /**
      * @doesNotPerformAssertions
      */
     public function testCleanup(): void
     {
         $this->deleteTestUser(self::$user->email);
     }
 }
+// @codingStandardsIgnoreEnd