+http://sabre.io/dav/building-a-caldav-client/
+0. Discovery
+PROPFIND / HTTP/1.1
+Depth: 0
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:current-user-principal />
+ </d:prop>
+</d:propfind>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:response>
+ <d:href>/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:current-user-principal>
+ <d:href>/principals/users/johndoe/</d:href>
+ </d:current-user-principal>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+Get calendar home:
+PROPFIND /principals/users/johndoe/ HTTP/1.1
+Depth: 0
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:prop>
+ <c:calendar-home-set />
+ </d:prop>
+</d:propfind>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:response>
+ <d:href>/principals/users/johndoe/</d:href>
+ <d:propstat>
+ <d:prop>
+ <c:calendar-home-set>
+ <d:href>/calendars/johndoe/</d:href>
+ </c:calendar-home-set>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+Get all calendars:
+PROPFIND /calendars/johndoe/ HTTP/1.1
+Depth: 1
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:prop>
+ <d:resourcetype />
+ <d:displayname />
+ <cs:getctag />
+ <c:supported-calendar-component-set />
+ </d:prop>
+</d:propfind>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:response>
+ <d:href>/calendars/johndoe/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:resourcetype>
+ <d:collection/>
+ </d:resourcetype>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/calendars/johndoe/home/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:resourcetype>
+ <d:collection/>
+ <c:calendar/>
+ </d:resourcetype>
+ <d:displayname>Home calendar</d:displayname>
+ <cs:getctag>3145</cs:getctag>
+ <c:supported-calendar-component-set>
+ <c:comp name="VEVENT" />
+ </c:supported-calendar-component-set>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/calendars/johndoe/tasks/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:resourcetype>
+ <d:collection/>
+ <c:calendar/>
+ </d:resourcetype>
+ <d:displayname>My TODO list</d:displayname>
+ <cs:getctag>3345</cs:getctag>
+ <c:supported-calendar-component-set>
+ <c:comp name="VTODO" />
+ </c:supported-calendar-component-set>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+1. Get display name and ctag
+PROPFIND /calendars/johndoe/home/ HTTP/1.1
+Depth: 0
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:prop>
+ <d:displayname />
+ <cs:getctag />
+ </d:prop>
+</d:propfind>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:response>
+ <d:href>/calendars/johndoe/home/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:displayname>Home calendar</d:displayname>
+ <cs:getctag>3145</cs:getctag>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+Failure:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:response>
+ <d:href>/calendars/johndoe/home/</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:displayname />
+ <cs:getctag />
+ </d:prop>
+ <d:status>HTTP/1.1 403 Forbidden</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+2. Save display name and ctag (if ctag changes the calendar has changes)
+
+3. Download objects
+REPORT /calendars/johndoe/home/ HTTP/1.1
+Depth: 1
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:prop>
+ <d:getetag />
+ <c:calendar-data />
+ </d:prop>
+ <c:filter>
+ <c:comp-filter name="VCALENDAR" />
+ </c:filter>
+</c:calendar-query>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:response>
+ <d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:getetag>"2134-314"</d:getetag>
+ <c:calendar-data>BEGIN:VCALENDAR
+ VERSION:2.0
+ CALSCALE:GREGORIAN
+ BEGIN:VTODO
+ UID:132456762153245
+ SUMMARY:Do the dishes
+ DUE:20121028T115600Z
+ END:VTODO
+ END:VCALENDAR
+ </c:calendar-data>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/calendars/johndoe/home/132456-34365.ics</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:getetag>"5467-323"</d:getetag>
+ <c:calendar-data>BEGIN:VCALENDAR
+ VERSION:2.0
+ CALSCALE:GREGORIAN
+ BEGIN:VEVENT
+ UID:132456-34365
+ SUMMARY:Weekly meeting
+ DTSTART:20120101T120000
+ DURATION:PT1H
+ RRULE:FREQ=WEEKLY
+ END:VEVENT
+ END:VCALENDAR
+ </c:calendar-data>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+For each object get:
+- Calendar data
+- url
+- etag
+
+4. Check for changes
+- Fetch ctag -> see 1.
+- If ctag is changes fetch all etags
+REPORT /calendars/johndoe/home/ HTTP/1.1
+Depth: 1
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:prop>
+ <d:getetag />
+ </d:prop>
+ <c:filter>
+ <c:comp-filter name="VCALENDAR" />
+ </c:filter>
+</c:calendar-query>
+
+Success:
+HTTP/1.1 207 Multi-status
+Content-Type: application/xml; charset=utf-8
+
+<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
+ <d:response>
+ <d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:getetag>"xxxx-xxx"</d:getetag>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:getetag>"5-12"</d:getetag>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+
+Compare local url's to request:
+ if match compare etag. if etag compares continue else update.
+ delete each local url not found
+ fetch every url not found local
+
+update/fetch:
+REPORT /calendars/johndoe/home/ HTTP/1.1
+Depth: 1
+Prefer: return-minimal
+Content-Type: application/xml; charset=utf-8
+
+<c:calendar-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <d:prop>
+ <d:getetag />
+ <c:calendar-data />
+ </d:prop>
+ <d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
+ <d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
+</c:calendar-multiget>
+
+5. Updating objects
+If-Match contains etag to update and You must not change the UID of the original object
+PUT /calendars/johndoe/home/132456762153245.ics HTTP/1.1
+Content-Type: text/calendar; charset=utf-8
+If-Match: "2134-314"
+
+BEGIN:VCALENDAR
+....
+END:VCALENDAR
+
+Success:
+HTTP/1.1 204 No Content
+ETag: "2134-315"
+
+If no etag is returned make an immediate GET to get etag
+
+6. Create an object
+PUT /calendars/johndoe/home/somerandomstring.ics HTTP/1.1
+Content-Type: text/calendar; charset=utf-8
+
+BEGIN:VCALENDAR
+....
+END:VCALENDAR
+
+Success:
+HTTP/1.1 201 Created
+ETag: "21345-324"
+
+7. Deleting an object
+DELETE /calendars/johndoe/home/132456762153245.ics HTTP/1.1
+If-Match: "2134-314"
+