diff --git a/3rdparty/Sabre.includes.php b/3rdparty/Sabre.includes.php
deleted file mode 100755
index c1334373663c646b05bba88d38d322fac8910039..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre.includes.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * Library include file
- *
- * This file is deprecated, don't use it!
- * Instead, use the specific includes files that are in the sub-packages.
- *
- *   Sabre/DAV/includes.php
- *   Sabre/HTTP/includes.php
- *
- *   etc..
- *
- * This file contains all includes to the rest of the SabreDAV library
- * Make sure the lib/ directory is in PHP's include_path.
- *
- * @package Sabre
- * @deprecated Don't use this file, it will be remove in a future version
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-
-include 'Sabre/HTTP/includes.php';
-include 'Sabre/DAV/includes.php';
-
diff --git a/3rdparty/Sabre/CalDAV/Backend/Abstract.php b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
old mode 100755
new mode 100644
index 7aba1d69ffe3052f344110c70c2f2139ddebadbf..88e5b4a1a079724700036786315ac76b7c843999
--- a/3rdparty/Sabre/CalDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
@@ -1,47 +1,19 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * Abstract Calendaring backend. Extend this class to create your own backends.
  *
+ * Checkout the BackendInterface for all the methods that must be implemented.
+ *
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-abstract class Sabre_CalDAV_Backend_Abstract {
-
-    /**
-     * Returns a list of calendars for a principal.
-     *
-     * Every project is an array with the following keys:
-     *  * id, a unique id that will be used by other functions to modify the
-     *    calendar. This can be the same as the uri or a database key.
-     *  * uri, which the basename of the uri with which the calendar is
-     *    accessed.
-     *  * principaluri. The owner of the calendar. Almost always the same as
-     *    principalUri passed to this method.
-     *
-     * Furthermore it can contain webdav properties in clark notation. A very
-     * common one is '{DAV:}displayname'.
-     *
-     * @param string $principalUri
-     * @return array
-     */
-    abstract function getCalendarsForUser($principalUri);
-
-    /**
-     * Creates a new calendar for a principal.
-     *
-     * If the creation was a success, an id must be returned that can be used to reference
-     * this calendar in other methods, such as updateCalendar.
-     *
-     * @param string $principalUri
-     * @param string $calendarUri
-     * @param array $properties
-     * @return void
-     */
-    abstract function createCalendar($principalUri,$calendarUri,array $properties);
+abstract class Sabre_CalDAV_Backend_Abstract implements Sabre_CalDAV_Backend_BackendInterface {
 
     /**
      * Updates properties for a calendar.
@@ -75,7 +47,7 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      * (403 Forbidden), which in turn also caused {DAV:}owner to fail
      * (424 Failed Dependency) because the request needs to be atomic.
      *
-     * @param string $calendarId
+     * @param mixed $calendarId
      * @param array $mutations
      * @return bool|array
      */
@@ -86,83 +58,97 @@ abstract class Sabre_CalDAV_Backend_Abstract {
     }
 
     /**
-     * Delete a calendar and all it's objects
+     * Performs a calendar-query on the contents of this calendar.
      *
-     * @param string $calendarId
-     * @return void
-     */
-    abstract function deleteCalendar($calendarId);
-
-    /**
-     * Returns all calendar objects within a calendar.
-     *
-     * Every item contains an array with the following keys:
-     *   * id - unique identifier which will be used for subsequent updates
-     *   * calendardata - The iCalendar-compatible calendar data
-     *   * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
-     *   * lastmodified - a timestamp of the last modification time
-     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
-     *   '  "abcdef"')
-     *   * calendarid - The calendarid as it was passed to this function.
-     *   * size - The size of the calendar objects, in bytes.
-     *
-     * Note that the etag is optional, but it's highly encouraged to return for
-     * speed reasons.
-     *
-     * The calendardata is also optional. If it's not returned
-     * 'getCalendarObject' will be called later, which *is* expected to return
-     * calendardata.
-     *
-     * If neither etag or size are specified, the calendardata will be
-     * used/fetched to determine these numbers. If both are specified the
-     * amount of times this is needed is reduced by a great degree.
-     *
-     * @param string $calendarId
-     * @return array
-     */
-    abstract function getCalendarObjects($calendarId);
-
-    /**
-     * Returns information from a single calendar object, based on it's object
-     * uri.
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
+     * calendar-query it is possible for a client to request a specific set of
+     * object, based on contents of iCalendar properties, date-ranges and
+     * iCalendar component types (VTODO, VEVENT).
+     *
+     * This method should just return a list of (relative) urls that match this
+     * query.
+     *
+     * The list of filters are specified as an array. The exact array is
+     * documented by Sabre_CalDAV_CalendarQueryParser.
+     *
+     * Note that it is extremely likely that getCalendarObject for every path
+     * returned from this method will be called almost immediately after. You
+     * may want to anticipate this to speed up these requests.
      *
-     * The returned array must have the same keys as getCalendarObjects. The
-     * 'calendardata' object is required here though, while it's not required
-     * for getCalendarObjects.
+     * This method provides a default implementation, which parses *all* the
+     * iCalendar objects in the specified calendar.
      *
-     * @param string $calendarId
-     * @param string $objectUri
+     * This default may well be good enough for personal use, and calendars
+     * that aren't very large. But if you anticipate high usage, big calendars
+     * or high loads, you are strongly adviced to optimize certain paths.
+     *
+     * The best way to do so is override this method and to optimize
+     * specifically for 'common filters'.
+     *
+     * Requests that are extremely common are:
+     *   * requests for just VEVENTS
+     *   * requests for just VTODO
+     *   * requests with a time-range-filter on either VEVENT or VTODO.
+     *
+     * ..and combinations of these requests. It may not be worth it to try to
+     * handle every possible situation and just rely on the (relatively
+     * easy to use) CalendarQueryValidator to handle the rest.
+     *
+     * Note that especially time-range-filters may be difficult to parse. A
+     * time-range filter specified on a VEVENT must for instance also handle
+     * recurrence rules correctly.
+     * A good example of how to interprete all these filters can also simply
+     * be found in Sabre_CalDAV_CalendarQueryFilter. This class is as correct
+     * as possible, so it gives you a good idea on what type of stuff you need
+     * to think of.
+     *
+     * @param mixed $calendarId
+     * @param array $filters
      * @return array
      */
-    abstract function getCalendarObject($calendarId,$objectUri);
+    public function calendarQuery($calendarId, array $filters) {
 
-    /**
-     * Creates a new calendar object.
-     *
-     * @param string $calendarId
-     * @param string $objectUri
-     * @param string $calendarData
-     * @return void
-     */
-    abstract function createCalendarObject($calendarId,$objectUri,$calendarData);
+        $result = array();
+        $objects = $this->getCalendarObjects($calendarId);
 
-    /**
-     * Updates an existing calendarobject, based on it's uri.
-     *
-     * @param string $calendarId
-     * @param string $objectUri
-     * @param string $calendarData
-     * @return void
-     */
-    abstract function updateCalendarObject($calendarId,$objectUri,$calendarData);
+        $validator = new Sabre_CalDAV_CalendarQueryValidator();
+
+        foreach($objects as $object) {
+
+            if ($this->validateFilterForObject($object, $filters)) {
+                $result[] = $object['uri'];
+            }
+
+        }
+
+        return $result;
+
+    }
 
     /**
-     * Deletes an existing calendar object.
+     * This method validates if a filters (as passed to calendarQuery) matches
+     * the given object.
      *
-     * @param string $calendarId
-     * @param string $objectUri
-     * @return void
+     * @param array $object
+     * @param array $filter
+     * @return bool
      */
-    abstract function deleteCalendarObject($calendarId,$objectUri);
+    protected function validateFilterForObject(array $object, array $filters) {
+
+        // Unfortunately, setting the 'calendardata' here is optional. If
+        // it was excluded, we actually need another call to get this as
+        // well.
+        if (!isset($object['calendardata'])) {
+            $object = $this->getCalendarObject($object['calendarid'], $object['uri']);
+        }
+
+        $data = is_resource($object['calendardata'])?stream_get_contents($object['calendardata']):$object['calendardata'];
+        $vObject = VObject\Reader::read($data);
+
+        $validator = new Sabre_CalDAV_CalendarQueryValidator();
+        return $validator->validate($vObject, $filters);
+
+    }
+
 
 }
diff --git a/3rdparty/Sabre/CalDAV/Backend/BackendInterface.php b/3rdparty/Sabre/CalDAV/Backend/BackendInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..881538ab60ef8bc52682683304ce6d2701e1b5a0
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Backend/BackendInterface.php
@@ -0,0 +1,231 @@
+<?php
+
+/**
+ * Every CalDAV backend must at least implement this interface.
+ * 
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Backend_BackendInterface {
+
+    /**
+     * Returns a list of calendars for a principal.
+     *
+     * Every project is an array with the following keys:
+     *  * id, a unique id that will be used by other functions to modify the
+     *    calendar. This can be the same as the uri or a database key.
+     *  * uri, which the basename of the uri with which the calendar is
+     *    accessed.
+     *  * principaluri. The owner of the calendar. Almost always the same as
+     *    principalUri passed to this method.
+     *
+     * Furthermore it can contain webdav properties in clark notation. A very
+     * common one is '{DAV:}displayname'.
+     *
+     * @param string $principalUri
+     * @return array
+     */
+    public function getCalendarsForUser($principalUri);
+
+    /**
+     * Creates a new calendar for a principal.
+     *
+     * If the creation was a success, an id must be returned that can be used to reference
+     * this calendar in other methods, such as updateCalendar.
+     *
+     * @param string $principalUri
+     * @param string $calendarUri
+     * @param array $properties
+     * @return void
+     */
+    public function createCalendar($principalUri,$calendarUri,array $properties);
+
+    /**
+     * Updates properties for a calendar.
+     *
+     * The mutations array uses the propertyName in clark-notation as key,
+     * and the array value for the property value. In the case a property
+     * should be deleted, the property value will be null.
+     *
+     * This method must be atomic. If one property cannot be changed, the
+     * entire operation must fail.
+     *
+     * If the operation was successful, true can be returned.
+     * If the operation failed, false can be returned.
+     *
+     * Deletion of a non-existent property is always successful.
+     *
+     * Lastly, it is optional to return detailed information about any
+     * failures. In this case an array should be returned with the following
+     * structure:
+     *
+     * array(
+     *   403 => array(
+     *      '{DAV:}displayname' => null,
+     *   ),
+     *   424 => array(
+     *      '{DAV:}owner' => null,
+     *   )
+     * )
+     *
+     * In this example it was forbidden to update {DAV:}displayname.
+     * (403 Forbidden), which in turn also caused {DAV:}owner to fail
+     * (424 Failed Dependency) because the request needs to be atomic.
+     *
+     * @param mixed $calendarId
+     * @param array $mutations
+     * @return bool|array
+     */
+    public function updateCalendar($calendarId, array $mutations); 
+
+    /**
+     * Delete a calendar and all it's objects
+     *
+     * @param mixed $calendarId
+     * @return void
+     */
+    public function deleteCalendar($calendarId);
+
+    /**
+     * Returns all calendar objects within a calendar.
+     *
+     * Every item contains an array with the following keys:
+     *   * id - unique identifier which will be used for subsequent updates
+     *   * calendardata - The iCalendar-compatible calendar data
+     *   * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
+     *   * lastmodified - a timestamp of the last modification time
+     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+     *   '  "abcdef"')
+     *   * calendarid - The calendarid as it was passed to this function.
+     *   * size - The size of the calendar objects, in bytes.
+     *
+     * Note that the etag is optional, but it's highly encouraged to return for
+     * speed reasons.
+     *
+     * The calendardata is also optional. If it's not returned
+     * 'getCalendarObject' will be called later, which *is* expected to return
+     * calendardata.
+     *
+     * If neither etag or size are specified, the calendardata will be
+     * used/fetched to determine these numbers. If both are specified the
+     * amount of times this is needed is reduced by a great degree.
+     *
+     * @param mixed $calendarId
+     * @return array
+     */
+    public function getCalendarObjects($calendarId);
+
+    /**
+     * Returns information from a single calendar object, based on it's object
+     * uri.
+     *
+     * The returned array must have the same keys as getCalendarObjects. The
+     * 'calendardata' object is required here though, while it's not required
+     * for getCalendarObjects.
+     *
+     * @param mixed $calendarId
+     * @param string $objectUri
+     * @return array
+     */
+    public function getCalendarObject($calendarId,$objectUri);
+
+    /**
+     * Creates a new calendar object.
+     *
+     * It is possible return an etag from this function, which will be used in
+     * the response to this PUT request. Note that the ETag must be surrounded
+     * by double-quotes.
+     *
+     * However, you should only really return this ETag if you don't mangle the
+     * calendar-data. If the result of a subsequent GET to this object is not
+     * the exact same as this request body, you should omit the ETag.
+     *
+     * @param mixed $calendarId
+     * @param string $objectUri
+     * @param string $calendarData
+     * @return string|null
+     */
+    public function createCalendarObject($calendarId,$objectUri,$calendarData);
+
+    /**
+     * Updates an existing calendarobject, based on it's uri.
+     *
+     * It is possible return an etag from this function, which will be used in
+     * the response to this PUT request. Note that the ETag must be surrounded
+     * by double-quotes.
+     *
+     * However, you should only really return this ETag if you don't mangle the
+     * calendar-data. If the result of a subsequent GET to this object is not
+     * the exact same as this request body, you should omit the ETag.
+     *
+     * @param mixed $calendarId
+     * @param string $objectUri
+     * @param string $calendarData
+     * @return string|null
+     */
+    public function updateCalendarObject($calendarId,$objectUri,$calendarData);
+
+    /**
+     * Deletes an existing calendar object.
+     *
+     * @param mixed $calendarId
+     * @param string $objectUri
+     * @return void
+     */
+    public function deleteCalendarObject($calendarId,$objectUri);
+
+    /**
+     * Performs a calendar-query on the contents of this calendar.
+     *
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
+     * calendar-query it is possible for a client to request a specific set of
+     * object, based on contents of iCalendar properties, date-ranges and
+     * iCalendar component types (VTODO, VEVENT).
+     *
+     * This method should just return a list of (relative) urls that match this
+     * query.
+     *
+     * The list of filters are specified as an array. The exact array is
+     * documented by Sabre_CalDAV_CalendarQueryParser.
+     *
+     * Note that it is extremely likely that getCalendarObject for every path
+     * returned from this method will be called almost immediately after. You
+     * may want to anticipate this to speed up these requests.
+     *
+     * This method provides a default implementation, which parses *all* the
+     * iCalendar objects in the specified calendar.
+     *
+     * This default may well be good enough for personal use, and calendars
+     * that aren't very large. But if you anticipate high usage, big calendars
+     * or high loads, you are strongly adviced to optimize certain paths.
+     *
+     * The best way to do so is override this method and to optimize
+     * specifically for 'common filters'.
+     *
+     * Requests that are extremely common are:
+     *   * requests for just VEVENTS
+     *   * requests for just VTODO
+     *   * requests with a time-range-filter on either VEVENT or VTODO.
+     *
+     * ..and combinations of these requests. It may not be worth it to try to
+     * handle every possible situation and just rely on the (relatively
+     * easy to use) CalendarQueryValidator to handle the rest.
+     *
+     * Note that especially time-range-filters may be difficult to parse. A
+     * time-range filter specified on a VEVENT must for instance also handle
+     * recurrence rules correctly.
+     * A good example of how to interprete all these filters can also simply
+     * be found in Sabre_CalDAV_CalendarQueryFilter. This class is as correct
+     * as possible, so it gives you a good idea on what type of stuff you need
+     * to think of.
+     *
+     * @param mixed $calendarId
+     * @param array $filters
+     * @return array
+     */
+    public function calendarQuery($calendarId, array $filters); 
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Backend/NotificationSupport.php b/3rdparty/Sabre/CalDAV/Backend/NotificationSupport.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5a1409d9b98d26d8280af2a165ed3f6da6adbb3
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Backend/NotificationSupport.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Adds caldav notification support to a backend.
+ *
+ * Note: This feature is experimental, and may change in between different
+ * SabreDAV versions.
+ *
+ * Notifications are defined at:
+ * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-notifications.txt
+ *
+ * These notifications are basically a list of server-generated notifications 
+ * displayed to the user. Users can dismiss notifications by deleting them.
+ *
+ * The primary usecase is to allow for calendar-sharing.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Backend_NotificationSupport extends Sabre_CalDAV_Backend_BackendInterface {
+
+    /**
+     * Returns a list of notifications for a given principal url.
+     *
+     * The returned array should only consist of implementations of
+     * Sabre_CalDAV_Notifications_INotificationType. 
+     * 
+     * @param string $principalUri
+     * @return array 
+     */
+    public function getNotificationsForPrincipal($principalUri);
+
+    /**
+     * This deletes a specific notifcation.
+     *
+     * This may be called by a client once it deems a notification handled. 
+     * 
+     * @param string $principalUri 
+     * @param Sabre_CalDAV_Notifications_INotificationType $notification 
+     * @return void
+     */
+    public function deleteNotification($principalUri, Sabre_CalDAV_Notifications_INotificationType $notification); 
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php
old mode 100755
new mode 100644
index ddacf940c74fa12e21ff389e06604325c55bf3ba..447f5f590cfab55747dc3e324a751fd639b56f98
--- a/3rdparty/Sabre/CalDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CalDAV/Backend/PDO.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * PDO CalDAV backend
  *
@@ -9,11 +11,21 @@
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
+    /**
+     * We need to specify a max date, because we need to stop *somewhere*
+     *
+     * On 32 bit system the maximum for a signed integer is 2147483647, so
+     * MAX_DATE cannot be higher than date('Y-m-d', 2147483647) which results
+     * in 2038-01-19 to avoid problems when the date is converted
+     * to a unix timestamp.
+     */
+    const MAX_DATE = '2038-01-01';
+
     /**
      * pdo
      *
@@ -37,8 +49,9 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
     /**
      * List of CalDAV properties, and how they map to database fieldnames
+     * Add your own properties by simply adding on to this array.
      *
-     * Add your own properties by simply adding on to this array
+     * Note that only string-based properties are supported here.
      *
      * @var array
      */
@@ -90,6 +103,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
         $fields[] = 'ctag';
         $fields[] = 'components';
         $fields[] = 'principaluri';
+        $fields[] = 'transparent';
 
         // Making fields a comma-delimited list
         $fields = implode(', ', $fields);
@@ -110,6 +124,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
                 'principaluri' => $row['principaluri'],
                 '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}getctag' => $row['ctag']?$row['ctag']:'0',
                 '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set' => new Sabre_CalDAV_Property_SupportedCalendarComponentSet($components),
+                '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-calendar-transp' => new Sabre_CalDAV_Property_ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
             );
 
 
@@ -142,11 +157,13 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
             'principaluri',
             'uri',
             'ctag',
+            'transparent',
         );
         $values = array(
             ':principaluri' => $principalUri,
             ':uri'          => $calendarUri,
             ':ctag'         => 1,
+            ':transparent'  => 0,
         );
 
         // Default value
@@ -160,6 +177,10 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
             }
             $values[':components'] = implode(',',$properties[$sccs]->getValue());
         }
+        $transp = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-calendar-transp';
+        if (isset($properties[$transp])) {
+            $values[':transparent'] = $properties[$transp]->getValue()==='transparent';
+        }
 
         foreach($this->propertyMap as $xmlName=>$dbName) {
             if (isset($properties[$xmlName])) {
@@ -225,17 +246,25 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
         foreach($mutations as $propertyName=>$propertyValue) {
 
-            // We don't know about this property.
-            if (!isset($this->propertyMap[$propertyName])) {
-                $hasError = true;
-                $result[403][$propertyName] = null;
-                unset($mutations[$propertyName]);
-                continue;
+            switch($propertyName) {
+                case '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-calendar-transp' :
+                    $fieldName = 'transparent';
+                    $newValues[$fieldName] = $propertyValue->getValue()==='transparent';
+                    break;
+                default :
+                    // Checking the property map
+                    if (!isset($this->propertyMap[$propertyName])) {
+                        // We don't know about this property.
+                        $hasError = true;
+                        $result[403][$propertyName] = null;
+                        unset($mutations[$propertyName]);
+                        continue;
+                    }
+
+                    $fieldName = $this->propertyMap[$propertyName];
+                    $newValues[$fieldName] = $propertyValue;
             }
 
-            $fieldName = $this->propertyMap[$propertyName];
-            $newValues[$fieldName] = $propertyValue;
-
         }
 
         // If there were any errors we need to fail the request
@@ -316,9 +345,22 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      */
     public function getCalendarObjects($calendarId) {
 
-        $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
+        $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
         $stmt->execute(array($calendarId));
-        return $stmt->fetchAll();
+
+        $result = array();
+        foreach($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
+            $result[] = array(
+                'id'           => $row['id'],
+                'uri'          => $row['uri'],
+                'lastmodified' => $row['lastmodified'],
+                'etag'         => '"' . $row['etag'] . '"',
+                'calendarid'   => $row['calendarid'],
+                'size'         => (int)$row['size'],
+            );
+        }
+
+        return $result;
 
     }
 
@@ -336,44 +378,166 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      */
     public function getCalendarObject($calendarId,$objectUri) {
 
-        $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
+        $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
         $stmt->execute(array($calendarId, $objectUri));
-        return $stmt->fetch();
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+        if(!$row) return null;
+
+        return array(
+            'id'           => $row['id'],
+            'uri'          => $row['uri'],
+            'lastmodified' => $row['lastmodified'],
+            'etag'         => '"' . $row['etag'] . '"',
+            'calendarid'   => $row['calendarid'],
+            'size'         => (int)$row['size'],
+            'calendardata' => $row['calendardata'],
+         );
 
     }
 
+
     /**
      * Creates a new calendar object.
      *
-     * @param string $calendarId
+     * It is possible return an etag from this function, which will be used in
+     * the response to this PUT request. Note that the ETag must be surrounded
+     * by double-quotes.
+     *
+     * However, you should only really return this ETag if you don't mangle the
+     * calendar-data. If the result of a subsequent GET to this object is not
+     * the exact same as this request body, you should omit the ETag.
+     *
+     * @param mixed $calendarId
      * @param string $objectUri
      * @param string $calendarData
-     * @return void
+     * @return string|null
      */
     public function createCalendarObject($calendarId,$objectUri,$calendarData) {
 
-        $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified) VALUES (?,?,?,?)');
-        $stmt->execute(array($calendarId,$objectUri,$calendarData,time()));
+        $extraData = $this->getDenormalizedData($calendarData);
+
+        $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence) VALUES (?,?,?,?,?,?,?,?,?)');
+        $stmt->execute(array(
+            $calendarId,
+            $objectUri,
+            $calendarData,
+            time(),
+            $extraData['etag'],
+            $extraData['size'],
+            $extraData['componentType'],
+            $extraData['firstOccurence'],
+            $extraData['lastOccurence'],
+        ));
         $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
         $stmt->execute(array($calendarId));
 
+        return '"' . $extraData['etag'] . '"';
+
     }
 
     /**
      * Updates an existing calendarobject, based on it's uri.
      *
-     * @param string $calendarId
+     * It is possible return an etag from this function, which will be used in
+     * the response to this PUT request. Note that the ETag must be surrounded
+     * by double-quotes.
+     *
+     * However, you should only really return this ETag if you don't mangle the
+     * calendar-data. If the result of a subsequent GET to this object is not
+     * the exact same as this request body, you should omit the ETag.
+     *
+     * @param mixed $calendarId
      * @param string $objectUri
      * @param string $calendarData
-     * @return void
+     * @return string|null
      */
     public function updateCalendarObject($calendarId,$objectUri,$calendarData) {
 
-        $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ? WHERE calendarid = ? AND uri = ?');
-        $stmt->execute(array($calendarData,time(),$calendarId,$objectUri));
+        $extraData = $this->getDenormalizedData($calendarData);
+
+        $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ? WHERE calendarid = ? AND uri = ?');
+        $stmt->execute(array($calendarData,time(), $extraData['etag'], $extraData['size'], $extraData['componentType'], $extraData['firstOccurence'], $extraData['lastOccurence'] ,$calendarId,$objectUri));
         $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
         $stmt->execute(array($calendarId));
 
+        return '"' . $extraData['etag'] . '"';
+
+    }
+
+    /**
+     * Parses some information from calendar objects, used for optimized
+     * calendar-queries.
+     *
+     * Returns an array with the following keys:
+     *   * etag
+     *   * size
+     *   * componentType
+     *   * firstOccurence
+     *   * lastOccurence
+     *
+     * @param string $calendarData
+     * @return array
+     */
+    protected function getDenormalizedData($calendarData) {
+
+        $vObject = VObject\Reader::read($calendarData);
+        $componentType = null;
+        $component = null;
+        $firstOccurence = null;
+        $lastOccurence = null;
+        foreach($vObject->getComponents() as $component) {
+            if ($component->name!=='VTIMEZONE') {
+                $componentType = $component->name;
+                break;
+            }
+        }
+        if (!$componentType) {
+            throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
+        }
+        if ($componentType === 'VEVENT') {
+            $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
+            // Finding the last occurence is a bit harder
+            if (!isset($component->RRULE)) {
+                if (isset($component->DTEND)) {
+                    $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
+                } elseif (isset($component->DURATION)) {
+                    $endDate = clone $component->DTSTART->getDateTime();
+                    $endDate->add(VObject\DateTimeParser::parse($component->DURATION->value));
+                    $lastOccurence = $endDate->getTimeStamp();
+                } elseif ($component->DTSTART->getDateType()===VObject\Property\DateTime::DATE) {
+                    $endDate = clone $component->DTSTART->getDateTime();
+                    $endDate->modify('+1 day');
+                    $lastOccurence = $endDate->getTimeStamp();
+                } else {
+                    $lastOccurence = $firstOccurence;
+                }
+            } else {
+                $it = new VObject\RecurrenceIterator($vObject, (string)$component->UID);
+                $maxDate = new DateTime(self::MAX_DATE);
+                if ($it->isInfinite()) {
+                    $lastOccurence = $maxDate->getTimeStamp();
+                } else {
+                    $end = $it->getDtEnd();
+                    while($it->valid() && $end < $maxDate) {
+                        $end = $it->getDtEnd();
+                        $it->next();
+
+                    }
+                    $lastOccurence = $end->getTimeStamp();
+                }
+
+            }
+        }
+
+        return array(
+            'etag' => md5($calendarData),
+            'size' => strlen($calendarData),
+            'componentType' => $componentType,
+            'firstOccurence' => $firstOccurence,
+            'lastOccurence'  => $lastOccurence,
+        );
+
     }
 
     /**
@@ -392,5 +556,132 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
     }
 
+    /**
+     * Performs a calendar-query on the contents of this calendar.
+     *
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
+     * calendar-query it is possible for a client to request a specific set of
+     * object, based on contents of iCalendar properties, date-ranges and
+     * iCalendar component types (VTODO, VEVENT).
+     *
+     * This method should just return a list of (relative) urls that match this
+     * query.
+     *
+     * The list of filters are specified as an array. The exact array is
+     * documented by Sabre_CalDAV_CalendarQueryParser.
+     *
+     * Note that it is extremely likely that getCalendarObject for every path
+     * returned from this method will be called almost immediately after. You
+     * may want to anticipate this to speed up these requests.
+     *
+     * This method provides a default implementation, which parses *all* the
+     * iCalendar objects in the specified calendar.
+     *
+     * This default may well be good enough for personal use, and calendars
+     * that aren't very large. But if you anticipate high usage, big calendars
+     * or high loads, you are strongly adviced to optimize certain paths.
+     *
+     * The best way to do so is override this method and to optimize
+     * specifically for 'common filters'.
+     *
+     * Requests that are extremely common are:
+     *   * requests for just VEVENTS
+     *   * requests for just VTODO
+     *   * requests with a time-range-filter on a VEVENT.
+     *
+     * ..and combinations of these requests. It may not be worth it to try to
+     * handle every possible situation and just rely on the (relatively
+     * easy to use) CalendarQueryValidator to handle the rest.
+     *
+     * Note that especially time-range-filters may be difficult to parse. A
+     * time-range filter specified on a VEVENT must for instance also handle
+     * recurrence rules correctly.
+     * A good example of how to interprete all these filters can also simply
+     * be found in Sabre_CalDAV_CalendarQueryFilter. This class is as correct
+     * as possible, so it gives you a good idea on what type of stuff you need
+     * to think of.
+     *
+     * This specific implementation (for the PDO) backend optimizes filters on
+     * specific components, and VEVENT time-ranges.
+     *
+     * @param string $calendarId
+     * @param array $filters
+     * @return array
+     */
+    public function calendarQuery($calendarId, array $filters) {
+
+        $result = array();
+        $validator = new Sabre_CalDAV_CalendarQueryValidator();
+
+        $componentType = null;
+        $requirePostFilter = true;
+        $timeRange = null;
+
+        // if no filters were specified, we don't need to filter after a query
+        if (!$filters['prop-filters'] && !$filters['comp-filters']) {
+            $requirePostFilter = false;
+        }
+
+        // Figuring out if there's a component filter
+        if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) {
+            $componentType = $filters['comp-filters'][0]['name'];
+
+            // Checking if we need post-filters
+            if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) {
+                $requirePostFilter = false;
+            }
+            // There was a time-range filter
+            if ($componentType == 'VEVENT' && isset($filters['comp-filters'][0]['time-range'])) {
+                $timeRange = $filters['comp-filters'][0]['time-range'];
+
+                // If start time OR the end time is not specified, we can do a
+                // 100% accurate mysql query.
+                if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) {
+                    $requirePostFilter = false;
+                }
+            }
 
+        }
+
+        if ($requirePostFilter) {
+            $query = "SELECT uri, calendardata FROM ".$this->calendarObjectTableName." WHERE calendarid = :calendarid";
+        } else {
+            $query = "SELECT uri FROM ".$this->calendarObjectTableName." WHERE calendarid = :calendarid";
+        }
+
+        $values = array(
+            'calendarid' => $calendarId,
+        );
+
+        if ($componentType) {
+            $query.=" AND componenttype = :componenttype";
+            $values['componenttype'] = $componentType;
+        }
+
+        if ($timeRange && $timeRange['start']) {
+            $query.=" AND lastoccurence > :startdate";
+            $values['startdate'] = $timeRange['start']->getTimeStamp();
+        }
+        if ($timeRange && $timeRange['end']) {
+            $query.=" AND firstoccurence < :enddate";
+            $values['enddate'] = $timeRange['end']->getTimeStamp();
+        }
+
+        $stmt = $this->pdo->prepare($query);
+        $stmt->execute($values);
+
+        $result = array();
+        while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+            if ($requirePostFilter) {
+                if (!$this->validateFilterForObject($row, $filters)) {
+                    continue;
+                }
+            }
+            $result[] = $row['uri'];
+
+        }
+
+        return $result;
+
+    }
 }
diff --git a/3rdparty/Sabre/CalDAV/Backend/SharingSupport.php b/3rdparty/Sabre/CalDAV/Backend/SharingSupport.php
new file mode 100644
index 0000000000000000000000000000000000000000..f73f0ff3d8afbb5bb447dfb6a664b1e83f018d18
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Backend/SharingSupport.php
@@ -0,0 +1,238 @@
+<?php
+
+/**
+ * Adds support for sharing features to a CalDAV server.
+ *
+ * Note: This feature is experimental, and may change in between different
+ * SabreDAV versions.
+ *
+ * Early warning: Currently SabreDAV provides no implementation for this. This
+ * is, because in it's current state there is no elegant way to do this.
+ * The problem lies in the fact that a real CalDAV server with sharing support
+ * would first need email support (with invite notifications), and really also
+ * a browser-frontend that allows people to accept or reject these shares.
+ *
+ * In addition, the CalDAV backends are currently kept as independent as
+ * possible, and should not be aware of principals, email addresses or
+ * accounts.
+ *
+ * Adding an implementation for Sharing to standard-sabredav would contradict
+ * these goals, so for this reason this is currently not implemented, although
+ * it may very well in the future; but probably not before SabreDAV 2.0.
+ *
+ * The interface works however, so if you implement all this, and do it
+ * correctly sharing _will_ work. It's not particularly easy, and I _urge you_
+ * to make yourself acquainted with the following document first:
+ *
+ * https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
+ *
+ * An overview
+ * ===========
+ *
+ * Implementing this interface will allow a user to share his or her calendars
+ * to other users. Effectively, when a calendar is shared the calendar will
+ * show up in both the Sharer's and Sharee's calendar-home root.
+ * This interface adds a few methods that ensure that this happens, and there
+ * are also a number of new requirements in the base-class you must now follow.
+ *
+ *
+ * How it works
+ * ============
+ *
+ * When a user shares a calendar, the addShare() method will be called with a
+ * list of sharees that are now added, and a list of sharees that have been
+ * removed.
+ * Removal is instant, but when a sharee is added the sharee first gets a
+ * chance to accept or reject the invitation for a share.
+ *
+ * After a share is accepted, the calendar will be returned from
+ * getUserCalendars for both the sharer, and the sharee.
+ *
+ * If the sharee deletes the calendar, only their share gets deleted. When the
+ * owner deletes a calendar, it will be removed for everybody.
+ *
+ *
+ * Notifications
+ * =============
+ *
+ * During all these sharing operations, a lot of notifications are sent back
+ * and forward.
+ *
+ * Whenever the list of sharees for a calendar has been changed (they have been
+ * added, removed or modified) all sharees should get a notification for this
+ * change.
+ * This notification is always represented by:
+ *
+ * Sabre_CalDAV_Notifications_Notification_Invite
+ *
+ * In the case of an invite, the sharee may reply with an 'accept' or
+ * 'decline'. These are always represented by:
+ *
+ * Sabre_CalDAV_Notifications_Notification_Invite
+ *
+ *
+ * Calendar access by sharees
+ * ==========================
+ *
+ * As mentioned earlier, shared calendars must now also be returned for
+ * getCalendarsForUser for sharees. A few things change though.
+ *
+ * The following properties must be specified:
+ *
+ * 1. {http://calendarserver.org/ns/}shared-url
+ *
+ * This property MUST contain the url to the original calendar, that is.. the
+ * path to the calendar from the owner.
+ *
+ * 2. {http://sabredav.org/ns}owner-principal
+ *
+ * This is a url to to the principal who is sharing the calendar.
+ *
+ * 3. {http://sabredav.org/ns}read-only
+ *
+ * This should be either 0 or 1, depending on if the user has read-only or
+ * read-write access to the calendar.
+ *
+ * Only when this is done, the calendar will correctly be marked as a calendar
+ * that's shared to him, thus allowing clients to display the correct interface
+ * and ACL enforcement.
+ *
+ * If a sharee deletes their calendar, only their instance of the calendar
+ * should be deleted, the original should still exists.
+ * Pretty much any 'dead' WebDAV properties on these shared calendars should be
+ * specific to a user. This means that if the displayname is changed by a
+ * sharee, the original is not affected. This is also true for:
+ *   * The description
+ *   * The color
+ *   * The order
+ *   * And any other dead properties.
+ *
+ * Properties like a ctag should not be different for multiple instances of the
+ * calendar.
+ *
+ * Lastly, objects *within* calendars should also have user-specific data. The
+ * two things that are user-specific are:
+ *   * VALARM objects
+ *   * The TRANSP property
+ *
+ * This _also_ implies that if a VALARM is deleted by a sharee for some event,
+ * this has no effect on the original VALARM.
+ *
+ * Understandably, the this last requirement is one of the hardest.
+ * Realisticly, I can see people ignoring this part of the spec, but that could
+ * cause a different set of issues.
+ *
+ *
+ * Publishing
+ * ==========
+ *
+ * When a user publishes a url, the server should generate a 'publish url'.
+ * This is a read-only url, anybody can use to consume the calendar feed.
+ *
+ * Calendars are in one of two states:
+ *   * published
+ *   * unpublished
+ *
+ * If a calendar is published, the following property should be returned
+ * for each calendar in getCalendarsForPrincipal.
+ *
+ * {http://calendarserver.org/ns/}publish-url
+ *
+ * This element should contain a {DAV:}href element, which points to the
+ * public url that does not require authentication. Unlike every other href,
+ * this url must be absolute.
+ *
+ * Ideally, the following property is always returned
+ *
+ * {http://calendarserver.org/ns/}pre-publish-url
+ *
+ * This property should contain the url that the calendar _would_ have, if it
+ * were to be published. iCal uses this to display the url, before the user
+ * will actually publish it.
+ *
+ *
+ * Selectively disabling publish or share feature
+ * ==============================================
+ *
+ * If Sabre_CalDAV_Property_AllowedSharingModes is returned from
+ * getCalendarsByUser, this allows the server to specify wether either sharing,
+ * or publishing is supported.
+ *
+ * This allows a client to determine in advance which features are available,
+ * and update the interface appropriately. If this property is not returned by
+ * the backend, the SharingPlugin automatically injects it and assumes both
+ * features are available.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Backend_SharingSupport extends Sabre_CalDAV_Backend_NotificationSupport {
+
+    /**
+     * Updates the list of shares.
+     *
+     * The first array is a list of people that are to be added to the
+     * calendar.
+     *
+     * Every element in the add array has the following properties:
+     *   * href - A url. Usually a mailto: address
+     *   * commonName - Usually a first and last name, or false
+     *   * summary - A description of the share, can also be false
+     *   * readOnly - A boolean value
+     *
+     * Every element in the remove array is just the address string.
+     *
+     * Note that if the calendar is currently marked as 'not shared' by and
+     * this method is called, the calendar should be 'upgraded' to a shared
+     * calendar.
+     *
+     * @param mixed $calendarId
+     * @param array $add
+     * @param array $remove
+     * @return void
+     */
+    function updateShares($calendarId, array $add, array $remove);
+
+    /**
+     * Returns the list of people whom this calendar is shared with.
+     *
+     * Every element in this array should have the following properties:
+     *   * href - Often a mailto: address
+     *   * commonName - Optional, for example a first + last name
+     *   * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants.
+     *   * readOnly - boolean
+     *   * summary - Optional, a description for the share
+     *
+     * @param mixed $calendarId
+     * @return array
+     */
+    function getShares($calendarId);
+
+    /**
+     * This method is called when a user replied to a request to share.
+     *
+     * If the user chose to accept the share, this method should return the
+     * newly created calendar url.
+     *
+     * @param string href The sharee who is replying (often a mailto: address)
+     * @param int status One of the SharingPlugin::STATUS_* constants
+     * @param string $calendarUri The url to the calendar thats being shared
+     * @param string $inReplyTo The unique id this message is a response to
+     * @param string $summary A description of the reply
+     * @return null|string
+     */
+    function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
+
+    /**
+     * Publishes a calendar
+     *
+     * @param mixed $calendarId
+     * @param bool $value
+     * @return void
+     */
+    function setPublishStatus($calendarId, $value);
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php
old mode 100755
new mode 100644
index 623df2dd1b8951cb9d6730f9b6849265dcf1f159..63253febd5cb54da70ede250ffb14a179ee6529c
--- a/3rdparty/Sabre/CalDAV/Calendar.php
+++ b/3rdparty/Sabre/CalDAV/Calendar.php
@@ -9,7 +9,7 @@
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
@@ -24,7 +24,7 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     /**
      * CalDAV backend
      *
-     * @var Sabre_CalDAV_Backend_Abstract
+     * @var Sabre_CalDAV_Backend_BackendInterface
      */
     protected $caldavBackend;
 
@@ -39,16 +39,15 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * Constructor
      *
      * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend
      * @param array $calendarInfo
      */
-    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $calendarInfo) {
+    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_BackendInterface $caldavBackend, $calendarInfo) {
 
         $this->caldavBackend = $caldavBackend;
         $this->principalBackend = $principalBackend;
         $this->calendarInfo = $calendarInfo;
 
-
     }
 
     /**
@@ -92,9 +91,6 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
             case '{urn:ietf:params:xml:ns:caldav}supported-collation-set' :
                 $response[$prop] =  new Sabre_CalDAV_Property_SupportedCollationSet();
                 break;
-            case '{DAV:}owner' :
-                $response[$prop] = new Sabre_DAVACL_Property_Principal(Sabre_DAVACL_Property_Principal::HREF,$this->calendarInfo['principaluri']);
-                break;
             default :
                 if (isset($this->calendarInfo[$prop])) $response[$prop] = $this->calendarInfo[$prop];
                 break;
@@ -110,12 +106,21 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * The contained calendar objects are for example Events or Todo's.
      *
      * @param string $name
-     * @return Sabre_DAV_ICalendarObject
+     * @return Sabre_CalDAV_ICalendarObject
      */
     public function getChild($name) {
 
         $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name);
         if (!$obj) throw new Sabre_DAV_Exception_NotFound('Calendar object not found');
+
+        $obj['acl'] = $this->getACL();
+        // Removing the irrelivant
+        foreach($obj['acl'] as $key=>$acl) {
+            if ($acl['privilege'] === '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy') {
+                unset($obj['acl'][$key]);
+            }
+        }
+
         return new Sabre_CalDAV_CalendarObject($this->caldavBackend,$this->calendarInfo,$obj);
 
     }
@@ -130,6 +135,13 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
         $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
         $children = array();
         foreach($objs as $obj) {
+            $obj['acl'] = $this->getACL();
+            // Removing the irrelivant
+            foreach($obj['acl'] as $key=>$acl) {
+                if ($acl['privilege'] === '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy') {
+                    unset($obj['acl'][$key]);
+                }
+            }
             $children[] = new Sabre_CalDAV_CalendarObject($this->caldavBackend,$this->calendarInfo,$obj);
         }
         return $children;
@@ -262,27 +274,27 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
         return array(
             array(
                 'privilege' => '{DAV:}read',
-                'principal' => $this->calendarInfo['principaluri'],
+                'principal' => $this->getOwner(),
                 'protected' => true,
             ),
             array(
                 'privilege' => '{DAV:}write',
-                'principal' => $this->calendarInfo['principaluri'],
+                'principal' => $this->getOwner(),
                 'protected' => true,
             ),
             array(
                 'privilege' => '{DAV:}read',
-                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+                'principal' => $this->getOwner() . '/calendar-proxy-write',
                 'protected' => true,
             ),
             array(
                 'privilege' => '{DAV:}write',
-                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+                'principal' => $this->getOwner() . '/calendar-proxy-write',
                 'protected' => true,
             ),
             array(
                 'privilege' => '{DAV:}read',
-                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
+                'principal' => $this->getOwner() . '/calendar-proxy-read',
                 'protected' => true,
             ),
             array(
@@ -340,4 +352,27 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
 
     }
 
+    /**
+     * Performs a calendar-query on the contents of this calendar.
+     *
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
+     * calendar-query it is possible for a client to request a specific set of
+     * object, based on contents of iCalendar properties, date-ranges and
+     * iCalendar component types (VTODO, VEVENT).
+     *
+     * This method should just return a list of (relative) urls that match this
+     * query.
+     *
+     * The list of filters are specified as an array. The exact array is
+     * documented by Sabre_CalDAV_CalendarQueryParser.
+     *
+     * @param array $filters
+     * @return array
+     */
+    public function calendarQuery(array $filters) {
+
+        return $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
+
+    }
+
 }
diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php
old mode 100755
new mode 100644
index 72f0a578d16a554b847354867c608ca732b8f72e..40bd8588c707e61c7a444185ab413426e2fbd282
--- a/3rdparty/Sabre/CalDAV/CalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/CalendarObject.php
@@ -6,13 +6,13 @@
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV_ICalendarObject, Sabre_DAVACL_IACL {
 
     /**
-     * Sabre_CalDAV_Backend_Abstract
+     * Sabre_CalDAV_Backend_BackendInterface
      *
      * @var array
      */
@@ -35,11 +35,11 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     /**
      * Constructor
      *
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend
      * @param array $calendarInfo
      * @param array $objectData
      */
-    public function __construct(Sabre_CalDAV_Backend_Abstract $caldavBackend,array $calendarInfo,array $objectData) {
+    public function __construct(Sabre_CalDAV_Backend_BackendInterface $caldavBackend,array $calendarInfo,array $objectData) {
 
         $this->caldavBackend = $caldavBackend;
 
@@ -85,8 +85,8 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     /**
      * Updates the ICalendar-formatted object
      *
-     * @param string $calendarData
-     * @return void
+     * @param string|resource $calendarData
+     * @return string
      */
     public function put($calendarData) {
 
@@ -119,7 +119,7 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
      */
     public function getContentType() {
 
-        return 'text/calendar';
+        return 'text/calendar; charset=utf-8';
 
     }
 
@@ -143,7 +143,7 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     /**
      * Returns the last modification date as a unix timestamp
      *
-     * @return time
+     * @return int
      */
     public function getLastModified() {
 
@@ -206,6 +206,12 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
      */
     public function getACL() {
 
+        // An alternative acl may be specified in the object data.
+        if (isset($this->objectData['acl'])) {
+            return $this->objectData['acl'];
+        }
+
+        // The default ACL
         return array(
             array(
                 'privilege' => '{DAV:}read',
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
old mode 100755
new mode 100644
index bd0d343382f8b684b396e6addcc445e1dbbbaae1..b95095f96fc51177fa9fb06e1a07458aad94e4de
--- a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * Parses the calendar-query report request body.
  *
@@ -68,7 +70,7 @@ class Sabre_CalDAV_CalendarQueryParser {
 
         $this->xpath = new DOMXPath($dom);
         $this->xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
-        $this->xpath->registerNameSpace('dav','urn:DAV');
+        $this->xpath->registerNameSpace('dav','DAV:');
 
     }
 
@@ -241,12 +243,12 @@ class Sabre_CalDAV_CalendarQueryParser {
         $timeRangeNode = $timeRangeNodes->item(0);
 
         if ($start = $timeRangeNode->getAttribute('start')) {
-            $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+            $start = VObject\DateTimeParser::parseDateTime($start);
         } else {
             $start = null;
         }
         if ($end = $timeRangeNode->getAttribute('end')) {
-            $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+            $end = VObject\DateTimeParser::parseDateTime($end);
         } else {
             $end = null;
         }
@@ -274,13 +276,13 @@ class Sabre_CalDAV_CalendarQueryParser {
         if(!$start) {
             throw new Sabre_DAV_Exception_BadRequest('The "start" attribute is required for the CALDAV:expand element');
         } 
-        $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+        $start = VObject\DateTimeParser::parseDateTime($start);
 
         $end = $parentNode->getAttribute('end');
         if(!$end) {
             throw new Sabre_DAV_Exception_BadRequest('The "end" attribute is required for the CALDAV:expand element');
         } 
-        $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+        $end = VObject\DateTimeParser::parseDateTime($end);
         
         if ($end <= $start) {
             throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
old mode 100755
new mode 100644
index 8f674840e8780e441fac72019cb36396627fc855..53e86fc509f16d24e11b14737fb15e92c4328c57
--- a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * CalendarQuery Validator
  *
@@ -22,11 +24,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
      *
      * The list of filters must be formatted as parsed by Sabre_CalDAV_CalendarQueryParser
      *
-     * @param Sabre_VObject_Component $vObject
+     * @param VObject\Component $vObject
      * @param array $filters
      * @return bool
      */
-    public function validate(Sabre_VObject_Component $vObject,array $filters) {
+    public function validate(VObject\Component $vObject,array $filters) {
 
         // The top level object is always a component filter.
         // We'll parse it manually, as it's pretty simple.
@@ -48,11 +50,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
      * component we're checking should be specified, not the component to check
      * itself.
      *
-     * @param Sabre_VObject_Component $parent
+     * @param VObject\Component $parent
      * @param array $filters
      * @return bool
      */
-    protected function validateCompFilters(Sabre_VObject_Component $parent, array $filters) {
+    protected function validateCompFilters(VObject\Component $parent, array $filters) {
 
         foreach($filters as $filter) {
 
@@ -117,11 +119,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
      * property we're checking should be specified, not the property to check
      * itself.
      *
-     * @param Sabre_VObject_Component $parent
+     * @param VObject\Component $parent
      * @param array $filters
      * @return bool
      */
-    protected function validatePropFilters(Sabre_VObject_Component $parent, array $filters) {
+    protected function validatePropFilters(VObject\Component $parent, array $filters) {
 
         foreach($filters as $filter) {
 
@@ -187,11 +189,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
      * parameter we're checking should be specified, not the parameter to check
      * itself.
      *
-     * @param Sabre_VObject_Property $parent
+     * @param VObject\Property $parent
      * @param array $filters
      * @return bool
      */
-    protected function validateParamFilters(Sabre_VObject_Property $parent, array $filters) {
+    protected function validateParamFilters(VObject\Property $parent, array $filters) {
 
         foreach($filters as $filter) {
 
@@ -243,11 +245,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
      * A single text-match should be specified as well as the specific property
      * or parameter we need to validate.
      *
-     * @param Sabre_VObject_Node $parent
+     * @param VObject\Node $parent
      * @param array $textMatch
      * @return bool
      */
-    protected function validateTextMatch(Sabre_VObject_Node $parent, array $textMatch) {
+    protected function validateTextMatch(VObject\Node $parent, array $textMatch) {
 
         $value = (string)$parent;
 
@@ -263,12 +265,12 @@ class Sabre_CalDAV_CalendarQueryValidator {
      * This is all based on the rules specified in rfc4791, which are quite
      * complex.
      *
-     * @param Sabre_VObject_Node $component
+     * @param VObject\Node $component
      * @param DateTime $start
      * @param DateTime $end
      * @return bool
      */
-    protected function validateTimeRange(Sabre_VObject_Node $component, $start, $end) {
+    protected function validateTimeRange(VObject\Node $component, $start, $end) {
 
         if (is_null($start)) {
             $start = new DateTime('1900-01-01');
@@ -296,7 +298,7 @@ class Sabre_CalDAV_CalendarQueryValidator {
                 if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
 
                     // Fire up the iterator!
-                    $it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
+                    $it = new VObject\RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
                     while($it->valid()) {
                         $expandedEvent = $it->getEventObject();
 
diff --git a/3rdparty/Sabre/CalDAV/CalendarRootNode.php b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
old mode 100755
new mode 100644
index 3907913cc78600afc38698ddb42ba3d30cffeed7..eb62eea75a6116ad0ddb07b994c37095919afdc5
--- a/3rdparty/Sabre/CalDAV/CalendarRootNode.php
+++ b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
@@ -1,14 +1,15 @@
 <?php
 
 /**
- * Users collection
+ * Calendars collection
  *
- * This object is responsible for generating a collection of users.
+ * This object is responsible for generating a list of calendar-homes for each
+ * user.
  *
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollection {
@@ -16,7 +17,7 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
     /**
      * CalDAV backend
      *
-     * @var Sabre_CalDAV_Backend_Abstract
+     * @var Sabre_CalDAV_Backend_BackendInterface
      */
     protected $caldavBackend;
 
@@ -32,10 +33,10 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
      *
      *
      * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend
      * @param string $principalPrefix
      */
-    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CalDAV_Backend_Abstract $caldavBackend, $principalPrefix = 'principals') {
+    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CalDAV_Backend_BackendInterface $caldavBackend, $principalPrefix = 'principals') {
 
         parent::__construct($principalBackend, $principalPrefix);
         $this->caldavBackend = $caldavBackend;
diff --git a/3rdparty/Sabre/CalDAV/Exception/InvalidComponentType.php b/3rdparty/Sabre/CalDAV/Exception/InvalidComponentType.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ac617d22f0a23c98edd52c5da8fe5eca3b3fb5e
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Exception/InvalidComponentType.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Sabre_CalDAV_Exception_InvalidComponentType
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Exception_InvalidComponentType extends Sabre_DAV_Exception_Forbidden {
+
+    /**
+     * Adds in extra information in the xml response.
+     *
+     * This method adds the {CALDAV:}supported-calendar-component as defined in rfc4791
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $errorNode
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
+
+        $doc = $errorNode->ownerDocument;
+
+        $np = $doc->createElementNS(Sabre_CalDAV_Plugin::NS_CALDAV,'cal:supported-calendar-component');
+        $errorNode->appendChild($np);
+
+    }
+
+}
\ No newline at end of file
diff --git a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
old mode 100755
new mode 100644
index ec42b406b2f172c7289a00ba7975fc35f59fa877..d3e4e7b7201c27613bd333065e3da1bd5c59d247
--- a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
+++ b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * ICS Exporter
  *
@@ -82,7 +84,7 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
      */
     public function generateICS(array $nodes) {
 
-        $calendar = new Sabre_VObject_Component('vcalendar');
+        $calendar = new VObject\Component('vcalendar');
         $calendar->version = '2.0';
         if (Sabre_DAV_Server::$exposeVersion) {
             $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
@@ -103,7 +105,7 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
             }
             $nodeData = $node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'];
 
-            $nodeComp = Sabre_VObject_Reader::read($nodeData);
+            $nodeComp = VObject\Reader::read($nodeData);
 
             foreach($nodeComp->children() as $child) {
 
diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php
old mode 100755
new mode 100644
index 15d51ebcf79a2b7552257ac4b7c1d5e42596461a..40aa9f9579c07efbb1fea406cfaa4e7834dde94a
--- a/3rdparty/Sabre/CalDAV/ICalendar.php
+++ b/3rdparty/Sabre/CalDAV/ICalendar.php
@@ -8,11 +8,28 @@
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 interface Sabre_CalDAV_ICalendar extends Sabre_DAV_ICollection {
 
-
+    /**
+     * Performs a calendar-query on the contents of this calendar.
+     *
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
+     * calendar-query it is possible for a client to request a specific set of
+     * object, based on contents of iCalendar properties, date-ranges and
+     * iCalendar component types (VTODO, VEVENT).
+     *
+     * This method should just return a list of (relative) urls that match this
+     * query.
+     *
+     * The list of filters are specified as an array. The exact array is
+     * documented by Sabre_CalDAV_CalendarQueryParser.
+     *
+     * @param array $filters
+     * @return array
+     */
+    public function calendarQuery(array $filters);
 
 }
diff --git a/3rdparty/Sabre/CalDAV/ICalendarObject.php b/3rdparty/Sabre/CalDAV/ICalendarObject.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/IShareableCalendar.php b/3rdparty/Sabre/CalDAV/IShareableCalendar.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b55788c014887227ee1eca4f9b46ca9b2c9738c
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/IShareableCalendar.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * This interface represents a Calendar that can be shared with other users.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_IShareableCalendar extends Sabre_CalDAV_ICalendar {
+
+    /**
+     * Updates the list of shares.
+     *
+     * The first array is a list of people that are to be added to the
+     * calendar.
+     *
+     * Every element in the add array has the following properties:
+     *   * href - A url. Usually a mailto: address
+     *   * commonName - Usually a first and last name, or false
+     *   * summary - A description of the share, can also be false
+     *   * readOnly - A boolean value
+     *
+     * Every element in the remove array is just the address string.
+     *
+     * @param array $add
+     * @param array $remove
+     * @return void
+     */
+    function updateShares(array $add, array $remove);
+
+    /**
+     * Returns the list of people whom this calendar is shared with.
+     *
+     * Every element in this array should have the following properties:
+     *   * href - Often a mailto: address
+     *   * commonName - Optional, for example a first + last name
+     *   * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants.
+     *   * readOnly - boolean
+     *   * summary - Optional, a description for the share
+     *
+     * @return array
+     */
+    function getShares();
+
+}
diff --git a/3rdparty/Sabre/CalDAV/ISharedCalendar.php b/3rdparty/Sabre/CalDAV/ISharedCalendar.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb4d31fead5d4f62312a31989ead4aab8f29ceab
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/ISharedCalendar.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * This interface represents a Calendar that is shared by a different user.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_ISharedCalendar extends Sabre_CalDAV_ICalendar {
+
+    /**
+     * This method should return the url of the owners' copy of the shared
+     * calendar.
+     *
+     * @return string
+     */
+    function getSharedUrl();
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/Collection.php b/3rdparty/Sabre/CalDAV/Notifications/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..83b6c9301dcbcc245e24d6fff482821652412d2b
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/Collection.php
@@ -0,0 +1,169 @@
+<?php
+
+/**
+ * This node represents a list of notifications.
+ *
+ * It provides no additional functionality, but you must implement this
+ * interface to allow the Notifications plugin to mark the collection
+ * as a notifications collection.
+ *
+ * This collection should only return Sabre_CalDAV_Notifications_INode nodes as
+ * its children.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Notifications_Collection extends Sabre_DAV_Collection implements Sabre_CalDAV_Notifications_ICollection, Sabre_DAVACL_IACL {
+
+    /**
+     * The notification backend
+     *
+     * @var Sabre_CalDAV_Backend_NotificationSupport
+     */
+    protected $caldavBackend;
+
+    /**
+     * Principal uri
+     *
+     * @var string
+     */
+    protected $principalUri;
+
+    /**
+     * Constructor
+     *
+     * @param Sabre_CalDAV_Backend_NotificationSupport $caldavBackend
+     * @param string $principalUri
+     */
+    public function __construct(Sabre_CalDAV_Backend_NotificationSupport $caldavBackend, $principalUri) {
+
+        $this->caldavBackend = $caldavBackend;
+        $this->principalUri = $principalUri;
+
+    }
+
+    /**
+     * Returns all notifications for a principal
+     *
+     * @return array
+     */
+    public function getChildren() {
+
+        $children = array();
+        $notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri);
+
+        foreach($notifications as $notification) {
+
+            $children[] = new Sabre_CalDAV_Notifications_Node(
+                $this->caldavBackend,
+                $this->principalUri,
+                $notification
+            );
+        }
+
+        return $children;
+
+    }
+
+    /**
+     * Returns the name of this object
+     *
+     * @return string
+     */
+    public function getName() {
+
+        return 'notifications';
+
+    }
+
+    /**
+     * Returns the owner principal
+     *
+     * This must be a url to a principal, or null if there's no owner
+     *
+     * @return string|null
+     */
+    public function getOwner() {
+
+        return $this->principalUri;
+
+    }
+
+    /**
+     * Returns a group principal
+     *
+     * This must be a url to a principal, or null if there's no owner
+     *
+     * @return string|null
+     */
+    public function getGroup() {
+
+        return null;
+
+    }
+
+    /**
+     * Returns a list of ACE's for this node.
+     *
+     * Each ACE has the following properties:
+     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+     *     currently the only supported privileges
+     *   * 'principal', a url to the principal who owns the node
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
+     */
+    public function getACL() {
+
+        return array(
+            array(
+                'principal' => $this->getOwner(),
+                'privilege' => '{DAV:}read',
+                'protected' => true,
+            ),
+            array(
+                'principal' => $this->getOwner(),
+                'privilege' => '{DAV:}write',
+                'protected' => true,
+            )
+        );
+
+    }
+
+    /**
+     * Updates the ACL
+     *
+     * This method will receive a list of new ACE's as an array argument.
+     *
+     * @param array $acl
+     * @return void
+     */
+    public function setACL(array $acl) {
+
+        throw new Sabre_DAV_Exception_NotImplemented('Updating ACLs is not implemented here');
+
+    }
+
+    /**
+     * Returns the list of supported privileges for this node.
+     *
+     * The returned data structure is a list of nested privileges.
+     * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+     * standard structure.
+     *
+     * If null is returned from this method, the default privilege set is used,
+     * which is fine for most common usecases.
+     *
+     * @return array|null
+     */
+    public function getSupportedPrivilegeSet() {
+
+        return null;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/ICollection.php b/3rdparty/Sabre/CalDAV/Notifications/ICollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb873af3f92aecd9d5e68870218a9b813e03e5ad
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/ICollection.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * This node represents a list of notifications.
+ *
+ * It provides no additional functionality, but you must implement this
+ * interface to allow the Notifications plugin to mark the collection
+ * as a notifications collection.
+ *
+ * This collection should only return Sabre_CalDAV_Notifications_INode nodes as
+ * its children.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Notifications_ICollection extends Sabre_DAV_ICollection {
+
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/INode.php b/3rdparty/Sabre/CalDAV/Notifications/INode.php
new file mode 100644
index 0000000000000000000000000000000000000000..84721de5ab7794bebe31d9e393262d7b7cb1b8b5
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/INode.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * This node represents a single notification.
+ *
+ * The signature is mostly identical to that of Sabre_DAV_IFile, but the get() method
+ * MUST return an xml document that matches the requirements of the
+ * 'caldav-notifications.txt' spec.
+ *
+ * For a complete example, check out the Notification class, which contains
+ * some helper functions.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Notifications_INode {
+
+    /**
+     * This method must return an xml element, using the
+     * Sabre_CalDAV_Notifications_INotificationType classes.
+     *
+     * @return Sabre_DAVNotification_INotificationType
+     */
+    function getNotificationType();
+
+    /**
+     * Returns the etag for the notification.
+     *
+     * The etag must be surrounded by litteral double-quotes.
+     *
+     * @return string
+     */
+    function getETag();
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/INotificationType.php b/3rdparty/Sabre/CalDAV/Notifications/INotificationType.php
new file mode 100644
index 0000000000000000000000000000000000000000..02a65a01fa354efc7bffd38ff7327f98330625bb
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/INotificationType.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * This interface reflects a single notification type.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Notifications_INotificationType extends Sabre_DAV_PropertyInterface {
+
+    /**
+     * This method serializes the entire notification, as it is used in the
+     * response body.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    function serializeBody(Sabre_DAV_Server $server, \DOMElement $node);
+
+    /**
+     * Returns a unique id for this notification
+     *
+     * This is just the base url. This should generally be some kind of unique
+     * id.
+     *
+     * @return string
+     */
+    function getId();
+
+    /**
+     * Returns the ETag for this notification.
+     *
+     * The ETag must be surrounded by literal double-quotes.
+     *
+     * @return string
+     */
+    function getETag();
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/Node.php b/3rdparty/Sabre/CalDAV/Notifications/Node.php
new file mode 100644
index 0000000000000000000000000000000000000000..8021a75debf006d276b1940774e33521b8e5599b
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/Node.php
@@ -0,0 +1,188 @@
+<?php
+
+/**
+ * This node represents a single notification.
+ *
+ * The signature is mostly identical to that of Sabre_DAV_IFile, but the get() method
+ * MUST return an xml document that matches the requirements of the
+ * 'caldav-notifications.txt' spec.
+
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Notifications_Node extends Sabre_DAV_File implements Sabre_CalDAV_Notifications_INode, Sabre_DAVACL_IACL {
+
+    /**
+     * The notification backend
+     *
+     * @var Sabre_CalDAV_Backend_NotificationSupport
+     */
+    protected $caldavBackend;
+
+    /**
+     * The actual notification
+     *
+     * @var Sabre_CalDAV_Notifications_INotificationType
+     */
+    protected $notification;
+
+    /**
+     * Owner principal of the notification
+     *
+     * @var string
+     */
+    protected $principalUri;
+
+    /**
+     * Constructor
+     *
+     * @param Sabre_CalDAV_Backend_NotificationSupport $caldavBackend
+     * @param string $principalUri
+     * @param Sabre_CalDAV_Notifications_INotificationType $notification
+     */
+    public function __construct(Sabre_CalDAV_Backend_NotificationSupport $caldavBackend, $principalUri, Sabre_CalDAV_Notifications_INotificationType $notification) {
+
+        $this->caldavBackend = $caldavBackend;
+        $this->principalUri = $principalUri;
+        $this->notification = $notification;
+
+    }
+
+    /**
+     * Returns the path name for this notification
+     *
+     * @return id
+     */
+    public function getName() {
+
+        return $this->notification->getId() . '.xml';
+
+    }
+
+    /**
+     * Returns the etag for the notification.
+     *
+     * The etag must be surrounded by litteral double-quotes.
+     *
+     * @return string
+     */
+    public function getETag() {
+
+        return $this->notification->getETag();
+
+    }
+
+    /**
+     * This method must return an xml element, using the
+     * Sabre_CalDAV_Notifications_INotificationType classes.
+     *
+     * @return Sabre_DAVNotification_INotificationType
+     */
+    public function getNotificationType() {
+
+        return $this->notification;
+
+    }
+
+    /**
+     * Deletes this notification
+     *
+     * @return void
+     */
+    public function delete() {
+
+        $this->caldavBackend->deleteNotification($this->getOwner(), $this->notification);
+
+    }
+
+    /**
+     * Returns the owner principal
+     *
+     * This must be a url to a principal, or null if there's no owner
+     *
+     * @return string|null
+     */
+    public function getOwner() {
+
+        return $this->principalUri;
+
+    }
+
+    /**
+     * Returns a group principal
+     *
+     * This must be a url to a principal, or null if there's no owner
+     *
+     * @return string|null
+     */
+    public function getGroup() {
+
+        return null;
+
+    }
+
+    /**
+     * Returns a list of ACE's for this node.
+     *
+     * Each ACE has the following properties:
+     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+     *     currently the only supported privileges
+     *   * 'principal', a url to the principal who owns the node
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
+     */
+    public function getACL() {
+
+        return array(
+            array(
+                'principal' => $this->getOwner(),
+                'privilege' => '{DAV:}read',
+                'protected' => true,
+            ),
+            array(
+                'principal' => $this->getOwner(),
+                'privilege' => '{DAV:}write',
+                'protected' => true,
+            )
+        );
+
+    }
+
+    /**
+     * Updates the ACL
+     *
+     * This method will receive a list of new ACE's as an array argument.
+     *
+     * @param array $acl
+     * @return void
+     */
+    public function setACL(array $acl) {
+
+        throw new Sabre_DAV_Exception_NotImplemented('Updating ACLs is not implemented here');
+
+    }
+
+    /**
+     * Returns the list of supported privileges for this node.
+     *
+     * The returned data structure is a list of nested privileges.
+     * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+     * standard structure.
+     *
+     * If null is returned from this method, the default privilege set is used,
+     * which is fine for most common usecases.
+     *
+     * @return array|null
+     */
+    public function getSupportedPrivilegeSet() {
+
+        return null;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/Notification/Invite.php b/3rdparty/Sabre/CalDAV/Notifications/Notification/Invite.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6b36203f344bb418a9564add9bdbc4d18e65397
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/Notification/Invite.php
@@ -0,0 +1,276 @@
+<?php
+
+use Sabre_CalDAV_SharingPlugin as SharingPlugin;
+
+/**
+ * This class represents the cs:invite-notification notification element.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Notifications_Notification_Invite extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType {
+
+    /**
+     * A unique id for the message
+     *
+     * @var string
+     */
+    protected $id;
+
+    /**
+     * Timestamp of the notification
+     *
+     * @var DateTime
+     */
+    protected $dtStamp;
+
+    /**
+     * A url to the recipient of the notification. This can be an email
+     * address (mailto:), or a principal url.
+     *
+     * @var string
+     */
+    protected $href;
+
+    /**
+     * The type of message, see the SharingPlugin::STATUS_* constants.
+     *
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * True if access to a calendar is read-only.
+     *
+     * @var bool
+     */
+    protected $readOnly;
+
+    /**
+     * A url to the shared calendar.
+     *
+     * @var string
+     */
+    protected $hostUrl;
+
+    /**
+     * Url to the sharer of the calendar
+     *
+     * @var string
+     */
+    protected $organizer;
+
+    /**
+     * The name of the sharer.
+     *
+     * @var string
+     */
+    protected $commonName;
+
+    /**
+     * A description of the share request
+     *
+     * @var string
+     */
+    protected $summary;
+
+    /**
+     * The Etag for the notification
+     *
+     * @var string
+     */
+    protected $etag;
+
+    /**
+     * The list of supported components
+     *
+     * @var Sabre_CalDAV_Property_SupportedCalendarComponentSet
+     */
+    protected $supportedComponents;
+
+    /**
+     * Creates the Invite notification.
+     *
+     * This constructor receives an array with the following elements:
+     *
+     *   * id           - A unique id
+     *   * etag         - The etag
+     *   * dtStamp      - A DateTime object with a timestamp for the notification.
+     *   * type         - The type of notification, see SharingPlugin::STATUS_*
+     *                    constants for details.
+     *   * readOnly     - This must be set to true, if this is an invite for
+     *                    read-only access to a calendar.
+     *   * hostUrl      - A url to the shared calendar.
+     *   * organizer    - Url to the sharer principal.
+     *   * commonName   - The real name of the sharer (optional).
+     *   * summary      - Description of the share, can be the same as the
+     *                    calendar, but may also be modified (optional).
+     *   * supportedComponents - An instance of
+     *                    Sabre_CalDAV_Property_SupportedCalendarComponentSet.
+     *                    This allows the client to determine which components
+     *                    will be supported in the shared calendar. This is
+     *                    also optional.
+     *
+     * @param array $values All the options
+     */
+    public function __construct(array $values) {
+
+        $required = array(
+            'id',
+            'etag',
+            'href',
+            'dtStamp',
+            'type',
+            'readOnly',
+            'hostUrl',
+            'organizer',
+        );
+        foreach($required as $item) {
+            if (!isset($values[$item])) {
+                throw new InvalidArgumentException($item . ' is a required constructor option');
+            }
+        }
+
+        foreach($values as $key=>$value) {
+            if (!property_exists($this, $key)) {
+                throw new InvalidArgumentException('Unknown option: ' . $key);
+            }
+            $this->$key = $value;
+        }
+
+    }
+
+    /**
+     * Serializes the notification as a single property.
+     *
+     * You should usually just encode the single top-level element of the
+     * notification.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        $prop = $node->ownerDocument->createElement('cs:invite-notification');
+        $node->appendChild($prop);
+
+    }
+
+    /**
+     * This method serializes the entire notification, as it is used in the
+     * response body.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        $doc = $node->ownerDocument;
+
+        $dt = $doc->createElement('cs:dtstamp');
+        $this->dtStamp->setTimezone(new \DateTimezone('GMT'));
+        $dt->appendChild($doc->createTextNode($this->dtStamp->format('Ymd\\THis\\Z')));
+        $node->appendChild($dt);
+
+        $prop = $doc->createElement('cs:invite-notification');
+        $node->appendChild($prop);
+
+        $uid = $doc->createElement('cs:uid');
+        $uid->appendChild( $doc->createTextNode($this->id) );
+        $prop->appendChild($uid);
+
+        $href = $doc->createElement('d:href');
+        $href->appendChild( $doc->createTextNode( $this->href ) );
+        $prop->appendChild($href);
+
+        $nodeName = null;
+        switch($this->type) {
+
+            case SharingPlugin::STATUS_ACCEPTED :
+                $nodeName = 'cs:invite-accepted';
+                break;
+            case SharingPlugin::STATUS_DECLINED :
+                $nodeName = 'cs:invite-declined';
+                break;
+            case SharingPlugin::STATUS_DELETED :
+                $nodeName = 'cs:invite-deleted';
+                break;
+            case SharingPlugin::STATUS_NORESPONSE :
+                $nodeName = 'cs:invite-noresponse';
+                break;
+
+        }
+        $prop->appendChild(
+            $doc->createElement($nodeName)
+        );
+        $hostHref = $doc->createElement('d:href', $server->getBaseUri() . $this->hostUrl);
+        $hostUrl  = $doc->createElement('cs:hosturl');
+        $hostUrl->appendChild($hostHref);
+        $prop->appendChild($hostUrl);
+
+        $access = $doc->createElement('cs:access');
+        if ($this->readOnly) {
+            $access->appendChild($doc->createElement('cs:read'));
+        } else {
+            $access->appendChild($doc->createElement('cs:read-write'));
+        }
+        $prop->appendChild($access);
+
+        $organizerHref = $doc->createElement('d:href', $server->getBaseUri() . $this->organizer);
+        $organizerUrl  = $doc->createElement('cs:organizer');
+        if ($this->commonName) {
+            $commonName = $doc->createElement('cs:common-name');
+            $commonName->appendChild($doc->createTextNode($this->commonName));
+            $organizerUrl->appendChild($commonName);
+        }
+        $organizerUrl->appendChild($organizerHref);
+        $prop->appendChild($organizerUrl);
+
+        if ($this->summary) {
+            $summary = $doc->createElement('cs:summary');
+            $summary->appendChild($doc->createTextNode($this->summary));
+            $prop->appendChild($summary);
+        }
+        if ($this->supportedComponents) {
+
+            $xcomp = $doc->createElement('cal:supported-calendar-component-set');
+            $this->supportedComponents->serialize($server, $xcomp);
+            $prop->appendChild($xcomp);
+
+        }
+
+    }
+
+    /**
+     * Returns a unique id for this notification
+     *
+     * This is just the base url. This should generally be some kind of unique
+     * id.
+     *
+     * @return string
+     */
+    public function getId() {
+
+        return $this->id;
+
+    }
+
+    /**
+     * Returns the ETag for this notification.
+     *
+     * The ETag must be surrounded by literal double-quotes.
+     *
+     * @return string
+     */
+    public function getETag() {
+
+        return $this->etag;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/Notification/InviteReply.php b/3rdparty/Sabre/CalDAV/Notifications/Notification/InviteReply.php
new file mode 100644
index 0000000000000000000000000000000000000000..e935aa5aa1129c15c7358d5fc501e83c65e2212c
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/Notification/InviteReply.php
@@ -0,0 +1,216 @@
+<?php
+
+use Sabre_CalDAV_SharingPlugin as SharingPlugin;
+
+/**
+ * This class represents the cs:invite-reply notification element.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Notifications_Notification_InviteReply extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType {
+
+    /**
+     * A unique id for the message
+     *
+     * @var string
+     */
+    protected $id;
+
+    /**
+     * Timestamp of the notification
+     *
+     * @var DateTime
+     */
+    protected $dtStamp;
+
+    /**
+     * The unique id of the notification this was a reply to.
+     *
+     * @var string
+     */
+    protected $inReplyTo;
+
+    /**
+     * A url to the recipient of the original (!) notification.
+     *
+     * @var string
+     */
+    protected $href;
+
+    /**
+     * The type of message, see the SharingPlugin::STATUS_ constants.
+     *
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * A url to the shared calendar.
+     *
+     * @var string
+     */
+    protected $hostUrl;
+
+    /**
+     * A description of the share request
+     *
+     * @var string
+     */
+    protected $summary;
+
+    /**
+     * Notification Etag
+     *
+     * @var string
+     */
+    protected $etag;
+
+    /**
+     * Creates the Invite Reply Notification.
+     *
+     * This constructor receives an array with the following elements:
+     *
+     *   * id           - A unique id
+     *   * etag         - The etag
+     *   * dtStamp      - A DateTime object with a timestamp for the notification.
+     *   * inReplyTo    - This should refer to the 'id' of the notification
+     *                    this is a reply to.
+     *   * type         - The type of notification, see SharingPlugin::STATUS_*
+     *                    constants for details.
+     *   * hostUrl      - A url to the shared calendar.
+     *   * summary      - Description of the share, can be the same as the
+     *                    calendar, but may also be modified (optional).
+     */
+    public function __construct(array $values) {
+
+        $required = array(
+            'id',
+            'etag',
+            'href',
+            'dtStamp',
+            'inReplyTo',
+            'type',
+            'hostUrl',
+        );
+        foreach($required as $item) {
+            if (!isset($values[$item])) {
+                throw new InvalidArgumentException($item . ' is a required constructor option');
+            }
+        }
+
+        foreach($values as $key=>$value) {
+            if (!property_exists($this, $key)) {
+                throw new InvalidArgumentException('Unknown option: ' . $key);
+            }
+            $this->$key = $value;
+        }
+
+    }
+
+    /**
+     * Serializes the notification as a single property.
+     *
+     * You should usually just encode the single top-level element of the
+     * notification.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        $prop = $node->ownerDocument->createElement('cs:invite-reply');
+        $node->appendChild($prop);
+
+    }
+
+    /**
+     * This method serializes the entire notification, as it is used in the
+     * response body.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        $doc = $node->ownerDocument;
+
+        $dt = $doc->createElement('cs:dtstamp');
+        $this->dtStamp->setTimezone(new \DateTimezone('GMT'));
+        $dt->appendChild($doc->createTextNode($this->dtStamp->format('Ymd\\THis\\Z')));
+        $node->appendChild($dt);
+
+        $prop = $doc->createElement('cs:invite-reply');
+        $node->appendChild($prop);
+
+        $uid = $doc->createElement('cs:uid');
+        $uid->appendChild($doc->createTextNode($this->id));
+        $prop->appendChild($uid);
+
+        $inReplyTo = $doc->createElement('cs:in-reply-to');
+        $inReplyTo->appendChild( $doc->createTextNode($this->inReplyTo) );
+        $prop->appendChild($inReplyTo);
+
+        $href = $doc->createElement('d:href');
+        $href->appendChild( $doc->createTextNode($this->href) );
+        $prop->appendChild($href);
+
+        $nodeName = null;
+        switch($this->type) {
+
+            case SharingPlugin::STATUS_ACCEPTED :
+                $nodeName = 'cs:invite-accepted';
+                break;
+            case SharingPlugin::STATUS_DECLINED :
+                $nodeName = 'cs:invite-declined';
+                break;
+
+        }
+        $prop->appendChild(
+            $doc->createElement($nodeName)
+        );
+        $hostHref = $doc->createElement('d:href', $server->getBaseUri() . $this->hostUrl);
+        $hostUrl  = $doc->createElement('cs:hosturl');
+        $hostUrl->appendChild($hostHref);
+        $prop->appendChild($hostUrl);
+
+        if ($this->summary) {
+            $summary = $doc->createElement('cs:summary');
+            $summary->appendChild($doc->createTextNode($this->summary));
+            $prop->appendChild($summary);
+        }
+
+    }
+
+    /**
+     * Returns a unique id for this notification
+     *
+     * This is just the base url. This should generally be some kind of unique
+     * id.
+     *
+     * @return string
+     */
+    public function getId() {
+
+        return $this->id;
+
+    }
+
+    /**
+     * Returns the ETag for this notification.
+     *
+     * The ETag must be surrounded by literal double-quotes.
+     *
+     * @return string
+     */
+    public function getETag() {
+
+        return $this->etag;
+
+    }
+}
diff --git a/3rdparty/Sabre/CalDAV/Notifications/Notification/SystemStatus.php b/3rdparty/Sabre/CalDAV/Notifications/Notification/SystemStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..f09ed3525f5fcdfa51369887218d7e1c10e4325f
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Notifications/Notification/SystemStatus.php
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * SystemStatus notification
+ *
+ * This notification can be used to indicate to the user that the system is
+ * down.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Notifications_Notification_SystemStatus extends Sabre_DAV_Property implements Sabre_CalDAV_Notifications_INotificationType {
+
+    const TYPE_LOW = 1;
+    const TYPE_MEDIUM = 2;
+    const TYPE_HIGH = 3;
+
+    /**
+     * A unique id
+     *
+     * @var string
+     */
+    protected $id;
+
+    /**
+     * The type of alert. This should be one of the TYPE_ constants.
+     *
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * A human-readable description of the problem.
+     *
+     * @var string
+     */
+    protected $description;
+
+    /**
+     * A url to a website with more information for the user.
+     *
+     * @var string
+     */
+    protected $href;
+
+    /**
+     * Notification Etag
+     *
+     * @var string
+     */
+    protected $etag;
+
+    /**
+     * Creates the notification.
+     *
+     * Some kind of unique id should be provided. This is used to generate a
+     * url.
+     *
+     * @param string $id
+     * @param string $etag
+     * @param int $type
+     * @param string $description
+     * @param string $href
+     */
+    public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null) {
+
+        $this->id = $id;
+        $this->type = $type;
+        $this->description = $description;
+        $this->href = $href;
+        $this->etag = $etag;
+
+    }
+
+    /**
+     * Serializes the notification as a single property.
+     *
+     * You should usually just encode the single top-level element of the
+     * notification.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        switch($this->type) {
+            case self::TYPE_LOW :
+                $type = 'low';
+                break;
+            case self::TYPE_MEDIUM :
+                $type = 'medium';
+                break;
+            default :
+            case self::TYPE_HIGH :
+                $type = 'high';
+                break;
+        }
+
+        $prop = $node->ownerDocument->createElement('cs:systemstatus');
+        $prop->setAttribute('type', $type);
+
+        $node->appendChild($prop);
+
+    }
+
+    /**
+     * This method serializes the entire notification, as it is used in the
+     * response body.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serializeBody(Sabre_DAV_Server $server, \DOMElement $node) {
+
+        switch($this->type) {
+            case self::TYPE_LOW :
+                $type = 'low';
+                break;
+            case self::TYPE_MEDIUM :
+                $type = 'medium';
+                break;
+            default :
+            case self::TYPE_HIGH :
+                $type = 'high';
+                break;
+        }
+
+        $prop = $node->ownerDocument->createElement('cs:systemstatus');
+        $prop->setAttribute('type', $type);
+
+        if ($this->description) {
+            $text = $node->ownerDocument->createTextNode($this->description);
+            $desc = $node->ownerDocument->createElement('cs:description');
+            $desc->appendChild($text);
+            $prop->appendChild($desc);
+        }
+        if ($this->href) {
+            $text = $node->ownerDocument->createTextNode($this->href);
+            $href = $node->ownerDocument->createElement('d:href');
+            $href->appendChild($text);
+            $prop->appendChild($href);
+        }
+
+        $node->appendChild($prop);
+
+    }
+
+    /**
+     * Returns a unique id for this notification
+     *
+     * This is just the base url. This should generally be some kind of unique
+     * id.
+     *
+     * @return string
+     */
+    public function getId() {
+
+        return $this->id;
+
+    }
+
+    /*
+     * Returns the ETag for this notification.
+     *
+     * The ETag must be surrounded by literal double-quotes.
+     *
+     * @return string
+     */
+    public function getETag() {
+
+        return $this->etag;
+
+    }
+}
diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php
old mode 100755
new mode 100644
index c56ab38484484fe58837f4b34509d0197cf39203..f3d11969c8b60f83ac9bae4452266241f2daa9cf
--- a/3rdparty/Sabre/CalDAV/Plugin.php
+++ b/3rdparty/Sabre/CalDAV/Plugin.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * CalDAV plugin
  *
@@ -24,16 +26,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      */
     const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
 
-    /**
-     * The following constants are used to differentiate
-     * the various filters for the calendar-query report
-     */
-    const FILTER_COMPFILTER   = 1;
-    const FILTER_TIMERANGE    = 3;
-    const FILTER_PROPFILTER   = 4;
-    const FILTER_PARAMFILTER  = 5;
-    const FILTER_TEXTMATCH    = 6;
-
     /**
      * The hardcoded root for calendar objects. It is unfortunate
      * that we're stuck with it, but it will have to do for now
@@ -172,16 +164,19 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
         $server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
         $server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
+        $server->subscribeEvent('beforeMethod', array($this,'beforeMethod'));
 
         $server->xmlNamespaces[self::NS_CALDAV] = 'cal';
         $server->xmlNamespaces[self::NS_CALENDARSERVER] = 'cs';
 
         $server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet';
+        $server->propertyMap['{' . self::NS_CALDAV . '}schedule-calendar-transp'] = 'Sabre_CalDAV_Property_ScheduleCalendarTransp';
 
         $server->resourceTypeMapping['Sabre_CalDAV_ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar';
         $server->resourceTypeMapping['Sabre_CalDAV_Schedule_IOutbox'] = '{urn:ietf:params:xml:ns:caldav}schedule-outbox';
         $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read';
         $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write';
+        $server->resourceTypeMapping['Sabre_CalDAV_Notifications_ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification';
 
         array_push($server->protectedProperties,
 
@@ -205,7 +200,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             // CalendarServer extensions
             '{' . self::NS_CALENDARSERVER . '}getctag',
             '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for',
-            '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for'
+            '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for',
+            '{' . self::NS_CALENDARSERVER . '}notification-URL',
+            '{' . self::NS_CALENDARSERVER . '}notificationtype'
 
         );
     }
@@ -226,6 +223,13 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 // unknownMethod event.
                 return false;
             case 'POST' :
+
+                // Checking if this is a text/calendar content type
+                $contentType = $this->server->httpRequest->getHeader('Content-Type');
+                if (strpos($contentType, 'text/calendar')!==0) {
+                    return;
+                }
+
                 // Checking if we're talking to an outbox
                 try {
                     $node = $this->server->tree->getNodeForPath($uri);
@@ -235,7 +239,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 if (!$node instanceof Sabre_CalDAV_Schedule_IOutbox)
                     return;
 
-                $this->outboxRequest($node);
+                $this->outboxRequest($node, $uri);
                 return false;
 
         }
@@ -348,7 +352,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             if (in_array($calProp,$requestedProperties)) {
 
                 $addresses = $node->getAlternateUriSet();
-                $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl();
+                $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl() . '/';
                 unset($requestedProperties[$calProp]);
                 $returnedProperties[200][$calProp] = new Sabre_DAV_Property_HrefList($addresses, false);
 
@@ -390,8 +394,31 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
             }
 
+            // notification-URL property
+            $notificationUrl = '{' . self::NS_CALENDARSERVER . '}notification-URL';
+            if (($index = array_search($notificationUrl, $requestedProperties)) !== false) {
+                $principalId = $node->getName();
+                $calendarHomePath = 'calendars/' . $principalId . '/notifications/';
+                unset($requestedProperties[$index]);
+                $returnedProperties[200][$notificationUrl] = new Sabre_DAV_Property_Href($calendarHomePath);
+            }
+
         } // instanceof IPrincipal
 
+        if ($node instanceof Sabre_CalDAV_Notifications_INode) {
+
+            $propertyName = '{' . self::NS_CALENDARSERVER . '}notificationtype';
+            if (($index = array_search($propertyName, $requestedProperties)) !== false) {
+
+                $returnedProperties[200][$propertyName] =
+                    $node->getNotificationType();
+
+                unset($requestedProperties[$index]);
+
+            }
+
+        } // instanceof Notifications_INode
+
 
         if ($node instanceof Sabre_CalDAV_ICalendarObject) {
             // The calendar-data property is not supposed to be a 'real'
@@ -424,11 +451,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
     public function calendarMultiGetReport($dom) {
 
         $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
-        $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
+        $hrefElems = $dom->getElementsByTagNameNS('DAV:','href');
 
         $xpath = new DOMXPath($dom);
         $xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
-        $xpath->registerNameSpace('dav','urn:DAV');
+        $xpath->registerNameSpace('dav','DAV:');
 
         $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
         if ($expand->length>0) {
@@ -438,8 +465,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             if(!$start || !$end) {
                 throw new Sabre_DAV_Exception_BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element');
             }
-            $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
-            $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+            $start = VObject\DateTimeParser::parseDateTime($start);
+            $end = VObject\DateTimeParser::parseDateTime($end);
 
             if ($end <= $start) {
                 throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
@@ -458,7 +485,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             list($objProps) = $this->server->getPropertiesForPath($uri,$properties);
 
             if ($expand && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
-                $vObject = Sabre_VObject_Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
+                $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
                 $vObject->expand($start, $end);
                 $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
             }
@@ -467,9 +494,12 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
+        $prefer = $this->server->getHTTPPRefer();
+
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
-        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList));
+        $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
+        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal']));
 
     }
 
@@ -487,54 +517,95 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         $parser = new Sabre_CalDAV_CalendarQueryParser($dom);
         $parser->parse();
 
-        $requestedCalendarData = true;
-        $requestedProperties = $parser->requestedProperties;
+        $node = $this->server->tree->getNodeForPath($this->server->getRequestUri());
+        $depth = $this->server->getHTTPDepth(0);
 
-        if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
+        // The default result is an empty array
+        $result = array();
 
-            // We always retrieve calendar-data, as we need it for filtering.
-            $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
+        // The calendarobject was requested directly. In this case we handle
+        // this locally.
+        if ($depth == 0 && $node instanceof Sabre_CalDAV_ICalendarObject) {
 
-            // If calendar-data wasn't explicitly requested, we need to remove
-            // it after processing.
-            $requestedCalendarData = false;
-        }
+            $requestedCalendarData = true;
+            $requestedProperties = $parser->requestedProperties;
 
-        // These are the list of nodes that potentially match the requirement
-        $candidateNodes = $this->server->getPropertiesForPath(
-            $this->server->getRequestUri(),
-            $requestedProperties,
-            $this->server->getHTTPDepth(0)
-        );
+            if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
 
-        $verifiedNodes = array();
+                // We always retrieve calendar-data, as we need it for filtering.
+                $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
 
-        $validator = new Sabre_CalDAV_CalendarQueryValidator();
+                // If calendar-data wasn't explicitly requested, we need to remove
+                // it after processing.
+                $requestedCalendarData = false;
+            }
 
-        foreach($candidateNodes as $node) {
+            $properties = $this->server->getPropertiesForPath(
+                $this->server->getRequestUri(),
+                $requestedProperties,
+                0
+            );
 
-            // If the node didn't have a calendar-data property, it must not be a calendar object
-            if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']))
-                continue;
+            // This array should have only 1 element, the first calendar
+            // object.
+            $properties = current($properties);
 
-            $vObject = Sabre_VObject_Reader::read($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
-            if ($validator->validate($vObject,$parser->filters)) {
+            // If there wasn't any calendar-data returned somehow, we ignore
+            // this.
+            if (isset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) {
+
+                $validator = new Sabre_CalDAV_CalendarQueryValidator();
+                $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
+                if ($validator->validate($vObject,$parser->filters)) {
+
+                    // If the client didn't require the calendar-data property,
+                    // we won't give it back.
+                    if (!$requestedCalendarData) {
+                        unset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
+                    } else {
+                        if ($parser->expand) {
+                            $vObject->expand($parser->expand['start'], $parser->expand['end']);
+                            $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+                        }
+                    }
+
+                    $result = array($properties);
 
-                if (!$requestedCalendarData) {
-                    unset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
                 }
+
+            }
+
+        }
+        // If we're dealing with a calendar, the calendar itself is responsible
+        // for the calendar-query.
+        if ($node instanceof Sabre_CalDAV_ICalendar && $depth = 1) {
+
+            $nodePaths = $node->calendarQuery($parser->filters);
+
+            foreach($nodePaths as $path) {
+
+                list($properties) =
+                    $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $parser->requestedProperties);
+
                 if ($parser->expand) {
+                    // We need to do some post-processing
+                    $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
                     $vObject->expand($parser->expand['start'], $parser->expand['end']);
-                    $node[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+                    $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
                 }
-                $verifiedNodes[] = $node;
+
+                $result[] = $properties;
+
             }
 
         }
 
+        $prefer = $this->server->getHTTPPRefer();
+
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
-        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($verifiedNodes));
+        $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
+        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 
     }
 
@@ -561,10 +632,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
         if ($start) {
-            $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+            $start = VObject\DateTimeParser::parseDateTime($start);
         }
         if ($end) {
-            $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+            $end = VObject\DateTimeParser::parseDateTime($end);
         }
 
         if (!$start && !$end) {
@@ -583,15 +654,33 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             throw new Sabre_DAV_Exception_NotImplemented('The free-busy-query REPORT is only implemented on calendars');
         }
 
-        $objects = array_map(function($child) {
-            $obj = $child->get();
-            if (is_resource($obj)) {
-                $obj = stream_get_contents($obj);
-            }
+        // Doing a calendar-query first, to make sure we get the most
+        // performance.
+        $urls = $calendar->calendarQuery(array(
+            'name' => 'VCALENDAR',
+            'comp-filters' => array(
+                array(
+                    'name' => 'VEVENT',
+                    'comp-filters' => array(),
+                    'prop-filters' => array(),
+                    'is-not-defined' => false,
+                    'time-range' => array(
+                        'start' => $start,
+                        'end' => $end,
+                    ),
+                ),
+            ),
+            'prop-filters' => array(),
+            'is-not-defined' => false,
+            'time-range' => null,
+        ));
+
+        $objects = array_map(function($url) use ($calendar) {
+            $obj = $calendar->getChild($url)->get();
             return $obj;
-        }, $calendar->getChildren());
+        }, $urls);
 
-        $generator = new Sabre_VObject_FreeBusyGenerator();
+        $generator = new VObject\FreeBusyGenerator();
         $generator->setObjects($objects);
         $generator->setTimeRange($start, $end);
         $result = $generator->getResult();
@@ -620,7 +709,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         if (!$node instanceof Sabre_CalDAV_ICalendarObject)
             return;
 
-        $this->validateICalendar($data);
+        $this->validateICalendar($data, $path);
 
     }
 
@@ -640,7 +729,52 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         if (!$parentNode instanceof Sabre_CalDAV_Calendar)
             return;
 
-        $this->validateICalendar($data);
+        $this->validateICalendar($data, $path);
+
+    }
+
+    /**
+     * This event is triggered before any HTTP request is handled.
+     *
+     * We use this to intercept GET calls to notification nodes, and return the
+     * proper response.
+     *
+     * @param string $method
+     * @param string $path
+     * @return void
+     */
+    public function beforeMethod($method, $path) {
+
+        if ($method!=='GET') return;
+
+        try {
+            $node = $this->server->tree->getNodeForPath($path);
+        } catch (Sabre_DAV_Exception_NotFound $e) {
+            return;
+        }
+
+        if (!$node instanceof Sabre_CalDAV_Notifications_INode)
+            return;
+
+        if (!$this->server->checkPreconditions(true)) return false;
+
+        $dom = new DOMDocument('1.0', 'UTF-8');
+        $dom->formatOutput = true;
+
+        $root = $dom->createElement('cs:notification');
+        foreach($this->server->xmlNamespaces as $namespace => $prefix) {
+            $root->setAttribute('xmlns:' . $prefix, $namespace);
+        }
+
+        $dom->appendChild($root);
+        $node->getNotificationType()->serializeBody($this->server, $root);
+
+        $this->server->httpResponse->setHeader('Content-Type','application/xml');
+        $this->server->httpResponse->setHeader('ETag',$node->getETag());
+        $this->server->httpResponse->sendStatus(200);
+        $this->server->httpResponse->sendBody($dom->saveXML());
+
+        return false;
 
     }
 
@@ -650,9 +784,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * An exception is thrown if it's not.
      *
      * @param resource|string $data
+     * @param string $path
      * @return void
      */
-    protected function validateICalendar(&$data) {
+    protected function validateICalendar(&$data, $path) {
 
         // If it's a stream, we convert it to a string first.
         if (is_resource($data)) {
@@ -664,9 +799,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         try {
 
-            $vobj = Sabre_VObject_Reader::read($data);
+            $vobj = VObject\Reader::read($data);
 
-        } catch (Sabre_VObject_ParseException $e) {
+        } catch (VObject\ParseException $e) {
 
             throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
 
@@ -676,6 +811,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support iCalendar objects.');
         }
 
+        // Get the Supported Components for the target calendar
+        list($parentPath,$object) = Sabre_Dav_URLUtil::splitPath($path);
+        $calendarProperties = $this->server->getProperties($parentPath,array('{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'));
+        $supportedComponents = $calendarProperties['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue();
+
         $foundType = null;
         $foundUID = null;
         foreach($vobj->getComponents() as $component) {
@@ -687,6 +827,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 case 'VJOURNAL' :
                     if (is_null($foundType)) {
                         $foundType = $component->name;
+                        if (!in_array($foundType, $supportedComponents)) {
+                            throw new Sabre_CalDAV_Exception_InvalidComponentType('This calendar only supports ' . implode(', ', $supportedComponents) . '. We found a ' . $foundType);
+                        }
                         if (!isset($component->UID)) {
                             throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' component must have an UID');
                         }
@@ -711,12 +854,81 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This method handles POST requests to the schedule-outbox
+     * This method handles POST requests to the schedule-outbox.
+     *
+     * Currently, two types of requests are support:
+     *   * FREEBUSY requests from RFC 6638
+     *   * Simple iTIP messages from draft-desruisseaux-caldav-sched-04
+     *
+     * The latter is from an expired early draft of the CalDAV scheduling
+     * extensions, but iCal depends on a feature from that spec, so we
+     * implement it.
      *
      * @param Sabre_CalDAV_Schedule_IOutbox $outboxNode
+     * @param string $outboxUri
+     * @return void
+     */
+    public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode, $outboxUri) {
+
+        // Parsing the request body
+        try {
+            $vObject = VObject\Reader::read($this->server->httpRequest->getBody(true));
+        } catch (VObject\ParseException $e) {
+            throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
+        }
+
+        // The incoming iCalendar object must have a METHOD property, and a
+        // component. The combination of both determines what type of request
+        // this is.
+        $componentType = null;
+        foreach($vObject->getComponents() as $component) {
+            if ($component->name !== 'VTIMEZONE') {
+                $componentType = $component->name;
+                break;
+            }
+        }
+        if (is_null($componentType)) {
+            throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
+        }
+
+        // Validating the METHOD
+        $method = strtoupper((string)$vObject->METHOD);
+        if (!$method) {
+            throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
+        }
+
+        // So we support two types of requests:
+        //
+        // REQUEST with a VFREEBUSY component
+        // REQUEST, REPLY, ADD, CANCEL on VEVENT components
+
+        $acl = $this->server->getPlugin('acl');
+
+        if ($componentType === 'VFREEBUSY' && $method === 'REQUEST') {
+
+            $acl && $acl->checkPrivileges($outboxUri,'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy');
+            $this->handleFreeBusyRequest($outboxNode, $vObject);
+
+        } elseif ($componentType === 'VEVENT' && in_array($method, array('REQUEST','REPLY','ADD','CANCEL'))) {
+
+            $acl && $acl->checkPrivileges($outboxUri,'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-post-vevent');
+            $this->handleEventNotification($outboxNode, $vObject);
+
+        } else {
+
+            throw new Sabre_DAV_Exception_NotImplemented('SabreDAV supports only VFREEBUSY (REQUEST) and VEVENT (REQUEST, REPLY, ADD, CANCEL)');
+
+        }
+
+    }
+
+    /**
+     * This method handles the REQUEST, REPLY, ADD and CANCEL methods for
+     * VEVENT iTip messages.
+     *
      * @return void
      */
-    public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode) {
+    protected function handleEventNotification(Sabre_CalDAV_Schedule_IOutbox $outboxNode, VObject\Component $vObject) {
 
         $originator = $this->server->httpRequest->getHeader('Originator');
         $recipients = $this->server->httpRequest->getHeader('Recipient');
@@ -760,38 +972,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header');
         }
 
-        try {
-            $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
-        } catch (Sabre_VObject_ParseException $e) {
-            throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
-        }
-
-        // Checking for the object type
-        $componentType = null;
-        foreach($vObject->getComponents() as $component) {
-            if ($component->name !== 'VTIMEZONE') {
-                $componentType = $component->name;
-                break;
-            }
-        }
-        if (is_null($componentType)) {
-            throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
-        }
-
-        // Validating the METHOD
-        $method = strtoupper((string)$vObject->METHOD);
-        if (!$method) {
-            throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
-        }
-
-        if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') {
-            $result = $this->iMIPMessage($originator, $recipients, $vObject);
-            $this->server->httpResponse->sendStatus(200);
-            $this->server->httpResponse->setHeader('Content-Type','application/xml');
-            $this->server->httpResponse->sendBody($this->generateScheduleResponse($result));
-        } else {
-            throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
-        }
+        $result = $this->iMIPMessage($originator, $recipients, $vObject, $principal);
+        $this->server->httpResponse->sendStatus(200);
+        $this->server->httpResponse->setHeader('Content-Type','application/xml');
+        $this->server->httpResponse->sendBody($this->generateScheduleResponse($result));
 
     }
 
@@ -813,15 +997,15 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * @param string $originator
      * @param array $recipients
-     * @param Sabre_VObject_Component $vObject
+     * @param Sabre\VObject\Component $vObject
      * @return array
      */
-    protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+    protected function iMIPMessage($originator, array $recipients, VObject\Component $vObject, $principal) {
 
         if (!$this->imipHandler) {
             $resultStatus = '5.2;This server does not support this operation';
         } else {
-            $this->imipHandler->sendMessage($originator, $recipients, $vObject);
+            $this->imipHandler->sendMessage($originator, $recipients, $vObject, $principal);
             $resultStatus = '2.0;Success';
         }
 
@@ -832,7 +1016,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         return $result;
 
-
     }
 
     /**
@@ -877,6 +1060,204 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     }
 
+    /**
+     * This method is responsible for parsing a free-busy query request and
+     * returning it's result.
+     *
+     * @param Sabre_CalDAV_Schedule_IOutbox $outbox
+     * @param string $request
+     * @return string
+     */
+    protected function handleFreeBusyRequest(Sabre_CalDAV_Schedule_IOutbox $outbox, VObject\Component $vObject) {
+
+        $vFreeBusy = $vObject->VFREEBUSY;
+        $organizer = $vFreeBusy->organizer;
+
+        $organizer = (string)$organizer;
+
+        // Validating if the organizer matches the owner of the inbox.
+        $owner = $outbox->getOwner();
+
+        $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
+
+        $uas = $caldavNS . 'calendar-user-address-set';
+        $props = $this->server->getProperties($owner,array($uas));
+
+        if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) {
+            throw new Sabre_DAV_Exception_Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox');
+        }
+
+        if (!isset($vFreeBusy->ATTENDEE)) {
+            throw new Sabre_DAV_Exception_BadRequest('You must at least specify 1 attendee');
+        }
+
+        $attendees = array();
+        foreach($vFreeBusy->ATTENDEE as $attendee) {
+            $attendees[]= (string)$attendee;
+        }
+
+
+        if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) {
+            throw new Sabre_DAV_Exception_BadRequest('DTSTART and DTEND must both be specified');
+        }
+
+        $startRange = $vFreeBusy->DTSTART->getDateTime();
+        $endRange = $vFreeBusy->DTEND->getDateTime();
+
+        $results = array();
+        foreach($attendees as $attendee) {
+            $results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject);
+        }
+
+        $dom = new DOMDocument('1.0','utf-8');
+        $dom->formatOutput = true;
+        $scheduleResponse = $dom->createElement('cal:schedule-response');
+        foreach($this->server->xmlNamespaces as $namespace=>$prefix) {
+
+            $scheduleResponse->setAttribute('xmlns:' . $prefix,$namespace);
+
+        }
+        $dom->appendChild($scheduleResponse);
+
+        foreach($results as $result) {
+            $response = $dom->createElement('cal:response');
+
+            $recipient = $dom->createElement('cal:recipient');
+            $recipientHref = $dom->createElement('d:href');
+
+            $recipientHref->appendChild($dom->createTextNode($result['href']));
+            $recipient->appendChild($recipientHref);
+            $response->appendChild($recipient);
+
+            $reqStatus = $dom->createElement('cal:request-status');
+            $reqStatus->appendChild($dom->createTextNode($result['request-status']));
+            $response->appendChild($reqStatus);
+
+            if (isset($result['calendar-data'])) {
+
+                $calendardata = $dom->createElement('cal:calendar-data');
+                $calendardata->appendChild($dom->createTextNode(str_replace("\r\n","\n",$result['calendar-data']->serialize())));
+                $response->appendChild($calendardata);
+
+            }
+            $scheduleResponse->appendChild($response);
+        }
+
+        $this->server->httpResponse->sendStatus(200);
+        $this->server->httpResponse->setHeader('Content-Type','application/xml');
+        $this->server->httpResponse->sendBody($dom->saveXML());
+
+    }
+
+    /**
+     * Returns free-busy information for a specific address. The returned
+     * data is an array containing the following properties:
+     *
+     * calendar-data : A VFREEBUSY VObject
+     * request-status : an iTip status code.
+     * href: The principal's email address, as requested
+     *
+     * The following request status codes may be returned:
+     *   * 2.0;description
+     *   * 3.7;description
+     *
+     * @param string $email address
+     * @param DateTime $start
+     * @param DateTime $end
+     * @param Sabre_VObject_Component $request
+     * @return Sabre_VObject_Component
+     */
+    protected function getFreeBusyForEmail($email, DateTime $start, DateTime $end, VObject\Component $request) {
+
+        $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
+
+        $aclPlugin = $this->server->getPlugin('acl');
+        if (substr($email,0,7)==='mailto:') $email = substr($email,7);
+
+        $result = $aclPlugin->principalSearch(
+            array('{http://sabredav.org/ns}email-address' => $email),
+            array(
+                '{DAV:}principal-URL', $caldavNS . 'calendar-home-set',
+                '{http://sabredav.org/ns}email-address',
+            )
+        );
+
+        if (!count($result)) {
+            return array(
+                'request-status' => '3.7;Could not find principal',
+                'href' => 'mailto:' . $email,
+            );
+        }
+
+        if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) {
+            return array(
+                'request-status' => '3.7;No calendar-home-set property found',
+                'href' => 'mailto:' . $email,
+            );
+        }
+        $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
+
+        // Grabbing the calendar list
+        $objects = array();
+        foreach($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) {
+            if (!$node instanceof Sabre_CalDAV_ICalendar) {
+                continue;
+            }
+            $aclPlugin->checkPrivileges($homeSet . $node->getName() ,$caldavNS . 'read-free-busy');
+
+            // Getting the list of object uris within the time-range
+            $urls = $node->calendarQuery(array(
+                'name' => 'VCALENDAR',
+                'comp-filters' => array(
+                    array(
+                        'name' => 'VEVENT',
+                        'comp-filters' => array(),
+                        'prop-filters' => array(),
+                        'is-not-defined' => false,
+                        'time-range' => array(
+                            'start' => $start,
+                            'end' => $end,
+                        ),
+                    ),
+                ),
+                'prop-filters' => array(),
+                'is-not-defined' => false,
+                'time-range' => null,
+            ));
+
+            $calObjects = array_map(function($url) use ($node) {
+                $obj = $node->getChild($url)->get();
+                return $obj;
+            }, $urls);
+
+            $objects = array_merge($objects,$calObjects);
+
+        }
+
+        $vcalendar = VObject\Component::create('VCALENDAR');
+        $vcalendar->VERSION = '2.0';
+        $vcalendar->METHOD = 'REPLY';
+        $vcalendar->CALSCALE = 'GREGORIAN';
+        $vcalendar->PRODID = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
+
+        $generator = new VObject\FreeBusyGenerator();
+        $generator->setObjects($objects);
+        $generator->setTimeRange($start, $end);
+        $generator->setBaseObject($vcalendar);
+
+        $result = $generator->getResult();
+
+        $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email;
+        $vcalendar->VFREEBUSY->UID = (string)$request->VFREEBUSY->UID;
+        $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER;
+
+        return array(
+            'calendar-data' => $result,
+            'request-status' => '2.0;Success',
+            'href' => 'mailto:' . $email,
+        );
+    }
+
     /**
      * This method is used to generate HTML output for the
      * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
diff --git a/3rdparty/Sabre/CalDAV/Principal/Collection.php b/3rdparty/Sabre/CalDAV/Principal/Collection.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Principal/User.php b/3rdparty/Sabre/CalDAV/Principal/User.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Property/AllowedSharingModes.php b/3rdparty/Sabre/CalDAV/Property/AllowedSharingModes.php
new file mode 100644
index 0000000000000000000000000000000000000000..efe751732c55dc839b29c21837cdc23faa1019c5
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Property/AllowedSharingModes.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * AllowedSharingModes
+ *
+ * This property encodes the 'allowed-sharing-modes' property, as defined by
+ * the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/
+ * namespace.
+ *
+ * This property is a representation of the supported-calendar_component-set
+ * property in the CalDAV namespace. It simply requires an array of components,
+ * such as VEVENT, VTODO
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Property_AllowedSharingModes extends Sabre_DAV_Property {
+
+    /**
+     * Whether or not a calendar can be shared with another user
+     *
+     * @var bool
+     */
+    protected $canBeShared;
+
+    /**
+     * Whether or not the calendar can be placed on a public url.
+     *
+     * @var bool
+     */
+    protected $canBePublished;
+
+    /**
+     * Constructor
+     *
+     * @param bool $canBeShared
+     * @param bool $canBePublished
+     * @return void
+     */
+    public function __construct($canBeShared, $canBePublished) {
+
+        $this->canBeShared = $canBeShared;
+        $this->canBePublished = $canBePublished;
+
+    }
+
+    /**
+     * Serializes the property in a DOMDocument
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
+
+       $doc = $node->ownerDocument;
+       if ($this->canBeShared) {
+            $xcomp = $doc->createElement('cs:can-be-shared');
+            $node->appendChild($xcomp);
+       }
+       if ($this->canBePublished) {
+            $xcomp = $doc->createElement('cs:can-be-published');
+            $node->appendChild($xcomp);
+       }
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Property/Invite.php b/3rdparty/Sabre/CalDAV/Property/Invite.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ed94877df2c9a37588d0695392b1b85ad5c5d99
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Property/Invite.php
@@ -0,0 +1,173 @@
+<?php
+
+use Sabre_CalDAV_SharingPlugin as SharingPlugin;
+
+/**
+ * Invite property
+ *
+ * This property encodes the 'invite' property, as defined by
+ * the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/
+ * namespace.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Property_Invite extends Sabre_DAV_Property {
+
+    /**
+     * The list of users a calendar has been shared to.
+     *
+     * @var array
+     */
+    protected $users;
+
+    /**
+     * Creates the property.
+     *
+     * Users is an array. Each element of the array has the following
+     * properties:
+     *
+     *   * href - Often a mailto: address
+     *   * commonName - Optional, for example a first and lastname for a user.
+     *   * status - One of the SharingPlugin::STATUS_* constants.
+     *   * readOnly - true or false
+     *   * summary - Optional, description of the share
+     *
+     * @param array $users
+     */
+    public function __construct(array $users) {
+
+        $this->users = $users;
+
+    }
+
+    /**
+     * Returns the list of users, as it was passed to the constructor.
+     *
+     * @return array
+     */
+    public function getValue() {
+
+        return $this->users;
+
+    }
+
+    /**
+     * Serializes the property in a DOMDocument
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
+
+       $doc = $node->ownerDocument;
+       foreach($this->users as $user) {
+
+           $xuser = $doc->createElement('cs:user');
+
+           $href = $doc->createElement('d:href');
+           $href->appendChild($doc->createTextNode($user['href']));
+           $xuser->appendChild($href);
+
+           if (isset($user['commonName']) && $user['commonName']) {
+               $commonName = $doc->createElement('cs:common-name');
+               $commonName->appendChild($doc->createTextNode($user['commonName']));
+               $xuser->appendChild($commonName);
+           }
+
+           switch($user['status']) {
+
+               case SharingPlugin::STATUS_ACCEPTED :
+                   $status = $doc->createElement('cs:invite-accepted');
+                   $xuser->appendChild($status);
+                   break;
+               case SharingPlugin::STATUS_DECLINED :
+                   $status = $doc->createElement('cs:invite-declined');
+                   $xuser->appendChild($status);
+                   break;
+               case SharingPlugin::STATUS_NORESPONSE :
+                   $status = $doc->createElement('cs:invite-noresponse');
+                   $xuser->appendChild($status);
+                   break;
+               case SharingPlugin::STATUS_INVALID :
+                   $status = $doc->createElement('cs:invite-invalid');
+                   $xuser->appendChild($status);
+                   break;
+
+           }
+
+           $xaccess = $doc->createElement('cs:access');
+
+           if ($user['readOnly']) {
+                $xaccess->appendChild(
+                    $doc->createElement('cs:read')
+                );
+           } else {
+                $xaccess->appendChild(
+                    $doc->createElement('cs:read-write')
+                );
+           }
+           $xuser->appendChild($xaccess);
+
+           if (isset($user['summary']) && $user['summary']) {
+               $summary = $doc->createElement('cs:summary');
+               $summary->appendChild($doc->createTextNode($user['summary']));
+               $xuser->appendChild($summary);
+           }
+
+           $node->appendChild($xuser);
+
+       }
+
+    }
+
+    /**
+     * Unserializes the property.
+     *
+     * This static method should return a an instance of this object.
+     *
+     * @param DOMElement $prop
+     * @return Sabre_DAV_IProperty
+     */
+    static function unserialize(DOMElement $prop) {
+
+        $xpath = new \DOMXPath($prop->ownerDocument);
+        $xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER);
+        $xpath->registerNamespace('d',  'DAV:');
+
+        $users = array();
+
+        foreach($xpath->query('cs:user', $prop) as $user) {
+
+            $status = null;
+            if ($xpath->evaluate('boolean(cs:invite-accepted)', $user)) {
+                $status = SharingPlugin::STATUS_ACCEPTED;
+            } elseif ($xpath->evaluate('boolean(cs:invite-declined)', $user)) {
+                $status = SharingPlugin::STATUS_DECLINED;
+            } elseif ($xpath->evaluate('boolean(cs:invite-noresponse)', $user)) {
+                $status = SharingPlugin::STATUS_NORESPONSE;
+            } elseif ($xpath->evaluate('boolean(cs:invite-invalid)', $user)) {
+                $status = SharingPlugin::STATUS_INVALID;
+            } else {
+                throw new Sabre_DAV_Exception('Every cs:user property must have one of cs:invite-accepted, cs:invite-declined, cs:invite-noresponse or cs:invite-invalid');
+            }
+            $users[] = array(
+                'href' => $xpath->evaluate('string(d:href)', $user),
+                'commonName' => $xpath->evaluate('string(cs:common-name)', $user),
+                'readOnly' => $xpath->evaluate('boolean(cs:access/cs:read)', $user),
+                'summary' => $xpath->evaluate('string(cs:summary)', $user),
+                'status' => $status,
+            );
+
+        }
+
+        return new self($users);
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Property/ScheduleCalendarTransp.php b/3rdparty/Sabre/CalDAV/Property/ScheduleCalendarTransp.php
new file mode 100644
index 0000000000000000000000000000000000000000..76c1dbaec21e76b4fe87cce203c2ab84c12b7721
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Property/ScheduleCalendarTransp.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * schedule-calendar-transp property.
+ *
+ * This property is a representation of the schedule-calendar-transp property.
+ * This property is defined in RFC6638 (caldav scheduling).
+ *
+ * Its values are either 'transparent' or 'opaque'. If it's transparent, it
+ * means that this calendar will not be taken into consideration when a
+ * different user queries for free-busy information. If it's 'opaque', it will.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Property_ScheduleCalendarTransp extends Sabre_DAV_Property {
+
+    const TRANSPARENT = 'transparent';
+    const OPAQUE = 'opaque';
+
+    protected $value;
+
+    /**
+     * Creates the property
+     *
+     * @param string $value
+     */
+    public function __construct($value) {
+
+        if ($value !== self::TRANSPARENT && $value !== self::OPAQUE) {
+            throw new \InvalidArgumentException('The value must either be specified as "transparent" or "opaque"');
+        }
+        $this->value = $value;
+
+    }
+
+    /**
+     * Returns the current value
+     *
+     * @return string
+     */
+    public function getValue() {
+
+        return $this->value;
+
+    }
+
+    /**
+     * Serializes the property in a DOMDocument
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
+
+        $doc = $node->ownerDocument;
+        switch($this->value) {
+            case self::TRANSPARENT :
+                $xval = $doc->createElement('cal:transparent');
+                break;
+            case self::OPAQUE :
+                $xval = $doc->createElement('cal:opaque');
+                break;
+        }
+
+        $node->appendChild($xval);
+
+    }
+
+    /**
+     * Unserializes the DOMElement back into a Property class.
+     *
+     * @param DOMElement $node
+     * @return Sabre_CalDAV_Property_ScheduleCalendarTransp
+     */
+    static function unserialize(DOMElement $node) {
+
+        $value = null;
+        foreach($node->childNodes as $childNode) {
+            switch(Sabre_DAV_XMLUtil::toClarkNotation($childNode)) {
+                case '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}opaque' :
+                    $value = self::OPAQUE;
+                    break;
+                case '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}transparent' :
+                    $value = self::TRANSPARENT;
+                    break;
+            }
+        }
+        if (is_null($value))
+           return null;
+
+        return new self($value);
+
+    }
+}
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IMip.php b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
old mode 100755
new mode 100644
index 37e75fcc4a71c2626922319fef90a971ce6a4460..92c3c097c15676704efc22698731d5a3dcddda2e
--- a/3rdparty/Sabre/CalDAV/Schedule/IMip.php
+++ b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * iMIP handler.
  *
@@ -42,12 +44,13 @@ class Sabre_CalDAV_Schedule_IMip {
     /**
      * Sends one or more iTip messages through email.
      *
-     * @param string $originator
-     * @param array $recipients
-     * @param Sabre_VObject_Component $vObject
+     * @param string $originator Originator Email
+     * @param array $recipients Array of email addresses
+     * @param Sabre\VObject\Component $vObject
+     * @param string $principal Principal Url of the originator
      * @return void
      */
-    public function sendMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+    public function sendMessage($originator, array $recipients, VObject\Component $vObject, $principal) {
 
         foreach($recipients as $recipient) {
 
@@ -83,6 +86,9 @@ class Sabre_CalDAV_Schedule_IMip {
 
     }
 
+    // @codeCoverageIgnoreStart
+    // This is deemed untestable in a reasonable manner
+
     /**
      * This function is reponsible for sending the actual email.
      *
@@ -94,11 +100,11 @@ class Sabre_CalDAV_Schedule_IMip {
      */
     protected function mail($to, $subject, $body, array $headers) {
 
+
         mail($to, $subject, $body, implode("\r\n", $headers));
 
     }
 
+    // @codeCoverageIgnoreEnd
 
 }
-
-?>
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
old mode 100755
new mode 100644
index 014c37230d194a8bc2fb9efa5b4bb7b913b2a127..462aa527e23bd359635ad813395eb6248aa68d1c
--- a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
+++ b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
@@ -13,7 +13,7 @@
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_CalDAV_Schedule_Outbox extends Sabre_DAV_Directory implements Sabre_CalDAV_Schedule_IOutbox {
+class Sabre_CalDAV_Schedule_Outbox extends Sabre_DAV_Collection implements Sabre_CalDAV_Schedule_IOutbox {
 
     /**
      * The principal Uri
@@ -103,6 +103,11 @@ class Sabre_CalDAV_Schedule_Outbox extends Sabre_DAV_Directory implements Sabre_
                 'principal' => $this->getOwner(),
                 'protected' => true,
             ),
+            array(
+                'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-post-vevent',
+                'principal' => $this->getOwner(),
+                'protected' => true,
+            ),
             array(
                 'privilege' => '{DAV:}read',
                 'principal' => $this->getOwner(),
@@ -144,6 +149,9 @@ class Sabre_CalDAV_Schedule_Outbox extends Sabre_DAV_Directory implements Sabre_
         $default['aggregates'][] = array(
             'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
         );
+        $default['aggregates'][] = array(
+            'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-post-vevent',
+        );
 
         return $default;
 
diff --git a/3rdparty/Sabre/CalDAV/Server.php b/3rdparty/Sabre/CalDAV/Server.php
deleted file mode 100755
index 325e3d80a7fd081065ab216dd528c0b3927c966e..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/CalDAV/Server.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * CalDAV server
- *
- * Deprecated! Warning: This class is now officially deprecated
- *
- * This script is a convenience script. It quickly sets up a WebDAV server
- * with caldav and ACL support, and it creates the root 'principals' and
- * 'calendars' collections.
- *
- * Note that if you plan to do anything moderately complex, you are advised to
- * not subclass this server, but use Sabre_DAV_Server directly instead. This
- * class is nothing more than an 'easy setup'.
- *
- * @package Sabre
- * @subpackage CalDAV
- * @deprecated Don't use this class anymore, it will be removed in version 1.7.
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Sabre_CalDAV_Server extends Sabre_DAV_Server {
-
-    /**
-     * The authentication realm
-     *
-     * Note that if this changes, the hashes in the auth backend must also
-     * be recalculated.
-     *
-     * @var string
-     */
-    public $authRealm = 'SabreDAV';
-
-    /**
-     * Sets up the object. A PDO object must be passed to setup all the backends.
-     *
-     * @param PDO $pdo
-     */
-    public function __construct(PDO $pdo) {
-
-        /* Backends */
-        $authBackend = new Sabre_DAV_Auth_Backend_PDO($pdo);
-        $calendarBackend = new Sabre_CalDAV_Backend_PDO($pdo);
-        $principalBackend = new Sabre_DAVACL_PrincipalBackend_PDO($pdo);
-
-        /* Directory structure */
-        $tree = array(
-            new Sabre_CalDAV_Principal_Collection($principalBackend),
-            new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend),
-        );
-
-        /* Initializing server */
-        parent::__construct($tree);
-
-        /* Server Plugins */
-        $authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,$this->authRealm);
-        $this->addPlugin($authPlugin);
-
-        $aclPlugin = new Sabre_DAVACL_Plugin();
-        $this->addPlugin($aclPlugin);
-
-        $caldavPlugin = new Sabre_CalDAV_Plugin();
-        $this->addPlugin($caldavPlugin);
-
-    }
-
-}
diff --git a/3rdparty/Sabre/CalDAV/ShareableCalendar.php b/3rdparty/Sabre/CalDAV/ShareableCalendar.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e44885c6217c0e4060b5d637625d660b226c043
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/ShareableCalendar.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * This object represents a CalDAV calendar that can be shared with other
+ * users.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_ShareableCalendar extends Sabre_CalDAV_Calendar implements Sabre_CalDAV_IShareableCalendar {
+
+    /**
+     * Updates the list of shares.
+     *
+     * The first array is a list of people that are to be added to the
+     * calendar.
+     *
+     * Every element in the add array has the following properties:
+     *   * href - A url. Usually a mailto: address
+     *   * commonName - Usually a first and last name, or false
+     *   * summary - A description of the share, can also be false
+     *   * readOnly - A boolean value
+     *
+     * Every element in the remove array is just the address string.
+     *
+     * @param array $add
+     * @param array $remove
+     * @return void
+     */
+    public function updateShares(array $add, array $remove) {
+
+        $this->caldavBackend->updateShares($this->calendarInfo['id'], $add, $remove);
+
+    }
+
+    /**
+     * Returns the list of people whom this calendar is shared with.
+     *
+     * Every element in this array should have the following properties:
+     *   * href - Often a mailto: address
+     *   * commonName - Optional, for example a first + last name
+     *   * status - See the Sabre_CalDAV_SharingPlugin::STATUS_ constants.
+     *   * readOnly - boolean
+     *   * summary - Optional, a description for the share
+     *
+     * @return array
+     */
+    public function getShares() {
+
+        return $this->caldavBackend->getShares($this->calendarInfo['id']);
+
+    }
+
+    /**
+     * Marks this calendar as published.
+     *
+     * Publishing a calendar should automatically create a read-only, public,
+     * subscribable calendar.
+     *
+     * @param bool $value
+     * @return void
+     */
+    public function setPublishStatus($value) {
+
+        $this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value);
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/SharedCalendar.php b/3rdparty/Sabre/CalDAV/SharedCalendar.php
new file mode 100644
index 0000000000000000000000000000000000000000..9000697d3ec54584f41262700ef7012dd81621d2
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/SharedCalendar.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * This object represents a CalDAV calendar that is shared by a different user.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_SharedCalendar extends Sabre_CalDAV_Calendar implements Sabre_CalDAV_ISharedCalendar {
+
+    /**
+     * Constructor
+     *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+     * @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend
+     * @param array $calendarInfo
+     */
+    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_BackendInterface $caldavBackend, $calendarInfo) {
+
+        $required = array(
+            '{http://calendarserver.org/ns/}shared-url',
+            '{http://sabredav.org/ns}owner-principal',
+            '{http://sabredav.org/ns}read-only',
+        );
+        foreach($required as $r) {
+            if (!isset($calendarInfo[$r])) {
+                throw new InvalidArgumentException('The ' . $r . ' property must be specified for SharedCalendar(s)');
+            }
+        }
+
+        parent::__construct($principalBackend, $caldavBackend, $calendarInfo);
+
+    }
+
+    /**
+     * This method should return the url of the owners' copy of the shared
+     * calendar.
+     *
+     * @return string
+     */
+    public function getSharedUrl() {
+
+        return $this->calendarInfo['{http://calendarserver.org/ns/}shared-url'];
+
+    }
+
+    /**
+     * Returns the owner principal
+     *
+     * This must be a url to a principal, or null if there's no owner
+     *
+     * @return string|null
+     */
+    public function getOwner() {
+
+        return $this->calendarInfo['{http://sabredav.org/ns}owner-principal'];
+
+    }
+
+    /**
+     * Returns a list of ACE's for this node.
+     *
+     * Each ACE has the following properties:
+     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+     *     currently the only supported privileges
+     *   * 'principal', a url to the principal who owns the node
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
+     */
+    public function getACL() {
+
+        // The top-level ACL only contains access information for the true
+        // owner of the calendar, so we need to add the information for the
+        // sharee.
+        $acl = parent::getACL();
+        $acl[] = array(
+            'privilege' => '{DAV:}read',
+            'principal' => $this->calendarInfo['principaluri'],
+            'protected' => true,
+        );
+        if (!$this->calendarInfo['{http://sabredav.org/ns}read-only']) {
+            $acl[] = array(
+                'privilege' => '{DAV:}write',
+                'principal' => $this->calendarInfo['principaluri'],
+                'protected' => true,
+            );
+        }
+        return $acl;
+
+    }
+
+
+}
diff --git a/3rdparty/Sabre/CalDAV/SharingPlugin.php b/3rdparty/Sabre/CalDAV/SharingPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..31df8057b24bdcdf4a10ebb6d80530444a7dc49f
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/SharingPlugin.php
@@ -0,0 +1,475 @@
+<?php
+
+/**
+ * This plugin implements support for caldav sharing.
+ *
+ * This spec is defined at:
+ * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
+ *
+ * See:
+ * Sabre_CalDAV_Backend_SharingSupport for all the documentation.
+ *
+ * Note: This feature is experimental, and may change in between different
+ * SabreDAV versions.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_SharingPlugin extends Sabre_DAV_ServerPlugin {
+
+    /**
+     * These are the various status constants used by sharing-messages.
+     */
+    const STATUS_ACCEPTED = 1;
+    const STATUS_DECLINED = 2;
+    const STATUS_DELETED = 3;
+    const STATUS_NORESPONSE = 4;
+    const STATUS_INVALID = 5;
+
+    /**
+     * Reference to SabreDAV server object.
+     *
+     * @var Sabre_DAV_Server
+     */
+    protected $server;
+
+    /**
+     * This method should return a list of server-features.
+     *
+     * This is for example 'versioning' and is added to the DAV: header
+     * in an OPTIONS response.
+     *
+     * @return array
+     */
+    public function getFeatures() {
+
+        return array('calendarserver-sharing');
+
+    }
+
+    /**
+     * Returns a plugin name.
+     *
+     * Using this name other plugins will be able to access other plugins
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
+     */
+    public function getPluginName() {
+
+        return 'caldav-sharing';
+
+    }
+
+    /**
+     * This initializes the plugin.
+     *
+     * This function is called by Sabre_DAV_Server, after
+     * addPlugin is called.
+     *
+     * This method should set up the required event subscriptions.
+     *
+     * @param Sabre_DAV_Server $server
+     * @return void
+     */
+    public function initialize(Sabre_DAV_Server $server) {
+
+        $this->server = $server;
+        //$server->resourceTypeMapping['Sabre_CalDAV_IShareableCalendar'] = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner';
+        $server->resourceTypeMapping['Sabre_CalDAV_ISharedCalendar'] = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared';
+
+        array_push(
+            $this->server->protectedProperties,
+            '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite',
+            '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
+            '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url'
+        );
+
+        $this->server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties'));
+        $this->server->subscribeEvent('afterGetProperties', array($this, 'afterGetProperties'));
+        $this->server->subscribeEvent('updateProperties', array($this, 'updateProperties'));
+        $this->server->subscribeEvent('unknownMethod', array($this,'unknownMethod'));
+
+    }
+
+    /**
+     * This event is triggered when properties are requested for a certain
+     * node.
+     *
+     * This allows us to inject any properties early.
+     *
+     * @param string $path
+     * @param Sabre_DAV_INode $node
+     * @param array $requestedProperties
+     * @param array $returnedProperties
+     * @return void
+     */
+    public function beforeGetProperties($path, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) {
+
+        if ($node instanceof Sabre_CalDAV_IShareableCalendar) {
+            if (($index = array_search('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite', $requestedProperties))!==false) {
+
+                unset($requestedProperties[$index]);
+                $returnedProperties[200]['{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite'] =
+                    new Sabre_CalDAV_Property_Invite(
+                        $node->getShares()
+                    );
+
+            }
+
+        }
+        if ($node instanceof Sabre_CalDAV_ISharedCalendar) {
+            if (($index = array_search('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url', $requestedProperties))!==false) {
+
+                unset($requestedProperties[$index]);
+                $returnedProperties[200]['{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-url'] =
+                    new Sabre_DAV_Property_Href(
+                        $node->getSharedUrl()
+                    );
+
+            }
+
+        }
+
+    }
+
+    /**
+     * This method is triggered *after* all properties have been retrieved.
+     * This allows us to inject the correct resourcetype for calendars that
+     * have been shared.
+     *
+     * @param string $path
+     * @param array $properties
+     * @param Sabre_DAV_INode $node
+     * @return void
+     */
+    public function afterGetProperties($path, &$properties, Sabre_DAV_INode $node) {
+
+        if ($node instanceof Sabre_CalDAV_IShareableCalendar) {
+            if (isset($properties[200]['{DAV:}resourcetype'])) {
+                if (count($node->getShares())>0) {
+                    $properties[200]['{DAV:}resourcetype']->add(
+                        '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner'
+                    );
+                }
+            }
+            $propName = '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes';
+            if (array_key_exists($propName, $properties[404])) {
+                unset($properties[404][$propName]);
+                $properties[200][$propName] = new Sabre_CalDAV_Property_AllowedSharingModes(true,false);
+            }
+
+        }
+
+    }
+
+    /**
+     * This method is trigged when a user attempts to update a node's
+     * properties.
+     *
+     * A previous draft of the sharing spec stated that it was possible to use
+     * PROPPATCH to remove 'shared-owner' from the resourcetype, thus unsharing
+     * the calendar.
+     *
+     * Even though this is no longer in the current spec, we keep this around
+     * because OS X 10.7 may still make use of this feature.
+     *
+     * @param array $mutations
+     * @param array $result
+     * @param Sabre_DAV_INode $node
+     * @return void
+     */
+    public function updateProperties(array &$mutations, array &$result, Sabre_DAV_INode $node) {
+
+        if (!$node instanceof Sabre_CalDAV_IShareableCalendar)
+            return;
+
+        if (!isset($mutations['{DAV:}resourcetype'])) {
+            return;
+        }
+
+        // Only doing something if shared-owner is indeed not in the list.
+        if($mutations['{DAV:}resourcetype']->is('{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}shared-owner')) return; 
+
+        $shares = $node->getShares();
+        $remove = array();
+        foreach($shares as $share) {
+            $remove[] = $share['href'];
+        }
+        $node->updateShares(array(), $remove);
+
+        // We're marking this update as 200 OK
+        $result[200]['{DAV:}resourcetype'] = null;
+
+        // Removing it from the mutations list
+        unset($mutations['{DAV:}resourcetype']);
+
+    }
+
+    /**
+     * This event is triggered when the server didn't know how to handle a
+     * certain request.
+     *
+     * We intercept this to handle POST requests on calendars.
+     *
+     * @param string $method
+     * @param string $uri
+     * @return null|bool
+     */
+    public function unknownMethod($method, $uri) {
+
+        if ($method!=='POST') {
+            return;
+        }
+
+        // Only handling xml
+        $contentType = $this->server->httpRequest->getHeader('Content-Type');
+        if (strpos($contentType,'application/xml')===false && strpos($contentType,'text/xml')===false)
+            return;
+
+        // Making sure the node exists
+        try {
+            $node = $this->server->tree->getNodeForPath($uri);
+        } catch (Sabre_DAV_Exception_NotFound $e) {
+            return;
+        }
+
+
+        $dom = Sabre_DAV_XMLUtil::loadDOMDocument($this->server->httpRequest->getBody(true));
+
+        $documentType = Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild);
+
+        switch($documentType) {
+
+            // Dealing with the 'share' document, which modified invitees on a
+            // calendar.
+            case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}share' :
+
+                // We can only deal with IShareableCalendar objects
+                if (!$node instanceof Sabre_CalDAV_IShareableCalendar) {
+                    return;
+                }
+
+                // Getting ACL info
+                $acl = $this->server->getPlugin('acl');
+
+                // If there's no ACL support, we allow everything
+                if ($acl) {
+                    $acl->checkPrivileges($uri, '{DAV:}write');
+                }
+
+                $mutations = $this->parseShareRequest($dom);
+
+                $node->updateShares($mutations[0], $mutations[1]);
+
+                $this->server->httpResponse->sendStatus(200);
+                // Adding this because sending a response body may cause issues,
+                // and I wanted some type of indicator the response was handled.
+                $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
+
+                // Breaking the event chain
+                return false;
+
+            // The invite-reply document is sent when the user replies to an
+            // invitation of a calendar share.
+            case '{'. Sabre_CalDAV_Plugin::NS_CALENDARSERVER.'}invite-reply' :
+
+                // This only works on the calendar-home-root node.
+                if (!$node instanceof Sabre_CalDAV_UserCalendars) {
+                    return;
+                }
+
+                // Getting ACL info
+                $acl = $this->server->getPlugin('acl');
+
+                // If there's no ACL support, we allow everything
+                if ($acl) {
+                    $acl->checkPrivileges($uri, '{DAV:}write');
+                }
+
+                $message = $this->parseInviteReplyRequest($dom);
+
+                $url = $node->shareReply(
+                    $message['href'],
+                    $message['status'],
+                    $message['calendarUri'],
+                    $message['inReplyTo'],
+                    $message['summary']
+                );
+
+                $this->server->httpResponse->sendStatus(200);
+                // Adding this because sending a response body may cause issues,
+                // and I wanted some type of indicator the response was handled.
+                $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
+
+                if ($url) {
+                    $dom = new DOMDocument('1.0', 'UTF-8');
+                    $dom->formatOutput = true;
+
+                    $root = $dom->createElement('cs:shared-as');
+                    foreach($this->server->xmlNamespaces as $namespace => $prefix) {
+                        $root->setAttribute('xmlns:' . $prefix, $namespace);
+                    }
+
+                    $dom->appendChild($root);
+                    $href = new Sabre_DAV_Property_Href($url);
+
+                    $href->serialize($this->server, $root);
+                    $this->server->httpResponse->setHeader('Content-Type','application/xml');
+                    $this->server->httpResponse->sendBody($dom->saveXML());
+
+                }
+
+                // Breaking the event chain
+                return false;
+
+            case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}publish-calendar' :
+
+                // We can only deal with IShareableCalendar objects
+                if (!$node instanceof Sabre_CalDAV_IShareableCalendar) {
+                    return;
+                }
+
+                // Getting ACL info
+                $acl = $this->server->getPlugin('acl');
+
+                // If there's no ACL support, we allow everything
+                if ($acl) {
+                    $acl->checkPrivileges($uri, '{DAV:}write');
+                }
+
+                $node->setPublishStatus(true);
+
+                // iCloud sends back the 202, so we will too.
+                $this->server->httpResponse->sendStatus(202);
+
+                // Adding this because sending a response body may cause issues,
+                // and I wanted some type of indicator the response was handled.
+                $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
+
+                // Breaking the event chain
+                return false;
+
+            case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}unpublish-calendar' :
+
+                // We can only deal with IShareableCalendar objects
+                if (!$node instanceof Sabre_CalDAV_IShareableCalendar) {
+                    return;
+                }
+
+                // Getting ACL info
+                $acl = $this->server->getPlugin('acl');
+
+                // If there's no ACL support, we allow everything
+                if ($acl) {
+                    $acl->checkPrivileges($uri, '{DAV:}write');
+                }
+
+                $node->setPublishStatus(false);
+
+                $this->server->httpResponse->sendStatus(200);
+
+                // Adding this because sending a response body may cause issues,
+                // and I wanted some type of indicator the response was handled.
+                $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
+
+                // Breaking the event chain
+                return false;
+
+        }
+
+
+    }
+
+    /**
+     * Parses the 'share' POST request.
+     *
+     * This method returns an array, containing two arrays.
+     * The first array is a list of new sharees. Every element is a struct
+     * containing a:
+     *   * href element. (usually a mailto: address)
+     *   * commonName element (often a first and lastname, but can also be
+     *     false)
+     *   * readOnly (true or false)
+     *   * summary (A description of the share, can also be false)
+     *
+     * The second array is a list of sharees that are to be removed. This is
+     * just a simple array with 'hrefs'.
+     *
+     * @param DOMDocument $dom
+     * @return array
+     */
+    protected function parseShareRequest(DOMDocument $dom) {
+
+        $xpath = new \DOMXPath($dom);
+        $xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER);
+        $xpath->registerNamespace('d', 'DAV:');
+
+
+        $set = array();
+        $elems = $xpath->query('cs:set');
+
+        for($i=0; $i < $elems->length; $i++) {
+
+            $xset = $elems->item($i);
+            $set[] = array(
+                'href' => $xpath->evaluate('string(d:href)', $xset),
+                'commonName' => $xpath->evaluate('string(cs:common-name)', $xset),
+                'summary' => $xpath->evaluate('string(cs:summary)', $xset),
+                'readOnly' => $xpath->evaluate('boolean(cs:read)', $xset)!==false
+            );
+
+        }
+
+        $remove = array();
+        $elems = $xpath->query('cs:remove');
+
+        for($i=0; $i < $elems->length; $i++) {
+
+            $xremove = $elems->item($i);
+            $remove[] = $xpath->evaluate('string(d:href)', $xremove);
+
+        }
+
+        return array($set, $remove);
+
+    }
+
+    /**
+     * Parses the 'invite-reply' POST request.
+     *
+     * This method returns an array, containing the following properties:
+     *   * href - The sharee who is replying
+     *   * status - One of the self::STATUS_* constants
+     *   * calendarUri - The url of the shared calendar
+     *   * inReplyTo - The unique id of the share invitation.
+     *   * summary - Optional description of the reply.
+     *
+     * @param DOMDocument $dom
+     * @return array
+     */
+    protected function parseInviteReplyRequest(DOMDocument $dom) {
+
+        $xpath = new \DOMXPath($dom);
+        $xpath->registerNamespace('cs', Sabre_CalDAV_Plugin::NS_CALENDARSERVER);
+        $xpath->registerNamespace('d', 'DAV:');
+
+        $hostHref = $xpath->evaluate('string(cs:hosturl/d:href)');
+        if (!$hostHref) {
+            throw new Sabre_DAV_Exception_BadRequest('The {' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}hosturl/{DAV:}href element is required');
+        }
+
+        return array(
+            'href' => $xpath->evaluate('string(d:href)'),
+            'calendarUri' => $this->server->calculateUri($hostHref),
+            'inReplyTo' => $xpath->evaluate('string(cs:in-reply-to)'),
+            'summary' => $xpath->evaluate('string(cs:summary)'),
+            'status' => $xpath->evaluate('boolean(cs:invite-accepted)')?self::STATUS_ACCEPTED:self::STATUS_DECLINED
+        );
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/UserCalendars.php b/3rdparty/Sabre/CalDAV/UserCalendars.php
old mode 100755
new mode 100644
index b8d3f0573fa4c9c2b43084b1a63937aaf137b33f..3194e6677ab84695d0c02a7a358a6d139b50f312
--- a/3rdparty/Sabre/CalDAV/UserCalendars.php
+++ b/3rdparty/Sabre/CalDAV/UserCalendars.php
@@ -6,7 +6,7 @@
  * @package Sabre
  * @subpackage CalDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL {
@@ -21,7 +21,7 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     /**
      * CalDAV backend
      *
-     * @var Sabre_CalDAV_Backend_Abstract
+     * @var Sabre_CalDAV_Backend_BackendInterface
      */
     protected $caldavBackend;
 
@@ -36,10 +36,10 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      * Constructor
      *
      * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param Sabre_CalDAV_Backend_BackendInterface $caldavBackend
      * @param mixed $userUri
      */
-    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $userUri) {
+    public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_BackendInterface $caldavBackend, $userUri) {
 
         $this->principalBackend = $principalBackend;
         $this->caldavBackend = $caldavBackend;
@@ -168,9 +168,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
         $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
         $objs = array();
         foreach($calendars as $calendar) {
-            $objs[] = new Sabre_CalDAV_Calendar($this->principalBackend, $this->caldavBackend, $calendar);
+            if ($this->caldavBackend instanceof Sabre_CalDAV_Backend_SharingSupport) {
+                if (isset($calendar['{http://calendarserver.org/ns/}shared-url'])) {
+                    $objs[] = new Sabre_CalDAV_SharedCalendar($this->principalBackend, $this->caldavBackend, $calendar);
+                } else {
+                    $objs[] = new Sabre_CalDAV_ShareableCalendar($this->principalBackend, $this->caldavBackend, $calendar);
+                }
+            } else {
+                $objs[] = new Sabre_CalDAV_Calendar($this->principalBackend, $this->caldavBackend, $calendar);
+            }
         }
         $objs[] = new Sabre_CalDAV_Schedule_Outbox($this->principalInfo['uri']);
+
+        // We're adding a notifications node, if it's supported by the backend.
+        if ($this->caldavBackend instanceof Sabre_CalDAV_Backend_NotificationSupport) {
+            $objs[] = new Sabre_CalDAV_Notifications_Collection($this->caldavBackend, $this->principalInfo['uri']);
+        }
         return $objs;
 
     }
@@ -185,8 +198,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      */
     public function createExtendedCollection($name, array $resourceType, array $properties) {
 
-        if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar',$resourceType) || count($resourceType)!==2) {
-            throw new Sabre_DAV_Exception_InvalidResourceType('Unknown resourceType for this collection');
+        $isCalendar = false;
+        foreach($resourceType as $rt) {
+            switch ($rt) {
+                case '{DAV:}collection' :
+                case '{http://calendarserver.org/ns/}shared-owner' :
+                    // ignore
+                    break;
+                case '{urn:ietf:params:xml:ns:caldav}calendar' :
+                    $isCalendar = true;
+                    break;
+                default :
+                    throw new Sabre_DAV_Exception_InvalidResourceType('Unknown resourceType: ' . $rt);
+            }
+        }
+        if (!$isCalendar) {
+            throw new Sabre_DAV_Exception_InvalidResourceType('You can only create calendars in this collection');
         }
         $this->caldavBackend->createCalendar($this->principalInfo['uri'], $name, $properties);
 
@@ -295,4 +322,27 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
 
     }
 
+    /**
+     * This method is called when a user replied to a request to share.
+     *
+     * This method should return the url of the newly created calendar if the
+     * share was accepted.
+     *
+     * @param string href The sharee who is replying (often a mailto: address)
+     * @param int status One of the SharingPlugin::STATUS_* constants
+     * @param string $calendarUri The url to the calendar thats being shared
+     * @param string $inReplyTo The unique id this message is a response to
+     * @param string $summary A description of the reply
+     * @return null|string
+     */
+    public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {
+
+        if (!$this->caldavBackend instanceof Sabre_CalDAV_Backend_SharingSupport) {
+            throw new Sabre_DAV_Exception_NotImplemented('Sharing support is not implemented by this backend.');
+        }
+
+        return $this->caldavBackend->shareReply($href, $status, $calendarUri, $inReplyTo, $summary);
+
+    }
+
 }
diff --git a/3rdparty/Sabre/CalDAV/Version.php b/3rdparty/Sabre/CalDAV/Version.php
old mode 100755
new mode 100644
index ace9901c0895669cfa71e9faf4b0ff157f6f2df0..0ad14fa08691c1d734576bd2d2b42e1dcfe50417
--- a/3rdparty/Sabre/CalDAV/Version.php
+++ b/3rdparty/Sabre/CalDAV/Version.php
@@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.6.4';
+    const VERSION = '1.7.0';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CalDAV/includes.php b/3rdparty/Sabre/CalDAV/includes.php
old mode 100755
new mode 100644
index 1ecb870a0e134c76bf318e7b7bf68f6176d8a923..8b38e398f653575191de08f9c18d848c89bbb90e
--- a/3rdparty/Sabre/CalDAV/includes.php
+++ b/3rdparty/Sabre/CalDAV/includes.php
@@ -16,28 +16,47 @@
  */
 
 // Begin includes
-include __DIR__ . '/Backend/Abstract.php';
-include __DIR__ . '/Backend/PDO.php';
+include __DIR__ . '/Backend/BackendInterface.php';
+include __DIR__ . '/Backend/NotificationSupport.php';
+include __DIR__ . '/Backend/SharingSupport.php';
 include __DIR__ . '/CalendarQueryParser.php';
 include __DIR__ . '/CalendarQueryValidator.php';
 include __DIR__ . '/CalendarRootNode.php';
+include __DIR__ . '/Exception/InvalidComponentType.php';
 include __DIR__ . '/ICalendar.php';
 include __DIR__ . '/ICalendarObject.php';
 include __DIR__ . '/ICSExportPlugin.php';
+include __DIR__ . '/IShareableCalendar.php';
+include __DIR__ . '/ISharedCalendar.php';
+include __DIR__ . '/Notifications/ICollection.php';
+include __DIR__ . '/Notifications/INode.php';
+include __DIR__ . '/Notifications/INotificationType.php';
+include __DIR__ . '/Notifications/Node.php';
+include __DIR__ . '/Notifications/Notification/Invite.php';
+include __DIR__ . '/Notifications/Notification/InviteReply.php';
+include __DIR__ . '/Notifications/Notification/SystemStatus.php';
 include __DIR__ . '/Plugin.php';
 include __DIR__ . '/Principal/Collection.php';
 include __DIR__ . '/Principal/ProxyRead.php';
 include __DIR__ . '/Principal/ProxyWrite.php';
 include __DIR__ . '/Principal/User.php';
+include __DIR__ . '/Property/AllowedSharingModes.php';
+include __DIR__ . '/Property/Invite.php';
+include __DIR__ . '/Property/ScheduleCalendarTransp.php';
 include __DIR__ . '/Property/SupportedCalendarComponentSet.php';
 include __DIR__ . '/Property/SupportedCalendarData.php';
 include __DIR__ . '/Property/SupportedCollationSet.php';
 include __DIR__ . '/Schedule/IMip.php';
 include __DIR__ . '/Schedule/IOutbox.php';
 include __DIR__ . '/Schedule/Outbox.php';
-include __DIR__ . '/Server.php';
+include __DIR__ . '/SharingPlugin.php';
 include __DIR__ . '/UserCalendars.php';
 include __DIR__ . '/Version.php';
+include __DIR__ . '/Backend/Abstract.php';
+include __DIR__ . '/Backend/PDO.php';
 include __DIR__ . '/Calendar.php';
 include __DIR__ . '/CalendarObject.php';
+include __DIR__ . '/Notifications/Collection.php';
+include __DIR__ . '/ShareableCalendar.php';
+include __DIR__ . '/SharedCalendar.php';
 // End includes
diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php
old mode 100755
new mode 100644
index 12297175a85327aef5c69c665fd7047cef0f63ae..8d545114d97c61e9ce395d85be29ce19c4f8c144
--- a/3rdparty/Sabre/CardDAV/AddressBook.php
+++ b/3rdparty/Sabre/CardDAV/AddressBook.php
@@ -55,7 +55,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      * Returns a card
      *
      * @param string $name
-     * @return Sabre_DAV_Card
+     * @return Sabre_CardDAV_ICard
      */
     public function getChild($name) {
 
@@ -104,7 +104,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      *
      * @param string $name
      * @param resource $vcardData
-     * @return void|null
+     * @return string|null
      */
     public function createFile($name,$vcardData = null) {
 
diff --git a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/AddressBookRoot.php b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/Backend/Abstract.php b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php
old mode 100755
new mode 100644
index d7c663338375ac8b068851c574d49b45a49a75b7..0e35d321eb8e581ef64f6987b285455201ada6ae
--- a/3rdparty/Sabre/CardDAV/Card.php
+++ b/3rdparty/Sabre/CardDAV/Card.php
@@ -6,7 +6,7 @@
  * @package Sabre
  * @subpackage CardDAV
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard, Sabre_DAVACL_IACL {
@@ -78,7 +78,7 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
      * Updates the VCard-formatted object
      *
      * @param string $cardData
-     * @return void
+     * @return string|null
      */
     public function put($cardData) {
 
@@ -114,7 +114,7 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
      */
     public function getContentType() {
 
-        return 'text/x-vcard';
+        return 'text/x-vcard; charset=utf-8';
 
     }
 
@@ -128,7 +128,13 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
         if (isset($this->cardData['etag'])) {
             return $this->cardData['etag'];
         } else {
-            return '"' . md5($this->get()) . '"';
+            $data = $this->get();
+            if (is_string($data)) {
+                return '"' . md5($data) . '"';
+            } else {
+                // We refuse to calculate the md5 if it's a stream.
+                return null;
+            }
         }
 
     }
@@ -136,7 +142,7 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     /**
      * Returns the last modification date as a unix timestamp
      *
-     * @return time
+     * @return int
      */
     public function getLastModified() {
 
diff --git a/3rdparty/Sabre/CardDAV/IAddressBook.php b/3rdparty/Sabre/CardDAV/IAddressBook.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/ICard.php b/3rdparty/Sabre/CardDAV/ICard.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/IDirectory.php b/3rdparty/Sabre/CardDAV/IDirectory.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php
old mode 100755
new mode 100644
index 96def6dd96bc473d17427182371b98338df0fb54..12bccaec4fb8ca6ff92bd63ad6870f36657a2442
--- a/3rdparty/Sabre/CardDAV/Plugin.php
+++ b/3rdparty/Sabre/CardDAV/Plugin.php
@@ -1,5 +1,7 @@
 <?php
 
+use Sabre\VObject;
+
 /**
  * CardDAV plugin
  *
@@ -48,6 +50,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         /* Events */
         $server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties'));
+        $server->subscribeEvent('afterGetProperties',  array($this, 'afterGetProperties'));
         $server->subscribeEvent('updateProperties', array($this, 'updateProperties'));
         $server->subscribeEvent('report', array($this,'report'));
         $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
@@ -153,10 +156,6 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 if (is_resource($val))
                     $val = stream_get_contents($val);
 
-                // Taking out \r to not screw up the xml output
-                //$returnedProperties[200][$addressDataProp] = str_replace("\r","", $val);
-                // The stripping of \r breaks the Mail App in OSX Mountain Lion
-                // this is fixed in master, but not backported. /Tanghus
                 $returnedProperties[200][$addressDataProp] = $val;
 
             }
@@ -190,7 +189,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * @param array $mutations
      * @param array $result
      * @param Sabre_DAV_INode $node
-     * @return void
+     * @return bool
      */
     public function updateProperties(&$mutations, &$result, $node) {
 
@@ -272,7 +271,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
 
-        $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
+        $hrefElems = $dom->getElementsByTagNameNS('DAV:','href');
         $propertyList = array();
 
         foreach($hrefElems as $elem) {
@@ -282,9 +281,12 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
+        $prefer = $this->server->getHTTPPRefer();
+
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
-        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList));
+        $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
+        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal']));
 
     }
 
@@ -348,9 +350,9 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         try {
 
-            $vobj = Sabre_VObject_Reader::read($data);
+            $vobj = VObject\Reader::read($data);
 
-        } catch (Sabre_VObject_ParseException $e) {
+        } catch (VObject\ParseException $e) {
 
             throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage());
 
@@ -360,6 +362,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
             throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support vcard objects.');
         }
 
+        if (!isset($vobj->UID)) {
+            throw new Sabre_DAV_Exception_BadRequest('Every vcard must have an UID.');
+        }
+
     }
 
 
@@ -424,9 +430,12 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
+        $prefer = $this->server->getHTTPPRefer();
+
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
-        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result));
+        $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
+        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 
     }
 
@@ -440,7 +449,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
      */
     public function validateFilters($vcardData, array $filters, $test) {
 
-        $vcard = Sabre_VObject_Reader::read($vcardData);
+        $vcard = VObject\Reader::read($vcardData);
 
         if (!$filters) return true;
 
@@ -615,6 +624,30 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     }
 
+    /**
+     * This event is triggered after webdav-properties have been retrieved.
+     *
+     * @return bool
+     */
+    public function afterGetProperties($uri, &$properties) {
+
+        // If the request was made using the SOGO connector, we must rewrite
+        // the content-type property. By default SabreDAV will send back
+        // text/x-vcard; charset=utf-8, but for SOGO we must strip that last
+        // part.
+        if (!isset($properties[200]['{DAV:}getcontenttype']))
+            return;
+
+        if (strpos($this->server->httpRequest->getHeader('User-Agent'),'Thunderbird')===false) {
+            return;
+        }
+
+        if (strpos($properties[200]['{DAV:}getcontenttype'],'text/x-vcard')===0) {
+            $properties[200]['{DAV:}getcontenttype'] = 'text/x-vcard';
+        }
+
+    }
+
     /**
      * This method is used to generate HTML output for the
      * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/UserAddressBooks.php b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/CardDAV/VCFExportPlugin.php b/3rdparty/Sabre/CardDAV/VCFExportPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..8850fef8afbef9270eac2129d006a2699c8976d9
--- /dev/null
+++ b/3rdparty/Sabre/CardDAV/VCFExportPlugin.php
@@ -0,0 +1,107 @@
+<?php
+
+use Sabre\VObject;
+
+/**
+ * VCF Exporter
+ *
+ * This plugin adds the ability to export entire address books as .vcf files.
+ * This is useful for clients that don't support CardDAV yet. They often do
+ * support vcf files.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @author Thomas Tanghus (http://tanghus.net/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin {
+
+    /**
+     * Reference to Server class
+     *
+     * @var Sabre_DAV_Server
+     */
+    private $server;
+
+    /**
+     * Initializes the plugin and registers event handlers
+     *
+     * @param Sabre_DAV_Server $server
+     * @return void
+     */
+    public function initialize(Sabre_DAV_Server $server) {
+
+        $this->server = $server;
+        $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90);
+
+    }
+
+    /**
+     * 'beforeMethod' event handles. This event handles intercepts GET requests ending
+     * with ?export
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
+     */
+    public function beforeMethod($method, $uri) {
+
+        if ($method!='GET') return;
+        if ($this->server->httpRequest->getQueryString()!='export') return;
+
+        // splitting uri
+        list($uri) = explode('?',$uri,2);
+
+        $node = $this->server->tree->getNodeForPath($uri);
+
+        if (!($node instanceof Sabre_CardDAV_IAddressBook)) return;
+
+        // Checking ACL, if available.
+        if ($aclPlugin = $this->server->getPlugin('acl')) {
+            $aclPlugin->checkPrivileges($uri, '{DAV:}read');
+        }
+
+        $this->server->httpResponse->setHeader('Content-Type','text/directory');
+        $this->server->httpResponse->sendStatus(200);
+
+        $nodes = $this->server->getPropertiesForPath($uri, array(
+            '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data',
+        ),1);
+
+        $this->server->httpResponse->sendBody($this->generateVCF($nodes));
+
+        // Returning false to break the event chain
+        return false;
+
+    }
+
+    /**
+     * Merges all vcard objects, and builds one big vcf export
+     *
+     * @param array $nodes
+     * @return string
+     */
+    public function generateVCF(array $nodes) {
+
+        $output = "";
+
+        foreach($nodes as $node) {
+
+            if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) {
+                continue;
+            }
+            $nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'];
+
+            // Parsing this node so VObject can clean up the output.
+            $output .=
+               VObject\Reader::read($nodeData)->serialize();
+
+        }
+
+        return $output;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php
old mode 100755
new mode 100644
index d0623f0d3e8658b89f747e619ad5547655d4ed93..6b70a2df9b5a336d0ed0f2bc0c5e0578167c44a0
--- a/3rdparty/Sabre/CardDAV/Version.php
+++ b/3rdparty/Sabre/CardDAV/Version.php
@@ -16,7 +16,7 @@ class Sabre_CardDAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.6.3';
+    const VERSION = '1.7.0';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CardDAV/includes.php b/3rdparty/Sabre/CardDAV/includes.php
old mode 100755
new mode 100644
index c3b8c04b077584a2a9d168a5e0dc99fcedbf477d..08b4f76bd019ab4d14e96481dc8952b4a9b24723
--- a/3rdparty/Sabre/CardDAV/includes.php
+++ b/3rdparty/Sabre/CardDAV/includes.php
@@ -26,6 +26,7 @@ include __DIR__ . '/IDirectory.php';
 include __DIR__ . '/Plugin.php';
 include __DIR__ . '/Property/SupportedAddressData.php';
 include __DIR__ . '/UserAddressBooks.php';
+include __DIR__ . '/VCFExportPlugin.php';
 include __DIR__ . '/Version.php';
 include __DIR__ . '/AddressBook.php';
 include __DIR__ . '/Card.php';
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php
old mode 100755
new mode 100644
index 09bbdd2ae021e013c83c85bcbbc77f9cfb8a6ace..b6440ab63403c1ab5dc7a313e6db897a49f74ed0
--- a/3rdparty/Sabre/DAV/Browser/Plugin.php
+++ b/3rdparty/Sabre/DAV/Browser/Plugin.php
@@ -338,7 +338,7 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
             $icon = '';
 
             if ($this->enableAssets) {
-                $node = $parent->getChild($name);
+                $node = $this->server->tree->getNodeForPath(($path?$path.'/':'') . $name);
                 foreach(array_reverse($this->iconMap) as $class=>$iconName) {
 
                     if ($node instanceof $class) {
diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php
old mode 100755
new mode 100644
index 9a428765e904bc8e5e92b05d7f4299890e7f150d..9d9f4c96b022d37d52f58fa549a01f45a9dc5735
--- a/3rdparty/Sabre/DAV/Client.php
+++ b/3rdparty/Sabre/DAV/Client.php
@@ -16,12 +16,25 @@
  */
 class Sabre_DAV_Client {
 
+    /**
+     * The propertyMap is a key-value array.
+     *
+     * If you use the propertyMap, any {DAV:}multistatus responses with the
+     * proeprties listed in this array, will automatically be mapped to a
+     * respective class.
+     *
+     * The {DAV:}resourcetype property is automatically added. This maps to
+     * Sabre_DAV_Property_ResourceType
+     *
+     * @var array
+     */
     public $propertyMap = array();
 
     protected $baseUri;
     protected $userName;
     protected $password;
     protected $proxy;
+    protected $trustedCertificates;
 
     /**
      * Basic authentication
@@ -87,6 +100,18 @@ class Sabre_DAV_Client {
 
     }
 
+    /**
+     * Add trusted root certificates to the webdav client.
+     *
+     * The parameter certificates should be a absulute path to a file
+     * which contains all trusted certificates
+     *
+     * @param string $certificates
+     */
+    public function addTrustedCertificates($certificates) {
+        $this->trustedCertificates = $certificates;
+    }
+
     /**
      * Does a PROPFIND request
      *
@@ -143,13 +168,13 @@ class Sabre_DAV_Client {
         if ($depth===0) {
             reset($result);
             $result = current($result);
-            return $result[200];
+            return isset($result[200])?$result[200]:array();
         }
 
         $newResult = array();
         foreach($result as $href => $statusList) {
 
-            $newResult[$href] = $statusList[200];
+            $newResult[$href] = isset($statusList[200])?$statusList[200]:array();
 
         }
 
@@ -279,6 +304,10 @@ class Sabre_DAV_Client {
             CURLOPT_MAXREDIRS => 5,
         );
 
+        if($this->trustedCertificates) {
+            $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates;
+        }
+
         switch ($method) {
             case 'HEAD' :
 
@@ -363,10 +392,30 @@ class Sabre_DAV_Client {
 
         if ($response['statusCode']>=400) {
             switch ($response['statusCode']) {
+                case 400 :
+                    throw new Sabre_DAV_Exception_BadRequest('Bad request');
+                case 401 :
+                    throw new Sabre_DAV_Exception_NotAuthenticated('Not authenticated');
+                case 402 :
+                    throw new Sabre_DAV_Exception_PaymentRequired('Payment required');
+                case 403 :
+                    throw new Sabre_DAV_Exception_Forbidden('Forbidden');
                 case 404:
-                    throw new Sabre_DAV_Exception_NotFound('Resource ' . $url . ' not found.');
-                    break;
-
+                    throw new Sabre_DAV_Exception_NotFound('Resource not found.');
+                case 405 :
+                    throw new Sabre_DAV_Exception_MethodNotAllowed('Method not allowed');
+                case 409 :
+                    throw new Sabre_DAV_Exception_Conflict('Conflict');
+                case 412 :
+                    throw new Sabre_DAV_Exception_PreconditionFailed('Precondition failed');
+                case 416 :
+                    throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('Requested Range Not Satisfiable');
+                case 500 :
+                    throw new Sabre_DAV_Exception('Internal server error');
+                case 501 :
+                    throw new Sabre_DAV_Exception_NotImplemented('Not Implemented');
+                case 507 :
+                    throw new Sabre_DAV_Exception_InsufficientStorage('Insufficient storage');
                 default:
                     throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
             }
@@ -386,6 +435,7 @@ class Sabre_DAV_Client {
      * @param array $settings
      * @return array
      */
+    // @codeCoverageIgnoreStart
     protected function curlRequest($url, $settings) {
 
         $curl = curl_init($url);
@@ -399,6 +449,7 @@ class Sabre_DAV_Client {
         );
 
     }
+    // @codeCoverageIgnoreEnd
 
     /**
      * Returns the full url based on the given url (which may be relative). All
@@ -453,19 +504,17 @@ class Sabre_DAV_Client {
      */
     public function parseMultiStatus($body) {
 
-        $body = Sabre_DAV_XMLUtil::convertDAVNamespace($body);
-
         $responseXML = simplexml_load_string($body, null, LIBXML_NOBLANKS | LIBXML_NOCDATA);
         if ($responseXML===false) {
             throw new InvalidArgumentException('The passed data is not valid XML');
         }
 
-        $responseXML->registerXPathNamespace('d', 'urn:DAV');
+        $responseXML->registerXPathNamespace('d', 'DAV:');
 
         $propResult = array();
 
         foreach($responseXML->xpath('d:response') as $response) {
-            $response->registerXPathNamespace('d', 'urn:DAV');
+            $response->registerXPathNamespace('d', 'DAV:');
             $href = $response->xpath('d:href');
             $href = (string)$href[0];
 
@@ -473,7 +522,7 @@ class Sabre_DAV_Client {
 
             foreach($response->xpath('d:propstat') as $propStat) {
 
-                $propStat->registerXPathNamespace('d', 'urn:DAV');
+                $propStat->registerXPathNamespace('d', 'DAV:');
                 $status = $propStat->xpath('d:status');
                 list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3);
 
diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php
old mode 100755
new mode 100644
index 776c22531b2485bdcabb5c47a9ae2efec75bdd1a..c7648a8a52d593daab6df038d936c127fd838458
--- a/3rdparty/Sabre/DAV/Collection.php
+++ b/3rdparty/Sabre/DAV/Collection.php
@@ -17,9 +17,13 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
     /**
      * Returns a child object, by its name.
      *
-     * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
+     * This method makes use of the getChildren method to grab all the child
+     * nodes, and compares the name.
      * Generally its wise to override this, as this can usually be optimized
      *
+     * This method must throw Sabre_DAV_Exception_NotFound if the node does not
+     * exist.
+     *
      * @param string $name
      * @throws Sabre_DAV_Exception_NotFound
      * @return Sabre_DAV_INode
diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php
deleted file mode 100755
index 6db8febc02e900ceba08c74370bbffa7968fd46b..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/DAV/Directory.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-/**
- * Directory class
- *
- * This class is now deprecated in favor of the Sabre_DAV_Collection class.
- *
- * @package Sabre
- * @subpackage DAV
- * @deprecated Use Sabre_DAV_Collection instead
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-abstract class Sabre_DAV_Directory extends Sabre_DAV_Collection {
-}
-
diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotSupported.php
old mode 100755
new mode 100644
similarity index 87%
rename from 3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
rename to 3rdparty/Sabre/DAV/Exception/ReportNotSupported.php
index e86800f30381b9baf877e39d74c0c3a75b561598..a2906865f8e54d18920d08972e350583946703b4
--- a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/ReportNotSupported.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * ReportNotImplemented
+ * ReportNotSupported
  *
  * This exception is thrown when the client requested an unknown report through the REPORT method
  *
@@ -11,7 +11,7 @@
  * @author Evert Pot (http://www.rooftopsolutions.nl/) 
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_DAV_Exception_ReportNotImplemented extends Sabre_DAV_Exception_NotImplemented {
+class Sabre_DAV_Exception_ReportNotSupported extends Sabre_DAV_Exception_Forbidden {
 
     /**
      * This method allows the exception to include additional information into the WebDAV error response
diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php
old mode 100755
new mode 100644
index 3af2d755583747f2c6c3e02c51030ebe9b3cc3df..72fec744d0fb204dbe54bd4bc3bba67cd3c11bf4
--- a/3rdparty/Sabre/DAV/FS/Directory.php
+++ b/3rdparty/Sabre/DAV/FS/Directory.php
@@ -17,7 +17,7 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
      * Data will either be supplied as a stream resource, or in certain cases
      * as a string. Keep in mind that you may have to support either.
      *
-     * After succesful creation of the file, you may choose to return the ETag
+     * After successful creation of the file, you may choose to return the ETag
      * of the new file here.
      *
      * The returned ETag must be surrounded by double-quotes (The quotes should
@@ -58,6 +58,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     /**
      * Returns a specific child node, referenced by its name
      *
+     * This method must throw Sabre_DAV_Exception_NotFound if the node does not
+     * exist.
+     *
      * @param string $name
      * @throws Sabre_DAV_Exception_NotFound
      * @return Sabre_DAV_INode
diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php
old mode 100755
new mode 100644
index 540057183b30380c24e8395ab6def0a792a06ff6..70dfdc2c3b597f602a785a9269d42f9b96c49c8d
--- a/3rdparty/Sabre/DAV/FSExt/Directory.php
+++ b/3rdparty/Sabre/DAV/FSExt/Directory.php
@@ -17,7 +17,7 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
      * Data will either be supplied as a stream resource, or in certain cases
      * as a string. Keep in mind that you may have to support either.
      *
-     * After succesful creation of the file, you may choose to return the ETag
+     * After successful creation of the file, you may choose to return the ETag
      * of the new file here.
      *
      * The returned ETag must be surrounded by double-quotes (The quotes should
@@ -64,6 +64,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     /**
      * Returns a specific child node, referenced by its name
      *
+     * This method must throw Sabre_DAV_Exception_NotFound if the node does not
+     * exist.
+     *
      * @param string $name
      * @throws Sabre_DAV_Exception_NotFound
      * @return Sabre_DAV_INode
diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php
old mode 100755
new mode 100644
index b93ce5aee2108bfbdb5bebf3a3a6619b7eda458b..590fb808e612744cb4652d66da62e18c310407e4
--- a/3rdparty/Sabre/DAV/FSExt/File.php
+++ b/3rdparty/Sabre/DAV/FSExt/File.php
@@ -9,15 +9,15 @@
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFile {
+class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_PartialUpdate_IFile {
 
     /**
      * Updates the data
      *
      * data is a readable stream resource.
      *
-     * @param resource $data
-     * @return void
+     * @param resource|string $data
+     * @return string
      */
     public function put($data) {
 
@@ -26,10 +26,34 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
 
     }
 
+    /**
+     * Updates the data at a given offset
+     *
+     * The data argument is a readable stream resource.
+     * The offset argument is a 0-based offset where the data should be
+     * written.
+     *
+     * param resource|string $data
+     * @return void
+     */
+    public function putRange($data, $offset) {
+
+        $f = fopen($this->path, 'c');
+        fseek($f,$offset-1);
+        if (is_string($data)) {
+            fwrite($f, $data);
+        } else {
+            stream_copy_to_stream($data,$f);
+        }
+        fclose($f);
+        return '"' . md5_file($this->path) . '"';
+
+    }
+
     /**
      * Returns the data
      *
-     * @return string
+     * @return resource
      */
     public function get() {
 
diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php
old mode 100755
new mode 100644
index 4626038a66e3fcb31e211adf577b742e704cf194..94431a0c496f86b1c86338706d153728fd83103d
--- a/3rdparty/Sabre/DAV/ICollection.php
+++ b/3rdparty/Sabre/DAV/ICollection.php
@@ -19,7 +19,7 @@ interface Sabre_DAV_ICollection extends Sabre_DAV_INode {
      * Data will either be supplied as a stream resource, or in certain cases
      * as a string. Keep in mind that you may have to support either.
      *
-     * After succesful creation of the file, you may choose to return the ETag
+     * After successful creation of the file, you may choose to return the ETag
      * of the new file here.
      *
      * The returned ETag must be surrounded by double-quotes (The quotes should
@@ -50,6 +50,9 @@ interface Sabre_DAV_ICollection extends Sabre_DAV_INode {
     /**
      * Returns a specific child node, referenced by its name
      *
+     * This method must throw Sabre_DAV_Exception_NotFound if the node does not
+     * exist.
+     *
      * @param string $name
      * @return Sabre_DAV_INode
      */
diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php
old mode 100755
new mode 100644
index 478f822ae712a8d4b438f61e827de6d2f84c8f9e..1eca8986a5cdd9714da513addabf7315901968f5
--- a/3rdparty/Sabre/DAV/IFile.php
+++ b/3rdparty/Sabre/DAV/IFile.php
@@ -51,7 +51,7 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode {
      *
      * If null is returned, we'll assume application/octet-stream
      *
-     * @return void
+     * @return string|null
      */
     function getContentType();
 
diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php
old mode 100755
new mode 100644
index 035b3a6386306c7721bec88301571293b7ac7b16..957ac506a9c1bb9baf96e2689fae69ea17ca50b1
--- a/3rdparty/Sabre/DAV/Locks/Plugin.php
+++ b/3rdparty/Sabre/DAV/Locks/Plugin.php
@@ -152,6 +152,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
             case 'MKCOL' :
             case 'PROPPATCH' :
             case 'PUT' :
+            case 'PATCH' :
                 $lastLock = null;
                 if (!$this->validateLock($uri,$lastLock))
                     throw new Sabre_DAV_Exception_Locked($lastLock);
diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php
old mode 100755
new mode 100644
index 070b7176afdf6ea09e47ba2c2084799028656d79..3b95dfec2fa2dc43865e50a795882658e8222c1a
--- a/3rdparty/Sabre/DAV/Node.php
+++ b/3rdparty/Sabre/DAV/Node.php
@@ -27,7 +27,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
     }
 
     /**
-     * Deleted the current node
+     * Deletes the current node
      *
      * @throws Sabre_DAV_Exception_Forbidden
      * @return void
diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php
old mode 100755
new mode 100644
index bce5146390026a417230243fc94be0299db93a6d..3b7f222d64b1c217c57f2993697e944cdfa009ca
--- a/3rdparty/Sabre/DAV/ObjectTree.php
+++ b/3rdparty/Sabre/DAV/ObjectTree.php
@@ -51,24 +51,30 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
         $path = trim($path,'/');
         if (isset($this->cache[$path])) return $this->cache[$path];
 
-        //if (!$path || $path=='.') return $this->rootNode;
-        $currentNode = $this->rootNode;
+        // Is it the root node?
+        if (!strlen($path)) {
+            return $this->rootNode;
+        }
 
-        // We're splitting up the path variable into folder/subfolder components and traverse to the correct node..
-        foreach(explode('/',$path) as $pathPart) {
+        // Attempting to fetch its parent
+        list($parentName, $baseName) = Sabre_DAV_URLUtil::splitPath($path);
 
-            // If this part of the path is just a dot, it actually means we can skip it
-            if ($pathPart=='.' || $pathPart=='') continue;
+        // If there was no parent, we must simply ask it from the root node.
+        if ($parentName==="") {
+            $node = $this->rootNode->getChild($baseName);
+        } else {
+            // Otherwise, we recursively grab the parent and ask him/her.
+            $parent = $this->getNodeForPath($parentName);
 
-            if (!($currentNode instanceof Sabre_DAV_ICollection))
+            if (!($parent instanceof Sabre_DAV_ICollection))
                 throw new Sabre_DAV_Exception_NotFound('Could not find node at path: ' . $path);
 
-            $currentNode = $currentNode->getChild($pathPart);
+            $node = $parent->getChild($baseName);
 
         }
 
-        $this->cache[$path] = $currentNode;
-        return $currentNode;
+        $this->cache[$path] = $node;
+        return $node;
 
     }
 
diff --git a/3rdparty/Sabre/DAV/PartialUpdate/IFile.php b/3rdparty/Sabre/DAV/PartialUpdate/IFile.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf5ad55c6dec3566b8e63a7ba769169d453b0c2e
--- /dev/null
+++ b/3rdparty/Sabre/DAV/PartialUpdate/IFile.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * This interface provides a way to modify only part of a target resource
+ * It may be used to update a file chunk, upload big a file into smaller
+ * chunks or resume an upload
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_DAV_PartialUpdate_IFile extends Sabre_DAV_IFile {
+
+    /**
+     * Updates the data at a given offset
+     *
+     * The data argument is a readable stream resource.
+     * The offset argument is an integer describing the offset. Contrary to
+     * what's sent in the request, the offset here is a 0-based index.
+     *
+     * After a successful put operation, you may choose to return an ETag. The
+     * etag must always be surrounded by double-quotes. These quotes must
+     * appear in the actual string you're returning.
+     *
+     * Clients may use the ETag from a PUT request to later on make sure that
+     * when they update the file, the contents haven't changed in the mean
+     * time.
+     *
+     * @param resource $data
+     * @param integer $offset
+     * @return string|null
+     */
+    function putRange($data, $offset);
+
+}
+
diff --git a/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php b/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..170acbc9785132db3098179d5ed3241c0b60c4ad
--- /dev/null
+++ b/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Partial update plugin (Patch method)
+ *
+ * This plugin provides a way to modify only part of a target resource
+ * It may bu used to update a file chunk, upload big a file into smaller
+ * chunks or resume an upload.
+ *
+ * $patchPlugin = new Sabre_DAV_Patch_Plugin();
+ * $server->addPlugin($patchPlugin);
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_DAV_PartialUpdate_Plugin extends Sabre_DAV_ServerPlugin {
+
+    /**
+     * Reference to server
+     *
+     * @var Sabre_DAV_Server
+     */
+    protected $server;
+
+    /**
+     * Initializes the plugin
+     *
+     * This method is automatically called by the Server class after addPlugin.
+     *
+     * @param Sabre_DAV_Server $server
+     * @return void
+     */
+    public function initialize(Sabre_DAV_Server $server) {
+
+        $this->server = $server;
+        $server->subscribeEvent('unknownMethod',array($this,'unknownMethod'));
+
+    }
+
+    /**
+     * Returns a plugin name.
+     *
+     * Using this name other plugins will be able to access other plugins
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
+     */
+    public function getPluginName() {
+
+        return 'partialupdate';
+
+    }
+
+    /**
+     * This method is called by the Server if the user used an HTTP method
+     * the server didn't recognize.
+     *
+     * This plugin intercepts the PATCH methods.
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool|null
+     */
+    public function unknownMethod($method, $uri) {
+
+        switch($method) {
+            
+            case 'PATCH':
+                return $this->httpPatch($uri);
+
+        }
+
+    }
+
+    /**
+     * Use this method to tell the server this plugin defines additional
+     * HTTP methods.
+     *
+     * This method is passed a uri. It should only return HTTP methods that are
+     * available for the specified uri.
+     * 
+     * We claim to support PATCH method (partial update) if and only if
+     *     - the node exist
+     *     - the node implements our partial update interface
+     *
+     * @param string $uri
+     * @return array
+     */
+    public function getHTTPMethods($uri) {
+        
+        $tree = $this->server->tree;
+        
+        if ($tree->nodeExists($uri) && 
+            $tree->getNodeForPath($uri) instanceof Sabre_DAV_PartialUpdate_IFile) {
+            return array('PATCH');
+         }
+         
+         return array();
+
+    }
+
+    /**
+     * Returns a list of features for the HTTP OPTIONS Dav: header.
+     *
+     * @return array
+     */
+    public function getFeatures() {
+
+        return array('sabredav-partialupdate');
+
+    }
+
+    /**
+     * Patch an uri
+     *
+     * The WebDAV patch request can be used to modify only a part of an 
+     * existing resource. If the resource does not exist yet and the first
+     * offset is not 0, the request fails
+     *
+     * @param string $uri
+     * @return void
+     */
+    protected function httpPatch($uri) {
+
+        // Get the node. Will throw a 404 if not found
+        $node = $this->server->tree->getNodeForPath($uri);
+        if (!($node instanceof Sabre_DAV_PartialUpdate_IFile)) {
+            throw new Sabre_DAV_Exception_MethodNotAllowed('The target resource does not support the PATCH method.');
+        }
+
+        $range = $this->getHTTPUpdateRange();
+
+        if (!$range) {
+            throw new Sabre_DAV_Exception_BadRequest('No valid "X-Update-Range" found in the headers');
+        }
+        
+        $contentType = strtolower(
+            $this->server->httpRequest->getHeader('Content-Type')
+        );
+        
+        if ($contentType != 'application/x-sabredav-partialupdate') {
+            throw new Sabre_DAV_Exception_UnsupportedMediaType('Unknown Content-Type header "' . $contentType . '"');
+        }
+
+        $len = $this->server->httpRequest->getHeader('Content-Length');
+
+        // Load the begin and end data
+        $start = ($range[0])?$range[0]:0;
+        $end   = ($range[1])?$range[1]:$len-1;
+
+        // Check consistency
+        if($end < $start)
+            throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')');
+        if($end - $start + 1 != $len)
+            throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('Actual data length (' . $len . ') is not consistent with begin (' . $range[0] . ') and end (' . $range[1] . ') offsets');
+
+        // Checking If-None-Match and related headers.
+        if (!$this->server->checkPreconditions()) return;
+
+        if (!$this->server->broadcastEvent('beforeWriteContent',array($uri, $node, null)))
+            return;
+
+        $body = $this->server->httpRequest->getBody();
+        $etag = $node->putRange($body, $start-1);
+
+        $this->server->broadcastEvent('afterWriteContent',array($uri, $node));
+
+        $this->server->httpResponse->setHeader('Content-Length','0');
+        if ($etag) $this->server->httpResponse->setHeader('ETag',$etag);
+        $this->server->httpResponse->sendStatus(204);
+
+        return false;
+
+    }
+    
+   /**
+     * Returns the HTTP custom range update header
+     *
+     * This method returns null if there is no well-formed HTTP range request
+     * header or array($start, $end).
+     *
+     * The first number is the offset of the first byte in the range.
+     * The second number is the offset of the last byte in the range.
+     *
+     * If the second offset is null, it should be treated as the offset of the last byte of the entity
+     * If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity
+     *
+     * @return array|null
+     */
+    public function getHTTPUpdateRange() {
+
+        $range = $this->server->httpRequest->getHeader('X-Update-Range');
+        if (is_null($range)) return null;
+
+        // Matching "Range: bytes=1234-5678: both numbers are optional
+
+        if (!preg_match('/^bytes=([0-9]*)-([0-9]*)$/i',$range,$matches)) return null;
+
+        if ($matches[1]==='' && $matches[2]==='') return null;
+
+        return array(
+            $matches[1]!==''?$matches[1]:null,
+            $matches[2]!==''?$matches[2]:null,
+        );
+
+    }
+}
diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php
old mode 100755
new mode 100644
index 1cfada3236c5500a64e4c343d0437db7f22dbb76..6487bf44bc4eafc66be4b470735923c9dd5643a3
--- a/3rdparty/Sabre/DAV/Property.php
+++ b/3rdparty/Sabre/DAV/Property.php
@@ -11,10 +11,16 @@
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-abstract class Sabre_DAV_Property {
-
-    abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop);
+abstract class Sabre_DAV_Property implements Sabre_DAV_PropertyInterface {
 
+    /**
+     * Unserializes the property.
+     *
+     * This static method should return a an instance of this object.
+     *
+     * @param DOMElement $prop
+     * @return Sabre_DAV_IProperty
+     */
     static function unserialize(DOMElement $prop) {
 
         throw new Sabre_DAV_Exception('Unserialize has not been implemented for this class');
diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php
old mode 100755
new mode 100644
index dac564f24d70745d18f88970fc494267bb9081c7..cd1d867f71b3f03afc7b2af77c736df136024ad8
--- a/3rdparty/Sabre/DAV/Property/Href.php
+++ b/3rdparty/Sabre/DAV/Property/Href.php
@@ -82,7 +82,7 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
      */
     static function unserialize(DOMElement $dom) {
 
-        if (Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)==='{DAV:}href') {
+        if ($dom->firstChild && Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)==='{DAV:}href') {
             return new self($dom->firstChild->textContent,false);
         }
 
diff --git a/3rdparty/Sabre/DAV/Property/HrefList.php b/3rdparty/Sabre/DAV/Property/HrefList.php
old mode 100755
new mode 100644
index 7a52272e8859fe9c6e17fb71a590c4678d6a4525..282c452ca0b5e71d9ef8804a80ba25f45d4aa2d8
--- a/3rdparty/Sabre/DAV/Property/HrefList.php
+++ b/3rdparty/Sabre/DAV/Property/HrefList.php
@@ -79,7 +79,7 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
      * It will only decode {DAV:}href values.
      *
      * @param DOMElement $dom
-     * @return Sabre_DAV_Property_Href
+     * @return Sabre_DAV_Property_HrefList
      */
     static function unserialize(DOMElement $dom) {
 
diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php
old mode 100755
new mode 100644
index 88afbcfb26d4e6d8b96f27e6b6e6d2978e81ed3d..9f21163d12ef0fce55b021c7279b5e3d6d6aec4e
--- a/3rdparty/Sabre/DAV/Property/Response.php
+++ b/3rdparty/Sabre/DAV/Property/Response.php
@@ -138,7 +138,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
                 if (is_scalar($propertyValue)) {
                     $text = $document->createTextNode($propertyValue);
                     $currentProperty->appendChild($text);
-                } elseif ($propertyValue instanceof Sabre_DAV_Property) {
+                } elseif ($propertyValue instanceof Sabre_DAV_PropertyInterface) {
                     $propertyValue->serialize($server,$currentProperty);
                 } elseif (!is_null($propertyValue)) {
                     throw new Sabre_DAV_Exception('Unknown property value type: ' . gettype($propertyValue) . ' for property: ' . $propertyName);
diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/PropertyInterface.php b/3rdparty/Sabre/DAV/PropertyInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..515072cbd35f8074a3d790c037c99c25b253819a
--- /dev/null
+++ b/3rdparty/Sabre/DAV/PropertyInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * PropertyInterface
+ *
+ * Implement this interface to create new complex properties
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_DAV_PropertyInterface {
+
+    public function serialize(Sabre_DAV_Server $server, DOMElement $prop);
+
+    static function unserialize(DOMElement $prop); 
+
+}
+
diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php
old mode 100755
new mode 100644
index 0dfac8b0c711fdb8f7b8e60e2d89c23389aa976f..cf6f87e68abcfd02029c8d860b32f25627d17069
--- a/3rdparty/Sabre/DAV/Server.php
+++ b/3rdparty/Sabre/DAV/Server.php
@@ -12,7 +12,7 @@
 class Sabre_DAV_Server {
 
     /**
-     * Inifinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree
+     * Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree
      */
     const DEPTH_INFINITY = -1;
 
@@ -102,7 +102,6 @@ class Sabre_DAV_Server {
         '{DAV:}getetag',
         '{DAV:}getlastmodified',
         '{DAV:}lockdiscovery',
-        '{DAV:}resourcetype',
         '{DAV:}supportedlock',
 
         // RFC4331
@@ -162,7 +161,7 @@ class Sabre_DAV_Server {
      * If an array is passed, we automatically create a root node, and use
      * the nodes in the array as top-level children.
      *
-     * @param Sabre_DAV_Tree|Sabre_DAV_INode|null $treeOrNode The tree object
+     * @param Sabre_DAV_Tree|Sabre_DAV_INode|array|null $treeOrNode The tree object
      */
     public function __construct($treeOrNode = null) {
 
@@ -207,6 +206,10 @@ class Sabre_DAV_Server {
 
         } catch (Exception $e) {
 
+            try {
+                $this->broadcastEvent('exception', array($e));
+            } catch (Exception $ignore) {
+            }
             $DOM = new DOMDocument('1.0','utf-8');
             $DOM->formatOutput = true;
 
@@ -214,17 +217,23 @@ class Sabre_DAV_Server {
             $error->setAttribute('xmlns:s',self::NS_SABREDAV);
             $DOM->appendChild($error);
 
-            $error->appendChild($DOM->createElement('s:exception',get_class($e)));
-            $error->appendChild($DOM->createElement('s:message',$e->getMessage()));
+            $h = function($v) {
+
+                return htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8');
+
+            };
+
+            $error->appendChild($DOM->createElement('s:exception',$h(get_class($e))));
+            $error->appendChild($DOM->createElement('s:message',$h($e->getMessage())));
             if ($this->debugExceptions) {
-                $error->appendChild($DOM->createElement('s:file',$e->getFile()));
-                $error->appendChild($DOM->createElement('s:line',$e->getLine()));
-                $error->appendChild($DOM->createElement('s:code',$e->getCode()));
-                $error->appendChild($DOM->createElement('s:stacktrace',$e->getTraceAsString()));
+                $error->appendChild($DOM->createElement('s:file',$h($e->getFile())));
+                $error->appendChild($DOM->createElement('s:line',$h($e->getLine())));
+                $error->appendChild($DOM->createElement('s:code',$h($e->getCode())));
+                $error->appendChild($DOM->createElement('s:stacktrace',$h($e->getTraceAsString())));
 
             }
             if (self::$exposeVersion) {
-                $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION));
+                $error->appendChild($DOM->createElement('s:sabredav-version',$h(Sabre_DAV_Version::VERSION)));
             }
 
             if($e instanceof Sabre_DAV_Exception) {
@@ -508,7 +517,7 @@ class Sabre_DAV_Server {
 
         if (!$this->checkPreconditions(true)) return false;
 
-        if (!($node instanceof Sabre_DAV_IFile)) throw new Sabre_DAV_Exception_NotImplemented('GET is only implemented on File objects');
+        if (!$node instanceof Sabre_DAV_IFile) throw new Sabre_DAV_Exception_NotImplemented('GET is only implemented on File objects');
         $body = $node->get();
 
         // Converting string into stream, if needed.
@@ -696,6 +705,7 @@ class Sabre_DAV_Server {
         // This is a multi-status response
         $this->httpResponse->sendStatus(207);
         $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
+        $this->httpResponse->setHeader('Vary','Brief,Prefer');
 
         // Normally this header is only needed for OPTIONS responses, however..
         // iCal seems to also depend on these being set for PROPFIND. Since
@@ -704,7 +714,10 @@ class Sabre_DAV_Server {
         foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures());
         $this->httpResponse->setHeader('DAV',implode(', ',$features));
 
-        $data = $this->generateMultiStatus($newProperties);
+        $prefer = $this->getHTTPPrefer();
+        $minimal = $prefer['return-minimal'];
+
+        $data = $this->generateMultiStatus($newProperties, $minimal);
         $this->httpResponse->sendBody($data);
 
     }
@@ -724,6 +737,30 @@ class Sabre_DAV_Server {
 
         $result = $this->updateProperties($uri, $newProperties);
 
+        $prefer = $this->getHTTPPrefer();
+        $this->httpResponse->setHeader('Vary','Brief,Prefer');
+
+        if ($prefer['return-minimal']) {
+
+            // If return-minimal is specified, we only have to check if the
+            // request was succesful, and don't need to return the
+            // multi-status.
+            $ok = true;
+            foreach($result as $code=>$prop) {
+                if ((int)$code > 299) {
+                    $ok = false;
+                }
+            }
+
+            if ($ok) {
+
+                $this->httpResponse->sendStatus(204);
+                return;
+
+            }
+
+        }
+
         $this->httpResponse->sendStatus(207);
         $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
 
@@ -927,7 +964,7 @@ class Sabre_DAV_Server {
      * This method moves one uri to a different uri. A lot of the actual request processing is done in getCopyMoveInfo
      *
      * @param string $uri
-     * @return void
+     * @return bool
      */
     protected function httpMove($uri) {
 
@@ -1009,7 +1046,7 @@ class Sabre_DAV_Server {
         if ($this->broadcastEvent('report',array($reportName,$dom, $uri))) {
 
             // If broadcastEvent returned true, it means the report was not supported
-            throw new Sabre_DAV_Exception_ReportNotImplemented();
+            throw new Sabre_DAV_Exception_ReportNotSupported();
 
         }
 
@@ -1158,6 +1195,85 @@ class Sabre_DAV_Server {
 
     }
 
+    /**
+     * Returns the HTTP Prefer header information.
+     *
+     * The prefer header is defined in:
+     * http://tools.ietf.org/html/draft-snell-http-prefer-14
+     *
+     * This method will return an array with options.
+     *
+     * Currently, the following options may be returned:
+     *   array(
+     *      'return-asynch'         => true,
+     *      'return-minimal'        => true,
+     *      'return-representation' => true,
+     *      'wait'                  => 30,
+     *      'strict'                => true,
+     *      'lenient'               => true,
+     *   )
+     *
+     * This method also supports the Brief header, and will also return
+     * 'return-minimal' if the brief header was set to 't'.
+     *
+     * For the boolean options, false will be returned if the headers are not
+     * specified. For the integer options it will be 'null'.
+     *
+     * @return array
+     */
+    public function getHTTPPrefer() {
+
+        $result = array(
+            'return-asynch'         => false,
+            'return-minimal'        => false,
+            'return-representation' => false,
+            'wait'                  => null,
+            'strict'                => false,
+            'lenient'               => false,
+        );
+
+        if ($prefer = $this->httpRequest->getHeader('Prefer')) {
+
+            $parameters = array_map('trim',
+                explode(',', $prefer)
+            );
+
+            foreach($parameters as $parameter) {
+
+                // Right now our regex only supports the tokens actually
+                // specified in the draft. We may need to expand this if new
+                // tokens get registered.
+                if(!preg_match('/^(?P<token>[a-z0-9-]+)(?:=(?P<value>[0-9]+))?$/', $parameter, $matches)) {
+                    continue;
+                }
+
+                switch($matches['token']) {
+
+                    case 'return-asynch' :
+                    case 'return-minimal' :
+                    case 'return-representation' :
+                    case 'strict' :
+                    case 'lenient' :
+                        $result[$matches['token']] = true;
+                        break;
+                    case 'wait' :
+                        $result[$matches['token']] = $matches['value'];
+                        break;
+
+                }
+
+            }
+
+        }
+
+        if ($this->httpRequest->getHeader('Brief')=='t') {
+            $result['return-minimal'] = true;
+        }
+
+        return $result;
+
+    }
+
 
     /**
      * Returns information about Copy and Move requests
@@ -1433,15 +1549,18 @@ class Sabre_DAV_Server {
 
             }
 
-            $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties));
+            $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties, $node));
 
             $newProperties['href'] = trim($myPath,'/');
 
             // Its is a WebDAV recommendation to add a trailing slash to collectionnames.
-            // Apple's iCal also requires a trailing slash for principals (rfc 3744).
-            // Therefore we add a trailing / for any non-file. This might need adjustments
-            // if we find there are other edge cases.
-            if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype']) && count($newProperties[200]['{DAV:}resourcetype']->getValue())>0) $newProperties['href'] .='/';
+            // Apple's iCal also requires a trailing slash for principals (rfc 3744), though this is non-standard.
+            if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype'])) {
+                $rt = $newProperties[200]['{DAV:}resourcetype'];
+                if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) {
+                    $newProperties['href'] .='/';
+                }
+            }
 
             // If the resourcetype property was manually added to the requested property list,
             // we will remove it again.
@@ -1476,11 +1595,14 @@ class Sabre_DAV_Server {
         if (!$this->broadcastEvent('beforeBind',array($uri))) return false;
 
         $parent = $this->tree->getNodeForPath($dir);
+        if (!$parent instanceof Sabre_DAV_ICollection) {
+            throw new Sabre_DAV_Exception_Conflict('Files can only be created as children of collections');
+        }
 
         if (!$this->broadcastEvent('beforeCreateFile',array($uri, &$data, $parent))) return false;
 
         $etag = $parent->createFile($name,$data);
-        $this->tree->markDirty($dir);
+        $this->tree->markDirty($dir . '/' . $name);
 
         $this->broadcastEvent('afterBind',array($uri));
         $this->broadcastEvent('afterCreateFile',array($uri, $parent));
@@ -1901,12 +2023,15 @@ class Sabre_DAV_Server {
 
 
     /**
-     * Generates a WebDAV propfind response body based on a list of nodes
+     * Generates a WebDAV propfind response body based on a list of nodes.
+     *
+     * If 'strip404s' is set to true, all 404 responses will be removed.
      *
      * @param array $fileProperties The list with nodes
+     * @param bool strip404s
      * @return string
      */
-    public function generateMultiStatus(array $fileProperties) {
+    public function generateMultiStatus(array $fileProperties, $strip404s = false) {
 
         $dom = new DOMDocument('1.0','utf-8');
         //$dom->formatOutput = true;
@@ -1925,6 +2050,10 @@ class Sabre_DAV_Server {
             $href = $entry['href'];
             unset($entry['href']);
 
+            if ($strip404s && isset($entry[404])) {
+                unset($entry[404]);
+            }
+
             $response = new Sabre_DAV_Property_Response($href,$entry);
             $response->serialize($this,$multiStatus);
 
@@ -1995,7 +2124,7 @@ class Sabre_DAV_Server {
         if (!$body) return array();
 
         $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
-        $elem = $dom->getElementsByTagNameNS('urn:DAV','propfind')->item(0);
+        $elem = $dom->getElementsByTagNameNS('DAV:','propfind')->item(0);
         return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem));
 
     }
diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php
old mode 100755
new mode 100644
index 131863d13fbf3a9823282d0b9aebb5b7c4e9a760..120569ffccd3ae937f3102ef8c50762554ecdbd7
--- a/3rdparty/Sabre/DAV/ServerPlugin.php
+++ b/3rdparty/Sabre/DAV/ServerPlugin.php
@@ -19,7 +19,7 @@ abstract class Sabre_DAV_ServerPlugin {
      * This function is called by Sabre_DAV_Server, after
      * addPlugin is called.
      *
-     * This method should set up the requires event subscriptions.
+     * This method should set up the required event subscriptions.
      *
      * @param Sabre_DAV_Server $server
      * @return void
diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php
old mode 100755
new mode 100644
index 4acf971caa5c457905b0a02a65bb524e12b59a60..79e2eaaacd4af4bc1dcccd6a91121f50ae14d42f
--- a/3rdparty/Sabre/DAV/SimpleCollection.php
+++ b/3rdparty/Sabre/DAV/SimpleCollection.php
@@ -31,7 +31,7 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
     /**
      * Creates this node
      *
-     * The name of the node must be passed, child nodes can also be bassed.
+     * The name of the node must be passed, child nodes can also be passed.
      * This nodes must be instances of Sabre_DAV_INode
      *
      * @param string $name
@@ -78,6 +78,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
      * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
      * Generally its wise to override this, as this can usually be optimized
      *
+     * This method must throw Sabre_DAV_Exception_NotFound if the node does not
+     * exist.
+     *
      * @param string $name
      * @throws Sabre_DAV_Exception_NotFound
      * @return Sabre_DAV_INode
diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php
deleted file mode 100755
index 621222ebc53a6dbfc4e3b89f1b58288cee7652bc..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/DAV/SimpleDirectory.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-/**
- * SimpleDirectory
- *
- * The SimpleDirectory is used to quickly setup static directory structures.
- * Just create the object with a proper name, and add children to use it.
- *
- * This class is now deprecated, use Sabre_DAV_SimpleCollection instead.
- *
- * @package Sabre
- * @subpackage DAV
- * @deprecated Use Sabre_DAV_SimpleCollection instead.
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Sabre_DAV_SimpleDirectory extends Sabre_DAV_SimpleCollection {
-
-}
-
diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php
old mode 100755
new mode 100644
index 274646240ab9cbd8fb2137e989b9d305a12f4373..55611cf214859ad7f22c8dabe0cc1dffb88491e1
--- a/3rdparty/Sabre/DAV/Version.php
+++ b/3rdparty/Sabre/DAV/Version.php
@@ -14,7 +14,7 @@ class Sabre_DAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.6.4';
+    const VERSION = '1.7.1';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php
old mode 100755
new mode 100644
index 60eff3b159ac15bf34a4f09fd0f2d7a721542785..712fa3fc014f37d43c028cba7d6d69b1d8a0f4e3
--- a/3rdparty/Sabre/DAV/XMLUtil.php
+++ b/3rdparty/Sabre/DAV/XMLUtil.php
@@ -20,9 +20,6 @@ class Sabre_DAV_XMLUtil {
      * {http://www.example.org}myelem
      *
      * This format is used throughout the SabreDAV sourcecode.
-     * Elements encoded with the urn:DAV namespace will
-     * be returned as if they were in the DAV: namespace. This is to avoid
-     * compatibility problems.
      *
      * This function will return null if a nodetype other than an Element is passed.
      *
@@ -33,8 +30,7 @@ class Sabre_DAV_XMLUtil {
 
         if ($dom->nodeType !== XML_ELEMENT_NODE) return null;
 
-        // Mapping back to the real namespace, in case it was dav
-        if ($dom->namespaceURI=='urn:DAV') $ns = 'DAV:'; else $ns = $dom->namespaceURI;
+        $ns = $dom->namespaceURI;
 
         // Mapping to clark notation
         return '{' . $ns . '}' . $dom->localName;
@@ -64,29 +60,11 @@ class Sabre_DAV_XMLUtil {
 
     }
 
-    /**
-     * This method takes an XML document (as string) and converts all instances of the
-     * DAV: namespace to urn:DAV
-     *
-     * This is unfortunately needed, because the DAV: namespace violates the xml namespaces
-     * spec, and causes the DOM to throw errors
-     *
-     * @param string $xmlDocument
-     * @return array|string|null
-     */
-    static function convertDAVNamespace($xmlDocument) {
-
-        // This is used to map the DAV: namespace to urn:DAV. This is needed, because the DAV:
-        // namespace is actually a violation of the XML namespaces specification, and will cause errors
-        return preg_replace("/xmlns(:[A-Za-z0-9_]*)?=(\"|\')DAV:(\\2)/","xmlns\\1=\\2urn:DAV\\2",$xmlDocument);
-
-    }
-
     /**
      * This method provides a generic way to load a DOMDocument for WebDAV use.
      *
      * This method throws a Sabre_DAV_Exception_BadRequest exception for any xml errors.
-     * It does not preserve whitespace, and it converts the DAV: namespace to urn:DAV.
+     * It does not preserve whitespace.
      *
      * @param string $xml
      * @throws Sabre_DAV_Exception_BadRequest
@@ -118,10 +96,11 @@ class Sabre_DAV_XMLUtil {
         libxml_clear_errors();
 
         $dom = new DOMDocument();
-        $dom->loadXML(self::convertDAVNamespace($xml),LIBXML_NOWARNING | LIBXML_NOERROR);
 
         // We don't generally care about any whitespace
         $dom->preserveWhiteSpace = false;
+        
+        $dom->loadXML($xml,LIBXML_NOWARNING | LIBXML_NOERROR);
 
         if ($error = libxml_get_last_error()) {
             libxml_clear_errors();
diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php
old mode 100755
new mode 100644
index 6a4890677ea2bdad500410eae9e47ee89f6b914e..6728f88ce7692a60912dbed6fb02636f8d753e30
--- a/3rdparty/Sabre/DAV/includes.php
+++ b/3rdparty/Sabre/DAV/includes.php
@@ -28,7 +28,7 @@ include __DIR__ . '/Locks/Backend/PDO.php';
 include __DIR__ . '/Locks/LockInfo.php';
 include __DIR__ . '/Node.php';
 include __DIR__ . '/Property/IHref.php';
-include __DIR__ . '/Property.php';
+include __DIR__ . '/PropertyInterface.php';
 include __DIR__ . '/Server.php';
 include __DIR__ . '/ServerPlugin.php';
 include __DIR__ . '/StringUtil.php';
@@ -60,7 +60,7 @@ include __DIR__ . '/Exception/NotFound.php';
 include __DIR__ . '/Exception/NotImplemented.php';
 include __DIR__ . '/Exception/PaymentRequired.php';
 include __DIR__ . '/Exception/PreconditionFailed.php';
-include __DIR__ . '/Exception/ReportNotImplemented.php';
+include __DIR__ . '/Exception/ReportNotSupported.php';
 include __DIR__ . '/Exception/RequestedRangeNotSatisfiable.php';
 include __DIR__ . '/Exception/UnsupportedMediaType.php';
 include __DIR__ . '/FS/Node.php';
@@ -72,18 +72,11 @@ include __DIR__ . '/IQuota.php';
 include __DIR__ . '/Locks/Plugin.php';
 include __DIR__ . '/Mount/Plugin.php';
 include __DIR__ . '/ObjectTree.php';
-include __DIR__ . '/Property/GetLastModified.php';
-include __DIR__ . '/Property/Href.php';
-include __DIR__ . '/Property/HrefList.php';
-include __DIR__ . '/Property/LockDiscovery.php';
-include __DIR__ . '/Property/ResourceType.php';
-include __DIR__ . '/Property/Response.php';
-include __DIR__ . '/Property/ResponseList.php';
-include __DIR__ . '/Property/SupportedLock.php';
-include __DIR__ . '/Property/SupportedReportSet.php';
+include __DIR__ . '/PartialUpdate/IFile.php';
+include __DIR__ . '/PartialUpdate/Plugin.php';
+include __DIR__ . '/Property.php';
 include __DIR__ . '/Tree/Filesystem.php';
 include __DIR__ . '/Collection.php';
-include __DIR__ . '/Directory.php';
 include __DIR__ . '/Exception/ConflictingLock.php';
 include __DIR__ . '/Exception/FileNotFound.php';
 include __DIR__ . '/File.php';
@@ -91,7 +84,15 @@ include __DIR__ . '/FS/Directory.php';
 include __DIR__ . '/FS/File.php';
 include __DIR__ . '/FSExt/Directory.php';
 include __DIR__ . '/FSExt/File.php';
+include __DIR__ . '/Property/GetLastModified.php';
+include __DIR__ . '/Property/Href.php';
+include __DIR__ . '/Property/HrefList.php';
+include __DIR__ . '/Property/LockDiscovery.php';
+include __DIR__ . '/Property/ResourceType.php';
+include __DIR__ . '/Property/Response.php';
+include __DIR__ . '/Property/ResponseList.php';
+include __DIR__ . '/Property/SupportedLock.php';
+include __DIR__ . '/Property/SupportedReportSet.php';
 include __DIR__ . '/SimpleCollection.php';
-include __DIR__ . '/SimpleDirectory.php';
 include __DIR__ . '/SimpleFile.php';
 // End includes
diff --git a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
old mode 100755
new mode 100644
index e05b7749805c8cc40306f527f54734b72d17f830..f67eadad6e9d0f6aeca91fe2abf95a787196658d
--- a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
@@ -107,7 +107,7 @@ abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collec
      *
      * @param string $name
      * @throws Sabre_DAV_Exception_NotFound
-     * @return Sabre_DAV_IPrincipal
+     * @return Sabre_DAVACL_IPrincipal
      */
     public function getChild($name) {
 
diff --git a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/IACL.php b/3rdparty/Sabre/DAVACL/IACL.php
old mode 100755
new mode 100644
index 003e69934834a3b4ef0780b51c723ab486120d40..356bb481d55d96127d430e7c03c74cbafa4d5e91
--- a/3rdparty/Sabre/DAVACL/IACL.php
+++ b/3rdparty/Sabre/DAVACL/IACL.php
@@ -48,7 +48,7 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's.
+     * This method will receive a list of new ACE's as an array argument.
      *
      * @param array $acl
      * @return void
diff --git a/3rdparty/Sabre/DAVACL/IPrincipal.php b/3rdparty/Sabre/DAVACL/IPrincipal.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Plugin.php b/3rdparty/Sabre/DAVACL/Plugin.php
old mode 100755
new mode 100644
index 5c828c6d97be4f0cfc1273303daacc2284c432b6..5b17c8384756a093f184dd68e8e2d290354aba4e
--- a/3rdparty/Sabre/DAVACL/Plugin.php
+++ b/3rdparty/Sabre/DAVACL/Plugin.php
@@ -3,7 +3,7 @@
 /**
  * SabreDAV ACL Plugin
  *
- * This plugin provides funcitonality to enforce ACL permissions.
+ * This plugin provides functionality to enforce ACL permissions.
  * ACL is defined in RFC3744.
  *
  * In addition it also provides support for the {DAV:}current-user-principal
@@ -102,11 +102,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     );
 
     /**
-     * Any principal uri's added here, will automatically be added to the list 
-     * of ACL's. They will effectively receive {DAV:}all privileges, as a 
+     * Any principal uri's added here, will automatically be added to the list
+     * of ACL's. They will effectively receive {DAV:}all privileges, as a
      * protected privilege.
-     * 
-     * @var array 
+     *
+     * @var array
      */
     public $adminPrincipals = array();
 
@@ -233,6 +233,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         $authPlugin = $this->server->getPlugin('auth');
         if (is_null($authPlugin)) return null;
+        /** @var $authPlugin Sabre_DAV_Auth_Plugin */
 
         $userName = $authPlugin->getCurrentUser();
         if (!$userName) return null;
@@ -241,6 +242,14 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
     }
 
+    /**
+     * This array holds a cache for all the principals that are associated with
+     * a single principal.
+     *
+     * @var array
+     */
+    protected $currentUserPrincipalsCache = array();
+
     /**
      * Returns a list of principals that's associated to the current
      * user, either directly or through group membership.
@@ -253,6 +262,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         if (is_null($currentUser)) return array();
 
+        // First check our cache
+        if (isset($this->currentUserPrincipalsCache[$currentUser])) {
+            return $this->currentUserPrincipalsCache[$currentUser];
+        }
+
         $check = array($currentUser);
         $principals = array($currentUser);
 
@@ -277,6 +291,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
+        // Store the result in the cache
+        $this->currentUserPrincipalsCache[$currentUser] = $principals;
+
         return $principals;
 
     }
@@ -771,7 +788,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * @param array $requestedProperties
      * @param array $returnedProperties
      * @TODO really should be broken into multiple methods, or even a class.
-     * @return void
+     * @return bool
      */
     public function beforeGetProperties($uri, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) {
 
@@ -895,6 +912,18 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             $returnedProperties[200]['{DAV:}acl-restrictions'] = new Sabre_DAVACL_Property_AclRestrictions();
         }
 
+        /* Adding ACL properties */
+        if ($node instanceof Sabre_DAVACL_IACL) {
+
+            if (false !== ($index = array_search('{DAV:}owner', $requestedProperties))) {
+
+                unset($requestedProperties[$index]);
+                $returnedProperties[200]['{DAV:}owner'] = new Sabre_DAV_Property_Href($node->getOwner() . '/');
+
+            }
+
+        }
+
     }
 
     /**
@@ -928,6 +957,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         }
 
         $node->setGroupMemberSet($memberSet);
+        // We must also clear our cache, just in case
+
+        $this->currentUserPrincipalsCache = array();
 
         $result[200]['{DAV:}group-member-set'] = null;
         unset($propertyDelta['{DAV:}group-member-set']);
@@ -935,7 +967,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This method handels HTTP REPORT requests
+     * This method handles HTTP REPORT requests
      *
      * @param string $reportName
      * @param DOMNode $dom
@@ -1268,10 +1300,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         }
         $result = $this->principalSearch($searchProperties, $requestedProperties, $uri);
 
-        $xml = $this->server->generateMultiStatus($result);
-        $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
+        $prefer = $this->server->getHTTPPRefer();
+
         $this->server->httpResponse->sendStatus(207);
-        $this->server->httpResponse->sendBody($xml);
+        $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
+        $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
+        $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 
     }
 
diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/PrincipalCollection.php b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Property/Acl.php b/3rdparty/Sabre/DAVACL/Property/Acl.php
old mode 100755
new mode 100644
index 05e1a690b3cb23c1fdb3ba05ce19b18aa41f9fd7..3f79a8d532e3a9419700c0f72bba37e94fe7e7e2
--- a/3rdparty/Sabre/DAVACL/Property/Acl.php
+++ b/3rdparty/Sabre/DAVACL/Property/Acl.php
@@ -88,11 +88,11 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
     static public function unserialize(DOMElement $dom) {
 
         $privileges = array();
-        $xaces = $dom->getElementsByTagNameNS('urn:DAV','ace');
+        $xaces = $dom->getElementsByTagNameNS('DAV:','ace');
         for($ii=0; $ii < $xaces->length; $ii++) {
 
             $xace = $xaces->item($ii);
-            $principal = $xace->getElementsByTagNameNS('urn:DAV','principal');
+            $principal = $xace->getElementsByTagNameNS('DAV:','principal');
             if ($principal->length !== 1) {
                 throw new Sabre_DAV_Exception_BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
             }
@@ -116,17 +116,17 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
 
             $protected = false;
 
-            if ($xace->getElementsByTagNameNS('urn:DAV','protected')->length > 0) {
+            if ($xace->getElementsByTagNameNS('DAV:','protected')->length > 0) {
                 $protected = true;
             }
 
-            $grants = $xace->getElementsByTagNameNS('urn:DAV','grant');
+            $grants = $xace->getElementsByTagNameNS('DAV:','grant');
             if ($grants->length < 1) {
                 throw new Sabre_DAV_Exception_NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
             }
             $grant = $grants->item(0);
 
-            $xprivs = $grant->getElementsByTagNameNS('urn:DAV','privilege');
+            $xprivs = $grant->getElementsByTagNameNS('DAV:','privilege');
             for($jj=0; $jj<$xprivs->length; $jj++) {
 
                 $xpriv = $xprivs->item($jj);
diff --git a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Property/Principal.php b/3rdparty/Sabre/DAVACL/Property/Principal.php
old mode 100755
new mode 100644
index c36328a58e0b877086d43bb34f02050f5a0a1c8e..3f6817422761522f90a87de1dc16e33b1cdb49cf
--- a/3rdparty/Sabre/DAVACL/Property/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Property/Principal.php
@@ -15,7 +15,7 @@
 class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
 
     /**
-     * To specify a not-logged-in user, use the UNAUTHENTICTED principal
+     * To specify a not-logged-in user, use the UNAUTHENTICATED principal
      */
     const UNAUTHENTICATED = 1;
 
@@ -131,7 +131,7 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
      * Deserializes a DOM element into a property object.
      *
      * @param DOMElement $dom
-     * @return Sabre_DAV_Property_Principal
+     * @return Sabre_DAVACL_Property_Principal
      */
     static public function unserialize(DOMElement $dom) {
 
diff --git a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php
old mode 100755
new mode 100644
index 9950f748741b150087c6504afb6a65df5a005aef..084a9c13c896d55bb0e6ef2db0eaed1507ef5071
--- a/3rdparty/Sabre/DAVACL/Version.php
+++ b/3rdparty/Sabre/DAVACL/Version.php
@@ -14,7 +14,7 @@ class Sabre_DAVACL_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.6.0';
+    const VERSION = '1.7.0';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAVACL/includes.php b/3rdparty/Sabre/DAVACL/includes.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/AWSAuth.php b/3rdparty/Sabre/HTTP/AWSAuth.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/AbstractAuth.php b/3rdparty/Sabre/HTTP/AbstractAuth.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/BasicAuth.php b/3rdparty/Sabre/HTTP/BasicAuth.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/DigestAuth.php b/3rdparty/Sabre/HTTP/DigestAuth.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/Request.php b/3rdparty/Sabre/HTTP/Request.php
old mode 100755
new mode 100644
index 4746ef777047e06b4b3c3ec0dd01267c749f7460..74d5ed3d7ee8d8977d8cbf80305bc78ffcec7c1f
--- a/3rdparty/Sabre/HTTP/Request.php
+++ b/3rdparty/Sabre/HTTP/Request.php
@@ -184,7 +184,7 @@ class Sabre_HTTP_Request {
      * This method returns a readable stream resource.
      * If the asString parameter is set to true, a string is sent instead.
      *
-     * @param bool asString
+     * @param bool $asString
      * @return resource
      */
     public function getBody($asString = false) {
diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php
old mode 100755
new mode 100644
index ffe9bda2082d5fd65395038fae36cfa179da0062..9d436881bdf307fc74af4af664c1365b877cde05
--- a/3rdparty/Sabre/HTTP/Response.php
+++ b/3rdparty/Sabre/HTTP/Response.php
@@ -4,7 +4,7 @@
  * Sabre_HTTP_Response
  *
  * @package Sabre
- * @subpackage HTTP 
+ * @subpackage HTTP
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
@@ -85,6 +85,9 @@ class Sabre_HTTP_Response {
 
     }
 
+    // @codeCoverageIgnoreStart
+    // We cannot reasonably test header() related methods.
+
     /**
      * Sends an HTTP status header to the client
      *
@@ -114,7 +117,9 @@ class Sabre_HTTP_Response {
             return header($name . ': ' . $value, $replace);
         else return false;
 
+
     }
+    // @codeCoverageIgnoreEnd
 
     /**
      * Sets a bunch of HTTP Headers
diff --git a/3rdparty/Sabre/HTTP/Util.php b/3rdparty/Sabre/HTTP/Util.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php
old mode 100755
new mode 100644
index e6b4f7e53589964fd2db22be2f43ad62d771689f..8ccd7c9edf6905b1519b75e85003c2a4a47aefdc
--- a/3rdparty/Sabre/HTTP/Version.php
+++ b/3rdparty/Sabre/HTTP/Version.php
@@ -14,7 +14,7 @@ class Sabre_HTTP_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.6.4';
+    const VERSION = '1.7.0';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/HTTP/includes.php b/3rdparty/Sabre/HTTP/includes.php
old mode 100755
new mode 100644
diff --git a/3rdparty/Sabre/VObject/Component.php b/3rdparty/Sabre/VObject/Component.php
old mode 100755
new mode 100644
index b78a26133fa19e1f9e9dc19c333b7744188da190..7604e3a9bb8487c14e6cb2c98738df74a2baaac7
--- a/3rdparty/Sabre/VObject/Component.php
+++ b/3rdparty/Sabre/VObject/Component.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * VObject Component
  *
@@ -7,13 +9,11 @@
  * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
  * ends with END:COMPONENTNAME
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component extends Sabre_VObject_Element {
+class Component extends Node {
 
     /**
      * Name, for example VEVENT
@@ -30,18 +30,20 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     public $children = array();
 
     /**
-     * If coponents are added to this map, they will be automatically mapped
+     * If components are added to this map, they will be automatically mapped
      * to their respective classes, if parsed by the reader or constructed with
      * the 'create' method.
      *
      * @var array
      */
     static public $classMap = array(
-        'VCALENDAR'     => 'Sabre_VObject_Component_VCalendar',
-        'VEVENT'        => 'Sabre_VObject_Component_VEvent',
-        'VTODO'         => 'Sabre_VObject_Component_VTodo',
-        'VJOURNAL'      => 'Sabre_VObject_Component_VJournal',
-        'VALARM'        => 'Sabre_VObject_Component_VAlarm',
+        'VALARM'        => 'Sabre\\VObject\\Component\\VAlarm',
+        'VCALENDAR'     => 'Sabre\\VObject\\Component\\VCalendar',
+        'VCARD'         => 'Sabre\\VObject\\Component\\VCard',
+        'VEVENT'        => 'Sabre\\VObject\\Component\\VEvent',
+        'VJOURNAL'      => 'Sabre\\VObject\\Component\\VJournal',
+        'VTODO'         => 'Sabre\\VObject\\Component\\VTodo',
+        'VFREEBUSY'     => 'Sabre\\VObject\\Component\\VFreeBusy',
     );
 
     /**
@@ -50,7 +52,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      *
      * @param string $name
      * @param string $value
-     * @return Sabre_VObject_Component
+     * @return Component
      */
     static public function create($name, $value = null) {
 
@@ -71,9 +73,9 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      * be overridden with the iterator argument
      *
      * @param string $name
-     * @param Sabre_VObject_ElementList $iterator
+     * @param ElementList $iterator
      */
-    public function __construct($name, Sabre_VObject_ElementList $iterator = null) {
+    public function __construct($name, ElementList $iterator = null) {
 
         $this->name = strtoupper($name);
         if (!is_null($iterator)) $this->iterator = $iterator;
@@ -94,40 +96,54 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
          *
          * This is solely used by the childrenSort method.
          *
-         * A higher score means the item will be higher in the list
+         * A higher score means the item will be lower in the list.
+         * To avoid score collisions, each "score category" has a reasonable
+         * space to accomodate elements. The $key is added to the $score to
+         * preserve the original relative order of elements.
          *
-         * @param Sabre_VObject_Node $n
+         * @param int $key
+         * @param array $array
          * @return int
          */
-        $sortScore = function($n) {
+        $sortScore = function($key, $array) {
+
+            if ($array[$key] instanceof Component) {
 
-            if ($n instanceof Sabre_VObject_Component) {
                 // We want to encode VTIMEZONE first, this is a personal
                 // preference.
-                if ($n->name === 'VTIMEZONE') {
-                    return 1;
+                if ($array[$key]->name === 'VTIMEZONE') {
+                    $score=300000000;
+                    return $score+$key;
                 } else {
-                    return 0;
+                    $score=400000000;
+                    return $score+$key;
                 }
             } else {
+                // Properties get encoded first
                 // VCARD version 4.0 wants the VERSION property to appear first
-                if ($n->name === 'VERSION') {
-                    return 3;
-                } else {
-                    return 2;
+                if ($array[$key] instanceof Property) {
+                    if ($array[$key]->name === 'VERSION') {
+                        $score=100000000;
+                        return $score+$key;
+                    } else {
+                        // All other properties
+                        $score=200000000;
+                        return $score+$key;
+                    }
                 }
             }
 
         };
 
-        usort($this->children, function($a, $b) use ($sortScore) {
+        $tmp = $this->children;
+        uksort($this->children, function($a, $b) use ($sortScore, $tmp) {
 
-            $sA = $sortScore($a);
-            $sB = $sortScore($b);
+            $sA = $sortScore($a, $tmp);
+            $sB = $sortScore($b, $tmp);
 
             if ($sA === $sB) return 0;
 
-            return ($sA > $sB) ? -1 : 1;
+            return ($sA < $sB) ? -1 : 1;
 
         });
 
@@ -143,8 +159,8 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      *
      * You can call this method with the following syntaxes:
      *
-     * add(Sabre_VObject_Element $element)
-     * add(string $name, $value)
+     * add(Node $node)
+     * add(string $name, $value, array $parameters = array())
      *
      * The first version adds an Element
      * The second adds a property as a string.
@@ -153,26 +169,23 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      * @param mixed $itemValue
      * @return void
      */
-    public function add($item, $itemValue = null) {
+    public function add($item, $itemValue = null, array $parameters = array()) {
 
-        if ($item instanceof Sabre_VObject_Element) {
+        if ($item instanceof Node) {
             if (!is_null($itemValue)) {
-                throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject');
+                throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node');
             }
             $item->parent = $this;
             $this->children[] = $item;
         } elseif(is_string($item)) {
 
-            if (!is_scalar($itemValue)) {
-                throw new InvalidArgumentException('The second argument must be scalar');
-            }
-            $item = Sabre_VObject_Property::create($item,$itemValue);
+            $item = Property::create($item,$itemValue, $parameters);
             $item->parent = $this;
             $this->children[] = $item;
 
         } else {
 
-            throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
+            throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string');
 
         }
 
@@ -181,11 +194,11 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     /**
      * Returns an iterable list of children
      *
-     * @return Sabre_VObject_ElementList
+     * @return ElementList
      */
     public function children() {
 
-        return new Sabre_VObject_ElementList($this->children);
+        return new ElementList($this->children);
 
     }
 
@@ -218,7 +231,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
 
             if (
                 strtoupper($child->name) === $name &&
-                (is_null($group) || ( $child instanceof Sabre_VObject_Property && strtoupper($child->group) === $group))
+                (is_null($group) || ( $child instanceof Property && strtoupper($child->group) === $group))
             ) {
 
                 $result[$key] = $child;
@@ -241,7 +254,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
 
         $result = array();
         foreach($this->children as $child) {
-            if ($child instanceof Sabre_VObject_Component) {
+            if ($child instanceof Component) {
                 $result[] = $child;
             }
         }
@@ -250,6 +263,33 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
 
     }
 
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Node::REPAIR - If something is broken, and automatic repair may
+     *                    be attempted.
+     *
+     * An array is returned with warnings.
+     *
+     * Every item in the array has the following properties:
+     *    * level - (number between 1 and 3 with severity information)
+     *    * message - (human readable message)
+     *    * node - (reference to the offending node)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        $result = array();
+        foreach($this->children as $child) {
+            $result = array_merge($result, $child->validate($options));
+        }
+        return $result;
+
+    }
+
     /* Magic property accessors {{{ */
 
     /**
@@ -259,7 +299,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      * null is returned.
      *
      * @param string $name
-     * @return Sabre_VObject_Property
+     * @return Property
      */
     public function __get($name) {
 
@@ -268,8 +308,8 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
             return null;
         } else {
             $firstMatch = current($matches);
-            /** @var $firstMatch Sabre_VObject_Property */
-            $firstMatch->setIterator(new Sabre_VObject_ElementList(array_values($matches)));
+            /** @var $firstMatch Property */
+            $firstMatch->setIterator(new ElementList(array_values($matches)));
             return $firstMatch;
         }
 
@@ -291,7 +331,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     /**
      * Using the setter method you can add properties or subcomponents
      *
-     * You can either pass a Sabre_VObject_Component, Sabre_VObject_Property
+     * You can either pass a Component, Property
      * object, or a string to automatically create a Property.
      *
      * If the item already exists, it will be removed. If you want to add
@@ -306,7 +346,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
         $matches = $this->select($name);
         $overWrite = count($matches)?key($matches):null;
 
-        if ($value instanceof Sabre_VObject_Component || $value instanceof Sabre_VObject_Property) {
+        if ($value instanceof Component || $value instanceof Property) {
             $value->parent = $this;
             if (!is_null($overWrite)) {
                 $this->children[$overWrite] = $value;
@@ -314,7 +354,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
                 $this->children[] = $value;
             }
         } elseif (is_scalar($value)) {
-            $property = Sabre_VObject_Property::create($name,$value);
+            $property = Property::create($name,$value);
             $property->parent = $this;
             if (!is_null($overWrite)) {
                 $this->children[$overWrite] = $property;
@@ -322,7 +362,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
                 $this->children[] = $property;
             }
         } else {
-            throw new InvalidArgumentException('You must pass a Sabre_VObject_Component, Sabre_VObject_Property or scalar type');
+            throw new \InvalidArgumentException('You must pass a \\Sabre\\VObject\\Component, \\Sabre\\VObject\\Property or scalar type');
         }
 
     }
diff --git a/3rdparty/Sabre/VObject/Component/VAlarm.php b/3rdparty/Sabre/VObject/Component/VAlarm.php
old mode 100755
new mode 100644
index ebb4a9b18f69962a0446a6f4dece59ea2db1605a..383e16eef14c540feaa085d2d28232643abb16eb
--- a/3rdparty/Sabre/VObject/Component/VAlarm.php
+++ b/3rdparty/Sabre/VObject/Component/VAlarm.php
@@ -1,17 +1,18 @@
 <?php
 
+namespace Sabre\VObject\Component;
+use Sabre\VObject;
+
 /**
  * VAlarm component
  *
  * This component contains some additional functionality specific for VALARMs.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
+class VAlarm extends VObject\Component {
 
     /**
      * Returns a DateTime object when this alarm is going to trigger.
@@ -24,12 +25,19 @@ class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
 
         $trigger = $this->TRIGGER;
         if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
-            $triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($this->TRIGGER);
+            $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
             $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
 
             $parentComponent = $this->parent;
             if ($related === 'START') {
-                $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+
+                if ($parentComponent->name === 'VTODO') {
+                    $propName = 'DUE';
+                } else {
+                    $propName = 'DTSTART';
+                }
+
+                $effectiveTrigger = clone $parentComponent->$propName->getDateTime();
                 $effectiveTrigger->add($triggerDuration);
             } else {
                 if ($parentComponent->name === 'VTODO') {
@@ -37,7 +45,7 @@ class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
                 } elseif ($parentComponent->name === 'VEVENT') {
                     $endProp = 'DTEND';
                 } else {
-                    throw new Sabre_DAV_Exception('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
+                    throw new \LogicException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
                 }
 
                 if (isset($parentComponent->$endProp)) {
@@ -45,7 +53,7 @@ class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
                     $effectiveTrigger->add($triggerDuration);
                 } elseif (isset($parentComponent->DURATION)) {
                     $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
-                    $duration = Sabre_VObject_DateTimeParser::parseDuration($parentComponent->DURATION);
+                    $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION);
                     $effectiveTrigger->add($duration);
                     $effectiveTrigger->add($triggerDuration);
                 } else {
@@ -67,22 +75,22 @@ class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
      * The rules used to determine if an event falls within the specified
      * time-range is based on the CalDAV specification.
      *
-     * @param DateTime $start
-     * @param DateTime $end
+     * @param \DateTime $start
+     * @param \DateTime $end
      * @return bool
      */
-    public function isInTimeRange(DateTime $start, DateTime $end) {
+    public function isInTimeRange(\DateTime $start, \DateTime $end) {
 
         $effectiveTrigger = $this->getEffectiveTriggerTime();
 
         if (isset($this->DURATION)) {
-            $duration = Sabre_VObject_DateTimeParser::parseDuration($this->DURATION);
+            $duration = VObject\DateTimeParser::parseDuration($this->DURATION);
             $repeat = (string)$this->repeat;
             if (!$repeat) {
                 $repeat = 1;
             }
 
-            $period = new DatePeriod($effectiveTrigger, $duration, (int)$repeat);
+            $period = new \DatePeriod($effectiveTrigger, $duration, (int)$repeat);
 
             foreach($period as $occurrence) {
 
@@ -98,5 +106,3 @@ class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/VObject/Component/VCalendar.php b/3rdparty/Sabre/VObject/Component/VCalendar.php
old mode 100755
new mode 100644
index f3be29afdbb492c16b7fe28f0e04888c3291fd43..73f2f6d34fc88379325932f08bdf1228b1927204
--- a/3rdparty/Sabre/VObject/Component/VCalendar.php
+++ b/3rdparty/Sabre/VObject/Component/VCalendar.php
@@ -1,17 +1,19 @@
 <?php
 
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
 /**
  * The VCalendar component
  *
  * This component adds functionality to a component, specific for a VCALENDAR.
  * 
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/) 
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
+class VCalendar extends VObject\Component {
 
     /**
      * Returns a list of all 'base components'. For instance, if an Event has 
@@ -28,7 +30,7 @@ class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
         $components = array();
         foreach($this->children as $component) {
 
-            if (!$component instanceof Sabre_VObject_Component)
+            if (!$component instanceof VObject\Component)
                 continue;
 
             if (isset($component->{'RECURRENCE-ID'})) 
@@ -69,7 +71,7 @@ class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
      * @param DateTime $end 
      * @return void
      */
-    public function expand(DateTime $start, DateTime $end) {
+    public function expand(\DateTime $start, \DateTime $end) {
 
         $newEvents = array();
 
@@ -91,10 +93,10 @@ class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
 
             $uid = (string)$vevent->uid;
             if (!$uid) {
-                throw new LogicException('Event did not have a UID!');
+                throw new \LogicException('Event did not have a UID!');
             }
 
-            $it = new Sabre_VObject_RecurrenceIterator($this, $vevent->uid);
+            $it = new VObject\RecurrenceIterator($this, $vevent->uid);
             $it->fastForward($start);
 
             while($it->valid() && $it->getDTStart() < $end) {
@@ -114,9 +116,9 @@ class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
         foreach($newEvents as $newEvent) {
 
             foreach($newEvent->children as $child) {
-                if ($child instanceof Sabre_VObject_Property_DateTime &&
-                    $child->getDateType() == Sabre_VObject_Property_DateTime::LOCALTZ) {
-                        $child->setDateTime($child->getDateTime(),Sabre_VObject_Property_DateTime::UTC);
+                if ($child instanceof VObject\Property\DateTime &&
+                    $child->getDateType() == VObject\Property\DateTime::LOCALTZ) {
+                        $child->setDateTime($child->getDateTime(),VObject\Property\DateTime::UTC);
                     }
             }
 
@@ -129,5 +131,112 @@ class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
 
     } 
 
+    /**
+     * Validates the node for correctness.
+     * An array is returned with warnings.
+     *
+     * Every item in the array has the following properties:
+     *    * level - (number between 1 and 3 with severity information)
+     *    * message - (human readable message)
+     *    * node - (reference to the offending node)
+     * 
+     * @return array 
+     */
+    /*
+    public function validate() {
+
+        $warnings = array();
+
+        $version = $this->select('VERSION');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The VERSION property must appear in the VCALENDAR component exactly 1 time',
+                'node' => $this,
+            );
+        } else {
+            if ((string)$this->VERSION !== '2.0') {
+                $warnings[] = array(
+                    'level' => 1,
+                    'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
+                    'node' => $this,
+                );
+            }
+        } 
+        $version = $this->select('PRODID');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 2,
+                'message' => 'The PRODID property must appear in the VCALENDAR component exactly 1 time',
+                'node' => $this,
+            );
+        }
+        if (count($this->CALSCALE) > 1) {
+            $warnings[] = array(
+                'level' => 2,
+                'message' => 'The CALSCALE property must not be specified more than once.',
+                'node' => $this,
+            );
+        }
+        if (count($this->METHOD) > 1) {
+            $warnings[] = array(
+                'level' => 2,
+                'message' => 'The METHOD property must not be specified more than once.',
+                'node' => $this,
+            );
+        }
+
+        $allowedComponents = array(
+            'VEVENT',
+            'VTODO',
+            'VJOURNAL',
+            'VFREEBUSY',
+            'VTIMEZONE',
+        );
+        $allowedProperties = array(
+            'PRODID',
+            'VERSION',
+            'CALSCALE',
+            'METHOD',
+        );
+        $componentsFound = 0;
+        foreach($this->children as $child) {
+            if($child instanceof Component) {
+                $componentsFound++;
+                if (!in_array($child->name, $allowedComponents)) {
+                    $warnings[] = array(
+                        'level' => 1,
+                        'message' => 'The ' . $child->name . " component is not allowed in the VCALENDAR component",
+                        'node' => $this,
+                    );
+                }
+            }
+            if ($child instanceof Property) {
+                if (!in_array($child->name, $allowedProperties)) {
+                    $warnings[] = array(
+                        'level' => 2,
+                        'message' => 'The ' . $child->name . " property is not allowed in the VCALENDAR component",
+                        'node' => $this,
+                    );
+                }
+            }
+        }
+
+        if ($componentsFound===0) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'An iCalendar object must have at least 1 component.',
+                'node' => $this,
+            );
+        }
+
+        return array_merge(
+            $warnings,
+            parent::validate()
+        );
+
+    }
+     */
+
 }
 
diff --git a/3rdparty/Sabre/VObject/Component/VCard.php b/3rdparty/Sabre/VObject/Component/VCard.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2926985550debd5f8d8febb337726468dc942d5
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VCard.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * The VCard component
+ *
+ * This component represents the BEGIN:VCARD and END:VCARD found in every
+ * vcard.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class VCard extends VObject\Component {
+
+    /**
+     * VCards with version 2.1, 3.0 and 4.0 are found.
+     *
+     * If the VCARD doesn't know its version, 4.0 is assumed.
+     */
+    const DEFAULT_VERSION = '4.0';
+
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Node::REPAIR - If something is broken, and automatic repair may
+     *                    be attempted.
+     *
+     * An array is returned with warnings.
+     *
+     * Every item in the array has the following properties:
+     *    * level - (number between 1 and 3 with severity information)
+     *    * message - (human readable message)
+     *    * node - (reference to the offending node)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        $warnings = array();
+
+        $version = $this->select('VERSION');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The VERSION property must appear in the VCARD component exactly 1 time',
+                'node' => $this,
+            );
+            if ($options & self::REPAIR) {
+                $this->VERSION = self::DEFAULT_VERSION;
+            }
+        } else {
+            $version = (string)$this->VERSION;
+            if ($version!=='2.1' && $version!=='3.0' && $version!=='4.0') {
+                $warnings[] = array(
+                    'level' => 1,
+                    'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
+                    'node' => $this,
+                );
+                if ($options & self::REPAIR) {
+                    $this->VERSION = '4.0';
+                }
+            }
+
+        }
+        $version = $this->select('FN');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The FN property must appear in the VCARD component exactly 1 time',
+                'node' => $this,
+            );
+            if (($options & self::REPAIR) && count($version) === 0) {
+                // We're going to try to see if we can use the contents of the
+                // N property.
+                if (isset($this->N)) {
+                    $value = explode(';', (string)$this->N);
+                    if (isset($value[1]) && $value[1]) {
+                        $this->FN = $value[1] . ' ' . $value[0];
+                    } else {
+                        $this->FN = $value[0];
+                    }
+
+                // Otherwise, the ORG property may work
+                } elseif (isset($this->ORG)) {
+                    $this->FN = (string)$this->ORG;
+                }
+
+            }
+        }
+
+        return array_merge(
+            parent::validate($options),
+            $warnings
+        );
+
+    }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Component/VEvent.php b/3rdparty/Sabre/VObject/Component/VEvent.php
old mode 100755
new mode 100644
index d6b910874d0af8afb76bbfc8bab326995083d2e9..9d10966e2030479964e3882e08ceb8cb19f4dadc
--- a/3rdparty/Sabre/VObject/Component/VEvent.php
+++ b/3rdparty/Sabre/VObject/Component/VEvent.php
@@ -1,17 +1,18 @@
 <?php
 
+namespace Sabre\VObject\Component;
+use Sabre\VObject;
+
 /**
  * VEvent component
  *
  * This component contains some additional functionality specific for VEVENT's.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
+class VEvent extends VObject\Component {
 
     /**
      * Returns true or false depending on if the event falls in the specified
@@ -20,14 +21,14 @@ class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
      * The rules used to determine if an event falls within the specified
      * time-range is based on the CalDAV specification.
      *
-     * @param DateTime $start
-     * @param DateTime $end
+     * @param \DateTime $start
+     * @param \DateTime $end
      * @return bool
      */
-    public function isInTimeRange(DateTime $start, DateTime $end) {
+    public function isInTimeRange(\DateTime $start, \DateTime $end) {
 
         if ($this->RRULE) {
-            $it = new Sabre_VObject_RecurrenceIterator($this);
+            $it = new VObject\RecurrenceIterator($this);
             $it->fastForward($start);
 
             // We fast-forwarded to a spot where the end-time of the
@@ -53,8 +54,8 @@ class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
 
         } elseif (isset($this->DURATION)) {
             $effectiveEnd = clone $effectiveStart;
-            $effectiveEnd->add( Sabre_VObject_DateTimeParser::parseDuration($this->DURATION) );
-        } elseif ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+            $effectiveEnd->add( VObject\DateTimeParser::parseDuration($this->DURATION) );
+        } elseif ($this->DTSTART->getDateType() == VObject\Property\DateTime::DATE) {
             $effectiveEnd = clone $effectiveStart;
             $effectiveEnd->modify('+1 day');
         } else {
@@ -67,5 +68,3 @@ class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/VObject/Component/VFreeBusy.php b/3rdparty/Sabre/VObject/Component/VFreeBusy.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6da52cbd77f589198f6d4bd6bb2a8e6c90e4d16
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VFreeBusy.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * The VFreeBusy component
+ *
+ * This component adds functionality to a component, specific for VFREEBUSY
+ * components.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class VFreeBusy extends VObject\Component {
+
+    /**
+     * Checks based on the contained FREEBUSY information, if a timeslot is
+     * available.
+     *
+     * @param DateTime $start
+     * @param Datetime $end
+     * @return bool
+     */
+    public function isFree(\DateTime $start, \Datetime $end) {
+
+        foreach($this->select('FREEBUSY') as $freebusy) {
+
+            // We are only interested in FBTYPE=BUSY (the default),
+            // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
+            if (isset($freebusy['FBTYPE']) && strtoupper(substr((string)$freebusy['FBTYPE'],0,4))!=='BUSY') {
+                continue;
+            }
+
+            // The freebusy component can hold more than 1 value, separated by
+            // commas.
+            $periods = explode(',', (string)$freebusy);
+
+            foreach($periods as $period) {
+                // Every period is formatted as [start]/[end]. The start is an
+                // absolute UTC time, the end may be an absolute UTC time, or
+                // duration (relative) value.
+                list($busyStart, $busyEnd) = explode('/', $period);
+
+                $busyStart = VObject\DateTimeParser::parse($busyStart);
+                $busyEnd = VObject\DateTimeParser::parse($busyEnd);
+                if ($busyEnd instanceof \DateInterval) {
+                    $tmp = clone $busyStart;
+                    $tmp->add($busyEnd);
+                    $busyEnd = $tmp;
+                }
+
+                if($start < $busyEnd && $end > $busyStart) {
+                    return false;
+                }
+
+            }
+
+        }
+
+        return true;
+
+    }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Component/VJournal.php b/3rdparty/Sabre/VObject/Component/VJournal.php
old mode 100755
new mode 100644
index 22b3ec921e5a1b6e67dbdb0253ba5d6fece53cb8..f104a1f66edc389934ca4df55b99b724991db6c2
--- a/3rdparty/Sabre/VObject/Component/VJournal.php
+++ b/3rdparty/Sabre/VObject/Component/VJournal.php
@@ -1,17 +1,19 @@
 <?php
 
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
 /**
  * VJournal component
  *
  * This component contains some additional functionality specific for VJOURNALs.
  * 
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/) 
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component_VJournal extends Sabre_VObject_Component {
+class VJournal extends VObject\Component {
 
     /**
      * Returns true or false depending on if the event falls in the specified 
@@ -24,12 +26,12 @@ class Sabre_VObject_Component_VJournal extends Sabre_VObject_Component {
      * @param DateTime $end 
      * @return bool 
      */
-    public function isInTimeRange(DateTime $start, DateTime $end) {
+    public function isInTimeRange(\DateTime $start, \DateTime $end) {
 
         $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
         if ($dtstart) {
             $effectiveEnd = clone $dtstart;
-            if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+            if ($this->DTSTART->getDateType() == VObject\Property\DateTime::DATE) {
                 $effectiveEnd->modify('+1 day');
             }
 
@@ -42,5 +44,3 @@ class Sabre_VObject_Component_VJournal extends Sabre_VObject_Component {
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/VObject/Component/VTodo.php b/3rdparty/Sabre/VObject/Component/VTodo.php
old mode 100755
new mode 100644
index 79d06298d7f864ea5953f51f714906c3119feef8..5f879aea43560be1fb5a738ff146dd39a0bd0517
--- a/3rdparty/Sabre/VObject/Component/VTodo.php
+++ b/3rdparty/Sabre/VObject/Component/VTodo.php
@@ -1,17 +1,19 @@
 <?php
 
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
 /**
  * VTodo component
  *
  * This component contains some additional functionality specific for VTODOs.
  * 
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/) 
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Component_VTodo extends Sabre_VObject_Component {
+class VTodo extends VObject\Component {
 
     /**
      * Returns true or false depending on if the event falls in the specified 
@@ -24,10 +26,10 @@ class Sabre_VObject_Component_VTodo extends Sabre_VObject_Component {
      * @param DateTime $end 
      * @return bool 
      */
-    public function isInTimeRange(DateTime $start, DateTime $end) {
+    public function isInTimeRange(\DateTime $start, \DateTime $end) {
 
         $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
-        $duration = isset($this->DURATION)?Sabre_VObject_DateTimeParser::parseDuration($this->DURATION):null;
+        $duration = isset($this->DURATION)?VObject\DateTimeParser::parseDuration($this->DURATION):null;
         $due = isset($this->DUE)?$this->DUE->getDateTime():null;
         $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
         $created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
@@ -64,5 +66,3 @@ class Sabre_VObject_Component_VTodo extends Sabre_VObject_Component {
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/VObject/DateTimeParser.php b/3rdparty/Sabre/VObject/DateTimeParser.php
old mode 100755
new mode 100644
index 23a4bb69916cca390f4d697acb0c93f72756e1ab..d09ded96768dd66d0a20d37dc3d2e3b412f7a1cd
--- a/3rdparty/Sabre/VObject/DateTimeParser.php
+++ b/3rdparty/Sabre/VObject/DateTimeParser.php
@@ -1,18 +1,18 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * DateTimeParser
  *
  * This class is responsible for parsing the several different date and time
  * formats iCalendar and vCards have.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_DateTimeParser {
+class DateTimeParser {
 
     /**
      * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
@@ -25,22 +25,22 @@ class Sabre_VObject_DateTimeParser {
      * @param DateTimeZone $tz
      * @return DateTime
      */
-    static public function parseDateTime($dt,DateTimeZone $tz = null) {
+    static public function parseDateTime($dt,\DateTimeZone $tz = null) {
 
         // Format is YYYYMMDD + "T" + hhmmss
-        $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
+        $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
 
         if (!$result) {
-            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
+            throw new \LogicException('The supplied iCalendar datetime value is incorrect: ' . $dt);
         }
 
         if ($matches[7]==='Z' || is_null($tz)) {
-            $tz = new DateTimeZone('UTC');
+            $tz = new \DateTimeZone('UTC');
         }
-        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
+        $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
 
         // Still resetting the timezone, to normalize everything to UTC
-        $date->setTimeZone(new DateTimeZone('UTC'));
+        $date->setTimeZone(new \DateTimeZone('UTC'));
         return $date;
 
     }
@@ -54,13 +54,13 @@ class Sabre_VObject_DateTimeParser {
     static public function parseDate($date) {
 
         // Format is YYYYMMDD
-        $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
+        $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
 
         if (!$result) {
-            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar date value is incorrect: ' . $date);
+            throw new \LogicException('The supplied iCalendar date value is incorrect: ' . $date);
         }
 
-        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
+        $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new \DateTimeZone('UTC'));
         return $date;
 
     }
@@ -79,7 +79,7 @@ class Sabre_VObject_DateTimeParser {
 
         $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
         if (!$result) {
-            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar duration value is incorrect: ' . $duration);
+            throw new \LogicException('The supplied iCalendar duration value is incorrect: ' . $duration);
         }
 
         if (!$asString) {
@@ -128,7 +128,7 @@ class Sabre_VObject_DateTimeParser {
             if ($duration==='P') {
                 $duration = 'PT0S';
             }
-            $iv = new DateInterval($duration);
+            $iv = new \DateInterval($duration);
             if ($invert) $iv->invert = true;
 
             return $iv;
diff --git a/3rdparty/Sabre/VObject/Element.php b/3rdparty/Sabre/VObject/Element.php
deleted file mode 100755
index e20ff0b353c4491cd166ccad47a39c16a7f46c4f..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/VObject/Element.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-/**
- * Base class for all elements
- *
- * @package Sabre
- * @subpackage VObject
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-abstract class Sabre_VObject_Element extends Sabre_VObject_Node {
-
-    public $parent = null;
-
-}
diff --git a/3rdparty/Sabre/VObject/Element/DateTime.php b/3rdparty/Sabre/VObject/Element/DateTime.php
deleted file mode 100755
index 5e5eb7ab6f2e8a96485d33b9173c9a1726648edf..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/VObject/Element/DateTime.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * DateTime property
- *
- * this class got renamed to Sabre_VObject_Property_DateTime
- *
- * @package Sabre
- * @subpackage VObject
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- * @deprecated
- */
-class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property_DateTime {
-
-    /**
-     * Local 'floating' time
-     */
-    const LOCAL = 1;
-
-    /**
-     * UTC-based time
-     */
-    const UTC = 2;
-
-    /**
-     * Local time plus timezone
-     */
-    const LOCALTZ = 3;
-
-    /**
-     * Only a date, time is ignored
-     */
-    const DATE = 4;
-
-}
diff --git a/3rdparty/Sabre/VObject/Element/MultiDateTime.php b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
deleted file mode 100755
index 8a12ced94a80418c2c3640bd975c948cab75672c..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/VObject/Element/MultiDateTime.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-/**
- * Multi-DateTime property
- *
- * This class got renamed to Sabre_VObject_Property_MultiDateTime
- *
- * @package Sabre
- * @subpackage VObject
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- * @deprecated
- */
-class Sabre_VObject_Element_MultiDateTime extends Sabre_VObject_Property_MultiDateTime {
-
-}
diff --git a/3rdparty/Sabre/VObject/ElementList.php b/3rdparty/Sabre/VObject/ElementList.php
old mode 100755
new mode 100644
index 7e508db20f0841ff3f26b4300fe2ca85bdb19f90..b7f1c8eee22224d8f1385c27891ad7069df3e30a
--- a/3rdparty/Sabre/VObject/ElementList.php
+++ b/3rdparty/Sabre/VObject/ElementList.php
@@ -1,18 +1,18 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * VObject ElementList
  *
  * This class represents a list of elements. Lists are the result of queries,
  * such as doing $vcalendar->vevent where there's multiple VEVENT objects.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
+class ElementList implements \Iterator, \Countable, \ArrayAccess {
 
     /**
      * Inner elements
@@ -44,7 +44,7 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     /**
      * Returns current item in iteration
      *
-     * @return Sabre_VObject_Element
+     * @return Element
      */
     public function current() {
 
@@ -149,7 +149,7 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
      */
     public function offsetSet($offset,$value) {
 
-        throw new LogicException('You can not add new objects to an ElementList');
+        throw new \LogicException('You can not add new objects to an ElementList');
 
     }
 
@@ -163,7 +163,7 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
      */
     public function offsetUnset($offset) {
 
-        throw new LogicException('You can not remove objects from an ElementList');
+        throw new \LogicException('You can not remove objects from an ElementList');
 
     }
 
diff --git a/3rdparty/Sabre/VObject/FreeBusyGenerator.php b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
old mode 100755
new mode 100644
index 1c96a64a004b6a7055c0568f80903c122de6d9dd..c607d119ced27fcd76be386ee75da48a2956f611
--- a/3rdparty/Sabre/VObject/FreeBusyGenerator.php
+++ b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * This class helps with generating FREEBUSY reports based on existing sets of
  * objects.
@@ -10,13 +12,11 @@
  * VFREEBUSY components are described in RFC5545, The rules for what should
  * go in a single freebusy report is taken from RFC4791, section 7.10.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_FreeBusyGenerator {
+class FreeBusyGenerator {
 
     /**
      * Input objects
@@ -42,10 +42,33 @@ class Sabre_VObject_FreeBusyGenerator {
     /**
      * VCALENDAR object
      *
-     * @var Sabre_VObject_Component
+     * @var Component
      */
     protected $baseObject;
 
+    /**
+     * Creates the generator.
+     *
+     * Check the setTimeRange and setObjects methods for details about the
+     * arguments.
+     *
+     * @param DateTime $start
+     * @param DateTime $end
+     * @param mixed $objects
+     * @return void
+     */
+    public function __construct(\DateTime $start = null, \DateTime $end = null, $objects = null) {
+
+        if ($start && $end) {
+            $this->setTimeRange($start, $end);
+        }
+
+        if ($objects) {
+            $this->setObjects($objects);
+        }
+
+    }
+
     /**
      * Sets the VCALENDAR object.
      *
@@ -54,10 +77,10 @@ class Sabre_VObject_FreeBusyGenerator {
      *
      * The VFREEBUSY object will be automatically added though.
      *
-     * @param Sabre_VObject_Component $vcalendar
+     * @param Component $vcalendar
      * @return void
      */
-    public function setBaseObject(Sabre_VObject_Component $vcalendar) {
+    public function setBaseObject(Component $vcalendar) {
 
         $this->baseObject = $vcalendar;
 
@@ -66,22 +89,28 @@ class Sabre_VObject_FreeBusyGenerator {
     /**
      * Sets the input objects
      *
-     * Every object must either be a string or a Sabre_VObject_Component.
+     * You must either specify a valendar object as a strong, or as the parse
+     * Component.
+     * It's also possible to specify multiple objects as an array.
      *
-     * @param array $objects
+     * @param mixed $objects
      * @return void
      */
-    public function setObjects(array $objects) {
+    public function setObjects($objects) {
+
+        if (!is_array($objects)) {
+            $objects = array($objects);
+        }
 
         $this->objects = array();
         foreach($objects as $object) {
 
             if (is_string($object)) {
-                $this->objects[] = Sabre_VObject_Reader::read($object);
-            } elseif ($object instanceof Sabre_VObject_Component) {
+                $this->objects[] = Reader::read($object);
+            } elseif ($object instanceof Component) {
                 $this->objects[] = $object;
             } else {
-                throw new InvalidArgumentException('You can only pass strings or Sabre_VObject_Component arguments to setObjects');
+                throw new \InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component arguments to setObjects');
             }
 
         }
@@ -97,7 +126,7 @@ class Sabre_VObject_FreeBusyGenerator {
      * @param DateTime $end
      * @return void
      */
-    public function setTimeRange(DateTime $start = null, DateTime $end = null) {
+    public function setTimeRange(\DateTime $start = null, \DateTime $end = null) {
 
         $this->start = $start;
         $this->end = $end;
@@ -108,7 +137,7 @@ class Sabre_VObject_FreeBusyGenerator {
      * Parses the input data and returns a correct VFREEBUSY object, wrapped in
      * a VCALENDAR.
      *
-     * @return Sabre_VObject_Component
+     * @return Component
      */
     public function getResult() {
 
@@ -140,7 +169,7 @@ class Sabre_VObject_FreeBusyGenerator {
 
                         if ($component->RRULE) {
 
-                            $iterator = new Sabre_VObject_RecurrenceIterator($object, (string)$component->uid);
+                            $iterator = new RecurrenceIterator($object, (string)$component->uid);
                             if ($this->start) {
                                 $iterator->fastForward($this->start);
                             }
@@ -172,10 +201,10 @@ class Sabre_VObject_FreeBusyGenerator {
                             if (isset($component->DTEND)) {
                                 $endTime = $component->DTEND->getDateTime();
                             } elseif (isset($component->DURATION)) {
-                                $duration = Sabre_VObject_DateTimeParser::parseDuration((string)$component->DURATION);
+                                $duration = DateTimeParser::parseDuration((string)$component->DURATION);
                                 $endTime = clone $startTime;
                                 $endTime->add($duration);
-                            } elseif ($component->DTSTART->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
+                            } elseif ($component->DTSTART->getDateType() === Property\DateTime::DATE) {
                                 $endTime = clone $startTime;
                                 $endTime->modify('+1 day');
                             } else {
@@ -212,14 +241,14 @@ class Sabre_VObject_FreeBusyGenerator {
                             $values = explode(',', $freebusy);
                             foreach($values as $value) {
                                 list($startTime, $endTime) = explode('/', $value);
-                                $startTime = Sabre_VObject_DateTimeParser::parseDateTime($startTime);
+                                $startTime = DateTimeParser::parseDateTime($startTime);
 
                                 if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
-                                    $duration = Sabre_VObject_DateTimeParser::parseDuration($endTime);
+                                    $duration = DateTimeParser::parseDuration($endTime);
                                     $endTime = clone $startTime;
                                     $endTime->add($duration);
                                 } else {
-                                    $endTime = Sabre_VObject_DateTimeParser::parseDateTime($endTime);
+                                    $endTime = DateTimeParser::parseDateTime($endTime);
                                 }
 
                                 if($this->start && $this->start > $endTime) continue;
@@ -248,39 +277,35 @@ class Sabre_VObject_FreeBusyGenerator {
         if ($this->baseObject) {
             $calendar = $this->baseObject;
         } else {
-            $calendar = new Sabre_VObject_Component('VCALENDAR');
+            $calendar = new Component('VCALENDAR');
             $calendar->version = '2.0';
-            if (Sabre_DAV_Server::$exposeVersion) {
-                $calendar->prodid = '-//SabreDAV//Sabre VObject ' . Sabre_VObject_Version::VERSION . '//EN';
-            } else {
-                $calendar->prodid = '-//SabreDAV//Sabre VObject//EN';
-            }
+            $calendar->prodid = '-//Sabre//Sabre VObject ' . Version::VERSION . '//EN';
             $calendar->calscale = 'GREGORIAN';
         }
 
-        $vfreebusy = new Sabre_VObject_Component('VFREEBUSY');
+        $vfreebusy = new Component('VFREEBUSY');
         $calendar->add($vfreebusy);
 
         if ($this->start) {
-            $dtstart = new Sabre_VObject_Property_DateTime('DTSTART');
-            $dtstart->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
+            $dtstart = new Property\DateTime('DTSTART');
+            $dtstart->setDateTime($this->start,Property\DateTime::UTC);
             $vfreebusy->add($dtstart);
         }
         if ($this->end) {
-            $dtend = new Sabre_VObject_Property_DateTime('DTEND');
-            $dtend->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
+            $dtend = new Property\DateTime('DTEND');
+            $dtend->setDateTime($this->end,Property\DateTime::UTC);
             $vfreebusy->add($dtend);
         }
-        $dtstamp = new Sabre_VObject_Property_DateTime('DTSTAMP');
-        $dtstamp->setDateTime(new DateTime('now'), Sabre_VObject_Property_DateTime::UTC);
+        $dtstamp = new Property\DateTime('DTSTAMP');
+        $dtstamp->setDateTime(new \DateTime('now'), Property\DateTime::UTC);
         $vfreebusy->add($dtstamp);
 
         foreach($busyTimes as $busyTime) {
 
-            $busyTime[0]->setTimeZone(new DateTimeZone('UTC'));
-            $busyTime[1]->setTimeZone(new DateTimeZone('UTC'));
+            $busyTime[0]->setTimeZone(new \DateTimeZone('UTC'));
+            $busyTime[1]->setTimeZone(new \DateTimeZone('UTC'));
 
-            $prop = new Sabre_VObject_Property(
+            $prop = new Property(
                 'FREEBUSY',
                 $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
             );
diff --git a/3rdparty/Sabre/VObject/Node.php b/3rdparty/Sabre/VObject/Node.php
old mode 100755
new mode 100644
index d89e01b56c69e60904bbdc9496611951128b618a..5d2e1ce300fa2f1d8e29bc5b69d7dd0cfd4c56d7
--- a/3rdparty/Sabre/VObject/Node.php
+++ b/3rdparty/Sabre/VObject/Node.php
@@ -1,15 +1,20 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * Base class for all nodes
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Countable {
+abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable {
+
+    /**
+     * The following constants are used by the validate() method.
+     */
+    const REPAIR = 1;
 
     /**
      * Turns the object back into a serialized blob.
@@ -21,30 +26,53 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
     /**
      * Iterator override
      *
-     * @var Sabre_VObject_ElementList
+     * @var ElementList
      */
     protected $iterator = null;
 
     /**
      * A link to the parent node
      *
-     * @var Sabre_VObject_Node
+     * @var Node
      */
     public $parent = null;
 
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Node::REPAIR - If something is broken, and automatic repair may
+     *                    be attempted.
+     *
+     * An array is returned with warnings.
+     *
+     * Every item in the array has the following properties:
+     *    * level - (number between 1 and 3 with severity information)
+     *    * message - (human readable message)
+     *    * node - (reference to the offending node)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        return array();
+
+    }
+
     /* {{{ IteratorAggregator interface */
 
     /**
      * Returns the iterator for this object
      *
-     * @return Sabre_VObject_ElementList
+     * @return ElementList
      */
     public function getIterator() {
 
         if (!is_null($this->iterator))
             return $this->iterator;
 
-        return new Sabre_VObject_ElementList(array($this));
+        return new ElementList(array($this));
 
     }
 
@@ -53,10 +81,10 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
      *
      * Note that this is not actually part of the iterator interface
      *
-     * @param Sabre_VObject_ElementList $iterator
+     * @param ElementList $iterator
      * @return void
      */
-    public function setIterator(Sabre_VObject_ElementList $iterator) {
+    public function setIterator(ElementList $iterator) {
 
         $this->iterator = $iterator;
 
@@ -125,9 +153,14 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
     public function offsetSet($offset,$value) {
 
         $iterator = $this->getIterator();
-        return $iterator->offsetSet($offset,$value);
+        $iterator->offsetSet($offset,$value);
 
+    // @codeCoverageIgnoreStart
+    //
+    // This method always throws an exception, so we ignore the closing
+    // brace
     }
+    // @codeCoverageIgnoreEnd
 
     /**
      * Sets an item through ArrayAccess.
@@ -140,9 +173,14 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
     public function offsetUnset($offset) {
 
         $iterator = $this->getIterator();
-        return $iterator->offsetUnset($offset);
+        $iterator->offsetUnset($offset);
 
+    // @codeCoverageIgnoreStart
+    //
+    // This method always throws an exception, so we ignore the closing
+    // brace
     }
+    // @codeCoverageIgnoreEnd
 
     /* }}} */
 
diff --git a/3rdparty/Sabre/VObject/Parameter.php b/3rdparty/Sabre/VObject/Parameter.php
old mode 100755
new mode 100644
index 2e39af5f78ab1788067335f7b3f703845e26f4e8..d6d7c54c3bdac503f9595d37ec9db1a24d3794fa
--- a/3rdparty/Sabre/VObject/Parameter.php
+++ b/3rdparty/Sabre/VObject/Parameter.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * VObject Parameter
  *
@@ -8,13 +10,11 @@
  *   DTSTART;VALUE=DATE:20101108
  * VALUE=DATE would be the parameter name and value.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Parameter extends Sabre_VObject_Node {
+class Parameter extends Node {
 
     /**
      * Parameter name
@@ -38,6 +38,10 @@ class Sabre_VObject_Parameter extends Sabre_VObject_Node {
      */
     public function __construct($name, $value = null) {
 
+        if (!is_scalar($value) && !is_null($value)) {
+            throw new \InvalidArgumentException('The value argument must be a scalar value or null');
+        }
+
         $this->name = strtoupper($name);
         $this->value = $value;
 
diff --git a/3rdparty/Sabre/VObject/ParseException.php b/3rdparty/Sabre/VObject/ParseException.php
old mode 100755
new mode 100644
index 1b5e95bf16e49b5184b5fc089ec063457c5d3bab..91386fec536491c319fa08c099a0b2e20197c167
--- a/3rdparty/Sabre/VObject/ParseException.php
+++ b/3rdparty/Sabre/VObject/ParseException.php
@@ -1,12 +1,12 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
- * Exception thrown by Sabre_VObject_Reader if an invalid object was attempted to be parsed.
+ * Exception thrown by Reader if an invalid object was attempted to be parsed.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_ParseException extends Exception { }
+class ParseException extends \Exception { }
diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php
old mode 100755
new mode 100644
index ce74fe3865b86d38d0fa9a8a05d9363116d926f4..6f364a732579655e4056d71a0a6f0e9d6243d1c2
--- a/3rdparty/Sabre/VObject/Property.php
+++ b/3rdparty/Sabre/VObject/Property.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * VObject Property
  *
@@ -11,13 +13,11 @@
  *
  * Parameters can be accessed using the ArrayAccess interface.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Property extends Sabre_VObject_Element {
+class Property extends Node {
 
     /**
      * Propertyname
@@ -57,27 +57,37 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      * @var array
      */
     static public $classMap = array(
-        'COMPLETED'     => 'Sabre_VObject_Property_DateTime',
-        'CREATED'       => 'Sabre_VObject_Property_DateTime',
-        'DTEND'         => 'Sabre_VObject_Property_DateTime',
-        'DTSTAMP'       => 'Sabre_VObject_Property_DateTime',
-        'DTSTART'       => 'Sabre_VObject_Property_DateTime',
-        'DUE'           => 'Sabre_VObject_Property_DateTime',
-        'EXDATE'        => 'Sabre_VObject_Property_MultiDateTime',
-        'LAST-MODIFIED' => 'Sabre_VObject_Property_DateTime',
-        'RECURRENCE-ID' => 'Sabre_VObject_Property_DateTime',
-        'TRIGGER'       => 'Sabre_VObject_Property_DateTime',
+        'COMPLETED'     => 'Sabre\\VObject\\Property\\DateTime',
+        'CREATED'       => 'Sabre\\VObject\\Property\\DateTime',
+        'DTEND'         => 'Sabre\\VObject\\Property\\DateTime',
+        'DTSTAMP'       => 'Sabre\\VObject\\Property\\DateTime',
+        'DTSTART'       => 'Sabre\\VObject\\Property\\DateTime',
+        'DUE'           => 'Sabre\\VObject\\Property\\DateTime',
+        'EXDATE'        => 'Sabre\\VObject\\Property\\MultiDateTime',
+        'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\DateTime',
+        'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\DateTime',
+        'TRIGGER'       => 'Sabre\\VObject\\Property\\DateTime',
+        'N'             => 'Sabre\\VObject\\Property\\Compound',
+        'ORG'           => 'Sabre\\VObject\\Property\\Compound',
+        'ADR'           => 'Sabre\\VObject\\Property\\Compound',
+        'CATEGORIES'    => 'Sabre\\VObject\\Property\\Compound',
     );
 
     /**
      * Creates the new property by name, but in addition will also see if
      * there's a class mapped to the property name.
      *
+     * Parameters can be specified with the optional third argument. Parameters
+     * must be a key->value map of the parameter name, and value. If the value
+     * is specified as an array, it is assumed that multiple parameters with
+     * the same name should be added.
+     *
      * @param string $name
      * @param string $value
-     * @return void
+     * @param array $parameters
+     * @return Property
      */
-    static public function create($name, $value = null) {
+    static public function create($name, $value = null, array $parameters = array()) {
 
         $name = strtoupper($name);
         $shortName = $name;
@@ -87,9 +97,9 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         }
 
         if (isset(self::$classMap[$shortName])) {
-            return new self::$classMap[$shortName]($name, $value);
+            return new self::$classMap[$shortName]($name, $value, $parameters);
         } else {
-            return new self($name, $value);
+            return new self($name, $value, $parameters);
         }
 
     }
@@ -97,14 +107,20 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     /**
      * Creates a new property object
      *
-     * By default this object will iterate over its own children, but this can
-     * be overridden with the iterator argument
+     * Parameters can be specified with the optional third argument. Parameters
+     * must be a key->value map of the parameter name, and value. If the value
+     * is specified as an array, it is assumed that multiple parameters with
+     * the same name should be added.
      *
      * @param string $name
      * @param string $value
-     * @param Sabre_VObject_ElementList $iterator
+     * @param array $parameters
      */
-    public function __construct($name, $value = null, $iterator = null) {
+    public function __construct($name, $value = null, array $parameters = array()) {
+
+        if (!is_scalar($value) && !is_null($value)) {
+            throw new \InvalidArgumentException('The value argument must be scalar or null');
+        }
 
         $name = strtoupper($name);
         $group = null;
@@ -113,12 +129,21 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         }
         $this->name = $name;
         $this->group = $group;
-        if (!is_null($iterator)) $this->iterator = $iterator;
         $this->setValue($value);
 
-    }
+        foreach($parameters as $paramName => $paramValues) {
 
+            if (!is_array($paramValues)) {
+                $paramValues = array($paramValues);
+            }
 
+            foreach($paramValues as $paramValue) {
+                $this->add($paramName, $paramValue);
+            }
+
+        }
+
+    }
 
     /**
      * Updates the internal value
@@ -142,13 +167,12 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         $str = $this->name;
         if ($this->group) $str = $this->group . '.' . $this->name;
 
-        if (count($this->parameters)) {
-            foreach($this->parameters as $param) {
+        foreach($this->parameters as $param) {
 
-                $str.=';' . $param->serialize();
+            $str.=';' . $param->serialize();
 
-            }
         }
+
         $src = array(
             '\\',
             "\n",
@@ -180,7 +204,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      *
      * You can call this method with the following syntaxes:
      *
-     * add(Sabre_VObject_Parameter $element)
+     * add(Parameter $element)
      * add(string $name, $value)
      *
      * The first version adds an Parameter
@@ -192,24 +216,21 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      */
     public function add($item, $itemValue = null) {
 
-        if ($item instanceof Sabre_VObject_Parameter) {
+        if ($item instanceof Parameter) {
             if (!is_null($itemValue)) {
-                throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject');
+                throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject');
             }
             $item->parent = $this;
             $this->parameters[] = $item;
         } elseif(is_string($item)) {
 
-            if (!is_scalar($itemValue) && !is_null($itemValue)) {
-                throw new InvalidArgumentException('The second argument must be scalar');
-            }
-            $parameter = new Sabre_VObject_Parameter($item,$itemValue);
+            $parameter = new Parameter($item,$itemValue);
             $parameter->parent = $this;
             $this->parameters[] = $parameter;
 
         } else {
 
-            throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
+            throw new \InvalidArgumentException('The first argument must either be a Node a string');
 
         }
 
@@ -240,7 +261,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      * Returns a parameter, or parameter list.
      *
      * @param string $name
-     * @return Sabre_VObject_Element
+     * @return Node
      */
     public function offsetGet($name) {
 
@@ -258,7 +279,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         } elseif (count($result)===1) {
             return $result[0];
         } else {
-            $result[0]->setIterator(new Sabre_VObject_ElementList($result));
+            $result[0]->setIterator(new ElementList($result));
             return $result[0];
         }
 
@@ -273,25 +294,25 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      */
     public function offsetSet($name, $value) {
 
-        if (is_int($name)) return parent::offsetSet($name, $value);
+        if (is_int($name)) parent::offsetSet($name, $value);
 
         if (is_scalar($value)) {
             if (!is_string($name))
-                throw new InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
+                throw new \InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
 
             $this->offsetUnset($name);
-            $parameter = new Sabre_VObject_Parameter($name, $value);
+            $parameter = new Parameter($name, $value);
             $parameter->parent = $this;
             $this->parameters[] = $parameter;
 
-        } elseif ($value instanceof Sabre_VObject_Parameter) {
+        } elseif ($value instanceof Parameter) {
             if (!is_null($name))
-                throw new InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a Sabre_VObject_Parameter. Add using $array[]=$parameterObject.');
+                throw new \InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a \\Sabre\\VObject\\Parameter. Add using $array[]=$parameterObject.');
 
             $value->parent = $this;
             $this->parameters[] = $value;
         } else {
-            throw new InvalidArgumentException('You can only add parameters to the property object');
+            throw new \InvalidArgumentException('You can only add parameters to the property object');
         }
 
     }
@@ -304,7 +325,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      */
     public function offsetUnset($name) {
 
-        if (is_int($name)) return parent::offsetUnset($name);
+        if (is_int($name)) parent::offsetUnset($name);
         $name = strtoupper($name);
 
         foreach($this->parameters as $key=>$parameter) {
@@ -345,4 +366,65 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
 
     }
 
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Node::REPAIR - If something is broken, and automatic repair may
+     *                    be attempted.
+     *
+     * An array is returned with warnings.
+     *
+     * Every item in the array has the following properties:
+     *    * level - (number between 1 and 3 with severity information)
+     *    * message - (human readable message)
+     *    * node - (reference to the offending node)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        $warnings = array();
+
+        // Checking if our value is UTF-8
+        if (!StringUtil::isUTF8($this->value)) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'Property is not valid UTF-8!',
+                'node' => $this,
+            );
+            if ($options & self::REPAIR) {
+                $this->value = StringUtil::convertToUTF8($this->value);
+            }
+        }
+
+        // Checking if the propertyname does not contain any invalid bytes.
+        if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The propertyname: ' . $this->name . ' contains invalid characters. Only A-Z, 0-9 and - are allowed',
+                'node' => $this,
+            );
+            if ($options & self::REPAIR) {
+                // Uppercasing and converting underscores to dashes.
+                $this->name = strtoupper(
+                    str_replace('_', '-', $this->name)
+                );
+                // Removing every other invalid character
+                $this->name = preg_replace('/([^A-Z0-9-])/u', '', $this->name);
+
+            }
+
+        }
+
+        // Validating inner parameters
+        foreach($this->parameters as $param) {
+            $warnings = array_merge($warnings, $param->validate($options));
+        }
+
+        return $warnings;
+
+    }
+
 }
diff --git a/3rdparty/Sabre/VObject/Property/Compound.php b/3rdparty/Sabre/VObject/Property/Compound.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2c18e7726ee491a38d1dbf874b7740871478feb
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Property/Compound.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Sabre\VObject\Property;
+
+use Sabre\VObject;
+
+/**
+* Compound property.
+*
+* This class adds (de)serialization of compound properties to/from arrays.
+*
+* Currently the following properties from RFC 6350 are mapped to use this
+* class:
+*
+*  N:          Section 6.2.2
+*  ADR:        Section 6.3.1
+*  ORG:        Section 6.6.4
+*  CATEGORIES: Section 6.7.1
+*
+* In order to use this correctly, you must call setParts and getParts to
+* retrieve and modify dates respectively.
+*
+* @author Thomas Tanghus (http://tanghus.net/)
+* @author Lars Kneschke
+* @author Evert Pot (http://www.rooftopsolutions.nl/)
+* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+*/
+
+/**
+* This class represents a compound property in a vCard.
+*/
+class Compound extends VObject\Property {
+
+    /**
+    * If property names are added to this map, they will be (de)serialised as arrays
+    * using the getParts() and setParts() methods.
+    * The keys are the property names, values are delimiter chars.
+    *
+    * @var array
+    */
+    static public $delimiterMap = array(
+        'N'				=>	';',
+        'ADR'			=>	';',
+        'ORG'			=>	';',
+        'CATEGORIES'	=>	',',
+    );
+
+    /**
+     * The currently used delimiter.
+     *
+     * @var string
+     */
+    protected $delimiter = null;
+
+    /**
+    * Get a compound value as an array.
+    *
+    * @param $name string
+    * @return array
+    */
+    public function getParts() {
+
+        if (is_null($this->value)) {
+            return array();
+        }
+
+        $delimiter = $this->getDelimiter();
+
+        // split by any $delimiter which is NOT prefixed by a slash.
+        // Note that this is not a a perfect solution. If a value is prefixed
+        // by two slashes, it should actually be split anyway.
+        //
+        // Hopefully we can fix this better in a future version, where we can
+        // break compatibility a bit.
+        $compoundValues = preg_split("/(?<!\\\)$delimiter/", $this->value);
+
+        // remove slashes from any semicolon and comma left escaped in the single values
+        $compoundValues = array_map(
+            function($val) {
+                return strtr($val, array('\,' => ',', '\;' => ';'));
+        }, $compoundValues);
+
+        return $compoundValues;
+
+    }
+
+    /**
+     * Returns the delimiter for this property.
+     *
+     * @return string
+     */
+    public function getDelimiter() {
+
+        if (!$this->delimiter) {
+            if (isset(self::$delimiterMap[$this->name])) {
+                $this->delimiter = self::$delimiterMap[$this->name];
+            } else {
+                // To be a bit future proof, we are going to default the
+                // delimiter to ;
+                $this->delimiter = ';';
+            }
+        }
+        return $this->delimiter;
+
+    }
+
+    /**
+     * Set a compound value as an array.
+     *
+    *
+    * @param $name string
+    * @return array
+    */
+    public function setParts(array $values) {
+
+        // add slashes to all semicolons and commas in the single values
+        $values = array_map(
+            function($val) {
+                return strtr($val, array(',' => '\,', ';' => '\;'));
+            }, $values);
+
+        $this->setValue(
+            implode($this->getDelimiter(), $values)
+        );
+
+    }
+
+}
diff --git a/3rdparty/Sabre/VObject/Property/DateTime.php b/3rdparty/Sabre/VObject/Property/DateTime.php
old mode 100755
new mode 100644
index fe2372caa81cade8eb1aa149ea923e7fd62206dc..556cd441d8a7473ff168b2f38df9cf338a365ac9
--- a/3rdparty/Sabre/VObject/Property/DateTime.php
+++ b/3rdparty/Sabre/VObject/Property/DateTime.php
@@ -1,5 +1,9 @@
 <?php
 
+namespace Sabre\VObject\Property;
+
+use Sabre\VObject;
+
 /**
  * DateTime property
  *
@@ -13,13 +17,11 @@
  * If you use the 'value' or properties directly, this object does not keep
  * reference and results might appear incorrectly.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
+class DateTime extends VObject\Property {
 
     /**
      * Local 'floating' time
@@ -44,7 +46,7 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
     /**
      * DateTime representation
      *
-     * @var DateTime
+     * @var \DateTime
      */
     protected $dateTime;
 
@@ -58,11 +60,11 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
     /**
      * Updates the Date and Time.
      *
-     * @param DateTime $dt
+     * @param \DateTime $dt
      * @param int $dateType
      * @return void
      */
-    public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
+    public function setDateTime(\DateTime $dt, $dateType = self::LOCALTZ) {
 
         switch($dateType) {
 
@@ -73,7 +75,7 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
                 $this->offsetSet('VALUE','DATE-TIME');
                 break;
             case self::UTC :
-                $dt->setTimeZone(new DateTimeZone('UTC'));
+                $dt->setTimeZone(new \DateTimeZone('UTC'));
                 $this->setValue($dt->format('Ymd\\THis\\Z'));
                 $this->offsetUnset('VALUE');
                 $this->offsetUnset('TZID');
@@ -93,7 +95,7 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
                 $this->offsetSet('VALUE','DATE');
                 break;
             default :
-                throw new InvalidArgumentException('You must pass a valid dateType constant');
+                throw new \InvalidArgumentException('You must pass a valid dateType constant');
 
         }
         $this->dateTime = $dt;
@@ -106,7 +108,7 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
      *
      * If no value was set, this method returns null.
      *
-     * @return DateTime|null
+     * @return \DateTime|null
      */
     public function getDateTime() {
 
@@ -152,11 +154,11 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
      *
      * @param string|null $propertyValue The string to parse (yymmdd or
      *                                   ymmddThhmmss, etc..)
-     * @param Sabre_VObject_Property|null $property The instance of the
+     * @param \Sabre\VObject\Property|null $property The instance of the
      *                                              property we're parsing.
      * @return array
      */
-    static public function parseData($propertyValue, Sabre_VObject_Property $property = null) {
+    static public function parseData($propertyValue, VObject\Property $property = null) {
 
         if (is_null($propertyValue)) {
             return array(null, null);
@@ -167,14 +169,14 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
         $regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
 
         if (!preg_match($regex, $propertyValue, $matches)) {
-            throw new InvalidArgumentException($propertyValue . ' is not a valid DateTime or Date string');
+            throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string');
         }
 
         if (!isset($matches['hour'])) {
             // Date-only
             return array(
                 self::DATE,
-                new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
+                new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')),
             );
         }
 
@@ -187,8 +189,8 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
             $matches['second'];
 
         if (isset($matches['isutc'])) {
-            $dt = new DateTime($dateStr,new DateTimeZone('UTC'));
-            $dt->setTimeZone(new DateTimeZone('UTC'));
+            $dt = new \DateTime($dateStr,new \DateTimeZone('UTC'));
+            $dt->setTimeZone(new \DateTimeZone('UTC'));
             return array(
                 self::UTC,
                 $dt
@@ -198,56 +200,27 @@ class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
         // Finding the timezone.
         $tzid = $property['TZID'];
         if (!$tzid) {
+            // This was a floating time string. This implies we use the
+            // timezone from date_default_timezone_set / date.timezone ini
+            // setting.
             return array(
                 self::LOCAL,
-                new DateTime($dateStr)
+                new \DateTime($dateStr)
             );
         }
 
-        try {
-            // tzid an Olson identifier?
-            $tz = new DateTimeZone($tzid->value);
-        } catch (Exception $e) {
-
-            // Not an Olson id, we're going to try to find the information 
-            // through the time zone name map.
-            $newtzid = Sabre_VObject_WindowsTimezoneMap::lookup($tzid->value);
-            if (is_null($newtzid)) {
-
-                // Not a well known time zone name either, we're going to try 
-                // to find the information through the VTIMEZONE object.
-
-                // First we find the root object
-                $root = $property;
-                while($root->parent) {
-                    $root = $root->parent;
-                }
-
-                if (isset($root->VTIMEZONE)) {
-                    foreach($root->VTIMEZONE as $vtimezone) {
-                        if (((string)$vtimezone->TZID) == $tzid) {
-                            if (isset($vtimezone->{'X-LIC-LOCATION'})) {
-                                $newtzid = (string)$vtimezone->{'X-LIC-LOCATION'};
-                            } else {
-                                // No libical location specified. As a last resort we could 
-                                // try matching $vtimezone's DST rules against all known 
-                                // time zones returned by DateTimeZone::list*
-
-                                // TODO
-                            }
-                        }
-                    }
-                }
-            }
-
-            try {
-                $tz = new DateTimeZone($newtzid);
-            } catch (Exception $e) {
-                // If all else fails, we use the default PHP timezone
-                $tz = new DateTimeZone(date_default_timezone_get()); 
-            }
+        // To look up the timezone, we must first find the VCALENDAR component.
+        $root = $property;
+        while($root->parent) {
+            $root = $root->parent;
         }
-        $dt = new DateTime($dateStr, $tz);
+        if ($root->name === 'VCALENDAR') {
+            $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root);
+        } else {
+            $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid);
+        }
+
+        $dt = new \DateTime($dateStr, $tz);
         $dt->setTimeZone($tz);
 
         return array(
diff --git a/3rdparty/Sabre/VObject/Property/MultiDateTime.php b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
old mode 100755
new mode 100644
index ae53ab6a6173a87922c90f8a5bb129ab8a341d92..629ef4a1340c3c391de66ac2375430643aece7cf
--- a/3rdparty/Sabre/VObject/Property/MultiDateTime.php
+++ b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
@@ -1,5 +1,9 @@
 <?php
 
+namespace Sabre\VObject\Property;
+
+use Sabre\VObject;
+
 /**
  * Multi-DateTime property
  *
@@ -13,13 +17,11 @@
  * If you use the 'value' or properties directly, this object does not keep
  * reference and results might appear incorrectly.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
+class MultiDateTime extends VObject\Property {
 
     /**
      * DateTime representation
@@ -31,7 +33,7 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
     /**
      * dateType
      *
-     * This is one of the Sabre_VObject_Property_DateTime constants.
+     * This is one of the Sabre\VObject\Property\DateTime constants.
      *
      * @var int
      */
@@ -44,17 +46,17 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
      * @param int $dateType
      * @return void
      */
-    public function setDateTimes(array $dt, $dateType = Sabre_VObject_Property_DateTime::LOCALTZ) {
+    public function setDateTimes(array $dt, $dateType = VObject\Property\DateTime::LOCALTZ) {
 
         foreach($dt as $i)
-            if (!$i instanceof DateTime)
-                throw new InvalidArgumentException('You must pass an array of DateTime objects');
+            if (!$i instanceof \DateTime)
+                throw new \InvalidArgumentException('You must pass an array of DateTime objects');
 
         $this->offsetUnset('VALUE');
         $this->offsetUnset('TZID');
         switch($dateType) {
 
-            case Sabre_VObject_Property_DateTime::LOCAL :
+            case DateTime::LOCAL :
                 $val = array();
                 foreach($dt as $i) {
                     $val[] = $i->format('Ymd\\THis');
@@ -62,16 +64,16 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
                 $this->setValue(implode(',',$val));
                 $this->offsetSet('VALUE','DATE-TIME');
                 break;
-            case Sabre_VObject_Property_DateTime::UTC :
+            case DateTime::UTC :
                 $val = array();
                 foreach($dt as $i) {
-                    $i->setTimeZone(new DateTimeZone('UTC'));
+                    $i->setTimeZone(new \DateTimeZone('UTC'));
                     $val[] = $i->format('Ymd\\THis\\Z');
                 }
                 $this->setValue(implode(',',$val));
                 $this->offsetSet('VALUE','DATE-TIME');
                 break;
-            case Sabre_VObject_Property_DateTime::LOCALTZ :
+            case DateTime::LOCALTZ :
                 $val = array();
                 foreach($dt as $i) {
                     $val[] = $i->format('Ymd\\THis');
@@ -80,7 +82,7 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
                 $this->offsetSet('VALUE','DATE-TIME');
                 $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
                 break;
-            case Sabre_VObject_Property_DateTime::DATE :
+            case DateTime::DATE :
                 $val = array();
                 foreach($dt as $i) {
                     $val[] = $i->format('Ymd');
@@ -89,7 +91,7 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
                 $this->offsetSet('VALUE','DATE');
                 break;
             default :
-                throw new InvalidArgumentException('You must pass a valid dateType constant');
+                throw new \InvalidArgumentException('You must pass a valid dateType constant');
 
         }
         $this->dateTimes = $dt;
@@ -121,7 +123,7 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
             list(
                 $type,
                 $dt
-            ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+            ) = DateTime::parseData($val, $this);
             $dts[] = $dt;
             $this->dateType = $type;
         }
@@ -154,7 +156,7 @@ class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
             list(
                 $type,
                 $dt
-            ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+            ) = DateTime::parseData($val, $this);
             $dts[] = $dt;
             $this->dateType = $type;
         }
diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php
old mode 100755
new mode 100644
index eea73fa3dcee68163a42e9703a748feb783007fb..a24590cb3884a39260c3581ad8389492c872a6ba
--- a/3rdparty/Sabre/VObject/Reader.php
+++ b/3rdparty/Sabre/VObject/Reader.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * VCALENDAR/VCARD reader
  *
@@ -8,21 +10,38 @@
  * TODO: this class currently completely works 'statically'. This is pointless,
  * and defeats OOP principals. Needs refactoring in a future version.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Reader {
+class Reader {
+
+    /**
+     * If this option is passed to the reader, it will be less strict about the
+     * validity of the lines.
+     *
+     * Currently using this option just means, that it will accept underscores
+     * in property names.
+     */
+    const OPTION_FORGIVING = 1;
+
+    /**
+     * If this option is turned on, any lines we cannot parse will be ignored
+     * by the reader.
+     */
+    const OPTION_IGNORE_INVALID_LINES = 2;
 
     /**
      * Parses the file and returns the top component
      *
+     * The options argument is a bitfield. Pass any of the OPTIONS constant to
+     * alter the parsers' behaviour.
+     *
      * @param string $data
-     * @return Sabre_VObject_Element
+     * @param int $options
+     * @return Node
      */
-    static function read($data) {
+    static function read($data, $options = 0) {
 
         // Normalizing newlines
         $data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
@@ -48,7 +67,7 @@ class Sabre_VObject_Reader {
 
         reset($lines2);
 
-        return self::readLine($lines2);
+        return self::readLine($lines2, $options);
 
     }
 
@@ -58,37 +77,45 @@ class Sabre_VObject_Reader {
      * This method receives the full array of lines. The array pointer is used
      * to traverse.
      *
+     * This method returns null if an invalid line was encountered, and the
+     * IGNORE_INVALID_LINES option was turned on.
+     *
      * @param array $lines
-     * @return Sabre_VObject_Element
+     * @param int $options See the OPTIONS constants.
+     * @return Node
      */
-    static private function readLine(&$lines) {
+    static private function readLine(&$lines, $options = 0) {
 
         $line = current($lines);
         $lineNr = key($lines);
         next($lines);
 
         // Components
-        if (stripos($line,"BEGIN:")===0) {
+        if (strtoupper(substr($line,0,6)) === "BEGIN:") {
 
             $componentName = strtoupper(substr($line,6));
-            $obj = Sabre_VObject_Component::create($componentName);
+            $obj = Component::create($componentName);
 
             $nextLine = current($lines);
 
-            while(stripos($nextLine,"END:")!==0) {
-
-                $obj->add(self::readLine($lines));
+            while(strtoupper(substr($nextLine,0,4))!=="END:") {
 
+                $parsedLine = self::readLine($lines, $options);
                 $nextLine = current($lines);
 
+                if (is_null($parsedLine)) {
+                    continue;
+                }
+                $obj->add($parsedLine);
+
                 if ($nextLine===false)
-                    throw new Sabre_VObject_ParseException('Invalid VObject. Document ended prematurely.');
+                    throw new ParseException('Invalid VObject. Document ended prematurely.');
 
             }
 
             // Checking component name of the 'END:' line.
             if (substr($nextLine,4)!==$obj->name) {
-                throw new Sabre_VObject_ParseException('Invalid VObject, expected: "END:' . $obj->name . '" got: "' . $nextLine . '"');
+                throw new ParseException('Invalid VObject, expected: "END:' . $obj->name . '" got: "' . $nextLine . '"');
             }
             next($lines);
 
@@ -99,19 +126,26 @@ class Sabre_VObject_Reader {
         // Properties
         //$result = preg_match('/(?P<name>[A-Z0-9-]+)(?:;(?P<parameters>^(?<!:):))(.*)$/',$line,$matches);
 
-
-        $token = '[A-Z0-9-\.]+';
+        if ($options & self::OPTION_FORGIVING) {
+            $token = '[A-Z0-9-\._]+';
+        } else {
+            $token = '[A-Z0-9-\.]+';
+        }
         $parameters = "(?:;(?P<parameters>([^:^\"]|\"([^\"]*)\")*))?";
         $regex = "/^(?P<name>$token)$parameters:(?P<value>.*)$/i";
 
         $result = preg_match($regex,$line,$matches);
 
         if (!$result) {
-            throw new Sabre_VObject_ParseException('Invalid VObject, line ' . ($lineNr+1) . ' did not follow the icalendar/vcard format');
+            if ($options & self::OPTION_IGNORE_INVALID_LINES) {
+                return null;
+            } else {
+                throw new ParseException('Invalid VObject, line ' . ($lineNr+1) . ' did not follow the icalendar/vcard format');
+            }
         }
 
         $propertyName = strtoupper($matches['name']);
-        $propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
+        $propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n))#',function($matches) {
             if ($matches[2]==='n' || $matches[2]==='N') {
                 return "\n";
             } else {
@@ -119,7 +153,7 @@ class Sabre_VObject_Reader {
             }
         }, $matches['value']);
 
-        $obj = Sabre_VObject_Property::create($propertyName, $propertyValue);
+        $obj = Property::create($propertyName, $propertyValue);
 
         if ($matches['parameters']) {
 
@@ -137,7 +171,7 @@ class Sabre_VObject_Reader {
     /**
      * Reads a parameter list from a property
      *
-     * This method returns an array of Sabre_VObject_Parameter
+     * This method returns an array of Parameter
      *
      * @param string $parameters
      * @return array
@@ -171,7 +205,7 @@ class Sabre_VObject_Reader {
                 }
             }, $value);
 
-            $params[] = new Sabre_VObject_Parameter($match['paramName'], $value);
+            $params[] = new Parameter($match['paramName'], $value);
 
         }
 
diff --git a/3rdparty/Sabre/VObject/RecurrenceIterator.php b/3rdparty/Sabre/VObject/RecurrenceIterator.php
old mode 100755
new mode 100644
index 740270dd8f0794719b5086ddc6919a14c4b04238..46c7f447806644e433eb7f7b8fae28d6efe2bd13
--- a/3rdparty/Sabre/VObject/RecurrenceIterator.php
+++ b/3rdparty/Sabre/VObject/RecurrenceIterator.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * This class is used to determine new for a recurring event, when the next
  * events occur.
@@ -37,13 +39,11 @@
  * you may get unexpected results. The effect is that in some applications the
  * specified recurrence may look incorrect, or is missing.
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_RecurrenceIterator implements Iterator {
+class RecurrenceIterator implements \Iterator {
 
     /**
      * The initial event date
@@ -82,7 +82,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
     /**
      * Base event
      *
-     * @var Sabre_VObject_Component_VEvent
+     * @var Component\VEvent
      */
     public $baseEvent;
 
@@ -97,7 +97,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
     /**
      * list of events that are 'overridden'.
      *
-     * This is an array of Sabre_VObject_Component_VEvent objects.
+     * This is an array of Component\VEvent objects.
      *
      * @var array
      */
@@ -281,7 +281,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
      * If the current iteration of the event is an overriden event, this
      * property will hold the VObject
      *
-     * @var Sabre_Component_VObject
+     * @var Component
      */
     private $currentOverriddenEvent;
 
@@ -300,14 +300,14 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
      * You should pass a VCALENDAR component, as well as the UID of the event
      * we're going to traverse.
      *
-     * @param Sabre_VObject_Component $vcal
+     * @param Component $vcal
      * @param string|null $uid
      */
-    public function __construct(Sabre_VObject_Component $vcal, $uid=null) {
+    public function __construct(Component $vcal, $uid=null) {
 
         if (is_null($uid)) {
             if ($vcal->name === 'VCALENDAR') {
-                throw new InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
+                throw new \InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
             }
             $components = array($vcal);
             $uid = (string)$vcal->uid;
@@ -325,7 +325,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
             }
         }
         if (!$this->baseEvent) {
-            throw new InvalidArgumentException('Could not find a base event with uid: ' . $uid);
+            throw new \InvalidArgumentException('Could not find a base event with uid: ' . $uid);
         }
 
         $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
@@ -336,8 +336,8 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
         } else {
             $this->endDate = clone $this->startDate;
             if (isset($this->baseEvent->DURATION)) {
-                $this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value));
-            } elseif ($this->baseEvent->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) {
+                $this->endDate->add(DateTimeParser::parse($this->baseEvent->DURATION->value));
+            } elseif ($this->baseEvent->DTSTART->getDateType()===Property\DateTime::DATE) {
                 $this->endDate->modify('+1 day');
             }
         }
@@ -347,7 +347,11 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
 
         $parts = explode(';', $rrule);
 
-        foreach($parts as $part) {
+        // If no rrule was specified, we create a default setting
+        if (!$rrule) {
+            $this->frequency = 'daily';
+            $this->count = 1;
+        } else foreach($parts as $part) {
 
             list($key, $value) = explode('=', $part, 2);
 
@@ -358,14 +362,14 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
                         strtolower($value),
                         array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
                     )) {
-                        throw new InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
+                        throw new \InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
 
                     }
                     $this->frequency = strtolower($value);
                     break;
 
                 case 'UNTIL' :
-                    $this->until = Sabre_VObject_DateTimeParser::parse($value);
+                    $this->until = DateTimeParser::parse($value);
                     break;
 
                 case 'COUNT' :
@@ -374,6 +378,9 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
 
                 case 'INTERVAL' :
                     $this->interval = (int)$value;
+                    if ($this->interval < 1) {
+                        throw new \InvalidArgumentException('INTERVAL in RRULE must be a positive integer!');
+                    }
                     break;
 
                 case 'BYSECOND' :
@@ -427,7 +434,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
                 foreach(explode(',', (string)$exDate) as $exceptionDate) {
 
                     $this->exceptionDates[] =
-                        Sabre_VObject_DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
+                        DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
 
                 }
 
@@ -485,7 +492,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
      *
      * This method always returns a cloned instance.
      *
-     * @return void
+     * @return Component\VEvent
      */
     public function getEventObject() {
 
@@ -561,7 +568,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
      * @param DateTime $dt
      * @return void
      */
-    public function fastForward(DateTime $dt) {
+    public function fastForward(\DateTime $dt) {
 
         while($this->valid() && $this->getDTEnd() <= $dt) {
             $this->next();
@@ -569,6 +576,17 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
 
     }
 
+    /**
+     * Returns true if this recurring event never ends.
+     *
+     * @return bool
+     */
+    public function isInfinite() {
+
+        return !$this->count && !$this->until;
+
+    }
+
     /**
      * Goes on to the next iteration
      *
@@ -632,7 +650,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
 
             }
 
-            // Checking overriden events
+            // Checking overridden events
             foreach($this->overriddenEvents as $index=>$event) {
                 if ($index > $previousStamp && $index <= $currentStamp) {
 
@@ -880,7 +898,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
                     // The first occurrence that's higher than the current
                     // day of the month wins.
                     // If we advanced to the next month or year, the first
-                    // occurence is always correct.
+                    // occurrence is always correct.
                     if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
                         break 2;
                     }
diff --git a/3rdparty/Sabre/VObject/Splitter/ICalendar.php b/3rdparty/Sabre/VObject/Splitter/ICalendar.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a9a63e1b2195cbc963e8fb7d541d47ed9d21b7e
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Splitter/ICalendar.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Sabre\VObject\Splitter;
+
+use Sabre\VObject;
+
+/**
+ * Splitter
+ *
+ * This class is responsible for splitting up iCalendar objects.
+ *
+ * This class expects a single VCALENDAR object with one or more
+ * calendar-objects inside. Objects with identical UID's will be combined into
+ * a single object.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Dominik Tobschall
+ * @author Armin Hackmann
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ICalendar implements SplitterInterface {
+
+    /**
+     * Timezones
+     *
+     * @var array
+     */
+    protected $vtimezones = array();
+
+    /**
+     * iCalendar objects
+     *
+     * @var array
+     */
+    protected $objects = array();
+
+    /**
+     * Constructor
+     *
+     * The splitter should receive an readable file stream as it's input.
+     *
+     * @param resource $input
+     */
+    public function __construct($input) {
+
+        $data = VObject\Reader::read(stream_get_contents($input));
+        $vtimezones = array();
+        $components = array();
+
+        foreach($data->children as $component) {
+            if (!$component instanceof VObject\Component) {
+                continue;
+            }
+
+            // Get all timezones
+            if ($component->name === 'VTIMEZONE') {
+                $this->vtimezones[(string)$component->TZID] = $component;
+                continue;
+            }
+
+            // Get component UID for recurring Events search
+            if($component->UID) {
+                $uid = (string)$component->UID;
+            } else {
+                // Generating a random UID
+                $uid = sha1(microtime()) . '-vobjectimport';
+            }
+
+            // Take care of recurring events
+            if (!array_key_exists($uid, $this->objects)) {
+                $this->objects[$uid] = VObject\Component::create('VCALENDAR');
+            }
+
+            $this->objects[$uid]->add(clone $component);
+        }
+
+    }
+
+    /**
+     * Every time getNext() is called, a new object will be parsed, until we
+     * hit the end of the stream.
+     *
+     * When the end is reached, null will be returned.
+     *
+     * @return Sabre\VObject\Component|null
+     */
+    public function getNext() {
+
+        if($object=array_shift($this->objects)) {
+
+            // create our baseobject
+            $object->version = '2.0';
+            $object->prodid = '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN';
+            $object->calscale = 'GREGORIAN';
+
+            // add vtimezone information to obj (if we have it)
+            foreach ($this->vtimezones as $vtimezone) {
+                $object->add($vtimezone);
+            }
+
+            return $object;
+
+        } else {
+
+            return null;
+
+        }
+
+   }
+
+}
diff --git a/3rdparty/Sabre/VObject/Splitter/SplitterInterface.php b/3rdparty/Sabre/VObject/Splitter/SplitterInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f7a82450e3de9e6ad8f26c0752c0d8bbf26f525
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Splitter/SplitterInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\VObject\Splitter;
+
+/**
+ * VObject splitter
+ *
+ * The splitter is responsible for reading a large vCard or iCalendar object,
+ * and splitting it into multiple objects.
+ *
+ * This is for example for Card and CalDAV, which require every event and vcard
+ * to exist in their own objects, instead of one large one.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Dominik Tobschall
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface SplitterInterface {
+
+    /**
+     * Constructor
+     *
+     * The splitter should receive an readable file stream as it's input.
+     *
+     * @param resource $input
+     */
+    function __construct($input);
+
+    /**
+     * Every time getNext() is called, a new object will be parsed, until we
+     * hit the end of the stream.
+     *
+     * When the end is reached, null will be returned.
+     *
+     * @return Sabre\VObject\Component|null
+     */
+    function getNext();
+
+}
diff --git a/3rdparty/Sabre/VObject/Splitter/VCard.php b/3rdparty/Sabre/VObject/Splitter/VCard.php
new file mode 100644
index 0000000000000000000000000000000000000000..829491ed07a2dc7e2e24173edd353a006bcd080f
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Splitter/VCard.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Sabre\VObject\Splitter;
+
+use Sabre\VObject;
+
+/**
+ * Splitter
+ *
+ * This class is responsible for splitting up VCard objects.
+ *
+ * It is assumed that the input stream contains 1 or more VCARD objects. This
+ * class checks for BEGIN:VCARD and END:VCARD and parses each encountered
+ * component individually.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Dominik Tobschall
+ * @author Armin Hackmann
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class VCard implements SplitterInterface {
+
+    /**
+     * File handle
+     *
+     * @var resource
+     */
+    protected $input;
+
+    /**
+     * Constructor
+     *
+     * The splitter should receive an readable file stream as it's input.
+     *
+     * @param resource $input
+     */
+    public function __construct($input) {
+
+        $this->input = $input;
+
+    }
+
+    /**
+     * Every time getNext() is called, a new object will be parsed, until we
+     * hit the end of the stream.
+     *
+     * When the end is reached, null will be returned.
+     *
+     * @return Sabre\VObject\Component|null
+     */
+    public function getNext() {
+
+        $vcard = '';
+
+        do {
+
+            if (feof($this->input)) {
+                return false;
+            }
+
+            $line = fgets($this->input);
+            $vcard .= $line;
+
+        } while(strtoupper(substr($line,0,4))!=="END:");
+
+        $object = VObject\Reader::read($vcard);
+
+        if($object->name !== 'VCARD') {
+            throw new \InvalidArgumentException("Thats no vCard!", 1);
+        }
+
+        return $object;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/VObject/StringUtil.php b/3rdparty/Sabre/VObject/StringUtil.php
new file mode 100644
index 0000000000000000000000000000000000000000..886a7135d67dbebcd491aa5cb03d3f87e3ba5117
--- /dev/null
+++ b/3rdparty/Sabre/VObject/StringUtil.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Useful utilities for working with various strings.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class StringUtil {
+
+    /**
+     * Returns true or false depending on if a string is valid UTF-8
+     *
+     * @param string $str
+     * @return bool
+     */
+    static function isUTF8($str) {
+
+        // First check.. mb_check_encoding
+        if (!mb_check_encoding($str, 'UTF-8')) {
+            return false;
+        }
+
+        // Control characters
+        if (preg_match('%(?:[\x00-\x08\x0B-\x0C\x0E\x0F])%', $str)) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    /**
+     * This method tries its best to convert the input string to UTF-8.
+     *
+     * Currently only ISO-5991-1 input and UTF-8 input is supported, but this
+     * may be expanded upon if we receive other examples.
+     *
+     * @param string $str
+     * @return string
+     */
+    static function convertToUTF8($str) {
+
+        $encoding = mb_detect_encoding($str , array('UTF-8','ISO-8859-1'), true);
+
+        if ($encoding === 'ISO-8859-1') {
+            $newStr = utf8_encode($str);
+        } else {
+            $newStr = $str;
+        }
+
+        // Removing any control characters
+        return (preg_replace('%(?:[\x00-\x08\x0B-\x0C\x0E\x0F])%', '', $newStr));
+
+    }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/TimeZoneUtil.php b/3rdparty/Sabre/VObject/TimeZoneUtil.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba73cf34a7970b9fe82a21b08adcda8d82384e17
--- /dev/null
+++ b/3rdparty/Sabre/VObject/TimeZoneUtil.php
@@ -0,0 +1,351 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Time zone name translation
+ *
+ * This file translates well-known time zone names into "Olson database" time zone names.
+ *
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Frank Edelhaeuser (fedel@users.sourceforge.net)
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class TimeZoneUtil {
+
+    public static $map = array(
+
+        // from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html
+        // snapshot taken on 2012/01/16
+
+        // windows
+        'AUS Central Standard Time'=>'Australia/Darwin',
+        'AUS Eastern Standard Time'=>'Australia/Sydney',
+        'Afghanistan Standard Time'=>'Asia/Kabul',
+        'Alaskan Standard Time'=>'America/Anchorage',
+        'Arab Standard Time'=>'Asia/Riyadh',
+        'Arabian Standard Time'=>'Asia/Dubai',
+        'Arabic Standard Time'=>'Asia/Baghdad',
+        'Argentina Standard Time'=>'America/Buenos_Aires',
+        'Armenian Standard Time'=>'Asia/Yerevan',
+        'Atlantic Standard Time'=>'America/Halifax',
+        'Azerbaijan Standard Time'=>'Asia/Baku',
+        'Azores Standard Time'=>'Atlantic/Azores',
+        'Bangladesh Standard Time'=>'Asia/Dhaka',
+        'Canada Central Standard Time'=>'America/Regina',
+        'Cape Verde Standard Time'=>'Atlantic/Cape_Verde',
+        'Caucasus Standard Time'=>'Asia/Yerevan',
+        'Cen. Australia Standard Time'=>'Australia/Adelaide',
+        'Central America Standard Time'=>'America/Guatemala',
+        'Central Asia Standard Time'=>'Asia/Almaty',
+        'Central Brazilian Standard Time'=>'America/Cuiaba',
+        'Central Europe Standard Time'=>'Europe/Budapest',
+        'Central European Standard Time'=>'Europe/Warsaw',
+        'Central Pacific Standard Time'=>'Pacific/Guadalcanal',
+        'Central Standard Time'=>'America/Chicago',
+        'Central Standard Time (Mexico)'=>'America/Mexico_City',
+        'China Standard Time'=>'Asia/Shanghai',
+        'Dateline Standard Time'=>'Etc/GMT+12',
+        'E. Africa Standard Time'=>'Africa/Nairobi',
+        'E. Australia Standard Time'=>'Australia/Brisbane',
+        'E. Europe Standard Time'=>'Europe/Minsk',
+        'E. South America Standard Time'=>'America/Sao_Paulo',
+        'Eastern Standard Time'=>'America/New_York',
+        'Egypt Standard Time'=>'Africa/Cairo',
+        'Ekaterinburg Standard Time'=>'Asia/Yekaterinburg',
+        'FLE Standard Time'=>'Europe/Kiev',
+        'Fiji Standard Time'=>'Pacific/Fiji',
+        'GMT Standard Time'=>'Europe/London',
+        'GTB Standard Time'=>'Europe/Istanbul',
+        'Georgian Standard Time'=>'Asia/Tbilisi',
+        'Greenland Standard Time'=>'America/Godthab',
+        'Greenwich Standard Time'=>'Atlantic/Reykjavik',
+        'Hawaiian Standard Time'=>'Pacific/Honolulu',
+        'India Standard Time'=>'Asia/Calcutta',
+        'Iran Standard Time'=>'Asia/Tehran',
+        'Israel Standard Time'=>'Asia/Jerusalem',
+        'Jordan Standard Time'=>'Asia/Amman',
+        'Kamchatka Standard Time'=>'Asia/Kamchatka',
+        'Korea Standard Time'=>'Asia/Seoul',
+        'Magadan Standard Time'=>'Asia/Magadan',
+        'Mauritius Standard Time'=>'Indian/Mauritius',
+        'Mexico Standard Time'=>'America/Mexico_City',
+        'Mexico Standard Time 2'=>'America/Chihuahua',
+        'Mid-Atlantic Standard Time'=>'Etc/GMT+2',
+        'Middle East Standard Time'=>'Asia/Beirut',
+        'Montevideo Standard Time'=>'America/Montevideo',
+        'Morocco Standard Time'=>'Africa/Casablanca',
+        'Mountain Standard Time'=>'America/Denver',
+        'Mountain Standard Time (Mexico)'=>'America/Chihuahua',
+        'Myanmar Standard Time'=>'Asia/Rangoon',
+        'N. Central Asia Standard Time'=>'Asia/Novosibirsk',
+        'Namibia Standard Time'=>'Africa/Windhoek',
+        'Nepal Standard Time'=>'Asia/Katmandu',
+        'New Zealand Standard Time'=>'Pacific/Auckland',
+        'Newfoundland Standard Time'=>'America/St_Johns',
+        'North Asia East Standard Time'=>'Asia/Irkutsk',
+        'North Asia Standard Time'=>'Asia/Krasnoyarsk',
+        'Pacific SA Standard Time'=>'America/Santiago',
+        'Pacific Standard Time'=>'America/Los_Angeles',
+        'Pacific Standard Time (Mexico)'=>'America/Santa_Isabel',
+        'Pakistan Standard Time'=>'Asia/Karachi',
+        'Paraguay Standard Time'=>'America/Asuncion',
+        'Romance Standard Time'=>'Europe/Paris',
+        'Russian Standard Time'=>'Europe/Moscow',
+        'SA Eastern Standard Time'=>'America/Cayenne',
+        'SA Pacific Standard Time'=>'America/Bogota',
+        'SA Western Standard Time'=>'America/La_Paz',
+        'SE Asia Standard Time'=>'Asia/Bangkok',
+        'Samoa Standard Time'=>'Pacific/Apia',
+        'Singapore Standard Time'=>'Asia/Singapore',
+        'South Africa Standard Time'=>'Africa/Johannesburg',
+        'Sri Lanka Standard Time'=>'Asia/Colombo',
+        'Syria Standard Time'=>'Asia/Damascus',
+        'Taipei Standard Time'=>'Asia/Taipei',
+        'Tasmania Standard Time'=>'Australia/Hobart',
+        'Tokyo Standard Time'=>'Asia/Tokyo',
+        'Tonga Standard Time'=>'Pacific/Tongatapu',
+        'US Eastern Standard Time'=>'America/Indianapolis',
+        'US Mountain Standard Time'=>'America/Phoenix',
+        'UTC'=>'Etc/GMT',
+        'UTC+12'=>'Etc/GMT-12',
+        'UTC-02'=>'Etc/GMT+2',
+        'UTC-11'=>'Etc/GMT+11',
+        'Ulaanbaatar Standard Time'=>'Asia/Ulaanbaatar',
+        'Venezuela Standard Time'=>'America/Caracas',
+        'Vladivostok Standard Time'=>'Asia/Vladivostok',
+        'W. Australia Standard Time'=>'Australia/Perth',
+        'W. Central Africa Standard Time'=>'Africa/Lagos',
+        'W. Europe Standard Time'=>'Europe/Berlin',
+        'West Asia Standard Time'=>'Asia/Tashkent',
+        'West Pacific Standard Time'=>'Pacific/Port_Moresby',
+        'Yakutsk Standard Time'=>'Asia/Yakutsk',
+
+        // Microsoft exchange timezones
+        // Source:
+        // http://msdn.microsoft.com/en-us/library/ms988620%28v=exchg.65%29.aspx
+        //
+        // Correct timezones deduced with help from:
+        // http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
+        'Universal Coordinated Time' => 'UTC',
+        'Casablanca, Monrovia' => 'Africa/Casablanca',
+        'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon',
+        'Greenwich Mean Time; Dublin, Edinburgh, London' =>  'Europe/London',
+        'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
+        'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague',
+        'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
+        'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris',
+        'Prague, Central Europe' => 'Europe/Prague',
+        'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo',
+        'West Central Africa' => 'Africa/Luanda', // This was a best guess
+        'Athens, Istanbul, Minsk' => 'Europe/Athens',
+        'Bucharest' => 'Europe/Bucharest',
+        'Cairo' => 'Africa/Cairo',
+        'Harare, Pretoria' => 'Africa/Harare',
+        'Helsinki, Riga, Tallinn' => 'Europe/Helsinki',
+        'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem',
+        'Baghdad' => 'Asia/Baghdad',
+        'Arab, Kuwait, Riyadh' => 'Asia/Kuwait',
+        'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
+        'East Africa, Nairobi' => 'Africa/Nairobi',
+        'Tehran' => 'Asia/Tehran',
+        'Abu Dhabi, Muscat' => 'Asia/Muscat', // Best guess
+        'Baku, Tbilisi, Yerevan' => 'Asia/Baku',
+        'Kabul' => 'Asia/Kabul',
+        'Ekaterinburg' => 'Asia/Yekaterinburg',
+        'Islamabad, Karachi, Tashkent' => 'Asia/Karachi',
+        'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta',
+        'Kathmandu, Nepal' => 'Asia/Kathmandu',
+        'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty',
+        'Astana, Dhaka' => 'Asia/Dhaka',
+        'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo',
+        'Rangoon' => 'Asia/Rangoon',
+        'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
+        'Krasnoyarsk' => 'Asia/Krasnoyarsk',
+        'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai',
+        'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk',
+        'Kuala Lumpur, Singapore' => 'Asia/Singapore',
+        'Perth, Western Australia' => 'Australia/Perth',
+        'Taipei' => 'Asia/Taipei',
+        'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
+        'Seoul, Korea Standard time' => 'Asia/Seoul',
+        'Yakutsk' => 'Asia/Yakutsk',
+        'Adelaide, Central Australia' => 'Australia/Adelaide',
+        'Darwin' => 'Australia/Darwin',
+        'Brisbane, East Australia' => 'Australia/Brisbane',
+        'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney',
+        'Guam, Port Moresby' => 'Pacific/Guam',
+        'Hobart, Tasmania' => 'Australia/Hobart',
+        'Vladivostok' => 'Asia/Vladivostok',
+        'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan',
+        'Auckland, Wellington' => 'Pacific/Auckland',
+        'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji',
+        'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu',
+        'Azores' => 'Atlantic/Azores',
+        'Cape Verde Is.' => 'Atlantic/Cape_Verde',
+        'Mid-Atlantic' => 'America/Noronha',
+        'Brasilia' => 'America/Sao_Paulo', // Best guess
+        'Buenos Aires' => 'America/Argentina/Buenos_Aires',
+        'Greenland' => 'America/Godthab',
+        'Newfoundland' => 'America/St_Johns',
+        'Atlantic Time (Canada)' => 'America/Halifax',
+        'Caracas, La Paz' => 'America/Caracas',
+        'Santiago' => 'America/Santiago',
+        'Bogota, Lima, Quito' => 'America/Bogota',
+        'Eastern Time (US & Canada)' => 'America/New_York',
+        'Indiana (East)' => 'America/Indiana/Indianapolis',
+        'Central America' => 'America/Guatemala',
+        'Central Time (US & Canada)' => 'America/Chicago',
+        'Mexico City, Tegucigalpa' => 'America/Mexico_City',
+        'Saskatchewan' => 'America/Edmonton',
+        'Arizona' => 'America/Phoenix',
+        'Mountain Time (US & Canada)' => 'America/Denver', // Best guess
+        'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', // Best guess
+        'Alaska' => 'America/Anchorage',
+        'Hawaii' => 'Pacific/Honolulu',
+        'Midway Island, Samoa' => 'Pacific/Midway',
+        'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein',
+
+    );
+
+    public static $microsoftExchangeMap = array(
+        0  => 'UTC',
+        31 => 'Africa/Casablanca',
+        2  => 'Europe/Lisbon',
+        1  => 'Europe/London',
+        4  => 'Europe/Berlin',
+        6  => 'Europe/Prague',
+        3  => 'Europe/Paris',
+        69 => 'Africa/Luanda', // This was a best guess
+        7  => 'Europe/Athens',
+        5  => 'Europe/Bucharest',
+        49 => 'Africa/Cairo',
+        50 => 'Africa/Harare',
+        59 => 'Europe/Helsinki',
+        27 => 'Asia/Jerusalem',
+        26 => 'Asia/Baghdad',
+        74 => 'Asia/Kuwait',
+        51 => 'Europe/Moscow',
+        56 => 'Africa/Nairobi',
+        25 => 'Asia/Tehran',
+        24 => 'Asia/Muscat', // Best guess
+        54 => 'Asia/Baku',
+        48 => 'Asia/Kabul',
+        58 => 'Asia/Yekaterinburg',
+        47 => 'Asia/Karachi',
+        23 => 'Asia/Calcutta',
+        62 => 'Asia/Kathmandu',
+        46 => 'Asia/Almaty',
+        71 => 'Asia/Dhaka',
+        66 => 'Asia/Colombo',
+        61 => 'Asia/Rangoon',
+        22 => 'Asia/Bangkok',
+        64 => 'Asia/Krasnoyarsk',
+        45 => 'Asia/Shanghai',
+        63 => 'Asia/Irkutsk',
+        21 => 'Asia/Singapore',
+        73 => 'Australia/Perth',
+        75 => 'Asia/Taipei',
+        20 => 'Asia/Tokyo',
+        72 => 'Asia/Seoul',
+        70 => 'Asia/Yakutsk',
+        19 => 'Australia/Adelaide',
+        44 => 'Australia/Darwin',
+        18 => 'Australia/Brisbane',
+        76 => 'Australia/Sydney',
+        43 => 'Pacific/Guam',
+        42 => 'Australia/Hobart',
+        68 => 'Asia/Vladivostok',
+        41 => 'Asia/Magadan',
+        17 => 'Pacific/Auckland',
+        40 => 'Pacific/Fiji',
+        67 => 'Pacific/Tongatapu',
+        29 => 'Atlantic/Azores',
+        53 => 'Atlantic/Cape_Verde',
+        30 => 'America/Noronha',
+         8 => 'America/Sao_Paulo', // Best guess
+        32 => 'America/Argentina/Buenos_Aires',
+        60 => 'America/Godthab',
+        28 => 'America/St_Johns',
+         9 => 'America/Halifax',
+        33 => 'America/Caracas',
+        65 => 'America/Santiago',
+        35 => 'America/Bogota',
+        10 => 'America/New_York',
+        34 => 'America/Indiana/Indianapolis',
+        55 => 'America/Guatemala',
+        11 => 'America/Chicago',
+        37 => 'America/Mexico_City',
+        36 => 'America/Edmonton',
+        38 => 'America/Phoenix',
+        12 => 'America/Denver', // Best guess
+        13 => 'America/Los_Angeles', // Best guess
+        14 => 'America/Anchorage',
+        15 => 'Pacific/Honolulu',
+        16 => 'Pacific/Midway',
+        39 => 'Pacific/Kwajalein',
+    );
+
+    /**
+     * This method will try to find out the correct timezone for an iCalendar
+     * date-time value.
+     *
+     * You must pass the contents of the TZID parameter, as well as the full
+     * calendar.
+     *
+     * If the lookup fails, this method will return UTC.
+     *
+     * @param string $tzid
+     * @param Sabre\VObject\Component $vcalendar
+     * @return DateTimeZone
+     */
+    static public function getTimeZone($tzid, Component $vcalendar = null) {
+
+        // First we will just see if the tzid is a support timezone identifier.
+        try {
+            return new \DateTimeZone($tzid);
+        } catch (\Exception $e) {
+        }
+
+        // Next, we check if the tzid is somewhere in our tzid map.
+        if (isset(self::$map[$tzid])) {
+            return new \DateTimeZone(self::$map[$tzid]);
+        }
+
+        if ($vcalendar) {
+
+            // If that didn't work, we will scan VTIMEZONE objects
+            foreach($vcalendar->select('VTIMEZONE') as $vtimezone) {
+
+                if ((string)$vtimezone->TZID === $tzid) {
+
+                    // Some clients add 'X-LIC-LOCATION' with the olson name.
+                    if (isset($vtimezone->{'X-LIC-LOCATION'})) {
+                        try {
+                            return new \DateTimeZone($vtimezone->{'X-LIC-LOCATION'});
+                        } catch (\Exception $e) {
+                        }
+
+                    }
+                    // Microsoft may add a magic number, which we also have an
+                    // answer for.
+                    if (isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) {
+                        if (isset(self::$microsoftExchangeMap[(int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->value])) {
+                            return new \DateTimeZone(self::$microsoftExchangeMap[(int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->value]);
+                        }
+                    }
+                }
+
+            }
+
+        }
+
+        // If we got all the way here, we default to UTC.
+        return new \DateTimeZone(date_default_timezone_get());
+
+
+    }
+
+
+}
diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php
old mode 100755
new mode 100644
index 9ee03d871181899be61043c38e056978d8d082f1..0065b7abc95cf978744562d802dd34b8cf4d5024
--- a/3rdparty/Sabre/VObject/Version.php
+++ b/3rdparty/Sabre/VObject/Version.php
@@ -1,20 +1,20 @@
 <?php
 
+namespace Sabre\VObject;
+
 /**
  * This class contains the version number for the VObject package
  *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_VObject_Version {
+class Version {
 
     /**
      * Full version number
      */
-    const VERSION = '1.3.4';
+    const VERSION = '2.0.2';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
deleted file mode 100755
index 5e1cc5d479bf9e4f28a27bcd1f0911e5ffeaec1d..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-
-/**
- * Time zone name translation
- *
- * This file translates well-known time zone names into "Olson database" time zone names.
- *
- * @package Sabre
- * @subpackage VObject 
- * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Frank Edelhaeuser (fedel@users.sourceforge.net) 
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Sabre_VObject_WindowsTimezoneMap {
-
-    protected static $map = array(
-
-        // from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html
-        // snapshot taken on 2012/01/16
-
-        // windows
-        'AUS Central Standard Time'=>'Australia/Darwin',
-        'AUS Eastern Standard Time'=>'Australia/Sydney',
-        'Afghanistan Standard Time'=>'Asia/Kabul',
-        'Alaskan Standard Time'=>'America/Anchorage',
-        'Arab Standard Time'=>'Asia/Riyadh',
-        'Arabian Standard Time'=>'Asia/Dubai',
-        'Arabic Standard Time'=>'Asia/Baghdad',
-        'Argentina Standard Time'=>'America/Buenos_Aires',
-        'Armenian Standard Time'=>'Asia/Yerevan',
-        'Atlantic Standard Time'=>'America/Halifax',
-        'Azerbaijan Standard Time'=>'Asia/Baku',
-        'Azores Standard Time'=>'Atlantic/Azores',
-        'Bangladesh Standard Time'=>'Asia/Dhaka',
-        'Canada Central Standard Time'=>'America/Regina',
-        'Cape Verde Standard Time'=>'Atlantic/Cape_Verde',
-        'Caucasus Standard Time'=>'Asia/Yerevan',
-        'Cen. Australia Standard Time'=>'Australia/Adelaide',
-        'Central America Standard Time'=>'America/Guatemala',
-        'Central Asia Standard Time'=>'Asia/Almaty',
-        'Central Brazilian Standard Time'=>'America/Cuiaba',
-        'Central Europe Standard Time'=>'Europe/Budapest',
-        'Central European Standard Time'=>'Europe/Warsaw',
-        'Central Pacific Standard Time'=>'Pacific/Guadalcanal',
-        'Central Standard Time'=>'America/Chicago',
-        'Central Standard Time (Mexico)'=>'America/Mexico_City',
-        'China Standard Time'=>'Asia/Shanghai',
-        'Dateline Standard Time'=>'Etc/GMT+12',
-        'E. Africa Standard Time'=>'Africa/Nairobi',
-        'E. Australia Standard Time'=>'Australia/Brisbane',
-        'E. Europe Standard Time'=>'Europe/Minsk',
-        'E. South America Standard Time'=>'America/Sao_Paulo',
-        'Eastern Standard Time'=>'America/New_York',
-        'Egypt Standard Time'=>'Africa/Cairo',
-        'Ekaterinburg Standard Time'=>'Asia/Yekaterinburg',
-        'FLE Standard Time'=>'Europe/Kiev',
-        'Fiji Standard Time'=>'Pacific/Fiji',
-        'GMT Standard Time'=>'Europe/London',
-        'GTB Standard Time'=>'Europe/Istanbul',
-        'Georgian Standard Time'=>'Asia/Tbilisi',
-        'Greenland Standard Time'=>'America/Godthab',
-        'Greenwich Standard Time'=>'Atlantic/Reykjavik',
-        'Hawaiian Standard Time'=>'Pacific/Honolulu',
-        'India Standard Time'=>'Asia/Calcutta',
-        'Iran Standard Time'=>'Asia/Tehran',
-        'Israel Standard Time'=>'Asia/Jerusalem',
-        'Jordan Standard Time'=>'Asia/Amman',
-        'Kamchatka Standard Time'=>'Asia/Kamchatka',
-        'Korea Standard Time'=>'Asia/Seoul',
-        'Magadan Standard Time'=>'Asia/Magadan',
-        'Mauritius Standard Time'=>'Indian/Mauritius',
-        'Mexico Standard Time'=>'America/Mexico_City',
-        'Mexico Standard Time 2'=>'America/Chihuahua',
-        'Mid-Atlantic Standard Time'=>'Etc/GMT+2',
-        'Middle East Standard Time'=>'Asia/Beirut',
-        'Montevideo Standard Time'=>'America/Montevideo',
-        'Morocco Standard Time'=>'Africa/Casablanca',
-        'Mountain Standard Time'=>'America/Denver',
-        'Mountain Standard Time (Mexico)'=>'America/Chihuahua',
-        'Myanmar Standard Time'=>'Asia/Rangoon',
-        'N. Central Asia Standard Time'=>'Asia/Novosibirsk',
-        'Namibia Standard Time'=>'Africa/Windhoek',
-        'Nepal Standard Time'=>'Asia/Katmandu',
-        'New Zealand Standard Time'=>'Pacific/Auckland',
-        'Newfoundland Standard Time'=>'America/St_Johns',
-        'North Asia East Standard Time'=>'Asia/Irkutsk',
-        'North Asia Standard Time'=>'Asia/Krasnoyarsk',
-        'Pacific SA Standard Time'=>'America/Santiago',
-        'Pacific Standard Time'=>'America/Los_Angeles',
-        'Pacific Standard Time (Mexico)'=>'America/Santa_Isabel',
-        'Pakistan Standard Time'=>'Asia/Karachi',
-        'Paraguay Standard Time'=>'America/Asuncion',
-        'Romance Standard Time'=>'Europe/Paris',
-        'Russian Standard Time'=>'Europe/Moscow',
-        'SA Eastern Standard Time'=>'America/Cayenne',
-        'SA Pacific Standard Time'=>'America/Bogota',
-        'SA Western Standard Time'=>'America/La_Paz',
-        'SE Asia Standard Time'=>'Asia/Bangkok',
-        'Samoa Standard Time'=>'Pacific/Apia',
-        'Singapore Standard Time'=>'Asia/Singapore',
-        'South Africa Standard Time'=>'Africa/Johannesburg',
-        'Sri Lanka Standard Time'=>'Asia/Colombo',
-        'Syria Standard Time'=>'Asia/Damascus',
-        'Taipei Standard Time'=>'Asia/Taipei',
-        'Tasmania Standard Time'=>'Australia/Hobart',
-        'Tokyo Standard Time'=>'Asia/Tokyo',
-        'Tonga Standard Time'=>'Pacific/Tongatapu',
-        'US Eastern Standard Time'=>'America/Indianapolis',
-        'US Mountain Standard Time'=>'America/Phoenix',
-        'UTC'=>'Etc/GMT',
-        'UTC+12'=>'Etc/GMT-12',
-        'UTC-02'=>'Etc/GMT+2',
-        'UTC-11'=>'Etc/GMT+11',
-        'Ulaanbaatar Standard Time'=>'Asia/Ulaanbaatar',
-        'Venezuela Standard Time'=>'America/Caracas',
-        'Vladivostok Standard Time'=>'Asia/Vladivostok',
-        'W. Australia Standard Time'=>'Australia/Perth',
-        'W. Central Africa Standard Time'=>'Africa/Lagos',
-        'W. Europe Standard Time'=>'Europe/Berlin',
-        'West Asia Standard Time'=>'Asia/Tashkent',
-        'West Pacific Standard Time'=>'Pacific/Port_Moresby',
-        'Yakutsk Standard Time'=>'Asia/Yakutsk',
-    );
-
-    static public function lookup($tzid) {
-        return isset(self::$map[$tzid]) ? self::$map[$tzid] : null;
-    }
-}
diff --git a/3rdparty/Sabre/VObject/includes.php b/3rdparty/Sabre/VObject/includes.php
old mode 100755
new mode 100644
index 0177a8f1ba69089c467da2f6dbe67a14c2914fa6..b74bd3b6cbfbb463b20913e8b4bc559a16cd55eb
--- a/3rdparty/Sabre/VObject/includes.php
+++ b/3rdparty/Sabre/VObject/includes.php
@@ -1,15 +1,11 @@
 <?php
 
 /**
- * Sabre_VObject includes file
+ * Includes file
  *
- * Including this file will automatically include all files from the VObject
- * package.
+ * This file includes the entire VObject library in one go.
+ * The benefit is that an autoloader is not needed, which is often faster.
  *
- * This often allows faster loadtimes, as autoload-speed is often quite slow.
- *
- * @package Sabre
- * @subpackage VObject
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
@@ -22,20 +18,23 @@ include __DIR__ . '/FreeBusyGenerator.php';
 include __DIR__ . '/Node.php';
 include __DIR__ . '/Parameter.php';
 include __DIR__ . '/ParseException.php';
+include __DIR__ . '/Property.php';
 include __DIR__ . '/Reader.php';
 include __DIR__ . '/RecurrenceIterator.php';
+include __DIR__ . '/Splitter/SplitterInterface.php';
+include __DIR__ . '/StringUtil.php';
+include __DIR__ . '/TimeZoneUtil.php';
 include __DIR__ . '/Version.php';
-include __DIR__ . '/WindowsTimezoneMap.php';
-include __DIR__ . '/Element.php';
-include __DIR__ . '/Property.php';
+include __DIR__ . '/Splitter/VCard.php';
 include __DIR__ . '/Component.php';
+include __DIR__ . '/Property/Compound.php';
 include __DIR__ . '/Property/DateTime.php';
 include __DIR__ . '/Property/MultiDateTime.php';
+include __DIR__ . '/Splitter/ICalendar.php';
 include __DIR__ . '/Component/VAlarm.php';
 include __DIR__ . '/Component/VCalendar.php';
 include __DIR__ . '/Component/VEvent.php';
+include __DIR__ . '/Component/VFreeBusy.php';
 include __DIR__ . '/Component/VJournal.php';
 include __DIR__ . '/Component/VTodo.php';
-include __DIR__ . '/Element/DateTime.php';
-include __DIR__ . '/Element/MultiDateTime.php';
 // End includes
diff --git a/3rdparty/Sabre/autoload.php b/3rdparty/Sabre/autoload.php
old mode 100755
new mode 100644
index c7b537d83d34ef7b0ea97ceb1cda770560bd5a66..505bd36efb052d7b7bf7d6dc49b495ebbc490093
--- a/3rdparty/Sabre/autoload.php
+++ b/3rdparty/Sabre/autoload.php
@@ -1,31 +1,27 @@
 <?php
 
 /**
- * SabreDAV's PHP autoloader
+ * SabreDAV's autoloader
  *
- * If you love the autoloader, and don't care as much about performance, this
- * file register a new autoload function using spl_autoload_register.
+ * This file is kept for backwards compatibility purposes.
+ * SabreDAV now uses the composer autoloader.
+ *
+ * You should stop including this file, and include 'vendor/autoload.php'
+ * instead.
  *
  * @package Sabre
  * @subpackage DAV
+ * @deprecated Will be removed in a future version!
  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
 
 /**
- * @param string $className
- * @return void
+ * We are assuming that the composer autoloader is just 2 directories up.
+ *
+ * This is not the case when sabredav is installed as a dependency. But, in
+ * those cases it's not expected that people will look for this file anyway.
  */
-function Sabre_autoload($className) {
-
-    if(strpos($className,'Sabre_')===0) {
-
-        include dirname(__FILE__) . '/' . str_replace('_','/',substr($className,6)) . '.php';
-
-    }
-
-}
-
-spl_autoload_register('Sabre_autoload');
 
+require __DIR__ . '/../../vendor/autoload.php';
diff --git a/apps/files/templates/index.php_orig b/apps/files/templates/index.php_orig
new file mode 100644
index 0000000000000000000000000000000000000000..aff484f0a7a1f88da346c4ef3f4749aa73be3b77
--- /dev/null
+++ b/apps/files/templates/index.php_orig
@@ -0,0 +1,90 @@
+<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]-->
+<div id="controls">
+	<?php echo($_['breadcrumb']); ?>
+	<?php if ($_['isCreatable']):?>
+		<div class="actions <?php if (isset($_['files']) and count($_['files'])==0):?>emptyfolder<?php endif; ?>">
+			<div id='new' class='button'>
+				<a><?php echo $l->t('New');?></a>
+				<ul class="popup popupTop">
+					<li style="background-image:url('<?php echo OCP\mimetype_icon('text/plain') ?>')" data-type='file'><p><?php echo $l->t('Text file');?></p></li>
+					<li style="background-image:url('<?php echo OCP\mimetype_icon('dir') ?>')" data-type='folder'><p><?php echo $l->t('Folder');?></p></li>
+					<li style="background-image:url('<?php echo OCP\image_path('core','actions/public.png') ?>')" data-type='web'><p><?php echo $l->t('From url');?></p></li>
+				</ul>
+			</div>
+			<div class="file_upload_wrapper svg">
+				<form data-upload-id='1' class="file_upload_form" action="<?php echo OCP\Util::linkTo('files', 'ajax/upload.php'); ?>" method="post" enctype="multipart/form-data" target="file_upload_target_1">
+					<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_['uploadMaxFilesize'] ?>" id="max_upload">
+					<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
+					<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
+					<input class="file_upload_start" type="file" name='files[]'/>
+					<a href="#" class="file_upload_button_wrapper" onclick="return false;" title="<?php echo $l->t('Upload'); echo  ' max. '.$_['uploadMaxHumanFilesize'] ?>"></a>
+					<button class="file_upload_filename"></button>
+					<iframe name="file_upload_target_1" class='file_upload_target' src=""></iframe>
+				</form>
+			</div>
+					<div id="upload">
+						<div id="uploadprogressbar"></div>
+						<input type="button" class="stop" style="display:none" value="<?php echo $l->t('Cancel upload');?>" onclick="javascript:Files.cancelUploads();" />
+					</div>
+
+		</div>
+		<div id="file_action_panel"></div>
+	<?php else:?>
+		<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
+	<?php endif;?>
+	<input type="hidden" name="permissions" value="<?php echo $_['permissions']; ?>" id="permissions">
+</div>
+<div id='notification'></div>
+
+<?php if (isset($_['files']) and $_['isCreatable'] and count($_['files'])==0):?>
+	<div id="emptyfolder"><?php echo $l->t('Nothing in here. Upload something!')?></div>
+<?php endif; ?>
+
+<table>
+	<thead>
+		<tr>
+			<th id='headerName'>
+				<input type="checkbox" id="select_all" />
+				<span class='name'><?php echo $l->t( 'Name' ); ?></span>
+				<span class='selectedActions'>
+<!-- 					<a href="" class="share"><img class='svg' alt="Share" src="<?php echo OCP\image_path("core", "actions/share.svg"); ?>" /> <?php echo $l->t('Share')?></a> -->
+					<?php if($_['allowZipDownload']) : ?>
+						<a href="" class="download"><img class='svg' alt="Download" src="<?php echo OCP\image_path("core", "actions/download.svg"); ?>" /> <?php echo $l->t('Download')?></a>
+					<?php endif; ?>
+				</span>
+			</th>
+			<th id="headerSize"><?php echo $l->t( 'Size' ); ?></th>
+			<th id="headerDate">
+				<span id="modified"><?php echo $l->t( 'Modified' ); ?></span>
+				<?php if ($_['permissions'] & OCP\Share::PERMISSION_DELETE): ?>
+<!-- 					NOTE: Temporary fix to allow unsharing of files in root of Shared folder -->
+					<?php if ($_['dir'] == '/Shared'): ?>
+						<span class="selectedActions"><a href="" class="delete"><?php echo $l->t('Unshare')?> <img class="svg" alt="<?php echo $l->t('Unshare')?>" src="<?php echo OCP\image_path("core", "actions/delete.svg"); ?>" /></a></span>
+					<?php else: ?>
+						<span class="selectedActions"><a href="" class="delete"><?php echo $l->t('Delete')?> <img class="svg" alt="<?php echo $l->t('Delete')?>" src="<?php echo OCP\image_path("core", "actions/delete.svg"); ?>" /></a></span>
+					<?php endif; ?>
+				<?php endif; ?>
+			</th>
+		</tr>
+	</thead>
+	<tbody id="fileList">
+		<?php echo($_['fileList']); ?>
+	</tbody>
+</table>
+<div id="editor"></div>
+<div id="uploadsize-message" title="<?php echo $l->t('Upload too large')?>">
+	<p>
+		<?php echo $l->t('The files you are trying to upload exceed the maximum size for file uploads on this server.');?>
+	</p>
+</div>
+<div id="scanning-message">
+	<h3>
+		<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></span>
+	</h3>
+	<p>
+		<?php echo $l->t('Current scanning');?> <span id='scan-current'></span>
+	</p>
+</div>
+
+<!-- config hints for javascript -->
+<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />
diff --git a/apps/files/templates/index.php_test b/apps/files/templates/index.php_test
new file mode 100644
index 0000000000000000000000000000000000000000..a509333aa45abaa5f3b3c5c7de19627aca50943a
--- /dev/null
+++ b/apps/files/templates/index.php_test
@@ -0,0 +1,90 @@
+<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]-->
+<div id="controls">
+	<?php echo($_['breadcrumb']); ?>
+	<?php if ($_['isCreatable']):?>
+		<div class="actions <?php if (isset($_['files']) and count($_['files'])==0):?>emptyfolder<?php endif; ?>">
+			<div id='new' class='button'>
+				<a><?php echo $l->t('New');?></a>
+				<ul class="popup popupTop">
+					<li style="background-image:url('<?php echo OCP\mimetype_icon('text/plain') ?>')" data-type='file'><p><?php echo $l->t('Text file');?></p></li>
+					<li style="background-image:url('<?php echo OCP\mimetype_icon('dir') ?>')" data-type='folder'><p><?php echo $l->t('Folder');?></p></li>
+					<li style="background-image:url('<?php echo OCP\image_path('core','actions/public.png') ?>')" data-type='web'><p><?php echo $l->t('From url');?></p></li>
+				</ul>
+			</div>
+			<div class="file_upload_wrapper svg">
+				<form data-upload-id='1' class="file_upload_form" action="<?php echo OCP\Util::linkTo('files', 'ajax/upload.php'); ?>" method="post" enctype="multipart/form-data" target="file_upload_target_1">
+<!--					<input type="hidden" name="MAX_FILE_SIZE" value="4000000000" id="max_upload"> -->
+					<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
+					<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
+					<input class="file_upload_start" type="file" name='files[]'/>
+					<a href="#" class="file_upload_button_wrapper" onclick="return false;" title="<?php echo $l->t('Upload'); echo  ' max. '.$_['uploadMaxHumanFilesize'] ?>"></a>
+					<button class="file_upload_filename"></button>
+					<iframe name="file_upload_target_1" class='file_upload_target' src=""></iframe>
+				</form>
+			</div>
+					<div id="upload">
+						<div id="uploadprogressbar"></div>
+						<input type="button" class="stop" style="display:none" value="<?php echo $l->t('Cancel upload');?>" onclick="javascript:Files.cancelUploads();" />
+					</div>
+
+		</div>
+		<div id="file_action_panel"></div>
+	<?php else:?>
+		<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
+	<?php endif;?>
+	<input type="hidden" name="permissions" value="<?php echo $_['permissions']; ?>" id="permissions">
+</div>
+<div id='notification'></div>
+
+<?php if (isset($_['files']) and $_['isCreatable'] and count($_['files'])==0):?>
+	<div id="emptyfolder"><?php echo $l->t('Nothing in here. Upload something!')?></div>
+<?php endif; ?>
+
+<table>
+	<thead>
+		<tr>
+			<th id='headerName'>
+				<input type="checkbox" id="select_all" />
+				<span class='name'><?php echo $l->t( 'Name' ); ?></span>
+				<span class='selectedActions'>
+<!-- 					<a href="" class="share"><img class='svg' alt="Share" src="<?php echo OCP\image_path("core", "actions/share.svg"); ?>" /> <?php echo $l->t('Share')?></a> -->
+					<?php if($_['allowZipDownload']) : ?>
+						<a href="" class="download"><img class='svg' alt="Download" src="<?php echo OCP\image_path("core", "actions/download.svg"); ?>" /> <?php echo $l->t('Download')?></a>
+					<?php endif; ?>
+				</span>
+			</th>
+			<th id="headerSize"><?php echo $l->t( 'Size' ); ?></th>
+			<th id="headerDate">
+				<span id="modified"><?php echo $l->t( 'Modified' ); ?></span>
+				<?php if ($_['permissions'] & OCP\Share::PERMISSION_DELETE): ?>
+<!-- 					NOTE: Temporary fix to allow unsharing of files in root of Shared folder -->
+					<?php if ($_['dir'] == '/Shared'): ?>
+						<span class="selectedActions"><a href="" class="delete"><?php echo $l->t('Unshare')?> <img class="svg" alt="<?php echo $l->t('Unshare')?>" src="<?php echo OCP\image_path("core", "actions/delete.svg"); ?>" /></a></span>
+					<?php else: ?>
+						<span class="selectedActions"><a href="" class="delete"><?php echo $l->t('Delete')?> <img class="svg" alt="<?php echo $l->t('Delete')?>" src="<?php echo OCP\image_path("core", "actions/delete.svg"); ?>" /></a></span>
+					<?php endif; ?>
+				<?php endif; ?>
+			</th>
+		</tr>
+	</thead>
+	<tbody id="fileList">
+		<?php echo($_['fileList']); ?>
+	</tbody>
+</table>
+<div id="editor"></div>
+<div id="uploadsize-message" title="<?php echo $l->t('Upload too large')?>">
+	<p>
+		<?php echo $l->t('The files you are trying to upload exceed the maximum size for file uploads on this server.');?>
+	</p>
+</div>
+<div id="scanning-message">
+	<h3>
+		<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></span>
+	</h3>
+	<p>
+		<?php echo $l->t('Current scanning');?> <span id='scan-current'></span>
+	</p>
+</div>
+
+<!-- config hints for javascript -->
+<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />
diff --git a/lib/base.php b/lib/base.php
index 15dc34f63d2e20a07aba3cc96a6646cc6caf0a77..f810b1f186e0e942a03df3df3c7cfcdf604db3f0 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -100,6 +100,9 @@ class OC{
 		elseif(strpos($className, 'Symfony\\Component\\Routing\\')===0) {
 			$path = 'symfony/routing/'.str_replace('\\', '/', $className) . '.php';
 		}
+		elseif(strpos($className, 'Sabre\\VObject')===0) {
+			$path = str_replace('\\', '/', $className) . '.php';
+		}
 		elseif(strpos($className, 'Test_')===0) {
 			$path =  'tests/lib/'.strtolower(str_replace('_', '/', substr($className, 5)) . '.php');
 		}else{
diff --git a/lib/vobject.php b/lib/vobject.php
index 2ccf8eda685eff3b8981e0e7d8b0d9e2b53ed6fe..44a5fbafdb3fd38e4c0dcc4e030152565c2dbbd0 100644
--- a/lib/vobject.php
+++ b/lib/vobject.php
@@ -24,11 +24,11 @@
  * This class provides a streamlined interface to the Sabre VObject classes
  */
 class OC_VObject{
-	/** @var Sabre_VObject_Component */
+	/** @var Sabre\VObject\Component */
 	protected $vobject;
 
 	/**
-	 * @returns Sabre_VObject_Component
+	 * @returns Sabre\VObject\Component
 	 */
 	public function getVObject() {
 		return $this->vobject;
@@ -41,9 +41,9 @@ class OC_VObject{
 	 */
 	public static function parse($data) {
 		try {
-			Sabre_VObject_Property::$classMap['LAST-MODIFIED'] = 'Sabre_VObject_Property_DateTime';
-			$vobject = Sabre_VObject_Reader::read($data);
-			if ($vobject instanceof Sabre_VObject_Component) {
+			Sabre\VObject\Property::$classMap['LAST-MODIFIED'] = 'Sabre\VObject\Property\DateTime';
+			$vobject = Sabre\VObject\Reader::read($data);
+			if ($vobject instanceof Sabre\VObject\Component) {
 				$vobject = new OC_VObject($vobject);
 			}
 			return $vobject;
@@ -89,13 +89,13 @@ class OC_VObject{
 
 	/**
 	 * Constuctor
-	 * @param Sabre_VObject_Component or string
+	 * @param Sabre\VObject\Component or string
 	 */
 	public function __construct($vobject_or_name) {
 		if (is_object($vobject_or_name)) {
 			$this->vobject = $vobject_or_name;
 		} else {
-			$this->vobject = new Sabre_VObject_Component($vobject_or_name);
+			$this->vobject = new Sabre\VObject\Component($vobject_or_name);
 		}
 	}
 
@@ -117,9 +117,9 @@ class OC_VObject{
 		if(is_array($value)) {
 			$value = OC_VObject::escapeSemicolons($value);
 		}
-		$property = new Sabre_VObject_Property( $name, $value );
+		$property = new Sabre\VObject\Property( $name, $value );
 		foreach($parameters as $name => $value) {
-			$property->parameters[] = new Sabre_VObject_Parameter($name, $value);
+			$property->parameters[] = new Sabre\VObject\Parameter($name, $value);
 		}
 
 		$this->vobject->add($property);
@@ -150,12 +150,12 @@ class OC_VObject{
 	 * @param int $dateType
 	 * @return void
 	 */
-	public function setDateTime($name, $datetime, $dateType=Sabre_VObject_Property_DateTime::LOCALTZ) {
+	public function setDateTime($name, $datetime, $dateType=Sabre\VObject\Property\DateTime::LOCALTZ) {
 		if ($datetime == 'now') {
 			$datetime = new DateTime();
 		}
 		if ($datetime instanceof DateTime) {
-			$datetime_element = new Sabre_VObject_Property_DateTime($name);
+			$datetime_element = new Sabre\VObject\Property\DateTime($name);
 			$datetime_element->setDateTime($datetime, $dateType);
 			$this->vobject->__set($name, $datetime_element);
 		}else{
@@ -183,7 +183,7 @@ class OC_VObject{
 			return $this->vobject->children;
 		}
 		$return = $this->vobject->__get($name);
-		if ($return instanceof Sabre_VObject_Component) {
+		if ($return instanceof Sabre\VObject\Component) {
 			$return = new OC_VObject($return);
 		}
 		return $return;