diff --git a/3rdparty/Sabre.includes.php b/3rdparty/Sabre.includes.php
old mode 100644
new mode 100755
index d41b287b77db5ea8f1ad7b4be78ab68046a803d5..c1334373663c646b05bba88d38d322fac8910039
--- a/3rdparty/Sabre.includes.php
+++ b/3rdparty/Sabre.includes.php
@@ -3,125 +3,24 @@
 /**
  * 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
+ * Make sure the lib/ directory is in PHP's include_path.
  *
  * @package Sabre
- * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
 
-/* Utilities */
-include 'Sabre/HTTP/Util.php';
-include 'Sabre/HTTP/Response.php';
-include 'Sabre/HTTP/Request.php';
-include 'Sabre/HTTP/AbstractAuth.php';
-include 'Sabre/HTTP/BasicAuth.php';
-include 'Sabre/HTTP/DigestAuth.php';
-include 'Sabre/HTTP/AWSAuth.php';
-
-/* Version */
-include 'Sabre/DAV/Version.php';
-include 'Sabre/HTTP/Version.php';
-
-/* Exceptions */
-include 'Sabre/DAV/Exception.php';
-include 'Sabre/DAV/Exception/BadRequest.php';
-include 'Sabre/DAV/Exception/Conflict.php';
-include 'Sabre/DAV/Exception/FileNotFound.php';
-include 'Sabre/DAV/Exception/InsufficientStorage.php';
-include 'Sabre/DAV/Exception/Locked.php';
-include 'Sabre/DAV/Exception/LockTokenMatchesRequestUri.php';
-include 'Sabre/DAV/Exception/MethodNotAllowed.php';
-include 'Sabre/DAV/Exception/NotImplemented.php';
-include 'Sabre/DAV/Exception/Forbidden.php';
-include 'Sabre/DAV/Exception/PreconditionFailed.php';
-include 'Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php';
-include 'Sabre/DAV/Exception/UnsupportedMediaType.php';
-include 'Sabre/DAV/Exception/NotAuthenticated.php';
-
-include 'Sabre/DAV/Exception/ConflictingLock.php';
-include 'Sabre/DAV/Exception/ReportNotImplemented.php';
-include 'Sabre/DAV/Exception/InvalidResourceType.php';
-
-/* Properties */
-include 'Sabre/DAV/Property.php';
-include 'Sabre/DAV/Property/GetLastModified.php';
-include 'Sabre/DAV/Property/ResourceType.php';
-include 'Sabre/DAV/Property/SupportedLock.php';
-include 'Sabre/DAV/Property/LockDiscovery.php';
-include 'Sabre/DAV/Property/IHref.php';
-include 'Sabre/DAV/Property/Href.php';
-include 'Sabre/DAV/Property/HrefList.php';
-include 'Sabre/DAV/Property/SupportedReportSet.php';
-include 'Sabre/DAV/Property/Response.php';
-include 'Sabre/DAV/Property/ResponseList.php';
-
-/* Node interfaces */
-include 'Sabre/DAV/INode.php';
-include 'Sabre/DAV/IFile.php';
-include 'Sabre/DAV/ICollection.php';
-include 'Sabre/DAV/IProperties.php';
-include 'Sabre/DAV/ILockable.php';
-include 'Sabre/DAV/IQuota.php';
-include 'Sabre/DAV/IExtendedCollection.php';
-
-/* Node abstract implementations */
-include 'Sabre/DAV/Node.php';
-include 'Sabre/DAV/File.php';
-include 'Sabre/DAV/Collection.php';
-include 'Sabre/DAV/Directory.php';
-
-/* Utilities */
-include 'Sabre/DAV/SimpleCollection.php';
-include 'Sabre/DAV/SimpleDirectory.php';
-include 'Sabre/DAV/XMLUtil.php';
-include 'Sabre/DAV/URLUtil.php';
-
-/* Filesystem implementation */
-include 'Sabre/DAV/FS/Node.php';
-include 'Sabre/DAV/FS/File.php';
-include 'Sabre/DAV/FS/Directory.php';
-
-/* Advanced filesystem implementation */
-include 'Sabre/DAV/FSExt/Node.php';
-include 'Sabre/DAV/FSExt/File.php';
-include 'Sabre/DAV/FSExt/Directory.php';
-
-/* Trees */
-include 'Sabre/DAV/Tree.php';
-include 'Sabre/DAV/ObjectTree.php';
-include 'Sabre/DAV/Tree/Filesystem.php';
-
-/* Server */
-include 'Sabre/DAV/Server.php';
-include 'Sabre/DAV/ServerPlugin.php';
-
-/* Browser */
-include 'Sabre/DAV/Browser/Plugin.php';
-include 'Sabre/DAV/Browser/MapGetToPropFind.php';
-include 'Sabre/DAV/Browser/GuessContentType.php';
-
-/* Locks */
-include 'Sabre/DAV/Locks/LockInfo.php';
-include 'Sabre/DAV/Locks/Plugin.php';
-include 'Sabre/DAV/Locks/Backend/Abstract.php';
-include 'Sabre/DAV/Locks/Backend/FS.php';
-include 'Sabre/DAV/Locks/Backend/PDO.php';
-
-/* Temporary File Filter plugin */
-include 'Sabre/DAV/TemporaryFileFilterPlugin.php';
-
-/* Authentication plugin */
-include 'Sabre/DAV/Auth/Plugin.php';
-include 'Sabre/DAV/Auth/IBackend.php';
-include 'Sabre/DAV/Auth/Backend/AbstractDigest.php';
-include 'Sabre/DAV/Auth/Backend/AbstractBasic.php';
-include 'Sabre/DAV/Auth/Backend/File.php';
-include 'Sabre/DAV/Auth/Backend/PDO.php';
-
-/* DavMount plugin */
-include 'Sabre/DAV/Mount/Plugin.php';
+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 100644
new mode 100755
index b694eef49e4696aa470cf56bc126c2bd1b273378..7aba1d69ffe3052f344110c70c2f2139ddebadbf
--- a/3rdparty/Sabre/CalDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
@@ -2,10 +2,10 @@
 
 /**
  * Abstract Calendaring backend. Extend this class to create your own backends.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -17,16 +17,16 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      * 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 
+     *  * 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. 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'. 
+     * common one is '{DAV:}displayname'.
      *
-     * @param string $principalUri 
-     * @return array 
+     * @param string $principalUri
+     * @return array
      */
     abstract function getCalendarsForUser($principalUri);
 
@@ -39,9 +39,9 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      * @param string $principalUri
      * @param string $calendarUri
      * @param array $properties
-     * @return void 
+     * @return void
      */
-    abstract function createCalendar($principalUri,$calendarUri,array $properties); 
+    abstract function createCalendar($principalUri,$calendarUri,array $properties);
 
     /**
      * Updates properties for a calendar.
@@ -56,7 +56,7 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      * If the operation was successful, true can be returned.
      * If the operation failed, false can be returned.
      *
-     * Deletion of a non-existant property is always succesful.
+     * 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
@@ -71,24 +71,24 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      *   )
      * )
      *
-     * In this example it was forbidden to update {DAV:}displayname. 
+     * 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 string $calendarId
      * @param array $mutations
-     * @return bool|array 
+     * @return bool|array
      */
     public function updateCalendar($calendarId, array $mutations) {
-        
-        return false; 
+
+        return false;
 
     }
 
     /**
-     * Delete a calendar and all it's objects 
-     * 
-     * @param string $calendarId 
+     * Delete a calendar and all it's objects
+     *
+     * @param string $calendarId
      * @return void
      */
     abstract function deleteCalendar($calendarId);
@@ -98,22 +98,27 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      *
      * Every item contains an array with the following keys:
      *   * id - unique identifier which will be used for subsequent updates
-     *   * calendardata - The iCalendar-compatible calnedar data
+     *   * 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.: 
+     *   * 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 
+     * 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 
+     * The calendardata is also optional. If it's not returned
+     * 'getCalendarObject' will be called later, which *is* expected to return
      * calendardata.
-     * 
-     * @param string $calendarId 
-     * @return array 
+     *
+     * 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);
 
@@ -121,41 +126,41 @@ abstract class Sabre_CalDAV_Backend_Abstract {
      * 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 
+     * 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 string $calendarId 
-     * @param string $objectUri 
-     * @return array 
+     *
+     * @param string $calendarId
+     * @param string $objectUri
+     * @return array
      */
     abstract function getCalendarObject($calendarId,$objectUri);
 
     /**
-     * Creates a new calendar object. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
-     * @param string $calendarData 
+     * Creates a new calendar object.
+     *
+     * @param string $calendarId
+     * @param string $objectUri
+     * @param string $calendarData
      * @return void
      */
     abstract function createCalendarObject($calendarId,$objectUri,$calendarData);
 
     /**
-     * Updates an existing calendarobject, based on it's uri. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
-     * @param string $calendarData 
+     * 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);
 
     /**
-     * Deletes an existing calendar object. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
+     * Deletes an existing calendar object.
+     *
+     * @param string $calendarId
+     * @param string $objectUri
      * @return void
      */
     abstract function deleteCalendarObject($calendarId,$objectUri);
diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php
old mode 100644
new mode 100755
index 7b1b33b912ee53a4fd4a94febccbcb6b4c871141..ddacf940c74fa12e21ff389e06604325c55bf3ba
--- a/3rdparty/Sabre/CalDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CalDAV/Backend/PDO.php
@@ -3,35 +3,35 @@
 /**
  * PDO CalDAV backend
  *
- * This backend is used to store calendar-data in a PDO database, such as 
+ * This backend is used to store calendar-data in a PDO database, such as
  * sqlite or MySQL
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
     /**
-     * pdo 
-     * 
+     * pdo
+     *
      * @var PDO
      */
     protected $pdo;
 
     /**
-     * The table name that will be used for calendars 
-     * 
-     * @var string 
+     * The table name that will be used for calendars
+     *
+     * @var string
      */
     protected $calendarTableName;
 
     /**
-     * The table name that will be used for calendar objects  
-     * 
-     * @var string 
+     * The table name that will be used for calendar objects
+     *
+     * @var string
      */
     protected $calendarObjectTableName;
 
@@ -39,7 +39,7 @@ 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
-     * 
+     *
      * @var array
      */
     public $propertyMap = array(
@@ -51,9 +51,11 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
     );
 
     /**
-     * Creates the backend 
-     * 
-     * @param PDO $pdo 
+     * Creates the backend
+     *
+     * @param PDO $pdo
+     * @param string $calendarTableName
+     * @param string $calendarObjectTableName
      */
     public function __construct(PDO $pdo, $calendarTableName = 'calendars', $calendarObjectTableName = 'calendarobjects') {
 
@@ -69,16 +71,16 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      * 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 
+     *  * 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. 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'. 
+     * common one is '{DAV:}displayname'.
      *
-     * @param string $principalUri 
-     * @return array 
+     * @param string $principalUri
+     * @return array
      */
     public function getCalendarsForUser($principalUri) {
 
@@ -89,15 +91,18 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
         $fields[] = 'components';
         $fields[] = 'principaluri';
 
-        // Making fields a comma-delimited list 
+        // Making fields a comma-delimited list
         $fields = implode(', ', $fields);
-        $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM `".$this->calendarTableName."` WHERE principaluri = ?"); 
+        $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM ".$this->calendarTableName." WHERE principaluri = ? ORDER BY calendarorder ASC");
         $stmt->execute(array($principalUri));
 
         $calendars = array();
         while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
 
-            $components = explode(',',$row['components']);
+            $components = array();
+            if ($row['components']) {
+                $components = explode(',',$row['components']);
+            }
 
             $calendar = array(
                 'id' => $row['id'],
@@ -106,7 +111,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
                 '{' . 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),
             );
-        
+
 
             foreach($this->propertyMap as $xmlName=>$dbName) {
                 $calendar[$xmlName] = $row[$dbName];
@@ -129,8 +134,9 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      * @param string $principalUri
      * @param string $calendarUri
      * @param array $properties
+     * @return string
      */
-    public function createCalendar($principalUri,$calendarUri, array $properties) {
+    public function createCalendar($principalUri, $calendarUri, array $properties) {
 
         $fieldNames = array(
             'principaluri',
@@ -158,13 +164,12 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
         foreach($this->propertyMap as $xmlName=>$dbName) {
             if (isset($properties[$xmlName])) {
 
-                $myValue = $properties[$xmlName];
                 $values[':' . $dbName] = $properties[$xmlName];
                 $fieldNames[] = $dbName;
             }
         }
 
-        $stmt = $this->pdo->prepare("INSERT INTO `".$this->calendarTableName."` (".implode(', ', $fieldNames).") VALUES (".implode(', ',array_keys($values)).")");
+        $stmt = $this->pdo->prepare("INSERT INTO ".$this->calendarTableName." (".implode(', ', $fieldNames).") VALUES (".implode(', ',array_keys($values)).")");
         $stmt->execute($values);
 
         return $this->pdo->lastInsertId();
@@ -184,7 +189,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      * If the operation was successful, true can be returned.
      * If the operation failed, false can be returned.
      *
-     * Deletion of a non-existant property is always succesful.
+     * 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
@@ -199,13 +204,13 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      *   )
      * )
      *
-     * In this example it was forbidden to update {DAV:}displayname. 
+     * 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 string $calendarId
-     * @param array $mutations 
-     * @return bool|array 
+     * @param array $mutations
+     * @return bool|array
      */
     public function updateCalendar($calendarId, array $mutations) {
 
@@ -220,7 +225,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
         foreach($mutations as $propertyName=>$propertyValue) {
 
-            // We don't know about this property. 
+            // We don't know about this property.
             if (!isset($this->propertyMap[$propertyName])) {
                 $hasError = true;
                 $result[403][$propertyName] = null;
@@ -230,7 +235,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
 
             $fieldName = $this->propertyMap[$propertyName];
             $newValues[$fieldName] = $propertyValue;
-                
+
         }
 
         // If there were any errors we need to fail the request
@@ -258,55 +263,60 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
         }
         $valuesSql[] = 'ctag = ctag + 1';
 
-        $stmt = $this->pdo->prepare("UPDATE `" . $this->calendarTableName . "` SET " . implode(', ',$valuesSql) . " WHERE id = ?");
-        $newValues['id'] = $calendarId; 
+        $stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET " . implode(', ',$valuesSql) . " WHERE id = ?");
+        $newValues['id'] = $calendarId;
         $stmt->execute(array_values($newValues));
 
-        return true; 
+        return true;
 
     }
 
     /**
-     * Delete a calendar and all it's objects 
-     * 
-     * @param string $calendarId 
+     * Delete a calendar and all it's objects
+     *
+     * @param string $calendarId
      * @return void
      */
     public function deleteCalendar($calendarId) {
 
-        $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
         $stmt->execute(array($calendarId));
 
-        $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarTableName.'` WHERE id = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarTableName.' WHERE id = ?');
         $stmt->execute(array($calendarId));
 
     }
 
     /**
-     * Returns all calendar objects within a calendar. 
+     * 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 calnedar data
+     *   * 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.: 
+     *   * 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 
+     * 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 
+     * The calendardata is also optional. If it's not returned
+     * 'getCalendarObject' will be called later, which *is* expected to return
      * calendardata.
-     * 
-     * @param string $calendarId 
-     * @return array 
+     *
+     * 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
      */
     public function getCalendarObjects($calendarId) {
 
-        $stmt = $this->pdo->prepare('SELECT * FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ?');
+        $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
         $stmt->execute(array($calendarId));
         return $stmt->fetchAll();
 
@@ -316,68 +326,68 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
      * 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 
+     * 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 string $calendarId 
-     * @param string $objectUri 
-     * @return array 
+     *
+     * @param string $calendarId
+     * @param string $objectUri
+     * @return array
      */
     public function getCalendarObject($calendarId,$objectUri) {
 
-        $stmt = $this->pdo->prepare('SELECT * FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ? AND uri = ?');
+        $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
         $stmt->execute(array($calendarId, $objectUri));
         return $stmt->fetch();
 
     }
 
     /**
-     * Creates a new calendar object. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
-     * @param string $calendarData 
+     * Creates a new calendar object.
+     *
+     * @param string $calendarId
+     * @param string $objectUri
+     * @param string $calendarData
      * @return void
      */
     public function createCalendarObject($calendarId,$objectUri,$calendarData) {
 
-        $stmt = $this->pdo->prepare('INSERT INTO `'.$this->calendarObjectTableName.'` (calendarid, uri, calendardata, lastmodified) VALUES (?,?,?,?)');
+        $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified) VALUES (?,?,?,?)');
         $stmt->execute(array($calendarId,$objectUri,$calendarData,time()));
-        $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarTableName.'` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
         $stmt->execute(array($calendarId));
 
     }
 
     /**
-     * Updates an existing calendarobject, based on it's uri. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
-     * @param string $calendarData 
+     * Updates an existing calendarobject, based on it's uri.
+     *
+     * @param string $calendarId
+     * @param string $objectUri
+     * @param string $calendarData
      * @return void
      */
     public function updateCalendarObject($calendarId,$objectUri,$calendarData) {
 
-        $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarObjectTableName.'` SET calendardata = ?, lastmodified = ? WHERE calendarid = ? AND uri = ?');
+        $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ? WHERE calendarid = ? AND uri = ?');
         $stmt->execute(array($calendarData,time(),$calendarId,$objectUri));
-        $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarTableName.'` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
         $stmt->execute(array($calendarId));
 
     }
 
     /**
-     * Deletes an existing calendar object. 
-     * 
-     * @param string $calendarId 
-     * @param string $objectUri 
+     * Deletes an existing calendar object.
+     *
+     * @param string $calendarId
+     * @param string $objectUri
      * @return void
      */
     public function deleteCalendarObject($calendarId,$objectUri) {
 
-        $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ? AND uri = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
         $stmt->execute(array($calendarId,$objectUri));
-        $stmt = $this->pdo->prepare('UPDATE `'. $this->calendarTableName .'` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt = $this->pdo->prepare('UPDATE '. $this->calendarTableName .' SET ctag = ctag + 1 WHERE id = ?');
         $stmt->execute(array($calendarId));
 
     }
diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php
old mode 100644
new mode 100755
index 0d2b3875771729f323e8f19cc86a2376eb77b6d6..623df2dd1b8951cb9d6730f9b6849265dcf1f159
--- a/3rdparty/Sabre/CalDAV/Calendar.php
+++ b/3rdparty/Sabre/CalDAV/Calendar.php
@@ -5,42 +5,42 @@
  *
  * A calendar can contain multiple TODO and or Events. These are represented
  * as Sabre_CalDAV_CalendarObject objects.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
 
     /**
-     * This is an array with calendar information 
-     * 
-     * @var array 
+     * This is an array with calendar information
+     *
+     * @var array
      */
     protected $calendarInfo;
 
     /**
-     * CalDAV backend 
-     * 
-     * @var Sabre_CalDAV_Backend_Abstract 
+     * CalDAV backend
+     *
+     * @var Sabre_CalDAV_Backend_Abstract
      */
     protected $caldavBackend;
 
     /**
      * Principal backend
-     * 
+     *
      * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
-     * Constructor 
-     * 
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend 
-     * @param array $calendarInfo 
-     * @return void
+     * Constructor
+     *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param array $calendarInfo
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $calendarInfo) {
 
@@ -52,9 +52,9 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     }
 
     /**
-     * Returns the name of the calendar 
-     * 
-     * @return string 
+     * Returns the name of the calendar
+     *
+     * @return string
      */
     public function getName() {
 
@@ -63,10 +63,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     }
 
     /**
-     * Updates properties such as the display name and description 
-     * 
-     * @param array $mutations 
-     * @return array 
+     * Updates properties such as the display name and description
+     *
+     * @param array $mutations
+     * @return array
      */
     public function updateProperties($mutations) {
 
@@ -75,10 +75,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     }
 
     /**
-     * Returns the list of properties 
-     * 
-     * @param array $properties 
-     * @return array 
+     * Returns the list of properties
+     *
+     * @param array $requestedProperties
+     * @return array
      */
     public function getProperties($requestedProperties) {
 
@@ -86,16 +86,16 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
 
         foreach($requestedProperties as $prop) switch($prop) {
 
-            case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' : 
-                $response[$prop] = new Sabre_CalDAV_Property_SupportedCalendarData(); 
+            case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' :
+                $response[$prop] = new Sabre_CalDAV_Property_SupportedCalendarData();
                 break;
-            case '{urn:ietf:params:xml:ns:caldav}supported-collation-set' : 
-                $response[$prop] =  new Sabre_CalDAV_Property_SupportedCollationSet(); 
+            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 : 
+            default :
                 if (isset($this->calendarInfo[$prop])) $response[$prop] = $this->calendarInfo[$prop];
                 break;
 
@@ -108,22 +108,22 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * Returns a calendar object
      *
      * The contained calendar objects are for example Events or Todo's.
-     * 
-     * @param string $name 
-     * @return Sabre_DAV_ICalendarObject 
+     *
+     * @param string $name
+     * @return Sabre_DAV_ICalendarObject
      */
     public function getChild($name) {
 
         $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name);
-        if (!$obj) throw new Sabre_DAV_Exception_FileNotFound('Calendar object not found');
+        if (!$obj) throw new Sabre_DAV_Exception_NotFound('Calendar object not found');
         return new Sabre_CalDAV_CalendarObject($this->caldavBackend,$this->calendarInfo,$obj);
 
     }
 
     /**
-     * Returns the full list of calendar objects  
-     * 
-     * @return array 
+     * Returns the full list of calendar objects
+     *
+     * @return array
      */
     public function getChildren() {
 
@@ -137,17 +137,17 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     }
 
     /**
-     * Checks if a child-node exists. 
-     * 
-     * @param string $name 
-     * @return bool 
+     * Checks if a child-node exists.
+     *
+     * @param string $name
+     * @return bool
      */
     public function childExists($name) {
 
         $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name);
-        if (!$obj) 
+        if (!$obj)
             return false;
-        else 
+        else
             return true;
 
     }
@@ -156,8 +156,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * Creates a new directory
      *
      * We actually block this, as subdirectories are not allowed in calendars.
-     * 
-     * @param string $name 
+     *
+     * @param string $name
      * @return void
      */
     public function createDirectory($name) {
@@ -170,32 +170,23 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * Creates a new file
      *
      * The contents of the new file must be a valid ICalendar string.
-     * 
-     * @param string $name 
-     * @param resource $calendarData 
-     * @return void
+     *
+     * @param string $name
+     * @param resource $calendarData
+     * @return string|null
      */
     public function createFile($name,$calendarData = null) {
 
-        $calendarData = stream_get_contents($calendarData);
-        // Converting to UTF-8, if needed
-        $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData);
-
-        $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set'];
-        if ($supportedComponents) {
-            $supportedComponents = $supportedComponents->getValue();
-        } else {
-            $supportedComponents = null;
+        if (is_resource($calendarData)) {
+            $calendarData = stream_get_contents($calendarData);
         }
-        Sabre_CalDAV_ICalendarUtil::validateICalendarObject($calendarData, $supportedComponents);
-
-        $this->caldavBackend->createCalendarObject($this->calendarInfo['id'],$name,$calendarData);
+        return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'],$name,$calendarData);
 
     }
 
     /**
-     * Deletes the calendar. 
-     * 
+     * Deletes the calendar.
+     *
      * @return void
      */
     public function delete() {
@@ -205,10 +196,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     }
 
     /**
-     * Renames the calendar. Note that most calendars use the 
-     * {DAV:}displayname to display a name to display a name. 
-     * 
-     * @param string $newName 
+     * Renames the calendar. Note that most calendars use the
+     * {DAV:}displayname to display a name to display a name.
+     *
+     * @param string $newName
      * @return void
      */
     public function setName($newName) {
@@ -219,7 +210,7 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
 
     /**
      * Returns the last modification date as a unix timestamp.
-     * 
+     *
      * @return void
      */
     public function getLastModified() {
@@ -231,8 +222,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -245,8 +236,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -258,13 +249,13 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -294,6 +285,11 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
                 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
                 'protected' => true,
             ),
+            array(
+                'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
+                'principal' => '{DAV:}authenticated',
+                'protected' => true,
+            ),
 
         );
 
@@ -302,9 +298,9 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -313,6 +309,35 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
 
     }
 
+    /**
+     * 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() {
+
+        $default = Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet();
+
+        // We need to inject 'read-free-busy' in the tree, aggregated under
+        // {DAV:}read.
+        foreach($default['aggregates'] as &$agg) {
 
+            if ($agg['privilege'] !== '{DAV:}read') continue;
+
+            $agg['aggregates'][] = array(
+                'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
+            );
+
+        }
+        return $default;
+
+    }
 
 }
diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php
old mode 100644
new mode 100755
index 0c99f18deb72cca5233bd50ffdce28bd3037fc86..72f0a578d16a554b847354867c608ca732b8f72e
--- a/3rdparty/Sabre/CalDAV/CalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/CalendarObject.php
@@ -1,43 +1,43 @@
 <?php
 
 /**
- * The CalendarObject represents a single VEVENT or VTODO within a Calendar. 
- * 
+ * The CalendarObject represents a single VEVENT or VTODO within a Calendar.
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV_ICalendarObject, Sabre_DAVACL_IACL {
 
     /**
-     * Sabre_CalDAV_Backend_Abstract 
-     * 
-     * @var array 
+     * Sabre_CalDAV_Backend_Abstract
+     *
+     * @var array
      */
     protected $caldavBackend;
 
     /**
-     * Array with information about this CalendarObject 
-     * 
-     * @var array 
+     * Array with information about this CalendarObject
+     *
+     * @var array
      */
     protected $objectData;
 
     /**
      * Array with information about the containing calendar
-     * 
-     * @var array 
+     *
+     * @var array
      */
     protected $calendarInfo;
 
     /**
-     * Constructor 
-     * 
+     * Constructor
+     *
      * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
      * @param array $calendarInfo
-     * @param array $objectData 
+     * @param array $objectData
      */
     public function __construct(Sabre_CalDAV_Backend_Abstract $caldavBackend,array $calendarInfo,array $objectData) {
 
@@ -56,9 +56,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     }
 
     /**
-     * Returns the uri for this object 
-     * 
-     * @return string 
+     * Returns the uri for this object
+     *
+     * @return string
      */
     public function getName() {
 
@@ -67,9 +67,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     }
 
     /**
-     * Returns the ICalendar-formatted object 
-     * 
-     * @return string 
+     * Returns the ICalendar-formatted object
+     *
+     * @return string
      */
     public function get() {
 
@@ -83,35 +83,27 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     }
 
     /**
-     * Updates the ICalendar-formatted object 
-     * 
-     * @param string $calendarData 
-     * @return void 
+     * Updates the ICalendar-formatted object
+     *
+     * @param string $calendarData
+     * @return void
      */
     public function put($calendarData) {
 
-        if (is_resource($calendarData))
+        if (is_resource($calendarData)) {
             $calendarData = stream_get_contents($calendarData);
-
-        // Converting to UTF-8, if needed
-        $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData);
-
-        $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set'];
-        if ($supportedComponents) {
-            $supportedComponents = $supportedComponents->getValue();
-        } else {
-            $supportedComponents = null;
         }
-        Sabre_CalDAV_ICalendarUtil::validateICalendarObject($calendarData, $supportedComponents);
-
-        $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'],$this->objectData['uri'],$calendarData);
+        $etag = $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'],$this->objectData['uri'],$calendarData);
         $this->objectData['calendardata'] = $calendarData;
+        $this->objectData['etag'] = $etag;
+
+        return $etag;
 
     }
 
     /**
-     * Deletes the calendar object 
-     * 
+     * Deletes the calendar object
+     *
      * @return void
      */
     public function delete() {
@@ -121,9 +113,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     }
 
     /**
-     * Returns the mime content-type 
-     * 
-     * @return string 
+     * Returns the mime content-type
+     *
+     * @return string
      */
     public function getContentType() {
 
@@ -134,9 +126,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     /**
      * Returns an ETag for this object.
      *
-     * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
-     * 
-     * @return string 
+     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
+     *
+     * @return string
      */
     public function getETag() {
 
@@ -150,8 +142,8 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
 
     /**
      * Returns the last modification date as a unix timestamp
-     * 
-     * @return time 
+     *
+     * @return time
      */
     public function getLastModified() {
 
@@ -160,21 +152,25 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     }
 
     /**
-     * Returns the size of this object in bytes 
-     * 
+     * Returns the size of this object in bytes
+     *
      * @return int
      */
     public function getSize() {
 
-        return strlen($this->objectData['calendardata']);
+        if (array_key_exists('size',$this->objectData)) {
+            return $this->objectData['size'];
+        } else {
+            return strlen($this->get());
+        }
 
     }
 
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -187,8 +183,8 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -200,13 +196,13 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -244,9 +240,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -255,6 +251,23 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
 
     }
 
+    /**
+     * 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/CalendarQueryParser.php b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
new file mode 100755
index 0000000000000000000000000000000000000000..bd0d343382f8b684b396e6addcc445e1dbbbaae1
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
@@ -0,0 +1,296 @@
+<?php
+
+/**
+ * Parses the calendar-query report request body.
+ *
+ * Whoever designed this format, and the CalDAV equivalent even more so,
+ * has no feel for design.
+ *
+ * @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_CalendarQueryParser {
+
+    /**
+     * List of requested properties the client wanted
+     *
+     * @var array
+     */
+    public $requestedProperties;
+
+    /**
+     * List of property/component filters.
+     *
+     * @var array
+     */
+    public $filters;
+
+    /**
+     * This property will contain null if CALDAV:expand was not specified, 
+     * otherwise it will contain an array with 2 elements (start, end). Each 
+     * contain a DateTime object.
+     *
+     * If expand is specified, recurring calendar objects are to be expanded 
+     * into their individual components, and only the components that fall 
+     * within the specified time-range are to be returned.
+     *
+     * For more details, see rfc4791, section 9.6.5.
+     * 
+     * @var null|array 
+     */
+    public $expand;
+
+    /**
+     * DOM Document
+     *
+     * @var DOMDocument
+     */
+    protected $dom;
+
+    /**
+     * DOM XPath object
+     *
+     * @var DOMXPath
+     */
+    protected $xpath;
+
+    /**
+     * Creates the parser
+     *
+     * @param DOMDocument $dom
+     */
+    public function __construct(DOMDocument $dom) {
+
+        $this->dom = $dom;
+
+        $this->xpath = new DOMXPath($dom);
+        $this->xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
+        $this->xpath->registerNameSpace('dav','urn:DAV');
+
+    }
+
+    /**
+     * Parses the request.
+     *
+     * @return void
+     */
+    public function parse() {
+
+        $filterNode = null;
+
+        $filter = $this->xpath->query('/cal:calendar-query/cal:filter');
+        if ($filter->length !== 1) {
+            throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed');
+        }
+
+        $compFilters = $this->parseCompFilters($filter->item(0));
+        if (count($compFilters)!==1) {
+            throw new Sabre_DAV_Exception_BadRequest('There must be exactly 1 top-level comp-filter.');
+        }
+
+        $this->filters = $compFilters[0];
+        $this->requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($this->dom->firstChild));
+
+        $expand = $this->xpath->query('/cal:calendar-query/dav:prop/cal:calendar-data/cal:expand');
+        if ($expand->length>0) {
+            $this->expand = $this->parseExpand($expand->item(0));
+        }
+             
+
+    }
+
+    /**
+     * Parses all the 'comp-filter' elements from a node
+     *
+     * @param DOMElement $parentNode
+     * @return array
+     */
+    protected function parseCompFilters(DOMElement $parentNode) {
+
+        $compFilterNodes = $this->xpath->query('cal:comp-filter', $parentNode);
+        $result = array();
+
+        for($ii=0; $ii < $compFilterNodes->length; $ii++) {
+
+            $compFilterNode = $compFilterNodes->item($ii);
+
+            $compFilter = array();
+            $compFilter['name'] = $compFilterNode->getAttribute('name');
+            $compFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $compFilterNode)->length>0;
+            $compFilter['comp-filters'] = $this->parseCompFilters($compFilterNode);
+            $compFilter['prop-filters'] = $this->parsePropFilters($compFilterNode);
+            $compFilter['time-range'] = $this->parseTimeRange($compFilterNode);
+
+            if ($compFilter['time-range'] && !in_array($compFilter['name'],array(
+                'VEVENT',
+                'VTODO',
+                'VJOURNAL',
+                'VFREEBUSY',
+                'VALARM',
+            ))) {
+                throw new Sabre_DAV_Exception_BadRequest('The time-range filter is not defined for the ' . $compFilter['name'] . ' component');
+            };
+
+            $result[] = $compFilter;
+
+        }
+
+        return $result;
+
+    }
+
+    /**
+     * Parses all the prop-filter elements from a node
+     *
+     * @param DOMElement $parentNode
+     * @return array
+     */
+    protected function parsePropFilters(DOMElement $parentNode) {
+
+        $propFilterNodes = $this->xpath->query('cal:prop-filter', $parentNode);
+        $result = array();
+
+        for ($ii=0; $ii < $propFilterNodes->length; $ii++) {
+
+            $propFilterNode = $propFilterNodes->item($ii);
+            $propFilter = array();
+            $propFilter['name'] = $propFilterNode->getAttribute('name');
+            $propFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $propFilterNode)->length>0;
+            $propFilter['param-filters'] = $this->parseParamFilters($propFilterNode);
+            $propFilter['text-match'] = $this->parseTextMatch($propFilterNode);
+            $propFilter['time-range'] = $this->parseTimeRange($propFilterNode);
+
+            $result[] = $propFilter;
+
+        }
+
+        return $result;
+
+    }
+
+    /**
+     * Parses the param-filter element
+     *
+     * @param DOMElement $parentNode
+     * @return array
+     */
+    protected function parseParamFilters(DOMElement $parentNode) {
+
+        $paramFilterNodes = $this->xpath->query('cal:param-filter', $parentNode);
+        $result = array();
+
+        for($ii=0;$ii<$paramFilterNodes->length;$ii++) {
+
+            $paramFilterNode = $paramFilterNodes->item($ii);
+            $paramFilter = array();
+            $paramFilter['name'] = $paramFilterNode->getAttribute('name');
+            $paramFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $paramFilterNode)->length>0;
+            $paramFilter['text-match'] = $this->parseTextMatch($paramFilterNode);
+
+            $result[] = $paramFilter;
+
+        }
+
+        return $result;
+
+    }
+
+    /**
+     * Parses the text-match element
+     *
+     * @param DOMElement $parentNode
+     * @return array|null
+     */
+    protected function parseTextMatch(DOMElement $parentNode) {
+
+        $textMatchNodes = $this->xpath->query('cal:text-match', $parentNode);
+
+        if ($textMatchNodes->length === 0)
+            return null;
+
+        $textMatchNode = $textMatchNodes->item(0);
+        $negateCondition = $textMatchNode->getAttribute('negate-condition');
+        $negateCondition = $negateCondition==='yes';
+        $collation = $textMatchNode->getAttribute('collation');
+        if (!$collation) $collation = 'i;ascii-casemap';
+
+        return array(
+            'negate-condition' => $negateCondition,
+            'collation' => $collation,
+            'value' => $textMatchNode->nodeValue
+        );
+
+    }
+
+    /**
+     * Parses the time-range element
+     *
+     * @param DOMElement $parentNode
+     * @return array|null
+     */
+    protected function parseTimeRange(DOMElement $parentNode) {
+
+        $timeRangeNodes = $this->xpath->query('cal:time-range', $parentNode);
+        if ($timeRangeNodes->length === 0) {
+            return null;
+        }
+
+        $timeRangeNode = $timeRangeNodes->item(0);
+
+        if ($start = $timeRangeNode->getAttribute('start')) {
+            $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+        } else {
+            $start = null;
+        }
+        if ($end = $timeRangeNode->getAttribute('end')) {
+            $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+        } else {
+            $end = null;
+        }
+
+        if (!is_null($start) && !is_null($end) && $end <= $start) {
+            throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the time-range filter');
+        }
+
+        return array(
+            'start' => $start,
+            'end' => $end,
+        );
+
+    }
+
+    /**
+     * Parses the CALDAV:expand element
+     * 
+     * @param DOMElement $parentNode 
+     * @return void
+     */
+    protected function parseExpand(DOMElement $parentNode) {
+
+        $start = $parentNode->getAttribute('start');
+        if(!$start) {
+            throw new Sabre_DAV_Exception_BadRequest('The "start" attribute is required for the CALDAV:expand element');
+        } 
+        $start = Sabre_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);
+        
+        if ($end <= $start) {
+            throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
+        }
+
+        return array(
+            'start' => $start,
+            'end' => $end,
+        );
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
new file mode 100755
index 0000000000000000000000000000000000000000..1bb6b5d53faf4f6848d2675c701554558d525269
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
@@ -0,0 +1,347 @@
+<?php
+
+/**
+ * CalendarQuery Validator
+ *
+ * This class is responsible for checking if an iCalendar object matches a set
+ * of filters. The main function to do this is 'validate'.
+ *
+ * This is used to determine which icalendar objects should be returned for a
+ * calendar-query REPORT request.
+ *
+ * @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_CalendarQueryValidator {
+
+    /**
+     * Verify if a list of filters applies to the calendar data object
+     *
+     * The list of filters must be formatted as parsed by Sabre_CalDAV_CalendarQueryParser
+     *
+     * @param Sabre_VObject_Component $vObject
+     * @param array $filters
+     * @return bool
+     */
+    public function validate(Sabre_VObject_Component $vObject,array $filters) {
+
+        // The top level object is always a component filter.
+        // We'll parse it manually, as it's pretty simple.
+        if ($vObject->name !== $filters['name']) {
+            return false;
+        }
+
+        return
+            $this->validateCompFilters($vObject, $filters['comp-filters']) &&
+            $this->validatePropFilters($vObject, $filters['prop-filters']);
+
+
+    }
+
+    /**
+     * This method checks the validity of comp-filters.
+     *
+     * A list of comp-filters needs to be specified. Also the parent of the
+     * component we're checking should be specified, not the component to check
+     * itself.
+     *
+     * @param Sabre_VObject_Component $parent
+     * @param array $filters
+     * @return bool
+     */
+    protected function validateCompFilters(Sabre_VObject_Component $parent, array $filters) {
+
+        foreach($filters as $filter) {
+
+            $isDefined = isset($parent->$filter['name']);
+
+            if ($filter['is-not-defined']) {
+
+                if ($isDefined) {
+                    return false;
+                } else {
+                    continue;
+                }
+
+            }
+            if (!$isDefined) {
+                return false;
+            }
+
+            if ($filter['time-range']) {
+                foreach($parent->$filter['name'] as $subComponent) {
+                    if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
+                        continue 2;
+                    }
+                }
+                return false;
+            }
+
+            if (!$filter['comp-filters'] && !$filter['prop-filters']) {
+                continue;
+            }
+
+            // If there are sub-filters, we need to find at least one component
+            // for which the subfilters hold true.
+            foreach($parent->$filter['name'] as $subComponent) {
+
+                if (
+                    $this->validateCompFilters($subComponent, $filter['comp-filters']) &&
+                    $this->validatePropFilters($subComponent, $filter['prop-filters'])) {
+                        // We had a match, so this comp-filter succeeds
+                        continue 2;
+                }
+
+            }
+
+            // If we got here it means there were sub-comp-filters or
+            // sub-prop-filters and there was no match. This means this filter
+            // needs to return false.
+            return false;
+
+        }
+
+        // If we got here it means we got through all comp-filters alive so the
+        // filters were all true.
+        return true;
+
+    }
+
+    /**
+     * This method checks the validity of prop-filters.
+     *
+     * A list of prop-filters needs to be specified. Also the parent of the
+     * property we're checking should be specified, not the property to check
+     * itself.
+     *
+     * @param Sabre_VObject_Component $parent
+     * @param array $filters
+     * @return bool
+     */
+    protected function validatePropFilters(Sabre_VObject_Component $parent, array $filters) {
+
+        foreach($filters as $filter) {
+
+            $isDefined = isset($parent->$filter['name']);
+
+            if ($filter['is-not-defined']) {
+
+                if ($isDefined) {
+                    return false;
+                } else {
+                    continue;
+                }
+
+            }
+            if (!$isDefined) {
+                return false;
+            }
+
+            if ($filter['time-range']) {
+                foreach($parent->$filter['name'] as $subComponent) {
+                    if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
+                        continue 2;
+                    }
+                }
+                return false;
+            }
+
+            if (!$filter['param-filters'] && !$filter['text-match']) {
+                continue;
+            }
+
+            // If there are sub-filters, we need to find at least one property
+            // for which the subfilters hold true.
+            foreach($parent->$filter['name'] as $subComponent) {
+
+                if(
+                    $this->validateParamFilters($subComponent, $filter['param-filters']) &&
+                    (!$filter['text-match'] || $this->validateTextMatch($subComponent, $filter['text-match']))
+                ) {
+                    // We had a match, so this prop-filter succeeds
+                    continue 2;
+                }
+
+            }
+
+            // If we got here it means there were sub-param-filters or
+            // text-match filters and there was no match. This means the
+            // filter needs to return false.
+            return false;
+
+        }
+
+        // If we got here it means we got through all prop-filters alive so the
+        // filters were all true.
+        return true;
+
+    }
+
+    /**
+     * This method checks the validity of param-filters.
+     *
+     * A list of param-filters needs to be specified. Also the parent of the
+     * parameter we're checking should be specified, not the parameter to check
+     * itself.
+     *
+     * @param Sabre_VObject_Property $parent
+     * @param array $filters
+     * @return bool
+     */
+    protected function validateParamFilters(Sabre_VObject_Property $parent, array $filters) {
+
+        foreach($filters as $filter) {
+
+            $isDefined = isset($parent[$filter['name']]);
+
+            if ($filter['is-not-defined']) {
+
+                if ($isDefined) {
+                    return false;
+                } else {
+                    continue;
+                }
+
+            }
+            if (!$isDefined) {
+                return false;
+            }
+
+            if (!$filter['text-match']) {
+                continue;
+            }
+
+            // If there are sub-filters, we need to find at least one parameter
+            // for which the subfilters hold true.
+            foreach($parent[$filter['name']] as $subParam) {
+
+                if($this->validateTextMatch($subParam,$filter['text-match'])) {
+                    // We had a match, so this param-filter succeeds
+                    continue 2;
+                }
+
+            }
+
+            // If we got here it means there was a text-match filter and there
+            // were no matches. This means the filter needs to return false.
+            return false;
+
+        }
+
+        // If we got here it means we got through all param-filters alive so the
+        // filters were all true.
+        return true;
+
+    }
+
+    /**
+     * This method checks the validity of a text-match.
+     *
+     * 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 array $textMatch
+     * @return bool
+     */
+    protected function validateTextMatch(Sabre_VObject_Node $parent, array $textMatch) {
+
+        $value = (string)$parent;
+
+        $isMatching = Sabre_DAV_StringUtil::textMatch($value, $textMatch['value'], $textMatch['collation']);
+
+        return ($textMatch['negate-condition'] xor $isMatching);
+
+    }
+
+    /**
+     * Validates if a component matches the given time range.
+     *
+     * This is all based on the rules specified in rfc4791, which are quite
+     * complex.
+     *
+     * @param Sabre_VObject_Node $component
+     * @param DateTime $start
+     * @param DateTime $end
+     * @return bool
+     */
+    protected function validateTimeRange(Sabre_VObject_Node $component, $start, $end) {
+
+        if (is_null($start)) {
+            $start = new DateTime('1900-01-01');
+        }
+        if (is_null($end)) {
+            $end = new DateTime('3000-01-01');
+        }
+
+        switch($component->name) {
+
+            case 'VEVENT' :
+            case 'VTODO' :
+            case 'VJOURNAL' :
+
+                return $component->isInTimeRange($start, $end);
+
+            case 'VALARM' :
+
+                // If the valarm is wrapped in a recurring event, we need to
+                // expand the recursions, and validate each.
+                //
+                // Our datamodel doesn't easily allow us to do this straight
+                // in the VALARM component code, so this is a hack, and an
+                // expensive one too.
+                if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
+                    // Fire up the iterator!
+                    $it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
+                    while($it->valid()) {
+                        $expandedEvent = $it->getEventObject();
+
+                        // We need to check from these expanded alarms, which
+                        // one is the first to trigger. Based on this, we can
+                        // determine if we can 'give up' expanding events.
+                        $firstAlarm = null;
+                        foreach($expandedEvent->VALARM as $expandedAlarm) {
+                            $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
+                            if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
+                                $firstAlarm = $effectiveTrigger;
+                            }
+                            if ($expandedAlarm->isInTimeRange($start, $end)) {
+                                return true;
+                            }
+
+                        }
+                        if ($firstAlarm > $end) {
+                            return false;
+                        }
+                        $it->next();
+                    }
+                    return false;
+                } else {
+                    return $component->isInTimeRange($start, $end);
+                }
+
+            case 'VFREEBUSY' :
+                throw new Sabre_DAV_Exception_NotImplemented('time-range filters are currently not supported on ' . $component->name . ' components');
+
+            case 'COMPLETED' :
+            case 'CREATED' :
+            case 'DTEND' :
+            case 'DTSTAMP' :
+            case 'DTSTART' :
+            case 'DUE' :
+            case 'LAST-MODIFIED' :
+                return ($start <= $component->getDateTime() && $end >= $component->getDateTime());
+
+
+
+            default :
+                throw new Sabre_DAV_Exception_BadRequest('You cannot create a time-range filter on a ' . $component->name . ' component');
+
+        }
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/CalendarRootNode.php b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
old mode 100644
new mode 100755
index 69669a9d7fd96a5612661cf463621f242c8fcd3e..3907913cc78600afc38698ddb42ba3d30cffeed7
--- a/3rdparty/Sabre/CalDAV/CalendarRootNode.php
+++ b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
@@ -1,38 +1,38 @@
 <?php
 
 /**
- * Users collection 
+ * Users collection
  *
  * This object is responsible for generating a collection of users.
  *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollection {
 
     /**
-     * CalDAV backend 
-     * 
-     * @var Sabre_CalDAV_Backend_Abstract 
+     * CalDAV backend
+     *
+     * @var Sabre_CalDAV_Backend_Abstract
      */
     protected $caldavBackend;
 
     /**
-     * Constructor 
+     * Constructor
      *
      * This constructor needs both an authentication and a caldav backend.
      *
-     * By default this class will show a list of calendar collections for 
-     * principals in the 'principals' collection. If your main principals are 
-     * actually located in a different path, use the $principalPrefix argument 
+     * By default this class will show a list of calendar collections for
+     * principals in the 'principals' collection. If your main principals are
+     * actually located in a different path, use the $principalPrefix argument
      * to override this.
      *
      *
-     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend 
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend 
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
      * @param string $principalPrefix
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CalDAV_Backend_Abstract $caldavBackend, $principalPrefix = 'principals') {
@@ -46,9 +46,9 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
      * Returns the nodename
      *
      * We're overriding this, because the default will be the 'principalPrefix',
-     * and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT 
-     * 
-     * @return void
+     * and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT
+     *
+     * @return string
      */
     public function getName() {
 
@@ -62,9 +62,9 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
      * The passed array contains principal information, and is guaranteed to
      * at least contain a uri item. Other properties may or may not be
      * supplied by the authentication backend.
-     * 
-     * @param array $principal 
-     * @return Sabre_DAV_INode 
+     *
+     * @param array $principal
+     * @return Sabre_DAV_INode
      */
     public function getChildForPrincipal(array $principal) {
 
diff --git a/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php b/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php
deleted file mode 100644
index 656b7286a66538dbeb487983a226384705e7c6b9..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-/**
- * InvalidICalendarObject
- *
- * This exception is thrown when an attempt is made to create or update
- * an invalid ICalendar object
- * 
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 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_InvalidICalendarObject extends Sabre_DAV_Exception_PreconditionFailed {
-
-
-}
diff --git a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
old mode 100644
new mode 100755
index 4e2c6eb93d286da842e1ecb9035d031b0cb885c2..ec42b406b2f172c7289a00ba7975fc35f59fa877
--- a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
+++ b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
@@ -4,28 +4,28 @@
  * ICS Exporter
  *
  * This plugin adds the ability to export entire calendars as .ics files.
- * This is useful for clients that don't support CalDAV yet. They often do 
+ * This is useful for clients that don't support CalDAV yet. They often do
  * support ics files.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
 
     /**
-     * Reference to Server class 
-     * 
-     * @var Sabre_DAV_Server 
+     * Reference to Server class
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
     /**
-     * Initializes the plugin and registers event handlers 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin and registers event handlers
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -38,10 +38,10 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
     /**
      * 'beforeMethod' event handles. This event handles intercepts GET requests ending
      * with ?export
-     * 
+     *
      * @param string $method
      * @param string $uri
-     * @return void
+     * @return bool
      */
     public function beforeMethod($method, $uri) {
 
@@ -55,9 +55,19 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
 
         if (!($node instanceof Sabre_CalDAV_Calendar)) return;
 
+        // Checking ACL, if available.
+        if ($aclPlugin = $this->server->getPlugin('acl')) {
+            $aclPlugin->checkPrivileges($uri, '{DAV:}read');
+        }
+
         $this->server->httpResponse->setHeader('Content-Type','text/calendar');
         $this->server->httpResponse->sendStatus(200);
-        $this->server->httpResponse->sendBody($this->generateICS($this->server->tree->getChildren($uri)));
+
+        $nodes = $this->server->getPropertiesForPath($uri, array(
+            '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data',
+        ),1);
+
+        $this->server->httpResponse->sendBody($this->generateICS($nodes));
 
         // Returning false to break the event chain
         return false;
@@ -65,16 +75,20 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Merges all calendar objects, and builds one big ics export 
-     * 
-     * @param array $nodes 
-     * @return void
+     * Merges all calendar objects, and builds one big ics export
+     *
+     * @param array $nodes
+     * @return string
      */
     public function generateICS(array $nodes) {
 
         $calendar = new Sabre_VObject_Component('vcalendar');
         $calendar->version = '2.0';
-        $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
+        if (Sabre_DAV_Server::$exposeVersion) {
+            $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
+        } else {
+            $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
+        }
         $calendar->calscale = 'GREGORIAN';
 
         $collectedTimezones = array();
@@ -84,7 +98,11 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
 
         foreach($nodes as $node) {
 
-            $nodeData = $node->get();
+            if (!isset($node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'])) {
+                continue;
+            }
+            $nodeData = $node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'];
+
             $nodeComp = Sabre_VObject_Reader::read($nodeData);
 
             foreach($nodeComp->children() as $child) {
@@ -105,13 +123,10 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
                         $collectedTimezones[] = $child->TZID;
                         break;
 
-
                 }
 
-
             }
 
-
         }
 
         foreach($timezones as $tz) $calendar->add($tz);
@@ -119,6 +134,6 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
 
         return $calendar->serialize();
 
-    } 
+    }
 
 }
diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php
old mode 100644
new mode 100755
index 8193dff3a8393debda39bb09cf1df42a1f642763..15d51ebcf79a2b7552257ac4b7c1d5e42596461a
--- a/3rdparty/Sabre/CalDAV/ICalendar.php
+++ b/3rdparty/Sabre/CalDAV/ICalendar.php
@@ -4,15 +4,15 @@
  * Calendar interface
  *
  * Implement this interface to allow a node to be recognized as an calendar.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_ICalendar extends Sabre_DAV_ICollection {
 
- 
+
 
 }
diff --git a/3rdparty/Sabre/CalDAV/ICalendarObject.php b/3rdparty/Sabre/CalDAV/ICalendarObject.php
old mode 100644
new mode 100755
index 708300ad7bd83f731c6e0933ebaeaf31789aa876..280f982a310e225929c22dc0685caf3852c3f20a
--- a/3rdparty/Sabre/CalDAV/ICalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/ICalendarObject.php
@@ -1,20 +1,20 @@
 <?php
 
 /**
- * CalendarObject interface 
+ * CalendarObject interface
 /**
- * Extend the ICalendarObject interface to allow your custom nodes to be picked up as 
+ * Extend the ICalendarObject interface to allow your custom nodes to be picked up as
  * CalendarObjects.
  *
  * Calendar objects are resources such as Events, Todo's or Journals.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_ICalendarObject extends Sabre_DAV_IFile { 
+interface Sabre_CalDAV_ICalendarObject extends Sabre_DAV_IFile {
 
 }
 
diff --git a/3rdparty/Sabre/CalDAV/ICalendarUtil.php b/3rdparty/Sabre/CalDAV/ICalendarUtil.php
deleted file mode 100644
index 699abfdd6f5e0726701664a849405df4b422fe32..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/CalDAV/ICalendarUtil.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
-/**
- * This class contains several utilities related to the ICalendar (rfc2445) format
- *
- * This class is now deprecated, and won't be further maintained. Please use 
- * the Sabre_VObject package for your ics parsing needs.
- *
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 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 Use Sabre_VObject instead.
- */
-class Sabre_CalDAV_ICalendarUtil {
-
-    /**
-     * Validates an ICalendar object
-     *
-     * This method makes sure this ICalendar object is properly formatted.
-     * If we can't parse it, we'll throw exceptions.
-     *
-     * @param string $icalData 
-     * @param array $allowedComponents 
-     * @return bool 
-     */
-    static function validateICalendarObject($icalData, array $allowedComponents = null) {
-
-        $xcal = simplexml_load_string(self::toXCal($icalData));
-        if (!$xcal) throw new Sabre_CalDAV_Exception_InvalidICalendarObject('Invalid calendarobject format');
-
-        $xcal->registerXPathNameSpace('cal','urn:ietf:params:xml:ns:xcal');
-        
-        // Check if there's only 1 component
-        $components = array('vevent','vtodo','vjournal','vfreebusy');
-        $componentsFound = array();
-
-        foreach($components as $component) {
-            $test = $xcal->xpath('/cal:iCalendar/cal:vcalendar/cal:' . $component);
-            if (is_array($test)) $componentsFound = array_merge($componentsFound, $test);
-        }
-        if (count($componentsFound)<1) {
-            throw new Sabre_CalDAV_Exception_InvalidICalendarObject('One VEVENT, VTODO, VJOURNAL or VFREEBUSY must be specified. 0 found.');
-        }
-        $component = $componentsFound[0];
-
-        if (is_null($allowedComponents)) return true;
-
-        // Check if the component is allowed
-        $name = $component->getName();
-        if (!in_array(strtoupper($name),$allowedComponents)) {
-            throw new Sabre_CalDAV_Exception_InvalidICalendarObject(strtoupper($name) . ' is not allowed in this calendar.');
-        }
-
-        if (count($xcal->xpath('/cal:iCalendar/cal:vcalendar/cal:method'))>0) {
-            throw new Sabre_CalDAV_Exception_InvalidICalendarObject('The METHOD property is not allowed in calendar objects');
-        }
-
-        return true;
-
-    }
-
-    /**
-     * Converts ICalendar data to XML.
-     *
-     * Properties are converted to lowercase xml elements. Parameters are;
-     * converted to attributes. BEGIN:VEVENT is converted to <vevent> and
-     * END:VEVENT </vevent> as well as other components.
-     *
-     * It's a very loose parser. If any line does not conform to the spec, it
-     * will simply be ignored. It will try to detect if \r\n or \n line endings
-     * are used.
-     *
-     * @todo Currently quoted attributes are not parsed correctly.
-     * @see http://tools.ietf.org/html/draft-royer-calsch-xcal-03
-     * @param string $icalData 
-     * @return string. 
-     */
-    static function toXCAL($icalData) {
-
-        // Detecting line endings
-        $lb="\r\n";
-        if (strpos($icalData,"\r\n")!==false) $lb = "\r\n";
-        elseif (strpos($icalData,"\n")!==false) $lb = "\n";
-
-        // Splitting up items per line
-        $lines = explode($lb,$icalData);
-
-        // Properties can be folded over 2 lines. In this case the second
-        // line will be preceeded by a space or tab.
-        $lines2 = array();
-        foreach($lines as $line) {
-
-            if (!$line) continue;
-            if ($line[0]===" " || $line[0]==="\t") {
-                $lines2[count($lines2)-1].=substr($line,1);
-                continue;
-            }
-
-            $lines2[]=$line;
-
-        }
-
-        $xml = '<?xml version="1.0"?>' . "\n";
-        $xml.= "<iCalendar xmlns=\"urn:ietf:params:xml:ns:xcal\">\n";
-
-        $spaces = 2;
-        foreach($lines2 as $line) {
-
-            $matches = array();
-            // This matches PROPERTYNAME;ATTRIBUTES:VALUE
-            if (!preg_match('/^([^:^;]*)(?:;([^:]*))?:(.*)$/',$line,$matches))
-                continue;
-
-            $propertyName = strtolower($matches[1]);
-            $attributes = $matches[2];
-            $value = $matches[3];
-
-            // If the line was in the format BEGIN:COMPONENT or END:COMPONENT, we need to special case it.
-            if ($propertyName === 'begin') {
-                $xml.=str_repeat(" ",$spaces);
-                $xml.='<' . strtolower($value) . ">\n";
-                $spaces+=2;
-                continue;
-            } elseif ($propertyName === 'end') {
-                $spaces-=2;
-                $xml.=str_repeat(" ",$spaces);
-                $xml.='</' . strtolower($value) . ">\n";
-                continue;
-            }
-
-            $xml.=str_repeat(" ",$spaces);
-            $xml.='<' . $propertyName;
-            if ($attributes) {
-                // There can be multiple attributes
-                $attributes = explode(';',$attributes);
-                foreach($attributes as $att) {
-  
-                    list($attName,$attValue) = explode('=',$att,2);
-                    $attName = strtolower($attName);
-                    if ($attName === 'language') $attName='xml:lang';
-                    $xml.=' ' . $attName . '="' . htmlspecialchars($attValue) . '"';
-
-                }
-            }
-
-            $xml.='>'. htmlspecialchars(trim($value)) . '</' . $propertyName . ">\n";
-          
-        }
-        $xml.="</iCalendar>";
-        return $xml;
-
-    }
-
-}
-
diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php
old mode 100644
new mode 100755
index 02747c8395e3a2b6d0f32183074d598d707ffff6..d7d1d970518a8f32e1cdcfe9feed27a930804b6e
--- a/3rdparty/Sabre/CalDAV/Plugin.php
+++ b/3rdparty/Sabre/CalDAV/Plugin.php
@@ -8,8 +8,8 @@
  *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Plugin extends Sabre_DAV_ServerPlugin {
@@ -18,7 +18,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * This is the official CalDAV namespace
      */
     const NS_CALDAV = 'urn:ietf:params:xml:ns:caldav';
-    
+
     /**
      * This is the namespace for the proprietary calendarserver extensions
      */
@@ -41,21 +41,48 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
     const CALENDAR_ROOT = 'calendars';
 
     /**
-     * Reference to server object 
-     * 
-     * @var Sabre_DAV_Server 
+     * Reference to server object
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
+    /**
+     * The email handler for invites and other scheduling messages.
+     * 
+     * @var Sabre_CalDAV_Schedule_IMip 
+     */
+    protected $imipHandler;
+
+    /**
+     * Sets the iMIP handler.
+     *
+     * iMIP = The email transport of iCalendar scheduling messages. Setting 
+     * this is optional, but if you want the server to allow invites to be sent 
+     * out, you must set a handler.
+     *
+     * Specifically iCal will plain assume that the server supports this. If 
+     * the server doesn't, iCal will display errors when inviting people to 
+     * events.
+     *
+     * @param Sabre_CalDAV_Schedule_IMip $imipHandler 
+     * @return void
+     */
+    public function setIMipHandler(Sabre_CalDAV_Schedule_IMip $imipHandler) {
+
+        $this->imipHandler = $imipHandler;
+
+    }
+
     /**
      * 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 
+     * This method is passed a uri. It should only return HTTP methods that are
      * available for the specified uri.
      *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getHTTPMethods($uri) {
 
@@ -68,7 +95,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         if ($node instanceof Sabre_DAV_IExtendedCollection) {
             try {
                 $node->getChild($name);
-            } catch (Sabre_DAV_Exception_FileNotFound $e) {
+            } catch (Sabre_DAV_Exception_NotFound $e) {
                 return array('MKCALENDAR');
             }
         }
@@ -77,9 +104,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Returns a list of features for the DAV: HTTP header. 
-     * 
-     * @return array 
+     * Returns a list of features for the DAV: HTTP header.
+     *
+     * @return array
      */
     public function getFeatures() {
 
@@ -89,11 +116,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a plugin name.
-     * 
+     *
      * Using this name other plugins will be able to access other plugins
-     * using Sabre_DAV_Server::getPlugin 
-     * 
-     * @return string 
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
      */
     public function getPluginName() {
 
@@ -105,38 +132,46 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * Returns a list of reports this plugin supports.
      *
      * This will be used in the {DAV:}supported-report-set property.
-     * Note that you still need to subscribe to the 'report' event to actually 
-     * implement them 
-     * 
+     * Note that you still need to subscribe to the 'report' event to actually
+     * implement them
+     *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getSupportedReportSet($uri) {
 
         $node = $this->server->tree->getNodeForPath($uri);
+
+        $reports = array();
         if ($node instanceof Sabre_CalDAV_ICalendar || $node instanceof Sabre_CalDAV_ICalendarObject) {
-            return array(
-                 '{' . self::NS_CALDAV . '}calendar-multiget',
-                 '{' . self::NS_CALDAV . '}calendar-query',
-            );
+            $reports[] = '{' . self::NS_CALDAV . '}calendar-multiget';
+            $reports[] = '{' . self::NS_CALDAV . '}calendar-query';
         }
-        return array();
+        if ($node instanceof Sabre_CalDAV_ICalendar) {
+            $reports[] = '{' . self::NS_CALDAV . '}free-busy-query';
+        }
+        return $reports;
 
     }
 
     /**
-     * Initializes the plugin 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
 
         $this->server = $server;
+
         $server->subscribeEvent('unknownMethod',array($this,'unknownMethod'));
         //$server->subscribeEvent('unknownMethod',array($this,'unknownMethod2'),1000);
         $server->subscribeEvent('report',array($this,'report'));
         $server->subscribeEvent('beforeGetProperties',array($this,'beforeGetProperties'));
+        $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
+        $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
+        $server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
+        $server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
 
         $server->xmlNamespaces[self::NS_CALDAV] = 'cal';
         $server->xmlNamespaces[self::NS_CALENDARSERVER] = 'cs';
@@ -144,6 +179,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
         $server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet';
 
         $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';
 
@@ -161,7 +197,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             '{' . self::NS_CALDAV . '}calendar-data',
 
             // scheduling extension
+            '{' . self::NS_CALDAV . '}schedule-inbox-URL',
+            '{' . self::NS_CALDAV . '}schedule-outbox-URL',
             '{' . self::NS_CALDAV . '}calendar-user-address-set',
+            '{' . self::NS_CALDAV . '}calendar-user-type',
 
             // CalendarServer extensions
             '{' . self::NS_CALENDARSERVER . '}getctag',
@@ -173,36 +212,55 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * This function handles support for the MKCALENDAR method
-     * 
-     * @param string $method 
-     * @return bool 
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function unknownMethod($method, $uri) {
 
-        if ($method!=='MKCALENDAR') return;
+        switch ($method) {
+            case 'MKCALENDAR' :
+                $this->httpMkCalendar($uri);
+                // false is returned to stop the propagation of the
+                // unknownMethod event.
+                return false;
+            case 'POST' :
+                // Checking if we're talking to an outbox
+                try {
+                    $node = $this->server->tree->getNodeForPath($uri);
+                } catch (Sabre_DAV_Exception_NotFound $e) {
+                    return;
+                }
+                if (!$node instanceof Sabre_CalDAV_Schedule_IOutbox)
+                    return;
 
-        $this->httpMkCalendar($uri);
-        // false is returned to stop the unknownMethod event
-        return false;
+                $this->outboxRequest($node);
+                return false;
+
+        }
 
     }
 
     /**
-     * This functions handles REPORT requests specific to CalDAV 
-     * 
-     * @param string $reportName 
-     * @param DOMNode $dom 
-     * @return bool 
+     * This functions handles REPORT requests specific to CalDAV
+     *
+     * @param string $reportName
+     * @param DOMNode $dom
+     * @return bool
      */
     public function report($reportName,$dom) {
 
-        switch($reportName) { 
+        switch($reportName) {
             case '{'.self::NS_CALDAV.'}calendar-multiget' :
                 $this->calendarMultiGetReport($dom);
                 return false;
             case '{'.self::NS_CALDAV.'}calendar-query' :
                 $this->calendarQueryReport($dom);
                 return false;
+            case '{'.self::NS_CALDAV.'}free-busy-query' :
+                $this->freeBusyQueryReport($dom);
+                return false;
 
         }
 
@@ -212,9 +270,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * This function handles the MKCALENDAR HTTP method, which creates
      * a new calendar.
-     * 
+     *
      * @param string $uri
-     * @return void 
+     * @return void
      */
     public function httpMkCalendar($uri) {
 
@@ -238,7 +296,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 foreach(Sabre_DAV_XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) {
                     $properties[$k] = $prop;
                 }
-            
+
             }
         }
 
@@ -254,9 +312,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * beforeGetProperties
      *
      * This method handler is invoked before any after properties for a
-     * resource are fetched. This allows us to add in any CalDAV specific 
-     * properties. 
-     * 
+     * resource are fetched. This allows us to add in any CalDAV specific
+     * properties.
+     *
      * @param string $path
      * @param Sabre_DAV_INode $node
      * @param array $requestedProperties
@@ -270,12 +328,21 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
             // calendar-home-set property
             $calHome = '{' . self::NS_CALDAV . '}calendar-home-set';
             if (in_array($calHome,$requestedProperties)) {
-                $principalId = $node->getName(); 
+                $principalId = $node->getName();
                 $calendarHomePath = self::CALENDAR_ROOT . '/' . $principalId . '/';
                 unset($requestedProperties[$calHome]);
                 $returnedProperties[200][$calHome] = new Sabre_DAV_Property_Href($calendarHomePath);
             }
 
+            // schedule-outbox-URL property
+            $scheduleProp = '{' . self::NS_CALDAV . '}schedule-outbox-URL';
+            if (in_array($scheduleProp,$requestedProperties)) {
+                $principalId = $node->getName();
+                $outboxPath = self::CALENDAR_ROOT . '/' . $principalId . '/outbox';
+                unset($requestedProperties[$scheduleProp]);
+                $returnedProperties[200][$scheduleProp] = new Sabre_DAV_Property_Href($outboxPath);
+            }
+
             // calendar-user-address-set property
             $calProp = '{' . self::NS_CALDAV . '}calendar-user-address-set';
             if (in_array($calProp,$requestedProperties)) {
@@ -287,7 +354,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
             }
 
-            // These two properties are shortcuts for ical to easily find 
+            // These two properties are shortcuts for ical to easily find
             // other principals this principal has access to.
             $propRead = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for';
             $propWrite = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for';
@@ -301,8 +368,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
                     $groupNode = $this->server->tree->getNodeForPath($group);
 
-                    // If the node is either ap proxy-read or proxy-write 
-                    // group, we grab the parent principal and add it to the 
+                    // If the node is either ap proxy-read or proxy-write
+                    // group, we grab the parent principal and add it to the
                     // list.
                     if ($groupNode instanceof Sabre_CalDAV_Principal_ProxyRead) {
                         list($readList[]) = Sabre_DAV_URLUtil::splitPath($group);
@@ -327,8 +394,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
 
         if ($node instanceof Sabre_CalDAV_ICalendarObject) {
-            // The calendar-data property is not supposed to be a 'real' 
-            // property, but in large chunks of the spec it does act as such. 
+            // The calendar-data property is not supposed to be a 'real'
+            // property, but in large chunks of the spec it does act as such.
             // Therefore we simply expose it as a property.
             $calDataProp = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data';
             if (in_array($calDataProp, $requestedProperties)) {
@@ -350,18 +417,52 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * This report is used by the client to fetch the content of a series
      * of urls. Effectively avoiding a lot of redundant requests.
-     * 
-     * @param DOMNode $dom 
+     *
+     * @param DOMNode $dom
      * @return void
      */
     public function calendarMultiGetReport($dom) {
 
         $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
-
         $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
+
+        $xpath = new DOMXPath($dom);
+        $xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
+        $xpath->registerNameSpace('dav','urn:DAV');
+
+        $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
+        if ($expand->length>0) {
+            $expandElem = $expand->item(0);
+            $start = $expandElem->getAttribute('start');
+            $end = $expandElem->getAttribute('end');
+            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);
+
+            if ($end <= $start) {
+                throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
+            }
+
+            $expand = true;
+
+        } else {
+
+            $expand = false;
+
+        }
+
         foreach($hrefElems as $elem) {
             $uri = $this->server->calculateUri($elem->nodeValue);
             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->expand($start, $end);
+                $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+            }
+
             $propertyList[]=$objProps;
 
         }
@@ -377,48 +478,57 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * This report is used by clients to request calendar objects based on
      * complex conditions.
-     * 
-     * @param DOMNode $dom 
+     *
+     * @param DOMNode $dom
      * @return void
      */
     public function calendarQueryReport($dom) {
 
-        $requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
-
-        $filterNode = $dom->getElementsByTagNameNS('urn:ietf:params:xml:ns:caldav','filter');
-        if ($filterNode->length!==1) {
-            throw new Sabre_DAV_Exception_BadRequest('The calendar-query report must have a filter element');
-        }
-        $filters = Sabre_CalDAV_XMLUtil::parseCalendarQueryFilters($filterNode->item(0));
+        $parser = new Sabre_CalDAV_CalendarQueryParser($dom);
+        $parser->parse();
 
         $requestedCalendarData = true;
+        $requestedProperties = $parser->requestedProperties;
 
         if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
+
             // We always retrieve calendar-data, as we need it for filtering.
             $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
 
-            // If calendar-data wasn't explicitly requested, we need to remove 
+            // If calendar-data wasn't explicitly requested, we need to remove
             // it after processing.
             $requestedCalendarData = false;
         }
 
         // These are the list of nodes that potentially match the requirement
-        $candidateNodes = $this->server->getPropertiesForPath($this->server->getRequestUri(),$requestedProperties,$this->server->getHTTPDepth(0));
+        $candidateNodes = $this->server->getPropertiesForPath(
+            $this->server->getRequestUri(),
+            $requestedProperties,
+            $this->server->getHTTPDepth(0)
+        );
 
         $verifiedNodes = array();
 
+        $validator = new Sabre_CalDAV_CalendarQueryValidator();
+
         foreach($candidateNodes as $node) {
 
             // 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;
+            if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']))
+                continue;
+
+            $vObject = Sabre_VObject_Reader::read($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
+            if ($validator->validate($vObject,$parser->filters)) {
 
-            if ($this->validateFilters($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'],$filters)) {
-                
                 if (!$requestedCalendarData) {
                     unset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
                 }
+                if ($parser->expand) {
+                    $vObject->expand($parser->expand['start'], $parser->expand['end']);
+                    $node[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+                }
                 $verifiedNodes[] = $node;
-            } 
+            }
 
         }
 
@@ -428,360 +538,291 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     }
 
-
     /**
-     * Verify if a list of filters applies to the calendar data object 
+     * This method is responsible for parsing the request and generating the
+     * response for the CALDAV:free-busy-query REPORT.
      *
-     * The calendarData object must be a valid iCalendar blob. The list of 
-     * filters must be formatted as parsed by Sabre_CalDAV_Plugin::parseCalendarQueryFilters
-     *
-     * @param string $calendarData 
-     * @param array $filters 
-     * @return bool 
+     * @param DOMNode $dom
+     * @return void
      */
-    public function validateFilters($calendarData,$filters) {
-
-        // We are converting the calendar object to an XML structure
-        // This makes it far easier to parse
-        $xCalendarData = Sabre_CalDAV_ICalendarUtil::toXCal($calendarData);
-        $xml = simplexml_load_string($xCalendarData);
-        $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:xcal');
-
-        foreach($filters as $xpath=>$filter) {
-
-            // if-not-defined comes first
-            if (isset($filter['is-not-defined'])) {
-                if (!$xml->xpath($xpath))
-                    continue;
-                else
-                    return false;
-                
-            }
-
-            $elem = $xml->xpath($xpath);
-            
-            if (!$elem) return false;
-            $elem = $elem[0];
-
-            if (isset($filter['time-range'])) {
-
-                switch($elem->getName()) {
-                    case 'vevent' :
-                        $result = $this->validateTimeRangeFilterForEvent($xml,$xpath,$filter);
-                        if ($result===false) return false;
-                        break;
-                    case 'vtodo' :
-                        $result = $this->validateTimeRangeFilterForTodo($xml,$xpath,$filter);
-                        if ($result===false) return false;
-                        break;
-                    case 'vjournal' :
-                    case 'vfreebusy' :
-                    case 'valarm' :
-                        // TODO: not implemented
-                        break;
-
-                    /*
-
-                    case 'vjournal' :
-                        $result = $this->validateTimeRangeFilterForJournal($xml,$xpath,$filter);
-                        if ($result===false) return false;
-                        break;
-                    case 'vfreebusy' :
-                        $result = $this->validateTimeRangeFilterForFreeBusy($xml,$xpath,$filter);
-                        if ($result===false) return false;
-                        break;
-                    case 'valarm' :
-                        $result = $this->validateTimeRangeFilterForAlarm($xml,$xpath,$filter);
-                        if ($result===false) return false;
-                        break;
-
-                        */
-
-                }
+    protected function freeBusyQueryReport(DOMNode $dom) {
 
-            } 
+        $start = null;
+        $end = null;
 
-            if (isset($filter['text-match'])) {
-                $currentString = (string)$elem;
+        foreach($dom->firstChild->childNodes as $childNode) {
 
-                $isMatching = Sabre_DAV_StringUtil::textMatch($currentString, $filter['text-match']['value'], $filter['text-match']['collation']);
-                if ($filter['text-match']['negate-condition'] && $isMatching) return false;
-                if (!$filter['text-match']['negate-condition'] && !$isMatching) return false;
-                
+            $clark = Sabre_DAV_XMLUtil::toClarkNotation($childNode);
+            if ($clark == '{' . self::NS_CALDAV . '}time-range') {
+                $start = $childNode->getAttribute('start');
+                $end = $childNode->getAttribute('end');
+                break;
             }
 
         }
-        return true;
-        
-    }
-
-    /**
-     * Checks whether a time-range filter matches an event.
-     * 
-     * @param SimpleXMLElement $xml Event as xml object 
-     * @param string $currentXPath XPath to check 
-     * @param array $currentFilter Filter information 
-     * @return void
-     */
-    private function validateTimeRangeFilterForEvent(SimpleXMLElement $xml,$currentXPath,array $currentFilter) {
-
-        // Grabbing the DTSTART property
-        $xdtstart = $xml->xpath($currentXPath.'/c:dtstart');
-        if (!count($xdtstart)) {
-            throw new Sabre_DAV_Exception_BadRequest('DTSTART property missing from calendar object');
+        if ($start) {
+            $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+        }
+        if ($end) {
+            $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
         }
 
-        // The dtstart can be both a date, or datetime property
-        if ((string)$xdtstart[0]['value']==='DATE' || strlen((string)$xdtstart[0])===8) {
-            $isDateTime = false;
-        } else {
-            $isDateTime = true;
+        if (!$start && !$end) {
+            throw new Sabre_DAV_Exception_BadRequest('The freebusy report must have a time-range filter');
         }
+        $acl = $this->server->getPlugin('acl');
 
-        // Determining the timezone
-        if ($tzid = (string)$xdtstart[0]['tzid']) {
-            $tz = new DateTimeZone($tzid);
-        } else {
-            $tz = null;
+        if (!$acl) {
+            throw new Sabre_DAV_Exception('The ACL plugin must be loaded for free-busy queries to work');
         }
-        if ($isDateTime) {
-            $dtstart = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdtstart[0],$tz);
-        } else {
-            $dtstart = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdtstart[0]);
+        $uri = $this->server->getRequestUri();
+        $acl->checkPrivileges($uri,'{' . self::NS_CALDAV . '}read-free-busy');
+
+        $calendar = $this->server->tree->getNodeForPath($uri);
+        if (!$calendar instanceof Sabre_CalDAV_ICalendar) {
+            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);
+            }
+            return $obj;
+        }, $calendar->getChildren());
 
-        // Grabbing the DTEND property
-        $xdtend = $xml->xpath($currentXPath.'/c:dtend');
-        $dtend = null;
+        $generator = new Sabre_VObject_FreeBusyGenerator();
+        $generator->setObjects($objects);
+        $generator->setTimeRange($start, $end);
+        $result = $generator->getResult();
+        $result = $result->serialize();
 
-        if (count($xdtend)) {
-            // Determining the timezone
-            if ($tzid = (string)$xdtend[0]['tzid']) {
-                $tz = new DateTimeZone($tzid);
-            } else {
-                $tz = null;
-            }
+        $this->server->httpResponse->sendStatus(200);
+        $this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
+        $this->server->httpResponse->setHeader('Content-Length', strlen($result));
+        $this->server->httpResponse->sendBody($result);
 
-            // Since the VALUE prameter of both DTSTART and DTEND must be the same
-            // we can assume we don't need to check the VALUE paramter of DTEND.
-            if ($isDateTime) {
-                $dtend = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdtend[0],$tz);
-            } else {
-                $dtend = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdtend[0],$tz);
-            }
+    }
 
-        } 
-        
-        if (is_null($dtend)) {
-            // The DTEND property was not found. We will first see if the event has a duration
-            // property
-
-            $xduration = $xml->xpath($currentXPath.'/c:duration');
-            if (count($xduration)) {
-                $duration = Sabre_CalDAV_XMLUtil::parseICalendarDuration((string)$xduration[0]);
-
-                // Making sure that the duration is bigger than 0 seconds.
-                $tempDT = clone $dtstart;
-                $tempDT->modify($duration);
-                if ($tempDT > $dtstart) {
-
-                    // use DTEND = DTSTART + DURATION 
-                    $dtend = $tempDT;
-                } else {
-                    // use DTEND = DTSTART
-                    $dtend = $dtstart;
-                }
+    /**
+     * This method is triggered before a file gets updated with new content.
+     *
+     * This plugin uses this method to ensure that CalDAV objects receive
+     * valid calendar data.
+     *
+     * @param string $path
+     * @param Sabre_DAV_IFile $node
+     * @param resource $data
+     * @return void
+     */
+    public function beforeWriteContent($path, Sabre_DAV_IFile $node, &$data) {
 
-            }
-        }
+        if (!$node instanceof Sabre_CalDAV_ICalendarObject)
+            return;
+
+        $this->validateICalendar($data);
 
-        if (is_null($dtend)) {
-            if ($isDateTime) {
-                // DTEND = DTSTART
-                $dtend = $dtstart;
-            } else {
-                // DTEND = DTSTART + 1 DAY
-                $dtend = clone $dtstart;
-                $dtend->modify('+1 day');
-            }
-        }
-        // TODO: we need to properly parse RRULE's, but it's very difficult.
-        // For now, we're always returning events if they have an RRULE at all.
-        $rrule = $xml->xpath($currentXPath.'/c:rrule');
-        $hasRrule = (count($rrule))>0; 
-       
-        if (!is_null($currentFilter['time-range']['start']) && $currentFilter['time-range']['start'] >= $dtend)  return false;
-        if (!is_null($currentFilter['time-range']['end'])   && $currentFilter['time-range']['end']   <= $dtstart && !$hasRrule) return false;
-        return true;
-    
     }
 
-    private function validateTimeRangeFilterForTodo(SimpleXMLElement $xml,$currentXPath,array $filter) {
+    /**
+     * This method is triggered before a new file is created.
+     *
+     * This plugin uses this method to ensure that newly created calendar
+     * objects contain valid calendar data.
+     *
+     * @param string $path
+     * @param resource $data
+     * @param Sabre_DAV_ICollection $parentNode
+     * @return void
+     */
+    public function beforeCreateFile($path, &$data, Sabre_DAV_ICollection $parentNode) {
 
-        // Gathering all relevant elements
+        if (!$parentNode instanceof Sabre_CalDAV_Calendar)
+            return;
 
-        $dtStart = null;
-        $duration = null;
-        $due = null;
-        $completed = null;
-        $created = null;
+        $this->validateICalendar($data);
 
-        $xdt = $xml->xpath($currentXPath.'/c:dtstart');
-        if (count($xdt)) {
-            // The dtstart can be both a date, or datetime property
-            if ((string)$xdt[0]['value']==='DATE') {
-                $isDateTime = false;
-            } else {
-                $isDateTime = true;
-            }
+    }
 
-            // Determining the timezone
-            if ($tzid = (string)$xdt[0]['tzid']) {
-                $tz = new DateTimeZone($tzid);
-            } else {
-                $tz = null;
-            }
-            if ($isDateTime) {
-                $dtStart = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0],$tz);
-            } else {
-                $dtStart = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdt[0]);
-            }
+    /**
+     * Checks if the submitted iCalendar data is in fact, valid.
+     *
+     * An exception is thrown if it's not.
+     *
+     * @param resource|string $data
+     * @return void
+     */
+    protected function validateICalendar(&$data) {
+
+        // If it's a stream, we convert it to a string first.
+        if (is_resource($data)) {
+            $data = stream_get_contents($data);
         }
 
-        // Only need to grab duration if dtStart is set
-        if (!is_null($dtStart)) {
+        // Converting the data to unicode, if needed.
+        $data = Sabre_DAV_StringUtil::ensureUTF8($data);
 
-            $xduration = $xml->xpath($currentXPath.'/c:duration');
-            if (count($xduration)) {
-                $duration = Sabre_CalDAV_XMLUtil::parseICalendarDuration((string)$xduration[0]);
-            }
+        try {
+
+            $vobj = Sabre_VObject_Reader::read($data);
+
+        } catch (Sabre_VObject_ParseException $e) {
+
+            throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
 
         }
 
-        if (!is_null($dtStart) && !is_null($duration)) {
+    }
 
-            // Comparision from RFC 4791:
-            // (start <= DTSTART+DURATION) AND ((end > DTSTART) OR (end >= DTSTART+DURATION))
+    /**
+     * This method handles POST requests to the schedule-outbox
+     *
+     * @param Sabre_CalDAV_Schedule_IOutbox $outboxNode
+     * @return void
+     */
+    public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode) {
 
-            $end = clone $dtStart;
-            $end->modify($duration);
+        $originator = $this->server->httpRequest->getHeader('Originator');
+        $recipients = $this->server->httpRequest->getHeader('Recipient');
 
-            if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $end) &&
-                (is_null($filter['time-range']['end']) || $filter['time-range']['end'] > $dtStart || $filter['time-range']['end'] >= $end) ) {
-                return true;
-            } else {
-                return false;
-            }
+        if (!$originator) {
+            throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests');
+        } 
+        if (!$recipients) {
+            throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests');
+        } 
 
+        if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) {
+            throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address');
         }
+        $originator = substr($originator,7);
 
-        // Need to grab the DUE property
-        $xdt = $xml->xpath($currentXPath.'/c:due');
-        if (count($xdt)) {
-            // The due property can be both a date, or datetime property
-            if ((string)$xdt[0]['value']==='DATE') {
-                $isDateTime = false;
-            } else {
-                $isDateTime = true;
-            }
-            // Determining the timezone
-            if ($tzid = (string)$xdt[0]['tzid']) {
-                $tz = new DateTimeZone($tzid);
-            } else {
-                $tz = null;
-            }
-            if ($isDateTime) {
-                $due = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0],$tz);
-            } else {
-                $due = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdt[0]);
+        $recipients = explode(',',$recipients);
+        foreach($recipients as $k=>$recipient) {
+
+            $recipient = trim($recipient);
+            if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) { 
+                throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address');
             }
+            $recipient = substr($recipient, 7);
+            $recipients[$k] = $recipient;
         }
 
-        if (!is_null($dtStart) && !is_null($due)) {
-
-            // Comparision from RFC 4791:
-            // ((start < DUE) OR (start <= DTSTART)) AND ((end > DTSTART) OR (end >= DUE))
-            
-            if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] < $due || $filter['time-range']['start'] < $dtstart) &&
-                (is_null($filter['time-range']['end'])   || $filter['time-range']['end'] >= $due) ) {
-                return true;
-            } else {
-                return false;
-            }
+        // We need to make sure that 'originator' matches one of the email 
+        // addresses of the selected principal.
+        $principal = $outboxNode->getOwner();
+        $props = $this->server->getProperties($principal,array(
+            '{' . self::NS_CALDAV . '}calendar-user-address-set',
+        ));
 
+        $addresses = array();
+        if (isset($props['{' . self::NS_CALDAV . '}calendar-user-address-set'])) {
+            $addresses = $props['{' . self::NS_CALDAV . '}calendar-user-address-set']->getHrefs();
         }
 
-        if (!is_null($dtStart)) {
-            
-            // Comparision from RFC 4791
-            // (start <= DTSTART)  AND (end > DTSTART)
-            if ( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $dtStart) &&
-                 (is_null($filter['time-range']['end'])   || $filter['time-range']['end'] > $dtStart) ) {
-                 return true;
-            } else {
-                return false;
-            }
+        if (!in_array('mailto:' . $originator, $addresses)) {
+            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());
         }
 
-        if (!is_null($due)) {
-            
-            // Comparison from RFC 4791
-            // (start < DUE) AND (end >= DUE)
-            if ( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] < $due) &&
-                 (is_null($filter['time-range']['end'])   || $filter['time-range']['end'] >= $due) ) {
-                 return true;
-            } else {
-                return false;
+        // Checking for the object type
+        $componentType = null;
+        foreach($vObject->getComponents() as $component) {
+            if ($component->name !== 'VTIMEZONE') {
+                $componentType = $component->name;
+                break;
             }
-
-        }
-        // Need to grab the COMPLETED property
-        $xdt = $xml->xpath($currentXPath.'/c:completed');
-        if (count($xdt)) {
-            $completed = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0]);
         }
-        // Need to grab the CREATED property
-        $xdt = $xml->xpath($currentXPath.'/c:created');
-        if (count($xdt)) {
-            $created = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0]);
+        if (is_null($componentType)) {
+            throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
         }
 
-        if (!is_null($completed) && !is_null($created)) {
-            // Comparison from RFC 4791
-            // ((start <= CREATED) OR (start <= COMPLETED)) AND ((end >= CREATED) OR (end >= COMPLETED))
-            if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $created || $filter['time-range']['start'] <= $completed) &&
-                (is_null($filter['time-range']['end'])   || $filter['time-range']['end'] >= $created   || $filter['time-range']['end'] >= $completed)) {
-                return true;
-            } else {
-                return false;
-            }
+        // 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 (!is_null($completed)) {
-            // Comparison from RFC 4791
-            // (start <= COMPLETED) AND (end  >= COMPLETED)
-            if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $completed) &&
-                (is_null($filter['time-range']['end'])   || $filter['time-range']['end'] >= $completed)) {
-                return true;
-            } else {
-                return false;
-            }
+        if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') {
+            $this->iMIPMessage($originator, $recipients, $vObject);
+            $this->server->httpResponse->sendStatus(200);
+            $this->server->httpResponse->sendBody('Messages sent');
+        } else {
+            throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
         }
 
-        if (!is_null($created)) {
-            // Comparison from RFC 4791
-            // (end > CREATED)
-            if( (is_null($filter['time-range']['end']) || $filter['time-range']['end'] > $created) ) {
-                return true;
-            } else {
-                return false;
-            }
+    }
+
+    /**
+     * Sends an iMIP message by email.
+     * 
+     * @param string $originator 
+     * @param array $recipients 
+     * @param Sabre_VObject_Component $vObject 
+     * @return void
+     */
+    protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+
+        if (!$this->imipHandler) {
+            throw new Sabre_DAV_Exception_NotImplemented('No iMIP handler is setup on this server.');
         }
+        $this->imipHandler->sendMessage($originator, $recipients, $vObject); 
+
+    }
+
+    /**
+     * This method is used to generate HTML output for the
+     * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
+     * can use to create new calendars.
+     *
+     * @param Sabre_DAV_INode $node
+     * @param string $output
+     * @return bool
+     */
+    public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+        if (!$node instanceof Sabre_CalDAV_UserCalendars)
+            return;
+
+        $output.= '<tr><td colspan="2"><form method="post" action="">
+            <h3>Create new calendar</h3>
+            <input type="hidden" name="sabreAction" value="mkcalendar" />
+            <label>Name (uri):</label> <input type="text" name="name" /><br />
+            <label>Display name:</label> <input type="text" name="{DAV:}displayname" /><br />
+            <input type="submit" value="create" />
+            </form>
+            </td></tr>';
+
+        return false;
 
-        // Everything else is TRUE
-        return true;
+    }
+
+    /**
+     * This method allows us to intercept the 'mkcalendar' sabreAction. This
+     * action enables the user to create new calendars from the browser plugin.
+     *
+     * @param string $uri
+     * @param string $action
+     * @param array $postVars
+     * @return bool
+     */
+    public function browserPostAction($uri, $action, array $postVars) {
+
+        if ($action!=='mkcalendar')
+            return;
+
+        $resourceType = array('{DAV:}collection','{urn:ietf:params:xml:ns:caldav}calendar');
+        $properties = array();
+        if (isset($postVars['{DAV:}displayname'])) {
+            $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+        }
+        $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
+        return false;
 
     }
 
diff --git a/3rdparty/Sabre/CalDAV/Principal/Collection.php b/3rdparty/Sabre/CalDAV/Principal/Collection.php
old mode 100644
new mode 100755
index 13435b2448efc55a0f7b8439e6a8727174d2cfd7..abbefa5567a4c9f939fe7a9ce5faba22c749695b
--- a/3rdparty/Sabre/CalDAV/Principal/Collection.php
+++ b/3rdparty/Sabre/CalDAV/Principal/Collection.php
@@ -4,23 +4,23 @@
  * Principal collection
  *
  * This is an alternative collection to the standard ACL principal collection.
- * This collection adds support for the calendar-proxy-read and 
- * calendar-proxy-write sub-principals, as defined by the caldav-proxy 
+ * This collection adds support for the calendar-proxy-read and
+ * calendar-proxy-write sub-principals, as defined by the caldav-proxy
  * specification.
  *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Principal_Collection extends Sabre_DAVACL_AbstractPrincipalCollection {
 
     /**
-     * Returns a child object based on principal information 
-     * 
-     * @param array $principalInfo 
-     * @return Sabre_CalDAV_Principal_User 
+     * Returns a child object based on principal information
+     *
+     * @param array $principalInfo
+     * @return Sabre_CalDAV_Principal_User
      */
     public function getChildForPrincipal(array $principalInfo) {
 
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
old mode 100644
new mode 100755
index f531d85d1ffffacb2bf00101c942e0bb2b0953f3..4b3f035634a795f82ac33460ba9ccbf570b1a415
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
@@ -4,38 +4,38 @@
  * ProxyRead principal
  *
  * This class represents a principal group, hosted under the main principal.
- * This is needed to implement 'Calendar delegation' support. This class is 
+ * This is needed to implement 'Calendar delegation' support. This class is
  * instantiated by Sabre_CalDAV_Principal_User.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
 
     /**
-     * Principal information from the parent principal. 
-     * 
-     * @var array 
+     * Principal information from the parent principal.
+     *
+     * @var array
      */
     protected $principalInfo;
 
     /**
-     * Principal backend 
-     * 
-     * @var Sabre_DAVACL_IPrincipalBackend 
+     * Principal backend
+     *
+     * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
      * Creates the object.
      *
-     * Note that you MUST supply the parent principal information. 
-     * 
-     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend 
-     * @param array $principalInfo 
+     * Note that you MUST supply the parent principal information.
+     *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+     * @param array $principalInfo
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalInfo) {
 
@@ -46,8 +46,8 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
 
     /**
      * Returns this principals name.
-     * 
-     * @return string 
+     *
+     * @return string
      */
     public function getName() {
 
@@ -56,13 +56,13 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
     }
 
     /**
-     * Returns the last modification time 
+     * Returns the last modification time
      *
-     * @return null 
+     * @return null
      */
     public function getLastModified() {
 
-        return null; 
+        return null;
 
     }
 
@@ -70,7 +70,7 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
      * Deletes the current node
      *
      * @throws Sabre_DAV_Exception_Forbidden
-     * @return void 
+     * @return void
      */
     public function delete() {
 
@@ -80,7 +80,7 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
 
     /**
      * Renames the node
-     * 
+     *
      * @throws Sabre_DAV_Exception_Forbidden
      * @param string $name The new name
      * @return void
@@ -93,11 +93,11 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
 
 
     /**
-     * Returns a list of altenative urls for a principal
-     * 
+     * Returns a list of alternative urls for a principal
+     *
      * This can for example be an email address, or ldap url.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getAlternateUriSet() {
 
@@ -106,41 +106,41 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
     }
 
     /**
-     * Returns the full principal url 
-     * 
-     * @return string 
+     * Returns the full principal url
+     *
+     * @return string
      */
     public function getPrincipalUrl() {
 
-        return $this->principalInfo['uri'] . '/' . $this->getName(); 
+        return $this->principalInfo['uri'] . '/' . $this->getName();
 
     }
 
     /**
      * Returns the list of group members
-     * 
+     *
      * If this principal is a group, this function should return
-     * all member principal uri's for the group. 
-     * 
+     * all member principal uri's for the group.
+     *
      * @return array
      */
     public function getGroupMemberSet() {
 
-        return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); 
+        return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
 
     }
 
     /**
      * Returns the list of groups this principal is member of
-     * 
+     *
      * If this principal is a member of a (list of) groups, this function
-     * should return a list of principal uri's for it's members. 
-     * 
-     * @return array 
+     * should return a list of principal uri's for it's members.
+     *
+     * @return array
      */
     public function getGroupMembership() {
 
-        return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); 
+        return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
 
     }
 
@@ -149,11 +149,11 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
      *
      * If this principal is a group, this method sets all the group members.
      * The list of members is always overwritten, never appended to.
-     * 
-     * This method should throw an exception if the members could not be set. 
-     * 
-     * @param array $principals 
-     * @return void 
+     *
+     * This method should throw an exception if the members could not be set.
+     *
+     * @param array $principals
+     * @return void
      */
     public function setGroupMemberSet(array $principals) {
 
@@ -165,9 +165,9 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
      * Returns the displayname
      *
      * This should be a human readable name for the principal.
-     * If none is available, return the nodename. 
-     * 
-     * @return string 
+     * If none is available, return the nodename.
+     *
+     * @return string
      */
     public function getDisplayName() {
 
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
old mode 100644
new mode 100755
index 4d8face20607f51a3f81e449143bdace2708aff7..dd0c2e86edd70e5b8e7ef43bb3d0374482021d04
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
@@ -4,38 +4,38 @@
  * ProxyWrite principal
  *
  * This class represents a principal group, hosted under the main principal.
- * This is needed to implement 'Calendar delegation' support. This class is 
+ * This is needed to implement 'Calendar delegation' support. This class is
  * instantiated by Sabre_CalDAV_Principal_User.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
 
     /**
-     * Parent principal information 
-     * 
-     * @var array 
+     * Parent principal information
+     *
+     * @var array
      */
     protected $principalInfo;
 
     /**
-     * Principal Backend 
-     * 
-     * @var Sabre_DAVACL_IPrincipalBackend 
+     * Principal Backend
+     *
+     * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
      * Creates the object
      *
-     * Note that you MUST supply the parent principal information. 
-     * 
-     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend 
-     * @param array $principalInfo 
+     * Note that you MUST supply the parent principal information.
+     *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+     * @param array $principalInfo
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalInfo) {
 
@@ -46,8 +46,8 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
 
     /**
      * Returns this principals name.
-     * 
-     * @return string 
+     *
+     * @return string
      */
     public function getName() {
 
@@ -56,13 +56,13 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
     }
 
     /**
-     * Returns the last modification time 
+     * Returns the last modification time
      *
-     * @return null 
+     * @return null
      */
     public function getLastModified() {
 
-        return null; 
+        return null;
 
     }
 
@@ -70,7 +70,7 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
      * Deletes the current node
      *
      * @throws Sabre_DAV_Exception_Forbidden
-     * @return void 
+     * @return void
      */
     public function delete() {
 
@@ -80,7 +80,7 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
 
     /**
      * Renames the node
-     * 
+     *
      * @throws Sabre_DAV_Exception_Forbidden
      * @param string $name The new name
      * @return void
@@ -93,11 +93,11 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
 
 
     /**
-     * Returns a list of altenative urls for a principal
-     * 
+     * Returns a list of alternative urls for a principal
+     *
      * This can for example be an email address, or ldap url.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getAlternateUriSet() {
 
@@ -106,41 +106,41 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
     }
 
     /**
-     * Returns the full principal url 
-     * 
-     * @return string 
+     * Returns the full principal url
+     *
+     * @return string
      */
     public function getPrincipalUrl() {
 
-        return $this->principalInfo['uri'] . '/' . $this->getName(); 
+        return $this->principalInfo['uri'] . '/' . $this->getName();
 
     }
 
     /**
      * Returns the list of group members
-     * 
+     *
      * If this principal is a group, this function should return
-     * all member principal uri's for the group. 
-     * 
+     * all member principal uri's for the group.
+     *
      * @return array
      */
     public function getGroupMemberSet() {
 
-        return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); 
+        return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
 
     }
 
     /**
      * Returns the list of groups this principal is member of
-     * 
+     *
      * If this principal is a member of a (list of) groups, this function
-     * should return a list of principal uri's for it's members. 
-     * 
-     * @return array 
+     * should return a list of principal uri's for it's members.
+     *
+     * @return array
      */
     public function getGroupMembership() {
 
-        return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); 
+        return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
 
     }
 
@@ -149,11 +149,11 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
      *
      * If this principal is a group, this method sets all the group members.
      * The list of members is always overwritten, never appended to.
-     * 
-     * This method should throw an exception if the members could not be set. 
-     * 
-     * @param array $principals 
-     * @return void 
+     *
+     * This method should throw an exception if the members could not be set.
+     *
+     * @param array $principals
+     * @return void
      */
     public function setGroupMemberSet(array $principals) {
 
@@ -165,9 +165,9 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
      * Returns the displayname
      *
      * This should be a human readable name for the principal.
-     * If none is available, return the nodename. 
-     * 
-     * @return string 
+     * If none is available, return the nodename.
+     *
+     * @return string
      */
     public function getDisplayName() {
 
diff --git a/3rdparty/Sabre/CalDAV/Principal/User.php b/3rdparty/Sabre/CalDAV/Principal/User.php
old mode 100644
new mode 100755
index 034629b89b3154006e4756d3ffe614df8ca850b6..8453b877a73da3762382110378cf38aa91aeb65b
--- a/3rdparty/Sabre/CalDAV/Principal/User.php
+++ b/3rdparty/Sabre/CalDAV/Principal/User.php
@@ -1,25 +1,25 @@
 <?php
 
 /**
- * CalDAV principal 
+ * CalDAV principal
  *
- * This is a standard user-principal for CalDAV. This principal is also a 
- * collection and returns the caldav-proxy-read and caldav-proxy-write child 
+ * This is a standard user-principal for CalDAV. This principal is also a
+ * collection and returns the caldav-proxy-read and caldav-proxy-write child
  * principals.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Principal_User extends Sabre_DAVACL_Principal implements Sabre_DAV_ICollection {
 
     /**
-     * Creates a new file in the directory 
-     * 
-     * @param string $name Name of the file 
-     * @param resource $data Initial payload, passed as a readable stream resource. 
+     * Creates a new file in the directory
+     *
+     * @param string $name Name of the file
+     * @param resource $data Initial payload, passed as a readable stream resource.
      * @throws Sabre_DAV_Exception_Forbidden
      * @return void
      */
@@ -30,9 +30,9 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
     }
 
     /**
-     * Creates a new subdirectory 
-     * 
-     * @param string $name 
+     * Creates a new subdirectory
+     *
+     * @param string $name
      * @throws Sabre_DAV_Exception_Forbidden
      * @return void
      */
@@ -43,45 +43,60 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
     }
 
     /**
-     * Returns a specific child node, referenced by its name 
-     * 
-     * @param string $name 
-     * @return Sabre_DAV_INode 
+     * Returns a specific child node, referenced by its name
+     *
+     * @param string $name
+     * @return Sabre_DAV_INode
      */
     public function getChild($name) {
 
+        $principal = $this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/' . $name);
+        if (!$principal) {
+            throw new Sabre_DAV_Exception_NotFound('Node with name ' . $name . ' was not found');
+        }
         if ($name === 'calendar-proxy-read')
             return new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties);
 
         if ($name === 'calendar-proxy-write')
             return new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties);
 
-        throw new Sabre_DAV_Exception_FileNotFound('Node with name ' . $name . ' was not found');
+        throw new Sabre_DAV_Exception_NotFound('Node with name ' . $name . ' was not found');
 
     }
 
     /**
-     * Returns an array with all the child nodes 
-     * 
-     * @return Sabre_DAV_INode[] 
+     * Returns an array with all the child nodes
+     *
+     * @return Sabre_DAV_INode[]
      */
     public function getChildren() {
 
-        return array(
-            new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties),
-            new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties),
-        );
+        $r = array();
+        if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-read')) {
+            $r[] = new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties);
+        }
+        if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-write')) {
+            $r[] = new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties);
+        }
+
+        return $r;
 
     }
 
     /**
-     * Checks if a child-node with the specified name exists 
-     * 
-     * @return bool 
+     * Returns whether or not the child node exists
+     *
+     * @param string $name
+     * @return bool
      */
     public function childExists($name) {
 
-        return $name === 'calendar-proxy-read' ||  $name === 'calendar-proxy-write';
+        try {
+            $this->getChild($name);
+            return true;
+        } catch (Sabre_DAV_Exception_NotFound $e) {
+            return false;
+        }
 
     }
 
@@ -89,33 +104,28 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
-        return array(
-            array(
-                'privilege' => '{DAV:}read',
-                'principal' => $this->principalProperties['uri'],
-                'protected' => true,
-            ),
-            array(
-                'privilege' => '{DAV:}read',
-                'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read',
-                'protected' => true,
-            ),
-            array(
-                'privilege' => '{DAV:}read',
-                'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write',
-                'protected' => true,
-            ),
+        $acl = parent::getACL();
+        $acl[] = array(
+            'privilege' => '{DAV:}read',
+            'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read',
+            'protected' => true,
+        );
+        $acl[] = array(
+            'privilege' => '{DAV:}read',
+            'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write',
+            'protected' => true,
         );
+        return $acl;
 
     }
 
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
old mode 100644
new mode 100755
index 1bbaca6b8a75b2c57aafbc6ddf1f461af95b4f9e..2ea078d7dac03cbe8e241690739ad7c02bb17676
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
@@ -3,40 +3,40 @@
 /**
  * Supported component set property
  *
- * This property is a representation of the supported-calendar_component-set 
+ * 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
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_SupportedCalendarComponentSet extends Sabre_DAV_Property {
 
     /**
-     * List of supported components, such as "VEVENT, VTODO" 
-     * 
-     * @var array 
+     * List of supported components, such as "VEVENT, VTODO"
+     *
+     * @var array
      */
     private $components;
 
     /**
-     * Creates the property 
-     * 
-     * @param array $components 
+     * Creates the property
+     *
+     * @param array $components
      */
     public function __construct(array $components) {
 
-       $this->components = $components; 
+       $this->components = $components;
 
     }
 
     /**
-     * Returns the list of supported components 
-     * 
-     * @return array 
+     * Returns the list of supported components
+     *
+     * @return array
      */
     public function getValue() {
 
@@ -45,10 +45,10 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
     }
 
     /**
-     * Serializes the property in a DOMDocument 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * 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) {
@@ -58,7 +58,7 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
 
             $xcomp = $doc->createElement('cal:comp');
             $xcomp->setAttribute('name',$component);
-            $node->appendChild($xcomp); 
+            $node->appendChild($xcomp);
 
        }
 
@@ -66,9 +66,9 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
 
     /**
      * Unserializes the DOMElement back into a Property class.
-     * 
-     * @param DOMElement $node 
-     * @return void
+     *
+     * @param DOMElement $node
+     * @return Sabre_CalDAV_Property_SupportedCalendarComponentSet
      */
     static function unserialize(DOMElement $node) {
 
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
old mode 100644
new mode 100755
index 5010ee6d5257ad3085b646e95157d3870506279a..1d848dd5cf68acaa05977a0292297a559dff316a
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
@@ -9,17 +9,17 @@
  *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_SupportedCalendarData extends Sabre_DAV_Property {
 
     /**
-     * Serializes the property in a DOMDocument 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * 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) {
@@ -32,7 +32,7 @@ class Sabre_CalDAV_Property_SupportedCalendarData extends Sabre_DAV_Property {
         $caldata->setAttribute('content-type','text/calendar');
         $caldata->setAttribute('version','2.0');
 
-        $node->appendChild($caldata); 
+        $node->appendChild($caldata);
     }
 
 }
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
old mode 100644
new mode 100755
index e585e9db3d877b5dc8e1d67ff7961791ac98800d..24e84d4c17d99815fba07ec9d540787f74f68e71
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
@@ -4,27 +4,27 @@
  * supported-collation-set property
  *
  * This property is a representation of the supported-collation-set property
- * in the CalDAV namespace. 
+ * in the CalDAV namespace.
  *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_SupportedCollationSet extends Sabre_DAV_Property {
 
     /**
-     * Serializes the property in a DOM document 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * Serializes the property in a DOM document
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
 
         $doc = $node->ownerDocument;
-        
+
         $prefix = $node->lookupPrefix('urn:ietf:params:xml:ns:caldav');
         if (!$prefix) $prefix = 'cal';
 
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IMip.php b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
new file mode 100755
index 0000000000000000000000000000000000000000..37e75fcc4a71c2626922319fef90a971ce6a4460
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * iMIP handler.
+ *
+ * This class is responsible for sending out iMIP messages. iMIP is the
+ * email-based transport for iTIP. iTIP deals with scheduling operations for
+ * iCalendar objects.
+ *
+ * If you want to customize the email that gets sent out, you can do so by
+ * extending this class and overriding the sendMessage method.
+ *
+ * @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_Schedule_IMip {
+
+    /**
+     * Email address used in From: header.
+     *
+     * @var string
+     */
+    protected $senderEmail;
+
+    /**
+     * Creates the email handler.
+     *
+     * @param string $senderEmail. The 'senderEmail' is the email that shows up
+     *                             in the 'From:' address. This should
+     *                             generally be some kind of no-reply email
+     *                             address you own.
+     */
+    public function __construct($senderEmail) {
+
+        $this->senderEmail = $senderEmail;
+
+    }
+
+    /**
+     * Sends one or more iTip messages through email.
+     *
+     * @param string $originator
+     * @param array $recipients
+     * @param Sabre_VObject_Component $vObject
+     * @return void
+     */
+    public function sendMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+
+        foreach($recipients as $recipient) {
+
+            $to = $recipient;
+            $replyTo = $originator;
+            $subject = 'SabreDAV iTIP message';
+
+            switch(strtoupper($vObject->METHOD)) {
+                case 'REPLY' :
+                    $subject = 'Response for: ' . $vObject->VEVENT->SUMMARY;
+                    break;
+                case 'REQUEST' :
+                    $subject = 'Invitation for: ' .$vObject->VEVENT->SUMMARY;
+                    break;
+                case 'CANCEL' :
+                    $subject = 'Cancelled event: ' . $vObject->VEVENT->SUMMARY;
+                    break;
+            }
+
+            $headers = array();
+            $headers[] = 'Reply-To: ' . $replyTo;
+            $headers[] = 'From: ' . $this->senderEmail;
+            $headers[] = 'Content-Type: text/calendar; method=' . (string)$vObject->method . '; charset=utf-8';
+            if (Sabre_DAV_Server::$exposeVersion) {
+                $headers[] = 'X-Sabre-Version: ' . Sabre_DAV_Version::VERSION . '-' . Sabre_DAV_Version::STABILITY;
+            }
+
+            $vcalBody = $vObject->serialize();
+
+            $this->mail($to, $subject, $vcalBody, $headers);
+
+        }
+
+    }
+
+    /**
+     * This function is reponsible for sending the actual email.
+     *
+     * @param string $to Recipient email address
+     * @param string $subject Subject of the email
+     * @param string $body iCalendar body
+     * @param array $headers List of headers
+     * @return void
+     */
+    protected function mail($to, $subject, $body, array $headers) {
+
+        mail($to, $subject, $body, implode("\r\n", $headers));
+
+    }
+
+
+}
+
+?>
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
new file mode 100755
index 0000000000000000000000000000000000000000..46d77514bc048ba965fa091a84bd19233c5404f4
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Implement this interface to have a node be recognized as a CalDAV scheduling
+ * outbox.
+ *
+ * @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_Schedule_IOutbox extends Sabre_DAV_ICollection, Sabre_DAVACL_IACL {
+
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
new file mode 100755
index 0000000000000000000000000000000000000000..014c37230d194a8bc2fb9efa5b4bb7b913b2a127
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * The CalDAV scheduling outbox
+ *
+ * The outbox is mainly used as an endpoint in the tree for a client to do
+ * free-busy requests. This functionality is completely handled by the
+ * Scheduling plugin, so this object is actually mostly static.
+ *
+ * @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_Schedule_Outbox extends Sabre_DAV_Directory implements Sabre_CalDAV_Schedule_IOutbox {
+
+    /**
+     * The principal Uri
+     *
+     * @var string
+     */
+    protected $principalUri;
+
+    /**
+     * Constructor
+     *
+     * @param string $principalUri
+     */
+    public function __construct($principalUri) {
+
+        $this->principalUri = $principalUri;
+
+    }
+
+    /**
+     * Returns the name of the node.
+     *
+     * This is used to generate the url.
+     *
+     * @return string
+     */
+    public function getName() {
+
+        return 'outbox';
+
+    }
+
+    /**
+     * Returns an array with all the child nodes
+     *
+     * @return Sabre_DAV_INode[]
+     */
+    public function getChildren() {
+
+        return array();
+
+    }
+
+    /**
+     * 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(
+                'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
+                'principal' => $this->getOwner(),
+                'protected' => true,
+            ),
+            array(
+                'privilege' => '{DAV:}read',
+                'principal' => $this->getOwner(),
+                'protected' => true,
+            ),
+        );
+
+    }
+
+    /**
+     * Updates the ACL
+     *
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
+     * @return void
+     */
+    public function setACL(array $acl) {
+
+        throw new Sabre_DAV_Exception_MethodNotAllowed('You\'re not allowed to update the ACL');
+
+    }
+
+    /**
+     * 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() {
+
+        $default = Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet();
+        $default['aggregates'][] = array(
+            'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
+        );
+
+        return $default;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Server.php b/3rdparty/Sabre/CalDAV/Server.php
old mode 100644
new mode 100755
index 969d69c6279a262286d1453d960a8da8aefbb29d..325e3d80a7fd081065ab216dd528c0b3927c966e
--- a/3rdparty/Sabre/CalDAV/Server.php
+++ b/3rdparty/Sabre/CalDAV/Server.php
@@ -3,17 +3,20 @@
 /**
  * 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 
+ * 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
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -22,17 +25,17 @@ 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. 
-     * 
+     * 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 
+     *
+     * @param PDO $pdo
      */
     public function __construct(PDO $pdo) {
 
diff --git a/3rdparty/Sabre/CalDAV/UserCalendars.php b/3rdparty/Sabre/CalDAV/UserCalendars.php
old mode 100644
new mode 100755
index f52d65e9a73f222e325ec7695374ae4a0f93ffcb..b8d3f0573fa4c9c2b43084b1a63937aaf137b33f
--- a/3rdparty/Sabre/CalDAV/UserCalendars.php
+++ b/3rdparty/Sabre/CalDAV/UserCalendars.php
@@ -1,68 +1,68 @@
 <?php
 
 /**
- * The UserCalenders class contains all calendars associated to one user 
- * 
+ * The UserCalenders class contains all calendars associated to one user
+ *
  * @package Sabre
  * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL {
 
     /**
-     * Principal backend 
-     * 
+     * Principal backend
+     *
      * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
      * CalDAV backend
-     * 
+     *
      * @var Sabre_CalDAV_Backend_Abstract
      */
     protected $caldavBackend;
 
     /**
-     * Principal information 
-     * 
-     * @var array 
+     * Principal information
+     *
+     * @var array
      */
     protected $principalInfo;
-    
+
     /**
-     * Constructor 
-     * 
+     * Constructor
+     *
      * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
-     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend 
-     * @param mixed $userUri 
+     * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+     * @param mixed $userUri
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $userUri) {
 
         $this->principalBackend = $principalBackend;
         $this->caldavBackend = $caldavBackend;
         $this->principalInfo = $principalBackend->getPrincipalByPath($userUri);
-       
+
     }
 
     /**
-     * Returns the name of this object 
-     * 
+     * Returns the name of this object
+     *
      * @return string
      */
     public function getName() {
-      
+
         list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalInfo['uri']);
-        return $name; 
+        return $name;
 
     }
 
     /**
-     * Updates the name of this object 
-     * 
-     * @param string $name 
+     * Updates the name of this object
+     *
+     * @param string $name
      * @return void
      */
     public function setName($name) {
@@ -72,8 +72,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     }
 
     /**
-     * Deletes this object 
-     * 
+     * Deletes this object
+     *
      * @return void
      */
     public function delete() {
@@ -83,13 +83,13 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     }
 
     /**
-     * Returns the last modification date 
-     * 
-     * @return int 
+     * Returns the last modification date
+     *
+     * @return int
      */
     public function getLastModified() {
 
-        return null; 
+        return null;
 
     }
 
@@ -97,9 +97,9 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      * Creates a new file under this object.
      *
      * This is currently not allowed
-     * 
-     * @param string $filename 
-     * @param resource $data 
+     *
+     * @param string $filename
+     * @param resource $data
      * @return void
      */
     public function createFile($filename, $data=null) {
@@ -112,8 +112,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      * Creates a new directory under this object.
      *
      * This is currently not allowed.
-     * 
-     * @param string $filename 
+     *
+     * @param string $filename
      * @return void
      */
     public function createDirectory($filename) {
@@ -123,11 +123,11 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     }
 
     /**
-     * Returns a single calendar, by name 
-     * 
+     * Returns a single calendar, by name
+     *
      * @param string $name
      * @todo needs optimizing
-     * @return Sabre_CalDAV_Calendar 
+     * @return Sabre_CalDAV_Calendar
      */
     public function getChild($name) {
 
@@ -136,22 +136,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
                 return $child;
 
         }
-        throw new Sabre_DAV_Exception_FileNotFound('Calendar with name \'' . $name . '\' could not be found');
+        throw new Sabre_DAV_Exception_NotFound('Calendar with name \'' . $name . '\' could not be found');
 
     }
 
     /**
      * Checks if a calendar exists.
-     * 
+     *
      * @param string $name
      * @todo needs optimizing
-     * @return bool 
+     * @return bool
      */
     public function childExists($name) {
 
         foreach($this->getChildren() as $child) {
             if ($name==$child->getName())
-                return true; 
+                return true;
 
         }
         return false;
@@ -160,8 +160,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
 
     /**
      * Returns a list of calendars
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getChildren() {
 
@@ -170,15 +170,17 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
         foreach($calendars as $calendar) {
             $objs[] = new Sabre_CalDAV_Calendar($this->principalBackend, $this->caldavBackend, $calendar);
         }
+        $objs[] = new Sabre_CalDAV_Schedule_Outbox($this->principalInfo['uri']);
         return $objs;
 
     }
 
     /**
      * Creates a new calendar
-     * 
-     * @param string $name 
-     * @param string $properties 
+     *
+     * @param string $name
+     * @param array $resourceType
+     * @param array $properties
      * @return void
      */
     public function createExtendedCollection($name, array $resourceType, array $properties) {
@@ -193,8 +195,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -207,8 +209,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -220,13 +222,13 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -264,9 +266,9 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -275,6 +277,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
 
     }
 
+    /**
+     * 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/Version.php b/3rdparty/Sabre/CalDAV/Version.php
old mode 100644
new mode 100755
index df8fe1f6bd6fba8d724939a0ed3d9fe18014fac4..939e903c89f87830b572678b5619f413127c0f78
--- a/3rdparty/Sabre/CalDAV/Version.php
+++ b/3rdparty/Sabre/CalDAV/Version.php
@@ -2,10 +2,10 @@
 
 /**
  * This class contains the Sabre_CalDAV version constants.
- * 
+ *
  * @package Sabre
  * @subpackage CalDAV 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.5.3';
+    const VERSION = '1.6.2';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CalDAV/XMLUtil.php b/3rdparty/Sabre/CalDAV/XMLUtil.php
deleted file mode 100644
index bf349a36aae6f13418dd7f25fd1710bcc3975750..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/CalDAV/XMLUtil.php
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-
-/**
- * XML utilities for CalDAV 
- *
- * This class contains a few static methods used for parsing certain CalDAV 
- * requests.
- *
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 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_XMLUtil {
-
-    /**
-     * This function parses the calendar-query report request body
-     *
-     * The body is quite complicated, so we're turning it into a PHP
-     * array.
-     *
-     * The resulting associative array has xpath expressions as keys.
-     * By default the xpath expressions should simply be checked for existance
-     * The xpath expressions can point to elements or attributes.
-     * 
-     * The array values can contain a number of items, which alters the query
-     * filter. 
-     *
-     * * time-range. Must also check if the todo or event falls within the
-     *               specified timerange. How this is interpreted depends on
-     *               the type of object (VTODO, VEVENT, VJOURNAL, etc)
-     * * is-not-defined
-     *               Instead of checking if the attribute or element exist,
-     *               we must check if it doesn't.
-     * * text-match
-     *               Checks if the value of the attribute or element matches
-     *               the specified value. This is actually another array with
-     *               the 'collation', 'value' and 'negate-condition' items.
-     *
-     * Refer to the CalDAV spec for more information.
-     * 
-     * @param DOMNode $domNode 
-     * @param string $basePath used for recursive calls.
-     * @param array $filters used for recursive calls.
-     * @return array 
-     */
-    static public function parseCalendarQueryFilters($domNode,$basePath = '/c:iCalendar', &$filters = array()) {
-
-        foreach($domNode->childNodes as $child) {
-
-            switch(Sabre_DAV_XMLUtil::toClarkNotation($child)) {
-
-                case '{urn:ietf:params:xml:ns:caldav}comp-filter' :
-                case '{urn:ietf:params:xml:ns:caldav}prop-filter' :
-                   
-                    $filterName = $basePath . '/' . 'c:' . strtolower($child->getAttribute('name'));
-                    $filters[$filterName] = array(); 
-
-                    self::parseCalendarQueryFilters($child, $filterName,$filters);
-                    break;
-
-                case '{urn:ietf:params:xml:ns:caldav}time-range' :
-               
-                    if ($start = $child->getAttribute('start')) {
-                        $start = self::parseICalendarDateTime($start);
-                    } else {
-                        $start = null;
-                    }
-                    if ($end = $child->getAttribute('end')) {
-                        $end = self::parseICalendarDateTime($end);
-                    } else {
-                        $end = null;
-                    }
-
-                    if (!is_null($start) && !is_null($end) && $end <= $start) {
-                        throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the time-range filter');
-                    }
-
-                    $filters[$basePath]['time-range'] = array(
-                        'start' => $start,
-                        'end'   => $end
-                    );
-                    break;
-
-                case '{urn:ietf:params:xml:ns:caldav}is-not-defined' :
-                    $filters[$basePath]['is-not-defined'] = true;
-                    break;
-
-                case '{urn:ietf:params:xml:ns:caldav}param-filter' :
-               
-                    $filterName = $basePath . '/@' . strtolower($child->getAttribute('name'));
-                    $filters[$filterName] = array();
-                    self::parseCalendarQueryFilters($child, $filterName, $filters);
-                    break;
-
-                case '{urn:ietf:params:xml:ns:caldav}text-match' :
-               
-                    $collation = $child->getAttribute('collation');
-                    if (!$collation) $collation = 'i;ascii-casemap';
-
-                    $filters[$basePath]['text-match'] = array(
-                        'collation' => ($collation == 'default'?'i;ascii-casemap':$collation),
-                        'negate-condition' => $child->getAttribute('negate-condition')==='yes',
-                        'value' => $child->nodeValue,
-                    );
-                    break;
-
-            }
-
-        }
-
-        return $filters;
-
-    }
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
-     *
-     * Specifying a reference timezone is optional. It will only be used
-     * if the non-UTC format is used. The argument is used as a reference, the 
-     * returned DateTime object will still be in the UTC timezone.
-     *
-     * @param string $dt 
-     * @param DateTimeZone $tz 
-     * @return DateTime 
-     */
-    static public function parseICalendarDateTime($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);
-
-        if (!$result) {
-            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
-        }
-
-        if ($matches[7]==='Z' || is_null($tz)) {
-            $tz = new DateTimeZone('UTC');
-        } 
-        $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'));
-        return $date;
-
-    }
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
-     *
-     * @param string $date 
-     * @param DateTimeZone $tz 
-     * @return DateTime 
-     */
-    static public function parseICalendarDate($date) {
-
-        // Format is YYYYMMDD
-        $result = preg_match('/^([1-3][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);
-        }
-
-        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
-        return $date;
-
-    }
-   
-    /**
-     * Parses an iCalendar (RFC5545) formatted duration and returns a string suitable
-     * for strtotime or DateTime::modify.
-     *
-     * NOTE: When we require PHP 5.3 this can be replaced by the DateTimeInterval object, which
-     * supports ISO 8601 Intervals, which is a superset of ICalendar durations.
-     *
-     * For now though, we're just gonna live with this messy system
-     *
-     * @param string $duration
-     * @return string
-     */
-    static public function parseICalendarDuration($duration) {
-
-        $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);
-        }
-       
-        $parts = array(
-            'week',
-            'day',
-            'hour',
-            'minute',
-            'second',
-        );
-
-        $newDur = '';
-        foreach($parts as $part) {
-            if (isset($matches[$part]) && $matches[$part]) {
-                $newDur.=' '.$matches[$part] . ' ' . $part . 's';
-            }
-        }
-
-        $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
-        return $newDur;
-
-    }
-
-}
diff --git a/3rdparty/Sabre/CalDAV/includes.php b/3rdparty/Sabre/CalDAV/includes.php
new file mode 100755
index 0000000000000000000000000000000000000000..1ecb870a0e134c76bf318e7b7bf68f6176d8a923
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/includes.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * Sabre_CalDAV includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_CalDAV package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @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
+ */
+
+// Begin includes
+include __DIR__ . '/Backend/Abstract.php';
+include __DIR__ . '/Backend/PDO.php';
+include __DIR__ . '/CalendarQueryParser.php';
+include __DIR__ . '/CalendarQueryValidator.php';
+include __DIR__ . '/CalendarRootNode.php';
+include __DIR__ . '/ICalendar.php';
+include __DIR__ . '/ICalendarObject.php';
+include __DIR__ . '/ICSExportPlugin.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/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__ . '/UserCalendars.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/Calendar.php';
+include __DIR__ . '/CalendarObject.php';
+// End includes
diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php
old mode 100644
new mode 100755
index 471ca7b338a7734e392ddfd92fcb0c4db8bcf729..3b381e1eea3a27073fe0b28e60ca777ef16e3039
--- a/3rdparty/Sabre/CardDAV/AddressBook.php
+++ b/3rdparty/Sabre/CardDAV/AddressBook.php
@@ -7,34 +7,33 @@
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_CardDAV_IAddressBook, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
 
     /**
-     * This is an array with addressbook information 
-     * 
-     * @var array 
+     * This is an array with addressbook information
+     *
+     * @var array
      */
     private $addressBookInfo;
 
     /**
-     * CardDAV backend 
-     * 
-     * @var Sabre_CardDAV_Backend_Abstract 
+     * CardDAV backend
+     *
+     * @var Sabre_CardDAV_Backend_Abstract
      */
     private $carddavBackend;
 
     /**
-     * Constructor 
-     * 
-     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend 
-     * @param array $addressBookInfo 
-     * @return void
+     * Constructor
+     *
+     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
+     * @param array $addressBookInfo
      */
-    public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend,array $addressBookInfo) {
+    public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend, array $addressBookInfo) {
 
         $this->carddavBackend = $carddavBackend;
         $this->addressBookInfo = $addressBookInfo;
@@ -42,9 +41,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     }
 
     /**
-     * Returns the name of the addressbook 
-     * 
-     * @return string 
+     * Returns the name of the addressbook
+     *
+     * @return string
      */
     public function getName() {
 
@@ -55,21 +54,21 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     /**
      * Returns a card
      *
-     * @param string $name 
+     * @param string $name
      * @return Sabre_DAV_Card
      */
     public function getChild($name) {
 
         $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'],$name);
-        if (!$obj) throw new Sabre_DAV_Exception_FileNotFound('Card not found');
+        if (!$obj) throw new Sabre_DAV_Exception_NotFound('Card not found');
         return new Sabre_CardDAV_Card($this->carddavBackend,$this->addressBookInfo,$obj);
 
     }
 
     /**
      * Returns the full list of cards
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getChildren() {
 
@@ -85,9 +84,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     /**
      * Creates a new directory
      *
-     * We actually block this, as subdirectories are not allowed in addressbooks. 
-     * 
-     * @param string $name 
+     * We actually block this, as subdirectories are not allowed in addressbooks.
+     *
+     * @param string $name
      * @return void
      */
     public function createDirectory($name) {
@@ -99,11 +98,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     /**
      * Creates a new file
      *
-     * The contents of the new file must be a valid VCARD
-     * 
-     * @param string $name 
-     * @param resource $vcardData 
-     * @return void
+     * The contents of the new file must be a valid VCARD.
+     *
+     * This method may return an ETag.
+     *
+     * @param string $name
+     * @param resource $vcardData
+     * @return void|null
      */
     public function createFile($name,$vcardData = null) {
 
@@ -111,13 +112,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
         // Converting to UTF-8, if needed
         $vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData);
 
-        $this->carddavBackend->createCard($this->addressBookInfo['id'],$name,$vcardData);
+        return $this->carddavBackend->createCard($this->addressBookInfo['id'],$name,$vcardData);
 
     }
 
     /**
-     * Deletes the entire addressbook. 
-     * 
+     * Deletes the entire addressbook.
+     *
      * @return void
      */
     public function delete() {
@@ -128,8 +129,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
 
     /**
      * Renames the addressbook
-     * 
-     * @param string $newName 
+     *
+     * @param string $newName
      * @return void
      */
     public function setName($newName) {
@@ -140,7 +141,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
 
     /**
      * Returns the last modification date as a unix timestamp.
-     * 
+     *
      * @return void
      */
     public function getLastModified() {
@@ -162,7 +163,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      * If the operation was successful, true can be returned.
      * If the operation failed, false can be returned.
      *
-     * Deletion of a non-existant property is always succesful.
+     * 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
@@ -177,16 +178,16 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      *   )
      * )
      *
-     * In this example it was forbidden to update {DAV:}displayname. 
+     * 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 array $mutations 
-     * @return bool|array 
+     * @param array $mutations
+     * @return bool|array
      */
     public function updateProperties($mutations) {
 
-        return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $mutations); 
+        return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $mutations);
 
     }
 
@@ -198,8 +199,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      *
      * If the array is empty, it means 'all properties' were requested.
      *
-     * @param array $properties 
-     * @return void
+     * @param array $properties
+     * @return array
      */
     public function getProperties($properties) {
 
@@ -221,8 +222,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -235,8 +236,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -248,13 +249,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -277,9 +278,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -288,6 +289,22 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
 
     }
 
+    /**
+     * 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/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
old mode 100644
new mode 100755
index 08adc3b8157ecf72d8bb7508a8e3819384ce9c1b..85a4963127bff4ef3c1e227525ffdcddff7e01e6
--- a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
@@ -3,12 +3,12 @@
 /**
  * Parses the addressbook-query report request body.
  *
- * Whoever designed this format, and the CalDAV equavalent even more so, 
+ * Whoever designed this format, and the CalDAV equivalent even more so,
  * has no feel for design.
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -19,8 +19,8 @@ class Sabre_CardDAV_AddressBookQueryParser {
 
     /**
      * List of requested properties the client wanted
-     * 
-     * @var array 
+     *
+     * @var array
      */
     public $requestedProperties;
 
@@ -28,44 +28,43 @@ class Sabre_CardDAV_AddressBookQueryParser {
      * The number of results the client wants
      *
      * null means it wasn't specified, which in most cases means 'all results'.
-     * 
-     * @var int|null 
+     *
+     * @var int|null
      */
     public $limit;
 
     /**
      * List of property filters.
      *
-     * @var array 
+     * @var array
      */
     public $filters;
 
     /**
      * Either TEST_ANYOF or TEST_ALLOF
-     * 
-     * @var string 
+     *
+     * @var string
      */
     public $test;
 
     /**
      * DOM Document
-     * 
-     * @var DOMDocument 
+     *
+     * @var DOMDocument
      */
     protected $dom;
 
     /**
-     * DOM XPath object 
-     * 
-     * @var DOMXPath 
+     * DOM XPath object
+     *
+     * @var DOMXPath
      */
     protected $xpath;
 
     /**
      * Creates the parser
-     * 
-     * @param DOMNode $dom 
-     * @return void
+     *
+     * @param DOMDocument $dom
      */
     public function __construct(DOMDocument $dom) {
 
@@ -77,15 +76,14 @@ class Sabre_CardDAV_AddressBookQueryParser {
     }
 
     /**
-     * Parses the request. 
-     * 
-     * @param DOMNode $dom 
+     * Parses the request.
+     *
      * @return void
      */
     public function parse() {
 
         $filterNode = null;
-        
+
         $limit = $this->xpath->evaluate('number(/card:addressbook-query/card:limit/card:nresults)');
         if (is_nan($limit)) $limit = null;
 
@@ -120,9 +118,9 @@ class Sabre_CardDAV_AddressBookQueryParser {
 
     /**
      * Parses the prop-filter xml element
-     * 
-     * @param DOMElement $propFilterNode 
-     * @return array 
+     *
+     * @param DOMElement $propFilterNode
+     * @return array
      */
     protected function parsePropFilterNode(DOMElement $propFilterNode) {
 
@@ -157,13 +155,13 @@ class Sabre_CardDAV_AddressBookQueryParser {
     }
 
     /**
-     * Parses the param-filter element 
-     * 
-     * @param DOMElement $paramFilterNode 
-     * @return array 
+     * Parses the param-filter element
+     *
+     * @param DOMElement $paramFilterNode
+     * @return array
      */
     public function parseParamFilterNode(DOMElement $paramFilterNode) {
-        
+
         $paramFilter = array();
         $paramFilter['name'] = $paramFilterNode->getAttribute('name');
         $paramFilter['is-not-defined'] = $this->xpath->query('card:is-not-defined', $paramFilterNode)->length>0;
@@ -174,15 +172,15 @@ class Sabre_CardDAV_AddressBookQueryParser {
             $paramFilter['text-match'] = $this->parseTextMatchNode($textMatch->item(0));
         }
 
-        return $paramFilter; 
+        return $paramFilter;
 
     }
 
     /**
      * Text match
-     * 
-     * @param DOMElement $textMatchNode 
-     * @return void
+     *
+     * @param DOMElement $textMatchNode
+     * @return array
      */
     public function parseTextMatchNode(DOMElement $textMatchNode) {
 
@@ -204,8 +202,8 @@ class Sabre_CardDAV_AddressBookQueryParser {
             'match-type' => $matchType,
             'value' => $textMatchNode->nodeValue
         );
-          
 
-    } 
+
+    }
 
 }
diff --git a/3rdparty/Sabre/CardDAV/AddressBookRoot.php b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
old mode 100644
new mode 100755
index 1a80efba35e38e58251f0b13e815843f5e4d8f06..9d37b15f08e2ea04942ed1ffbff4152b50f5b007
--- a/3rdparty/Sabre/CardDAV/AddressBookRoot.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
@@ -1,45 +1,45 @@
 <?php
 
 /**
- * AddressBook rootnode 
+ * AddressBook rootnode
  *
  * This object lists a collection of users, which can contain addressbooks.
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollection {
 
     /**
-     * Principal Backend 
-     * 
+     * Principal Backend
+     *
      * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
-     * CardDAV backend 
-     * 
-     * @var Sabre_CardDAV_Backend_Abstract 
+     * CardDAV backend
+     *
+     * @var Sabre_CardDAV_Backend_Abstract
      */
     protected $carddavBackend;
 
     /**
-     * Constructor 
+     * Constructor
      *
      * This constructor needs both a principal and a carddav backend.
      *
-     * By default this class will show a list of addressbook collections for 
-     * principals in the 'principals' collection. If your main principals are 
-     * actually located in a different path, use the $principalPrefix argument 
+     * By default this class will show a list of addressbook collections for
+     * principals in the 'principals' collection. If your main principals are
+     * actually located in a different path, use the $principalPrefix argument
      * to override this.
      *
-     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend 
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
      * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
-     * @param string $principalPrefix 
+     * @param string $principalPrefix
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CardDAV_Backend_Abstract $carddavBackend, $principalPrefix = 'principals') {
 
@@ -49,9 +49,9 @@ class Sabre_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollec
     }
 
     /**
-     * Returns the name of the node 
-     * 
-     * @return string 
+     * Returns the name of the node
+     *
+     * @return string
      */
     public function getName() {
 
@@ -65,9 +65,9 @@ class Sabre_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollec
      * The passed array contains principal information, and is guaranteed to
      * at least contain a uri item. Other properties may or may not be
      * supplied by the authentication backend.
-     * 
-     * @param array $principal 
-     * @return Sabre_DAV_INode 
+     *
+     * @param array $principal
+     * @return Sabre_DAV_INode
      */
     public function getChildForPrincipal(array $principal) {
 
diff --git a/3rdparty/Sabre/CardDAV/Backend/Abstract.php b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
old mode 100644
new mode 100755
index 1f0253ddab802d28fbdbe121311fcb88f28af02c..e4806b7161f10a5a0f77ada0c8f907009866555d
--- a/3rdparty/Sabre/CardDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
@@ -5,14 +5,14 @@
  *
  * This class serves as a base-class for addressbook backends
  *
- * Note that there are references to 'addressBookId' scattered throughout the 
- * class. The value of the addressBookId is completely up to you, it can be any 
+ * Note that there are references to 'addressBookId' scattered throughout the
+ * class. The value of the addressBookId is completely up to you, it can be any
  * arbitrary value you can use as an unique identifier.
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_CardDAV_Backend_Abstract {
@@ -25,97 +25,142 @@ abstract class Sabre_CardDAV_Backend_Abstract {
      *   uri - the 'basename' part of the url
      *   principaluri - Same as the passed parameter
      *
-     * Any additional clark-notation property may be passed besides this. Some 
+     * Any additional clark-notation property may be passed besides this. Some
      * common ones are :
      *   {DAV:}displayname
      *   {urn:ietf:params:xml:ns:carddav}addressbook-description
      *   {http://calendarserver.org/ns/}getctag
-     * 
-     * @param string $principalUri 
-     * @return array 
+     *
+     * @param string $principalUri
+     * @return array
      */
-    public abstract function getAddressBooksForUser($principalUri); 
+    public abstract function getAddressBooksForUser($principalUri);
 
     /**
      * Updates an addressbook's properties
      *
-     * See Sabre_DAV_IProperties for a description of the mutations array, as 
-     * well as the return value. 
+     * See Sabre_DAV_IProperties for a description of the mutations array, as
+     * well as the return value.
      *
      * @param mixed $addressBookId
      * @param array $mutations
      * @see Sabre_DAV_IProperties::updateProperties
      * @return bool|array
      */
-    public abstract function updateAddressBook($addressBookId, array $mutations); 
+    public abstract function updateAddressBook($addressBookId, array $mutations);
 
     /**
-     * Creates a new address book 
+     * Creates a new address book
      *
-     * @param string $principalUri 
-     * @param string $url Just the 'basename' of the url. 
-     * @param array $properties 
+     * @param string $principalUri
+     * @param string $url Just the 'basename' of the url.
+     * @param array $properties
      * @return void
      */
-    abstract public function createAddressBook($principalUri, $url, array $properties); 
+    abstract public function createAddressBook($principalUri, $url, array $properties);
 
     /**
      * Deletes an entire addressbook and all its contents
      *
-     * @param mixed $addressBookId 
+     * @param mixed $addressBookId
      * @return void
      */
-    abstract public function deleteAddressBook($addressBookId); 
+    abstract public function deleteAddressBook($addressBookId);
 
     /**
-     * Returns all cards for a specific addressbook id. 
+     * Returns all cards for a specific addressbook id.
      *
      * This method should return the following properties for each card:
      *   * carddata - raw vcard data
      *   * uri - Some unique url
      *   * lastmodified - A unix timestamp
-
-     * @param mixed $addressbookId 
-     * @return array 
+     *
+     * It's recommended to also return the following properties:
+     *   * etag - A unique etag. This must change every time the card changes.
+     *   * size - The size of the card in bytes.
+     *
+     * If these last two properties are provided, less time will be spent
+     * calculating them. If they are specified, you can also ommit carddata.
+     * This may speed up certain requests, especially with large cards.
+     *
+     * @param mixed $addressbookId
+     * @return array
      */
-    public abstract function getCards($addressbookId); 
+    public abstract function getCards($addressbookId);
 
     /**
-     * Returns a specfic card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @return void
+     * Returns a specfic card.
+     *
+     * The same set of properties must be returned as with getCards. The only
+     * exception is that 'carddata' is absolutely required.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @return array
      */
-    public abstract function getCard($addressBookId, $cardUri); 
+    public abstract function getCard($addressBookId, $cardUri);
 
     /**
-     * Creates a new card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @param string $cardData 
-     * @return bool 
+     * Creates a new card.
+     *
+     * The addressbook id will be passed as the first argument. This is the
+     * same id as it is returned from the getAddressbooksForUser method.
+     *
+     * The cardUri is a base uri, and doesn't include the full path. The
+     * cardData argument is the vcard body, and is passed as a string.
+     *
+     * It is possible to return an ETag from this method. This ETag is for the
+     * newly created resource, and must be enclosed with double quotes (that
+     * is, the string itself must contain the double quotes).
+     *
+     * You should only return the ETag if you store the carddata as-is. If a
+     * subsequent GET request on the same card does not have the same body,
+     * byte-by-byte and you did return an ETag here, clients tend to get
+     * confused.
+     *
+     * If you don't return an ETag, you can just return null.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @param string $cardData
+     * @return string|null
      */
-    abstract public function createCard($addressBookId, $cardUri, $cardData); 
+    abstract public function createCard($addressBookId, $cardUri, $cardData);
 
     /**
-     * Updates a card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @param string $cardData 
-     * @return bool 
+     * Updates a card.
+     *
+     * The addressbook id will be passed as the first argument. This is the
+     * same id as it is returned from the getAddressbooksForUser method.
+     *
+     * The cardUri is a base uri, and doesn't include the full path. The
+     * cardData argument is the vcard body, and is passed as a string.
+     *
+     * It is possible to return an ETag from this method. This ETag should
+     * match that of the updated resource, and must be enclosed with double
+     * quotes (that is: the string itself must contain the actual quotes).
+     *
+     * You should only return the ETag if you store the carddata as-is. If a
+     * subsequent GET request on the same card does not have the same body,
+     * byte-by-byte and you did return an ETag here, clients tend to get
+     * confused.
+     *
+     * If you don't return an ETag, you can just return null.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @param string $cardData
+     * @return string|null
      */
-    abstract public function updateCard($addressBookId, $cardUri, $cardData); 
+    abstract public function updateCard($addressBookId, $cardUri, $cardData);
 
     /**
      * Deletes a card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @return bool 
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @return bool
      */
-    abstract public function deleteCard($addressBookId, $cardUri); 
+    abstract public function deleteCard($addressBookId, $cardUri);
 
 }
diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php
old mode 100644
new mode 100755
index f4e44610ccf1146bc3acf3548f23a78d91797977..413a77f3bccfb86695a294fcffcb2bb244beafd6
--- a/3rdparty/Sabre/CardDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CardDAV/Backend/PDO.php
@@ -4,19 +4,19 @@
  * PDO CardDAV backend
  *
  * This CardDAV backend uses PDO to store addressbooks
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
 
     /**
-     * PDO connection 
-     * 
-     * @var PDO 
+     * PDO connection
+     *
+     * @var PDO
      */
     protected $pdo;
 
@@ -31,28 +31,30 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
     protected $cardsTableName;
 
     /**
-     * Sets up the object 
-     * 
-     * @param PDO $pdo 
+     * Sets up the object
+     *
+     * @param PDO $pdo
+     * @param string $addressBooksTableName
+     * @param string $cardsTableName
      */
     public function __construct(PDO $pdo, $addressBooksTableName = 'addressbooks', $cardsTableName = 'cards') {
 
         $this->pdo = $pdo;
         $this->addressBooksTableName = $addressBooksTableName;
-        $this->cardsTableName = $cardsTableName; 
+        $this->cardsTableName = $cardsTableName;
 
     }
 
     /**
-     * Returns the list of addressbooks for a specific user. 
-     * 
-     * @param string $principalUri 
-     * @return array 
+     * Returns the list of addressbooks for a specific user.
+     *
+     * @param string $principalUri
+     * @return array
      */
     public function getAddressBooksForUser($principalUri) {
 
-        $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, ctag FROM `'.$this->addressBooksTableName.'` WHERE principaluri = ?');
-        $result = $stmt->execute(array($principalUri));
+        $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, ctag FROM '.$this->addressBooksTableName.' WHERE principaluri = ?');
+        $stmt->execute(array($principalUri));
 
         $addressBooks = array();
 
@@ -65,7 +67,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
                 '{DAV:}displayname' => $row['displayname'],
                 '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
                 '{http://calendarserver.org/ns/}getctag' => $row['ctag'],
-                '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => 
+                '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' =>
                     new Sabre_CardDAV_Property_SupportedAddressData(),
             );
 
@@ -79,8 +81,8 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
     /**
      * Updates an addressbook's properties
      *
-     * See Sabre_DAV_IProperties for a description of the mutations array, as 
-     * well as the return value. 
+     * See Sabre_DAV_IProperties for a description of the mutations array, as
+     * well as the return value.
      *
      * @param mixed $addressBookId
      * @param array $mutations
@@ -88,7 +90,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
      * @return bool|array
      */
     public function updateAddressBook($addressBookId, array $mutations) {
-        
+
         $updates = array();
 
         foreach($mutations as $property=>$newValue) {
@@ -101,7 +103,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
                     $updates['description'] = $newValue;
                     break;
                 default :
-                    // If any unsupported values were being updated, we must 
+                    // If any unsupported values were being updated, we must
                     // let the entire request fail.
                     return false;
             }
@@ -113,7 +115,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
             return false;
         }
 
-        $query = 'UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 ';
+        $query = 'UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 ';
         foreach($updates as $key=>$value) {
             $query.=', `' . $key . '` = :' . $key . ' ';
         }
@@ -129,11 +131,11 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
     }
 
     /**
-     * Creates a new address book 
+     * Creates a new address book
      *
-     * @param string $principalUri 
-     * @param string $url Just the 'basename' of the url. 
-     * @param array $properties 
+     * @param string $principalUri
+     * @param string $url Just the 'basename' of the url.
+     * @param array $properties
      * @return void
      */
     public function createAddressBook($principalUri, $url, array $properties) {
@@ -160,7 +162,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
 
         }
 
-        $query = 'INSERT INTO `' . $this->addressBooksTableName . '` (uri, displayname, description, principaluri, ctag) VALUES (:uri, :displayname, :description, :principaluri, 1)';
+        $query = 'INSERT INTO ' . $this->addressBooksTableName . ' (uri, displayname, description, principaluri, ctag) VALUES (:uri, :displayname, :description, :principaluri, 1)';
         $stmt = $this->pdo->prepare($query);
         $stmt->execute($values);
 
@@ -169,44 +171,61 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
     /**
      * Deletes an entire addressbook and all its contents
      *
-     * @param int $addressBookId 
+     * @param int $addressBookId
      * @return void
      */
     public function deleteAddressBook($addressBookId) {
 
-        $stmt = $this->pdo->prepare('DELETE FROM `' . $this->cardsTableName . '` WHERE addressbookid = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
         $stmt->execute(array($addressBookId));
 
-        $stmt = $this->pdo->prepare('DELETE FROM `' . $this->addressBooksTableName . '` WHERE id = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
         $stmt->execute(array($addressBookId));
 
     }
 
     /**
-     * Returns all cards for a specific addressbook id. 
-     * 
-     * @param mixed $addressbookId 
-     * @return array 
+     * Returns all cards for a specific addressbook id.
+     *
+     * This method should return the following properties for each card:
+     *   * carddata - raw vcard data
+     *   * uri - Some unique url
+     *   * lastmodified - A unix timestamp
+     *
+     * It's recommended to also return the following properties:
+     *   * etag - A unique etag. This must change every time the card changes.
+     *   * size - The size of the card in bytes.
+     *
+     * If these last two properties are provided, less time will be spent
+     * calculating them. If they are specified, you can also ommit carddata.
+     * This may speed up certain requests, especially with large cards.
+     *
+     * @param mixed $addressbookId
+     * @return array
      */
     public function getCards($addressbookId) {
 
-        $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM `' . $this->cardsTableName . '` WHERE addressbookid = ?');
+        $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
         $stmt->execute(array($addressbookId));
 
         return $stmt->fetchAll(PDO::FETCH_ASSOC);
 
-    
+
     }
+
     /**
-     * Returns a specfic card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @return array 
+     * Returns a specfic card.
+     *
+     * The same set of properties must be returned as with getCards. The only
+     * exception is that 'carddata' is absolutely required.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @return array
      */
     public function getCard($addressBookId, $cardUri) {
 
-        $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM `' . $this->cardsTableName . '` WHERE addressbookid = ? AND uri = ? LIMIT 1');
+        $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ? LIMIT 1');
         $stmt->execute(array($addressBookId, $cardUri));
 
         $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
@@ -216,59 +235,93 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
     }
 
     /**
-     * Creates a new card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @param string $cardData 
-     * @return bool 
+     * Creates a new card.
+     *
+     * The addressbook id will be passed as the first argument. This is the
+     * same id as it is returned from the getAddressbooksForUser method.
+     *
+     * The cardUri is a base uri, and doesn't include the full path. The
+     * cardData argument is the vcard body, and is passed as a string.
+     *
+     * It is possible to return an ETag from this method. This ETag is for the
+     * newly created resource, and must be enclosed with double quotes (that
+     * is, the string itself must contain the double quotes).
+     *
+     * You should only return the ETag if you store the carddata as-is. If a
+     * subsequent GET request on the same card does not have the same body,
+     * byte-by-byte and you did return an ETag here, clients tend to get
+     * confused.
+     *
+     * If you don't return an ETag, you can just return null.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @param string $cardData
+     * @return string|null
      */
     public function createCard($addressBookId, $cardUri, $cardData) {
 
-        $stmt = $this->pdo->prepare('INSERT INTO `' . $this->cardsTableName . '` (carddata, uri, lastmodified, addressbookid) VALUES (?, ?, ?, ?)');
+        $stmt = $this->pdo->prepare('INSERT INTO ' . $this->cardsTableName . ' (carddata, uri, lastmodified, addressbookid) VALUES (?, ?, ?, ?)');
 
         $result = $stmt->execute(array($cardData, $cardUri, time(), $addressBookId));
 
-        $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
         $stmt2->execute(array($addressBookId));
 
-        return $result;
+        return '"' . md5($cardData) . '"';
 
     }
 
     /**
-     * Updates a card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @param string $cardData 
-     * @return bool 
+     * Updates a card.
+     *
+     * The addressbook id will be passed as the first argument. This is the
+     * same id as it is returned from the getAddressbooksForUser method.
+     *
+     * The cardUri is a base uri, and doesn't include the full path. The
+     * cardData argument is the vcard body, and is passed as a string.
+     *
+     * It is possible to return an ETag from this method. This ETag should
+     * match that of the updated resource, and must be enclosed with double
+     * quotes (that is: the string itself must contain the actual quotes).
+     *
+     * You should only return the ETag if you store the carddata as-is. If a
+     * subsequent GET request on the same card does not have the same body,
+     * byte-by-byte and you did return an ETag here, clients tend to get
+     * confused.
+     *
+     * If you don't return an ETag, you can just return null.
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @param string $cardData
+     * @return string|null
      */
     public function updateCard($addressBookId, $cardUri, $cardData) {
 
-        $stmt = $this->pdo->prepare('UPDATE `' . $this->cardsTableName . '` SET carddata = ?, lastmodified = ? WHERE uri = ? AND addressbookid =?');
-        $result = $stmt->execute(array($cardData, time(), $cardUri, $addressBookId));
+        $stmt = $this->pdo->prepare('UPDATE ' . $this->cardsTableName . ' SET carddata = ?, lastmodified = ? WHERE uri = ? AND addressbookid =?');
+        $stmt->execute(array($cardData, time(), $cardUri, $addressBookId));
 
-        $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
         $stmt2->execute(array($addressBookId));
 
-        return $stmt->rowCount()===1;
+        return '"' . md5($cardData) . '"';
 
     }
 
     /**
      * Deletes a card
-     * 
-     * @param mixed $addressBookId 
-     * @param string $cardUri 
-     * @return bool 
+     *
+     * @param mixed $addressBookId
+     * @param string $cardUri
+     * @return bool
      */
     public function deleteCard($addressBookId, $cardUri) {
 
-        $stmt = $this->pdo->prepare('DELETE FROM `' . $this->cardsTableName . '` WHERE addressbookid = ? AND uri = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ?');
         $stmt->execute(array($addressBookId, $cardUri));
 
-        $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+        $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
         $stmt2->execute(array($addressBookId));
 
         return $stmt->rowCount()===1;
diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php
old mode 100644
new mode 100755
index 2844eaf7ed6b06f06f3a6fbea2c609a544cc16dd..d7c663338375ac8b068851c574d49b45a49a75b7
--- a/3rdparty/Sabre/CardDAV/Card.php
+++ b/3rdparty/Sabre/CardDAV/Card.php
@@ -2,10 +2,10 @@
 
 /**
  * The Card object represents a single Card from an addressbook
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -13,29 +13,29 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
 
     /**
      * CardDAV backend
-     * 
-     * @var Sabre_CardDAV_Backend_Abstract 
+     *
+     * @var Sabre_CardDAV_Backend_Abstract
      */
     private $carddavBackend;
 
     /**
      * Array with information about this Card
-     * 
-     * @var array 
+     *
+     * @var array
      */
     private $cardData;
 
     /**
-     * Array with information about the containing addressbook 
-     * 
-     * @var array 
+     * Array with information about the containing addressbook
+     *
+     * @var array
      */
     private $addressBookInfo;
 
     /**
-     * Constructor 
-     * 
-     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend 
+     * Constructor
+     *
+     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
      * @param array $addressBookInfo
      * @param array $cardData
      */
@@ -48,9 +48,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     }
 
     /**
-     * Returns the uri for this object 
-     * 
-     * @return string 
+     * Returns the uri for this object
+     *
+     * @return string
      */
     public function getName() {
 
@@ -59,25 +59,26 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     }
 
     /**
-     * Returns the VCard-formatted object 
-     * 
-     * @return string 
+     * Returns the VCard-formatted object
+     *
+     * @return string
      */
     public function get() {
 
-        $cardData = $this->cardData['carddata'];
-        $s = fopen('php://temp','r+');
-        fwrite($s, $cardData);
-        rewind($s);
-        return $s;
+        // Pre-populating 'carddata' is optional. If we don't yet have it
+        // already, we fetch it from the backend.
+        if (!isset($this->cardData['carddata'])) {
+            $this->cardData = $this->carddavBackend->getCard($this->addressBookInfo['id'], $this->cardData['uri']);
+        }
+        return $this->cardData['carddata'];
 
     }
 
     /**
-     * Updates the VCard-formatted object 
-     * 
-     * @param string $cardData 
-     * @return void 
+     * Updates the VCard-formatted object
+     *
+     * @param string $cardData
+     * @return void
      */
     public function put($cardData) {
 
@@ -87,14 +88,17 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
         // Converting to UTF-8, if needed
         $cardData = Sabre_DAV_StringUtil::ensureUTF8($cardData);
 
-        $this->carddavBackend->updateCard($this->addressBookInfo['id'],$this->cardData['uri'],$cardData);
+        $etag = $this->carddavBackend->updateCard($this->addressBookInfo['id'],$this->cardData['uri'],$cardData);
         $this->cardData['carddata'] = $cardData;
+        $this->cardData['etag'] = $etag;
+
+        return $etag;
 
     }
 
     /**
      * Deletes the card
-     * 
+     *
      * @return void
      */
     public function delete() {
@@ -104,9 +108,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     }
 
     /**
-     * Returns the mime content-type 
-     * 
-     * @return string 
+     * Returns the mime content-type
+     *
+     * @return string
      */
     public function getContentType() {
 
@@ -115,20 +119,24 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     }
 
     /**
-     * Returns an ETag for this object 
-     * 
-     * @return string 
+     * Returns an ETag for this object
+     *
+     * @return string
      */
     public function getETag() {
 
-        return '"' . md5($this->cardData['carddata']) . '"';
+        if (isset($this->cardData['etag'])) {
+            return $this->cardData['etag'];
+        } else {
+            return '"' . md5($this->get()) . '"';
+        }
 
     }
 
     /**
      * Returns the last modification date as a unix timestamp
-     * 
-     * @return time 
+     *
+     * @return time
      */
     public function getLastModified() {
 
@@ -137,21 +145,25 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     }
 
     /**
-     * Returns the size of this object in bytes 
-     * 
+     * Returns the size of this object in bytes
+     *
      * @return int
      */
     public function getSize() {
 
-        return strlen($this->cardData['carddata']);
+        if (array_key_exists('size', $this->cardData)) {
+            return $this->cardData['size'];
+        } else {
+            return strlen($this->get());
+        }
 
     }
 
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -164,8 +176,8 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -177,13 +189,13 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -205,9 +217,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -216,5 +228,23 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
 
     }
 
+    /**
+     * 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/CardDAV/IAddressBook.php b/3rdparty/Sabre/CardDAV/IAddressBook.php
old mode 100644
new mode 100755
index a0dffb30aea5c11cda8c04731c1068cc3c776089..2bc275bcf743b9ca19377527f3cc655ffa461935
--- a/3rdparty/Sabre/CardDAV/IAddressBook.php
+++ b/3rdparty/Sabre/CardDAV/IAddressBook.php
@@ -4,15 +4,15 @@
  * AddressBook interface
  *
  * Implement this interface to allow a node to be recognized as an addressbook.
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_CardDAV_IAddressBook extends Sabre_DAV_ICollection {
 
- 
+
 
 }
diff --git a/3rdparty/Sabre/CardDAV/ICard.php b/3rdparty/Sabre/CardDAV/ICard.php
old mode 100644
new mode 100755
index 25bcc551b73d98994a9c5c4d4d13eec939768e15..a17299316c174c45e90418c68026b6188db9d8fd
--- a/3rdparty/Sabre/CardDAV/ICard.php
+++ b/3rdparty/Sabre/CardDAV/ICard.php
@@ -1,18 +1,18 @@
 <?php
 
 /**
- * Card interface 
+ * Card interface
+ *
+ * Extend the ICard interface to allow your custom nodes to be picked up as
+ * 'Cards'.
  *
- * Extend the ICard interface to allow your custom nodes to be picked up as 
- * 'Cards'. 
- * 
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_CardDAV_ICard extends Sabre_DAV_IFile { 
+interface Sabre_CardDAV_ICard extends Sabre_DAV_IFile {
 
 }
 
diff --git a/3rdparty/Sabre/CardDAV/IDirectory.php b/3rdparty/Sabre/CardDAV/IDirectory.php
old mode 100644
new mode 100755
index e0d0797d285bb8e1dae530513c51d6d47e78856e..22d4afeb24a2e838754ec2a19750351bea757649
--- a/3rdparty/Sabre/CardDAV/IDirectory.php
+++ b/3rdparty/Sabre/CardDAV/IDirectory.php
@@ -3,7 +3,7 @@
 /**
  * IDirectory interface
  *
- * Implement this interface to have an addressbook marked as a 'directory'. A 
+ * Implement this interface to have an addressbook marked as a 'directory'. A
  * directory is an (often) global addressbook.
  *
  * A full description can be found in the IETF draft:
@@ -11,7 +11,7 @@
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php
old mode 100644
new mode 100755
index 14c9c72b0d532e5d009135547b9136396c15ab4e..9ebec243eb0c88ee4f569ccf85e0a5aeedc42e4b
--- a/3rdparty/Sabre/CardDAV/Plugin.php
+++ b/3rdparty/Sabre/CardDAV/Plugin.php
@@ -7,8 +7,8 @@
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
@@ -24,31 +24,34 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
     const NS_CARDDAV = 'urn:ietf:params:xml:ns:carddav';
 
     /**
-     * Add urls to this property to have them automatically exposed as 
+     * Add urls to this property to have them automatically exposed as
      * 'directories' to the user.
-     * 
+     *
      * @var array
      */
     public $directories = array();
 
     /**
-     * Server class 
+     * Server class
      *
-     * @var Sabre_DAV_Server 
+     * @var Sabre_DAV_Server
      */
     protected $server;
 
     /**
-     * Initializes the plugin 
+     * Initializes the plugin
      *
-     * @param Sabre_DAV_Server $server 
-     * @return void 
+     * @param Sabre_DAV_Server $server
+     * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
 
         /* Events */
         $server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties'));
+        $server->subscribeEvent('updateProperties', array($this, 'updateProperties'));
         $server->subscribeEvent('report', array($this,'report'));
+        $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
+        $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
 
         /* Namespaces */
         $server->xmlNamespaces[self::NS_CARDDAV] = 'card';
@@ -56,11 +59,14 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
         /* Mapping Interfaces to {DAV:}resourcetype values */
         $server->resourceTypeMapping['Sabre_CardDAV_IAddressBook'] = '{' . self::NS_CARDDAV . '}addressbook';
         $server->resourceTypeMapping['Sabre_CardDAV_IDirectory'] = '{' . self::NS_CARDDAV . '}directory';
-        
+
         /* Adding properties that may never be changed */
         $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}supported-address-data';
         $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}max-resource-size';
+        $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}addressbook-home-set';
+        $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}supported-collation-set';
 
+        $server->propertyMap['{http://calendarserver.org/ns/}me-card'] = 'Sabre_DAV_Property_Href';
 
         $this->server = $server;
 
@@ -69,7 +75,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * Returns a list of supported features.
      *
-     * This is used in the DAV: header in the OPTIONS and PROPFIND requests. 
+     * This is used in the DAV: header in the OPTIONS and PROPFIND requests.
      *
      * @return array
      */
@@ -83,11 +89,11 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
      * Returns a list of reports this plugin supports.
      *
      * This will be used in the {DAV:}supported-report-set property.
-     * Note that you still need to subscribe to the 'report' event to actually 
-     * implement them 
+     * Note that you still need to subscribe to the 'report' event to actually
+     * implement them
      *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getSupportedReportSet($uri) {
 
@@ -104,22 +110,22 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
 
     /**
-     * Adds all CardDAV-specific properties 
+     * Adds all CardDAV-specific properties
      *
      * @param string $path
-     * @param Sabre_DAV_INode $node 
+     * @param Sabre_DAV_INode $node
      * @param array $requestedProperties
-     * @param array $returnedProperties 
+     * @param array $returnedProperties
      * @return void
      */
-    public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) { 
+    public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) {
 
         if ($node instanceof Sabre_DAVACL_IPrincipal) {
 
             // calendar-home-set property
             $addHome = '{' . self::NS_CARDDAV . '}addressbook-home-set';
             if (in_array($addHome,$requestedProperties)) {
-                $principalId = $node->getName(); 
+                $principalId = $node->getName();
                 $addressbookHomePath = self::ADDRESSBOOK_ROOT . '/' . $principalId . '/';
                 unset($requestedProperties[array_search($addHome, $requestedProperties)]);
                 $returnedProperties[200][$addHome] = new Sabre_DAV_Property_Href($addressbookHomePath);
@@ -135,8 +141,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         if ($node instanceof Sabre_CardDAV_ICard) {
 
-            // The address-data property is not supposed to be a 'real' 
-            // property, but in large chunks of the spec it does act as such. 
+            // The address-data property is not supposed to be a 'real'
+            // property, but in large chunks of the spec it does act as such.
             // Therefore we simply expose it as a property.
             $addressDataProp = '{' . self::NS_CARDDAV . '}address-data';
             if (in_array($addressDataProp, $requestedProperties)) {
@@ -151,24 +157,95 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
             }
         }
 
+        if ($node instanceof Sabre_CardDAV_UserAddressBooks) {
+
+            $meCardProp = '{http://calendarserver.org/ns/}me-card';
+            if (in_array($meCardProp, $requestedProperties)) {
+
+                $props = $this->server->getProperties($node->getOwner(), array('{http://sabredav.org/ns}vcard-url'));
+                if (isset($props['{http://sabredav.org/ns}vcard-url'])) {
+
+                    $returnedProperties[200][$meCardProp] = new Sabre_DAV_Property_Href(
+                        $props['{http://sabredav.org/ns}vcard-url']
+                    );
+                    $pos = array_search($meCardProp, $requestedProperties);
+                    unset($requestedProperties[$pos]);
+
+                }
+
+            }
+
+        }
+
     }
 
     /**
-     * This functions handles REPORT requests specific to CardDAV 
+     * This event is triggered when a PROPPATCH method is executed
      *
-     * @param string $reportName 
+     * @param array $mutations
+     * @param array $result
+     * @param Sabre_DAV_INode $node
+     * @return void
+     */
+    public function updateProperties(&$mutations, &$result, $node) {
+
+        if (!$node instanceof Sabre_CardDAV_UserAddressBooks) {
+            return true;
+        }
+
+        $meCard = '{http://calendarserver.org/ns/}me-card';
+
+        // The only property we care about
+        if (!isset($mutations[$meCard]))
+            return true;
+
+        $value = $mutations[$meCard];
+        unset($mutations[$meCard]);
+
+        if ($value instanceof Sabre_DAV_Property_IHref) {
+            $value = $value->getHref();
+            $value = $this->server->calculateUri($value);
+        } elseif (!is_null($value)) {
+            $result[400][$meCard] = null;
+            return false;
+        }
+
+        $innerResult = $this->server->updateProperties(
+            $node->getOwner(),
+            array(
+                '{http://sabredav.org/ns}vcard-url' => $value,
+            )
+        );
+
+        $closureResult = false;
+        foreach($innerResult as $status => $props) {
+            if (is_array($props) && array_key_exists('{http://sabredav.org/ns}vcard-url', $props)) {
+                $result[$status][$meCard] = null;
+                $closureResult = ($status>=200 && $status<300);
+            }
+
+        }
+
+        return $result;
+
+    }
+
+    /**
+     * This functions handles REPORT requests specific to CardDAV
+     *
+     * @param string $reportName
      * @param DOMNode $dom
-     * @return bool 
+     * @return bool
      */
     public function report($reportName,$dom) {
 
-        switch($reportName) { 
+        switch($reportName) {
             case '{'.self::NS_CARDDAV.'}addressbook-multiget' :
                 $this->addressbookMultiGetReport($dom);
                 return false;
             case '{'.self::NS_CARDDAV.'}addressbook-query' :
                 $this->addressBookQueryReport($dom);
-                return false; 
+                return false;
             default :
                 return;
 
@@ -256,7 +333,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         $result = array();
         foreach($validNodes as $validNode) {
-            if ($depth==0) { 
+
+            if ($depth==0) {
                 $href = $this->server->getRequestUri();
             } else {
                 $href = $this->server->getRequestUri() . '/' . $validNode->getName();
@@ -265,7 +343,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
             list($result[]) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
 
         }
- 
+
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
         $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result));
@@ -274,17 +352,15 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Validates if a vcard makes it throught a list of filters.
-     * 
-     * @param string $vcardData 
-     * @param array $filters 
-     * @param string $test anyof or allof (which means OR or AND) 
-     * @return bool 
+     *
+     * @param string $vcardData
+     * @param array $filters
+     * @param string $test anyof or allof (which means OR or AND)
+     * @return bool
      */
     public function validateFilters($vcardData, array $filters, $test) {
 
         $vcard = Sabre_VObject_Reader::read($vcardData);
-        
-        $success = true;
 
         foreach($filters as $filter) {
 
@@ -299,10 +375,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
                 // We only need to check for existence
                 $success = $isDefined;
-                
+
             } else {
 
-                $vProperties = $vcard->select($filter['name']); 
+                $vProperties = $vcard->select($filter['name']);
 
                 $results = array();
                 if ($filter['param-filters']) {
@@ -328,7 +404,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
             } // else
 
-            // There are two conditions where we can already determine wether 
+            // There are two conditions where we can already determine whether
             // or not this filter succeeds.
             if ($test==='anyof' && $success) {
                 return true;
@@ -339,29 +415,28 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         } // foreach
 
-        // If we got all the way here, it means we haven't been able to 
+        // If we got all the way here, it means we haven't been able to
         // determine early if the test failed or not.
         //
-        // This implies for 'anyof' that the test failed, and for 'allof' that 
+        // This implies for 'anyof' that the test failed, and for 'allof' that
         // we succeeded. Sounds weird, but makes sense.
         return $test==='allof';
 
     }
 
     /**
-     * Validates if a param-filter can be applied to a specific property. 
-     * 
-     * @todo currently we're only validating the first parameter of the passed 
+     * Validates if a param-filter can be applied to a specific property.
+     *
+     * @todo currently we're only validating the first parameter of the passed
      *       property. Any subsequence parameters with the same name are
      *       ignored.
-     * @param Sabre_VObject_Property $vProperty 
-     * @param array $filters 
-     * @param string $test 
-     * @return bool 
+     * @param array $vProperties
+     * @param array $filters
+     * @param string $test
+     * @return bool
      */
     protected function validateParamFilters(array $vProperties, array $filters, $test) {
 
-        $success = false;
         foreach($filters as $filter) {
 
             $isDefined = false;
@@ -377,17 +452,16 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
                     $success = true;
                 }
 
-            // If there's no text-match, we can just check for existence 
+            // If there's no text-match, we can just check for existence
             } elseif (!$filter['text-match'] || !$isDefined) {
 
                 $success = $isDefined;
-                
+
             } else {
 
-                $texts = array();
                 $success = false;
                 foreach($vProperties as $vProperty) {
-                    // If we got all the way here, we'll need to validate the 
+                    // If we got all the way here, we'll need to validate the
                     // text-match filter.
                     $success = Sabre_DAV_StringUtil::textMatch($vProperty[$filter['name']]->value, $filter['text-match']['value'], $filter['text-match']['collation'], $filter['text-match']['match-type']);
                     if ($success) break;
@@ -398,7 +472,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
             } // else
 
-            // There are two conditions where we can already determine wether 
+            // There are two conditions where we can already determine whether
             // or not this filter succeeds.
             if ($test==='anyof' && $success) {
                 return true;
@@ -407,24 +481,24 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
                 return false;
             }
 
-        } 
+        }
 
-        // If we got all the way here, it means we haven't been able to 
+        // If we got all the way here, it means we haven't been able to
         // determine early if the test failed or not.
         //
-        // This implies for 'anyof' that the test failed, and for 'allof' that 
+        // This implies for 'anyof' that the test failed, and for 'allof' that
         // we succeeded. Sounds weird, but makes sense.
         return $test==='allof';
 
     }
 
     /**
-     * Validates if a text-filter can be applied to a specific property. 
-     * 
+     * Validates if a text-filter can be applied to a specific property.
+     *
      * @param array $texts
-     * @param array $filters 
-     * @param string $test 
-     * @return bool 
+     * @param array $filters
+     * @param string $test
+     * @return bool
      */
     protected function validateTextMatches(array $texts, array $filters, $test) {
 
@@ -440,7 +514,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
             if ($filter['negate-condition']) {
                 $success = !$success;
             }
-            
+
             if ($success && $test==='anyof')
                 return true;
 
@@ -450,14 +524,64 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
-        // If we got all the way here, it means we haven't been able to 
+        // If we got all the way here, it means we haven't been able to
         // determine early if the test failed or not.
         //
-        // This implies for 'anyof' that the test failed, and for 'allof' that 
+        // This implies for 'anyof' that the test failed, and for 'allof' that
         // we succeeded. Sounds weird, but makes sense.
         return $test==='allof';
 
     }
 
+    /**
+     * This method is used to generate HTML output for the
+     * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
+     * can use to create new calendars.
+     *
+     * @param Sabre_DAV_INode $node
+     * @param string $output
+     * @return bool
+     */
+    public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+        if (!$node instanceof Sabre_CardDAV_UserAddressBooks)
+            return;
+
+        $output.= '<tr><td colspan="2"><form method="post" action="">
+            <h3>Create new address book</h3>
+            <input type="hidden" name="sabreAction" value="mkaddressbook" />
+            <label>Name (uri):</label> <input type="text" name="name" /><br />
+            <label>Display name:</label> <input type="text" name="{DAV:}displayname" /><br />
+            <input type="submit" value="create" />
+            </form>
+            </td></tr>';
+
+        return false;
+
+    }
+
+    /**
+     * This method allows us to intercept the 'mkcalendar' sabreAction. This
+     * action enables the user to create new calendars from the browser plugin.
+     *
+     * @param string $uri
+     * @param string $action
+     * @param array $postVars
+     * @return bool
+     */
+    public function browserPostAction($uri, $action, array $postVars) {
+
+        if ($action!=='mkaddressbook')
+            return;
+
+        $resourceType = array('{DAV:}collection','{urn:ietf:params:xml:ns:carddav}addressbook');
+        $properties = array();
+        if (isset($postVars['{DAV:}displayname'])) {
+            $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+        }
+        $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
+        return false;
+
+    }
 
 }
diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
old mode 100644
new mode 100755
index d57d3a6e7bdfb3494b4f48300029e553e3c4f57c..36d9306e7aabd1ce55525922ce7e574a0acc640d
--- a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
+++ b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
@@ -4,11 +4,11 @@
  * Supported-address-data property
  *
  * This property is a representation of the supported-address-data property
- * in the CardDAV namespace. 
+ * in the CardDAV namespace.
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -16,15 +16,15 @@ class Sabre_CardDAV_Property_SupportedAddressData extends Sabre_DAV_Property {
 
     /**
      * supported versions
-     * 
-     * @var array 
+     *
+     * @var array
      */
     protected $supportedData = array();
-    
+
     /**
-     * Creates the property 
-     * 
-     * @param array $components 
+     * Creates the property
+     *
+     * @param array|null $supportedData
      */
     public function __construct(array $supportedData = null) {
 
@@ -35,22 +35,22 @@ class Sabre_CardDAV_Property_SupportedAddressData extends Sabre_DAV_Property {
             );
         }
 
-       $this->supportedData = $supportedData; 
+       $this->supportedData = $supportedData;
 
     }
-    
+
     /**
-     * Serializes the property in a DOMDocument 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * 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;
 
-        $prefix = 
+        $prefix =
             isset($server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV]) ?
             $server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV] :
             'card';
diff --git a/3rdparty/Sabre/CardDAV/UserAddressBooks.php b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
old mode 100644
new mode 100755
index e9f2de7f741e0ed553911b3acf61e973390932ed..3f11fb11238ba6274c2dbed7fc19bf9e27c3f290
--- a/3rdparty/Sabre/CardDAV/UserAddressBooks.php
+++ b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
@@ -7,7 +7,7 @@
  *
  * @package Sabre
  * @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -15,47 +15,47 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
 
     /**
      * Principal uri
-     * 
-     * @var array 
+     *
+     * @var array
      */
     protected $principalUri;
 
     /**
-     * carddavBackend 
-     * 
-     * @var Sabre_CardDAV_Backend_Abstract 
+     * carddavBackend
+     *
+     * @var Sabre_CardDAV_Backend_Abstract
      */
     protected $carddavBackend;
 
     /**
-     * Constructor 
-     * 
-     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend 
-     * @param string $principalUri 
+     * Constructor
+     *
+     * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
+     * @param string $principalUri
      */
     public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend, $principalUri) {
 
         $this->carddavBackend = $carddavBackend;
         $this->principalUri = $principalUri;
-       
+
     }
 
     /**
-     * Returns the name of this object 
-     * 
+     * Returns the name of this object
+     *
      * @return string
      */
     public function getName() {
-      
+
         list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalUri);
-        return $name; 
+        return $name;
 
     }
 
     /**
-     * Updates the name of this object 
-     * 
-     * @param string $name 
+     * Updates the name of this object
+     *
+     * @param string $name
      * @return void
      */
     public function setName($name) {
@@ -65,8 +65,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     }
 
     /**
-     * Deletes this object 
-     * 
+     * Deletes this object
+     *
      * @return void
      */
     public function delete() {
@@ -76,13 +76,13 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     }
 
     /**
-     * Returns the last modification date 
-     * 
-     * @return int 
+     * Returns the last modification date
+     *
+     * @return int
      */
     public function getLastModified() {
 
-        return null; 
+        return null;
 
     }
 
@@ -90,9 +90,9 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
      * Creates a new file under this object.
      *
      * This is currently not allowed
-     * 
-     * @param string $filename 
-     * @param resource $data 
+     *
+     * @param string $filename
+     * @param resource $data
      * @return void
      */
     public function createFile($filename, $data=null) {
@@ -105,8 +105,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
      * Creates a new directory under this object.
      *
      * This is currently not allowed.
-     * 
-     * @param string $filename 
+     *
+     * @param string $filename
      * @return void
      */
     public function createDirectory($filename) {
@@ -116,8 +116,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     }
 
     /**
-     * Returns a single calendar, by name 
-     * 
+     * Returns a single calendar, by name
+     *
      * @param string $name
      * @todo needs optimizing
      * @return Sabre_CardDAV_AddressBook
@@ -129,14 +129,14 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
                 return $child;
 
         }
-        throw new Sabre_DAV_Exception_FileNotFound('Addressbook with name \'' . $name . '\' could not be found');
+        throw new Sabre_DAV_Exception_NotFound('Addressbook with name \'' . $name . '\' could not be found');
 
     }
 
     /**
-     * Returns a list of addressbooks 
-     * 
-     * @return array 
+     * Returns a list of addressbooks
+     *
+     * @return array
      */
     public function getChildren() {
 
@@ -150,11 +150,11 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     }
 
     /**
-     * Creates a new addressbook 
-     * 
+     * Creates a new addressbook
+     *
      * @param string $name
-     * @param array $resourceType 
-     * @param array $properties 
+     * @param array $resourceType
+     * @param array $properties
      * @return void
      */
     public function createExtendedCollection($name, array $resourceType, array $properties) {
@@ -169,8 +169,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -183,8 +183,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -196,13 +196,13 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
@@ -225,9 +225,9 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -236,5 +236,22 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
 
     }
 
+    /**
+     * 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/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php
old mode 100644
new mode 100755
index 900fbf5e75c22861fd27901ea93ae8fe81c211b5..811b929e3978d11661901239b228573a3f0f2ab8
--- a/3rdparty/Sabre/CardDAV/Version.php
+++ b/3rdparty/Sabre/CardDAV/Version.php
@@ -4,10 +4,10 @@
  * Version Class
  *
  * This class contains the Sabre_CardDAV version information
- * 
+ *
  * @package Sabre
  * @subpackage CardDAV 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -16,7 +16,7 @@ class Sabre_CardDAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.5.3';
+    const VERSION = '1.6.1';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CardDAV/includes.php b/3rdparty/Sabre/CardDAV/includes.php
new file mode 100755
index 0000000000000000000000000000000000000000..c3b8c04b077584a2a9d168a5e0dc99fcedbf477d
--- /dev/null
+++ b/3rdparty/Sabre/CardDAV/includes.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Sabre_CardDAV includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_CardDAV package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @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
+ */
+
+// Begin includes
+include __DIR__ . '/AddressBookQueryParser.php';
+include __DIR__ . '/AddressBookRoot.php';
+include __DIR__ . '/Backend/Abstract.php';
+include __DIR__ . '/Backend/PDO.php';
+include __DIR__ . '/IAddressBook.php';
+include __DIR__ . '/ICard.php';
+include __DIR__ . '/IDirectory.php';
+include __DIR__ . '/Plugin.php';
+include __DIR__ . '/Property/SupportedAddressData.php';
+include __DIR__ . '/UserAddressBooks.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/AddressBook.php';
+include __DIR__ . '/Card.php';
+// End includes
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
old mode 100644
new mode 100755
index 11bab8c7af78b024f568a753af54af8c0be93444..1e89b84f9a1811cb1cbba40f9b8c5ef61513b2d7
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
@@ -8,9 +8,9 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author James David Low (http://jameslow.com/)
- * @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_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IBackend {
@@ -28,6 +28,8 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
      * This method should return true or false depending on if login
      * succeeded.
      *
+     * @param string $username
+     * @param string $password
      * @return bool
      */
     abstract protected function validateUserPass($username, $password);
@@ -47,13 +49,15 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
     /**
      * Authenticates the user based on the current request.
      *
-     * If authentication is succesful, true must be returned.
+     * If authentication is successful, true must be returned.
      * If authentication fails, an exception must be thrown.
      *
+     * @param Sabre_DAV_Server $server
+     * @param string $realm
      * @throws Sabre_DAV_Exception_NotAuthenticated
      * @return bool
      */
-    public function authenticate(Sabre_DAV_Server $server,$realm) {
+    public function authenticate(Sabre_DAV_Server $server, $realm) {
 
         $auth = new Sabre_HTTP_BasicAuth();
         $auth->setHTTPRequest($server->httpRequest);
@@ -75,5 +79,5 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
     }
 
 
-} 
+}
 
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
old mode 100644
new mode 100755
index 5bdc72753ece623b8bb5c9634c42d7494ba7ccf5..9833928b9769c33257b46cb217f46f837d835e79
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
@@ -4,12 +4,12 @@
  * HTTP Digest authentication backend class
  *
  * This class can be used by authentication objects wishing to use HTTP Digest
- * Most of the digest logic is handled, implementors just need to worry about 
- * the getDigestHash method 
+ * Most of the digest logic is handled, implementors just need to worry about
+ * the getDigestHash method
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -17,7 +17,7 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
 
     /**
      * This variable holds the currently logged in username.
-     * 
+     *
      * @var array|null
      */
     protected $currentUser;
@@ -25,24 +25,26 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
     /**
      * Returns a users digest hash based on the username and realm.
      *
-     * If the user was not known, null must be returned. 
-     * 
+     * If the user was not known, null must be returned.
+     *
      * @param string $realm
-     * @param string $username 
-     * @return string|null 
+     * @param string $username
+     * @return string|null
      */
-    abstract public function getDigestHash($realm,$username);
+    abstract public function getDigestHash($realm, $username);
 
     /**
      * Authenticates the user based on the current request.
      *
-     * If authentication is succesful, true must be returned.
+     * If authentication is successful, true must be returned.
      * If authentication fails, an exception must be thrown.
      *
+     * @param Sabre_DAV_Server $server
+     * @param string $realm
      * @throws Sabre_DAV_Exception_NotAuthenticated
-     * @return bool 
+     * @return bool
      */
-    public function authenticate(Sabre_DAV_Server $server,$realm) {
+    public function authenticate(Sabre_DAV_Server $server, $realm) {
 
         $digest = new Sabre_HTTP_DigestAuth();
 
@@ -83,9 +85,9 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
     }
 
     /**
-     * Returns the currently logged in username. 
-     * 
-     * @return string|null 
+     * Returns the currently logged in username.
+     *
+     * @return string|null
      */
     public function getCurrentUser() {
 
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
old mode 100644
new mode 100755
index 6bcd76bdcb0ca5c81f2a7d9ad167c03ed1a92054..d4294ea4d86dcaf87247acdbd966ce315f876b6f
--- a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
@@ -4,34 +4,36 @@
  * Apache authenticator
  *
  * This authentication backend assumes that authentication has been
- * conifgured in apache, rather than within SabreDAV.
+ * configured in apache, rather than within SabreDAV.
  *
  * Make sure apache is properly configured for this to work.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Auth_Backend_Apache implements Sabre_DAV_Auth_IBackend {
 
     /**
-     * Current apache user 
-     * 
-     * @var string 
+     * Current apache user
+     *
+     * @var string
      */
     protected $remoteUser;
-    
+
     /**
      * Authenticates the user based on the current request.
      *
-     * If authentication is succesful, true must be returned.
+     * If authentication is successful, true must be returned.
      * If authentication fails, an exception must be thrown.
      *
-     * @return bool 
+     * @param Sabre_DAV_Server $server
+     * @param string $realm
+     * @return bool
      */
-    public function authenticate(Sabre_DAV_Server $server,$realm) {
+    public function authenticate(Sabre_DAV_Server $server, $realm) {
 
         $remoteUser = $server->httpRequest->getRawServerValue('REMOTE_USER');
         if (is_null($remoteUser)) {
@@ -47,7 +49,7 @@ class Sabre_DAV_Auth_Backend_Apache implements Sabre_DAV_Auth_IBackend {
      * Returns information about the currently logged in user.
      *
      * If nobody is currently logged in, this method should return null.
-     * 
+     *
      * @return array|null
      */
     public function getCurrentUser() {
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php
old mode 100644
new mode 100755
index db1f04c477250bec0aab04cb7adbac38af7939e5..de308d64a6728c69be916c6d39362080d004db1f
--- a/3rdparty/Sabre/DAV/Auth/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/File.php
@@ -4,29 +4,28 @@
  * This is an authentication backend that uses a file to manage passwords.
  *
  * The backend file must conform to Apache's htdigest format
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest {
 
     /**
-     * List of users 
-     * 
+     * List of users
+     *
      * @var array
      */
     protected $users = array();
 
     /**
-     * Creates the backend object. 
+     * Creates the backend object.
      *
      * If the filename argument is passed in, it will parse out the specified file fist.
-     * 
-     * @param string $filename 
-     * @return void
+     *
+     * @param string|null $filename
      */
     public function __construct($filename=null) {
 
@@ -38,22 +37,22 @@ class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest
     /**
      * Loads an htdigest-formatted file. This method can be called multiple times if
      * more than 1 file is used.
-     * 
-     * @param string $filename 
+     *
+     * @param string $filename
      * @return void
      */
     public function loadFile($filename) {
 
         foreach(file($filename,FILE_IGNORE_NEW_LINES) as $line) {
 
-            if (substr_count($line, ":") !== 2) 
+            if (substr_count($line, ":") !== 2)
                 throw new Sabre_DAV_Exception('Malformed htdigest file. Every line should contain 2 colons');
-            
+
             list($username,$realm,$A1) = explode(':',$line);
 
             if (!preg_match('/^[a-zA-Z0-9]{32}$/', $A1))
                 throw new Sabre_DAV_Exception('Malformed htdigest file. Invalid md5 hash');
-                
+
             $this->users[$realm . ':' . $username] = $A1;
 
         }
@@ -62,10 +61,10 @@ class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest
 
     /**
      * Returns a users' information
-     * 
-     * @param string $realm 
-     * @param string $username 
-     * @return string 
+     *
+     * @param string $realm
+     * @param string $username
+     * @return string
      */
     public function getDigestHash($realm, $username) {
 
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
old mode 100644
new mode 100755
index 0301503601e2f853c6d40d3c9252b0f08bc6ab35..eac18a23fbbfb3bb46180ec3cb5d0cbd02601dc5
--- a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
@@ -4,38 +4,37 @@
  * This is an authentication backend that uses a file to manage passwords.
  *
  * The backend file must conform to Apache's htdigest format
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Auth_Backend_PDO extends Sabre_DAV_Auth_Backend_AbstractDigest {
 
     /**
-     * Reference to PDO connection 
-     * 
-     * @var PDO 
+     * Reference to PDO connection
+     *
+     * @var PDO
      */
     protected $pdo;
 
     /**
-     * PDO table name we'll be using  
-     * 
+     * PDO table name we'll be using
+     *
      * @var string
      */
     protected $tableName;
 
 
     /**
-     * Creates the backend object. 
+     * Creates the backend object.
      *
      * If the filename argument is passed in, it will parse out the specified file fist.
-     * 
-     * @param string $filename
-     * @param string $tableName The PDO table name to use 
-     * @return void
+     *
+     * @param PDO $pdo
+     * @param string $tableName The PDO table name to use
      */
     public function __construct(PDO $pdo, $tableName = 'users') {
 
@@ -45,15 +44,15 @@ class Sabre_DAV_Auth_Backend_PDO extends Sabre_DAV_Auth_Backend_AbstractDigest {
     }
 
     /**
-     * Returns the digest hash for a user. 
-     * 
-     * @param string $realm 
-     * @param string $username 
-     * @return string|null 
+     * Returns the digest hash for a user.
+     *
+     * @param string $realm
+     * @param string $username
+     * @return string|null
      */
     public function getDigestHash($realm,$username) {
 
-        $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM `'.$this->tableName.'` WHERE username = ?');
+        $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM '.$this->tableName.' WHERE username = ?');
         $stmt->execute(array($username));
         $result = $stmt->fetchAll();
 
diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php
old mode 100644
new mode 100755
index 1f67af4c2d90eabc8eacfb862b15c17592a28595..5be5d1bc93d7807a9a9eecd8b87100c19be30d5e
--- a/3rdparty/Sabre/DAV/Auth/IBackend.php
+++ b/3rdparty/Sabre/DAV/Auth/IBackend.php
@@ -5,7 +5,7 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,18 +14,20 @@ interface Sabre_DAV_Auth_IBackend {
     /**
      * Authenticates the user based on the current request.
      *
-     * If authentication is succesful, true must be returned.
+     * If authentication is successful, true must be returned.
      * If authentication fails, an exception must be thrown.
      *
-     * @return bool 
+     * @param Sabre_DAV_Server $server
+     * @param string $realm
+     * @return bool
      */
-    function authenticate(Sabre_DAV_Server $server,$realm); 
+    function authenticate(Sabre_DAV_Server $server,$realm);
 
     /**
      * Returns information about the currently logged in username.
      *
      * If nobody is currently logged in, this method should return null.
-     * 
+     *
      * @return string|null
      */
     function getCurrentUser();
diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php
old mode 100644
new mode 100755
index f3718fcf469d53c7039523c98de6f697fd3512bf..55a4e3916741c9a7d728a2c54ae0d5ba4f127eba
--- a/3rdparty/Sabre/DAV/Auth/Plugin.php
+++ b/3rdparty/Sabre/DAV/Auth/Plugin.php
@@ -2,48 +2,47 @@
 
 /**
  * This plugin provides Authentication for a WebDAV server.
- * 
+ *
  * It relies on a Backend object, which provides user information.
  *
  * Additionally, it provides support for:
  *  * {DAV:}current-user-principal property from RFC5397
  *  * {DAV:}principal-collection-set property from RFC3744
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Auth_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
-     * Reference to main server object 
-     * 
-     * @var Sabre_DAV_Server 
+     * Reference to main server object
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
     /**
      * Authentication backend
-     * 
-     * @var Sabre_DAV_Auth_Backend_Abstract 
+     *
+     * @var Sabre_DAV_Auth_IBackend
      */
     private $authBackend;
 
     /**
-     * The authentication realm. 
-     * 
-     * @var string 
+     * The authentication realm.
+     *
+     * @var string
      */
     private $realm;
 
     /**
-     * __construct 
-     * 
-     * @param Sabre_DAV_Auth_Backend_Abstract $authBackend 
-     * @param string $realm 
-     * @return void
+     * __construct
+     *
+     * @param Sabre_DAV_Auth_IBackend $authBackend
+     * @param string $realm
      */
     public function __construct(Sabre_DAV_Auth_IBackend $authBackend, $realm) {
 
@@ -53,9 +52,9 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Initializes the plugin. This function is automatically called by the server  
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin. This function is automatically called by the server
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -67,11 +66,11 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a plugin name.
-     * 
+     *
      * Using this name other plugins will be able to access other plugins
-     * using Sabre_DAV_Server::getPlugin 
-     * 
-     * @return string 
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
      */
     public function getPluginName() {
 
@@ -81,10 +80,10 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns the current users' principal uri.
-     * 
-     * If nobody is logged in, this will return null. 
-     * 
-     * @return string|null 
+     *
+     * If nobody is logged in, this will return null.
+     *
+     * @return string|null
      */
     public function getCurrentUser() {
 
@@ -97,10 +96,11 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * This method is called before any HTTP method and forces users to be authenticated
-     * 
+     *
      * @param string $method
+     * @param string $uri
      * @throws Sabre_DAV_Exception_NotAuthenticated
-     * @return bool 
+     * @return bool
      */
     public function beforeMethod($method, $uri) {
 
diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
old mode 100644
new mode 100755
index ee8c698d782412ef00ba66327a3053ec0c8bd0c6..b6c00d461cb95e3ac778d5810b94a439b26d99c9
--- a/3rdparty/Sabre/DAV/Browser/GuessContentType.php
+++ b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
@@ -10,10 +10,10 @@
  * There's really no accurate, fast and portable way to determine the contenttype
  * so this extension does what the rest of the world does, and guesses it based
  * on the file extension.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -43,9 +43,9 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
     );
 
     /**
-     * Initializes the plugin 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -57,16 +57,16 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Handler for teh afterGetProperties event 
-     * 
-     * @param string $path 
-     * @param array $properties 
+     * Handler for teh afterGetProperties event
+     *
+     * @param string $path
+     * @param array $properties
      * @return void
      */
     public function afterGetProperties($path, &$properties) {
 
         if (array_key_exists('{DAV:}getcontenttype', $properties[404])) {
-           
+
             list(, $fileName) = Sabre_DAV_URLUtil::splitPath($path);
             $contentType = $this->getContentType($fileName);
 
@@ -81,9 +81,9 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
 
     /**
      * Simple method to return the contenttype
-     * 
-     * @param string $fileName 
-     * @return string 
+     *
+     * @param string $fileName
+     * @return string
      */
     protected function getContentType($fileName) {
 
diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
old mode 100644
new mode 100755
index a66b57a3a90ac89ba9038cf0caa085f194c536fd..1588488764133f951cf103fad141763de653154e
--- a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
+++ b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
@@ -1,30 +1,30 @@
 <?php
 
 /**
- * This is a simple plugin that will map any GET request for non-files to 
+ * This is a simple plugin that will map any GET request for non-files to
  * PROPFIND allprops-requests.
  *
  * This should allow easy debugging of PROPFIND
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Browser_MapGetToPropFind extends Sabre_DAV_ServerPlugin {
 
     /**
-     * reference to server class 
-     * 
-     * @var Sabre_DAV_Server 
+     * reference to server class
+     *
+     * @var Sabre_DAV_Server
      */
     protected $server;
 
     /**
-     * Initializes the plugin and subscribes to events 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin and subscribes to events
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -34,21 +34,22 @@ class Sabre_DAV_Browser_MapGetToPropFind extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This method intercepts GET requests to non-files, and changes it into an HTTP PROPFIND request 
-     * 
-     * @param string $method 
-     * @return bool 
+     * This method intercepts GET requests to non-files, and changes it into an HTTP PROPFIND request
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function httpGetInterceptor($method, $uri) {
 
         if ($method!='GET') return true;
-       
+
         $node = $this->server->tree->getNodeForPath($uri);
         if ($node instanceof Sabre_DAV_IFile) return;
 
         $this->server->invokeMethod('PROPFIND',$uri);
         return false;
-        
+
     }
 
 }
diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php
old mode 100644
new mode 100755
index cd5617babb160819ad04d72cb4cc48c27c3fad99..09bbdd2ae021e013c83c85bcbbc77f9cfb8a6ace
--- a/3rdparty/Sabre/DAV/Browser/Plugin.php
+++ b/3rdparty/Sabre/DAV/Browser/Plugin.php
@@ -6,77 +6,126 @@
  * This plugin provides a html representation, so that a WebDAV server may be accessed
  * using a browser.
  *
- * The class intercepts GET requests to collection resources and generates a simple 
- * html index. 
- * 
+ * The class intercepts GET requests to collection resources and generates a simple
+ * html index.
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Browser_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
-     * reference to server class 
-     * 
-     * @var Sabre_DAV_Server 
+     * List of default icons for nodes.
+     *
+     * This is an array with class / interface names as keys, and asset names
+     * as values.
+     *
+     * The evaluation order is reversed. The last item in the list gets
+     * precendence.
+     *
+     * @var array
+     */
+    public $iconMap = array(
+        'Sabre_DAV_IFile' => 'icons/file',
+        'Sabre_DAV_ICollection' => 'icons/collection',
+        'Sabre_DAVACL_IPrincipal' => 'icons/principal',
+        'Sabre_CalDAV_ICalendar' => 'icons/calendar',
+        'Sabre_CardDAV_IAddressBook' => 'icons/addressbook',
+        'Sabre_CardDAV_ICard' => 'icons/card',
+    );
+
+    /**
+     * The file extension used for all icons
+     *
+     * @var string
+     */
+    public $iconExtension = '.png';
+
+    /**
+     * reference to server class
+     *
+     * @var Sabre_DAV_Server
      */
     protected $server;
 
     /**
-     * enableEditing
-     * 
-     * @var bool 
+     * enablePost turns on the 'actions' panel, which allows people to create
+     * folders and upload files straight from a browser.
+     *
+     * @var bool
      */
     protected $enablePost = true;
 
+    /**
+     * By default the browser plugin will generate a favicon and other images.
+     * To turn this off, set this property to false.
+     *
+     * @var bool
+     */
+    protected $enableAssets = true;
+
     /**
      * Creates the object.
      *
      * By default it will allow file creation and uploads.
      * Specify the first argument as false to disable this
-     * 
-     * @param bool $enablePost 
-     * @return void
+     *
+     * @param bool $enablePost
+     * @param bool $enableAssets
      */
-    public function __construct($enablePost=true) {
+    public function __construct($enablePost=true, $enableAssets = true) {
 
-        $this->enablePost = $enablePost; 
+        $this->enablePost = $enablePost;
+        $this->enableAssets = $enableAssets;
 
     }
 
     /**
-     * Initializes the plugin and subscribes to events 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin and subscribes to events
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
 
         $this->server = $server;
         $this->server->subscribeEvent('beforeMethod',array($this,'httpGetInterceptor'));
+        $this->server->subscribeEvent('onHTMLActionsPanel', array($this, 'htmlActionsPanel'),200);
         if ($this->enablePost) $this->server->subscribeEvent('unknownMethod',array($this,'httpPOSTHandler'));
     }
 
     /**
-     * This method intercepts GET requests to collections and returns the html 
-     * 
-     * @param string $method 
-     * @return bool 
+     * This method intercepts GET requests to collections and returns the html
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function httpGetInterceptor($method, $uri) {
 
-        if ($method!='GET') return true;
+        if ($method !== 'GET') return true;
+
+        // We're not using straight-up $_GET, because we want everything to be
+        // unit testable.
+        $getVars = array();
+        parse_str($this->server->httpRequest->getQueryString(), $getVars);
+
+        if (isset($getVars['sabreAction']) && $getVars['sabreAction'] === 'asset' && isset($getVars['assetName'])) {
+            $this->serveAsset($getVars['assetName']);
+            return false;
+        }
 
-        try { 
+        try {
             $node = $this->server->tree->getNodeForPath($uri);
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
-            // We're simply stopping when the file isn't found to not interfere 
+        } catch (Sabre_DAV_Exception_NotFound $e) {
+            // We're simply stopping when the file isn't found to not interfere
             // with other plugins.
             return;
         }
-        if ($node instanceof Sabre_DAV_IFile) 
+        if ($node instanceof Sabre_DAV_IFile)
             return;
 
         $this->server->httpResponse->sendStatus(200);
@@ -87,57 +136,71 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
         );
 
         return false;
-        
+
     }
 
     /**
-     * Handles POST requests for tree operations
-     * 
-     * This method is not yet used.
-     * 
-     * @param string $method 
+     * Handles POST requests for tree operations.
+     *
+     * @param string $method
+     * @param string $uri
      * @return bool
      */
     public function httpPOSTHandler($method, $uri) {
 
-        if ($method!='POST') return true;
-        if (isset($_POST['sabreAction'])) switch($_POST['sabreAction']) {
+        if ($method!='POST') return;
+        $contentType = $this->server->httpRequest->getHeader('Content-Type');
+        list($contentType) = explode(';', $contentType);
+        if ($contentType !== 'application/x-www-form-urlencoded' &&
+            $contentType !== 'multipart/form-data') {
+                return;
+        }
+        $postVars = $this->server->httpRequest->getPostVars();
 
-            case 'mkcol' :
-                if (isset($_POST['name']) && trim($_POST['name'])) {
-                    // Using basename() because we won't allow slashes
-                    list(, $folderName) = Sabre_DAV_URLUtil::splitPath(trim($_POST['name']));
-                    $this->server->createDirectory($uri . '/' . $folderName);
-                }
-                break;
-            case 'put' :
-                if ($_FILES) $file = current($_FILES);
-                else break;
-                $newName = trim($file['name']);
-                list(, $newName) = Sabre_DAV_URLUtil::splitPath(trim($file['name']));
-                if (isset($_POST['name']) && trim($_POST['name']))
-                    $newName = trim($_POST['name']);
-
-                // Making sure we only have a 'basename' component
-                list(, $newName) = Sabre_DAV_URLUtil::splitPath($newName);
-                    
-               
-                if (is_uploaded_file($file['tmp_name'])) {
-                    $parent = $this->server->tree->getNodeForPath(trim($uri,'/'));
-                    $parent->createFile($newName,fopen($file['tmp_name'],'r'));
-                }
+        if (!isset($postVars['sabreAction']))
+            return;
+
+        if ($this->server->broadcastEvent('onBrowserPostAction', array($uri, $postVars['sabreAction'], $postVars))) {
+
+            switch($postVars['sabreAction']) {
+
+                case 'mkcol' :
+                    if (isset($postVars['name']) && trim($postVars['name'])) {
+                        // Using basename() because we won't allow slashes
+                        list(, $folderName) = Sabre_DAV_URLUtil::splitPath(trim($postVars['name']));
+                        $this->server->createDirectory($uri . '/' . $folderName);
+                    }
+                    break;
+                case 'put' :
+                    if ($_FILES) $file = current($_FILES);
+                    else break;
+
+                    list(, $newName) = Sabre_DAV_URLUtil::splitPath(trim($file['name']));
+                    if (isset($postVars['name']) && trim($postVars['name']))
+                        $newName = trim($postVars['name']);
+
+                    // Making sure we only have a 'basename' component
+                    list(, $newName) = Sabre_DAV_URLUtil::splitPath($newName);
+
+                    if (is_uploaded_file($file['tmp_name'])) {
+                        $this->server->createFile($uri . '/' . $newName, fopen($file['tmp_name'],'r'));
+                    }
+                    break;
+
+            }
 
         }
         $this->server->httpResponse->setHeader('Location',$this->server->httpRequest->getUri());
+        $this->server->httpResponse->sendStatus(302);
         return false;
 
     }
 
     /**
-     * Escapes a string for html. 
-     * 
-     * @param string $value 
-     * @return void
+     * Escapes a string for html.
+     *
+     * @param string $value
+     * @return string
      */
     public function escapeHTML($value) {
 
@@ -146,118 +209,199 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Generates the html directory index for a given url 
+     * Generates the html directory index for a given url
      *
-     * @param string $path 
-     * @return string 
+     * @param string $path
+     * @return string
      */
     public function generateDirectoryIndex($path) {
 
+        $version = '';
+        if (Sabre_DAV_Server::$exposeVersion) {
+            $version = Sabre_DAV_Version::VERSION ."-". Sabre_DAV_Version::STABILITY;
+        }
+
         $html = "<html>
 <head>
-  <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . Sabre_DAV_Version::VERSION . "</title>
-  <style type=\"text/css\"> body { Font-family: arial}</style>
-</head>
+  <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . $version . "</title>
+  <style type=\"text/css\">
+  body { Font-family: arial}
+  h1 { font-size: 150% }
+  </style>
+        ";
+
+        if ($this->enableAssets) {
+            $html.='<link rel="shortcut icon" href="'.$this->getAssetUrl('favicon.ico').'" type="image/vnd.microsoft.icon" />';
+        }
+
+        $html .= "</head>
 <body>
   <h1>Index for " . $this->escapeHTML($path) . "/</h1>
   <table>
-    <tr><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>
-    <tr><td colspan=\"4\"><hr /></td></tr>";
-    
-    $files = $this->server->getPropertiesForPath($path,array(
-        '{DAV:}displayname',
-        '{DAV:}resourcetype',
-        '{DAV:}getcontenttype',
-        '{DAV:}getcontentlength',
-        '{DAV:}getlastmodified',
-    ),1);
+    <tr><th width=\"24\"></th><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>
+    <tr><td colspan=\"5\"><hr /></td></tr>";
 
-    $parent = $this->server->tree->getNodeForPath($path);
+        $files = $this->server->getPropertiesForPath($path,array(
+            '{DAV:}displayname',
+            '{DAV:}resourcetype',
+            '{DAV:}getcontenttype',
+            '{DAV:}getcontentlength',
+            '{DAV:}getlastmodified',
+        ),1);
 
+        $parent = $this->server->tree->getNodeForPath($path);
 
-    if ($path) {
 
-        list($parentUri) = Sabre_DAV_URLUtil::splitPath($path);
-        $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri);
+        if ($path) {
 
-        $html.= "<tr>
-<td><a href=\"{$fullPath}\">..</a></td>
-<td>[parent]</td>
-<td></td>
-<td></td>
-</tr>";
+            list($parentUri) = Sabre_DAV_URLUtil::splitPath($path);
+            $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri);
 
-    }
+            $icon = $this->enableAssets?'<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl('icons/parent' . $this->iconExtension) . '" width="24" alt="Parent" /></a>':'';
+            $html.= "<tr>
+    <td>$icon</td>
+    <td><a href=\"{$fullPath}\">..</a></td>
+    <td>[parent]</td>
+    <td></td>
+    <td></td>
+    </tr>";
 
-    foreach($files as $k=>$file) {
+        }
 
-        // This is the current directory, we can skip it
-        if (rtrim($file['href'],'/')==$path) continue;
+        foreach($files as $file) {
+
+            // This is the current directory, we can skip it
+            if (rtrim($file['href'],'/')==$path) continue;
+
+            list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']);
+
+            $type = null;
+
+
+            if (isset($file[200]['{DAV:}resourcetype'])) {
+                $type = $file[200]['{DAV:}resourcetype']->getValue();
+
+                // resourcetype can have multiple values
+                if (!is_array($type)) $type = array($type);
+
+                foreach($type as $k=>$v) {
+
+                    // Some name mapping is preferred
+                    switch($v) {
+                        case '{DAV:}collection' :
+                            $type[$k] = 'Collection';
+                            break;
+                        case '{DAV:}principal' :
+                            $type[$k] = 'Principal';
+                            break;
+                        case '{urn:ietf:params:xml:ns:carddav}addressbook' :
+                            $type[$k] = 'Addressbook';
+                            break;
+                        case '{urn:ietf:params:xml:ns:caldav}calendar' :
+                            $type[$k] = 'Calendar';
+                            break;
+                        case '{urn:ietf:params:xml:ns:caldav}schedule-inbox' :
+                            $type[$k] = 'Schedule Inbox';
+                            break;
+                        case '{urn:ietf:params:xml:ns:caldav}schedule-outbox' :
+                            $type[$k] = 'Schedule Outbox';
+                            break;
+                        case '{http://calendarserver.org/ns/}calendar-proxy-read' :
+                            $type[$k] = 'Proxy-Read';
+                            break;
+                        case '{http://calendarserver.org/ns/}calendar-proxy-write' :
+                            $type[$k] = 'Proxy-Write';
+                            break;
+                    }
 
-        list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']);
+                }
+                $type = implode(', ', $type);
+            }
 
-        $type = null;
+            // If no resourcetype was found, we attempt to use
+            // the contenttype property
+            if (!$type && isset($file[200]['{DAV:}getcontenttype'])) {
+                $type = $file[200]['{DAV:}getcontenttype'];
+            }
+            if (!$type) $type = 'Unknown';
 
+            $size = isset($file[200]['{DAV:}getcontentlength'])?(int)$file[200]['{DAV:}getcontentlength']:'';
+            $lastmodified = isset($file[200]['{DAV:}getlastmodified'])?$file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM):'';
 
-        if (isset($file[200]['{DAV:}resourcetype'])) {
-            $type = $file[200]['{DAV:}resourcetype']->getValue();
+            $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path?$path . '/':'') . $name,'/'));
 
-            // resourcetype can have multiple values
-            if (!is_array($type)) $type = array($type);
+            $displayName = isset($file[200]['{DAV:}displayname'])?$file[200]['{DAV:}displayname']:$name;
 
-            foreach($type as $k=>$v) { 
+            $displayName = $this->escapeHTML($displayName);
+            $type = $this->escapeHTML($type);
 
-                // Some name mapping is preferred 
-                switch($v) {
-                    case '{DAV:}collection' :
-                        $type[$k] = 'Collection';
-                        break;
-                    case '{DAV:}principal' :
-                        $type[$k] = 'Principal';
-                        break;
-                    case '{urn:ietf:params:xml:ns:carddav}addressbook' :
-                        $type[$k] = 'Addressbook';
-                        break;
-                    case '{urn:ietf:params:xml:ns:caldav}calendar' :
-                        $type[$k] = 'Calendar';
+            $icon = '';
+
+            if ($this->enableAssets) {
+                $node = $parent->getChild($name);
+                foreach(array_reverse($this->iconMap) as $class=>$iconName) {
+
+                    if ($node instanceof $class) {
+                        $icon = '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl($iconName . $this->iconExtension) . '" alt="" width="24" /></a>';
                         break;
+                    }
+
+
                 }
 
             }
-            $type = implode(', ', $type);
-        }
 
-        // If no resourcetype was found, we attempt to use
-        // the contenttype property
-        if (!$type && isset($file[200]['{DAV:}getcontenttype'])) {
-            $type = $file[200]['{DAV:}getcontenttype'];
+            $html.= "<tr>
+    <td>$icon</td>
+    <td><a href=\"{$fullPath}\">{$displayName}</a></td>
+    <td>{$type}</td>
+    <td>{$size}</td>
+    <td>{$lastmodified}</td>
+    </tr>";
+
         }
-        if (!$type) $type = 'Unknown';
 
-        $size = isset($file[200]['{DAV:}getcontentlength'])?(int)$file[200]['{DAV:}getcontentlength']:'';
-        $lastmodified = isset($file[200]['{DAV:}getlastmodified'])?$file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM):'';
+        $html.= "<tr><td colspan=\"5\"><hr /></td></tr>";
+
+        $output = '';
 
-        $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path?$path . '/':'') . $name,'/'));
+        if ($this->enablePost) {
+            $this->server->broadcastEvent('onHTMLActionsPanel',array($parent, &$output));
+        }
 
-        $displayName = isset($file[200]['{DAV:}displayname'])?$file[200]['{DAV:}displayname']:$name;
+        $html.=$output;
 
-        $name = $this->escapeHTML($name);
-        $displayName = $this->escapeHTML($displayName);
-        $type = $this->escapeHTML($type);
+        $html.= "</table>
+        <address>Generated by SabreDAV " . $version . " (c)2007-2012 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>
+        </body>
+        </html>";
 
-        $html.= "<tr>
-<td><a href=\"{$fullPath}\">{$displayName}</a></td>
-<td>{$type}</td>
-<td>{$size}</td>
-<td>{$lastmodified}</td>
-</tr>";
+        return $html;
 
     }
 
-  $html.= "<tr><td colspan=\"4\"><hr /></td></tr>";
+    /**
+     * This method is used to generate the 'actions panel' output for
+     * collections.
+     *
+     * This specifically generates the interfaces for creating new files, and
+     * creating new directories.
+     *
+     * @param Sabre_DAV_INode $node
+     * @param mixed $output
+     * @return void
+     */
+    public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+        if (!$node instanceof Sabre_DAV_ICollection)
+            return;
+
+        // We also know fairly certain that if an object is a non-extended
+        // SimpleCollection, we won't need to show the panel either.
+        if (get_class($node)==='Sabre_DAV_SimpleCollection')
+            return;
 
-  if ($this->enablePost && $parent instanceof Sabre_DAV_ICollection) {
-      $html.= '<tr><td><form method="post" action="">
+        $output.= '<tr><td colspan="2"><form method="post" action="">
             <h3>Create new folder</h3>
             <input type="hidden" name="sabreAction" value="mkcol" />
             Name: <input type="text" name="name" /><br />
@@ -270,15 +414,75 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
             File: <input type="file" name="file" /><br />
             <input type="submit" value="upload" />
             </form>
-       </td></tr>';
-  }
+            </td></tr>';
+
+    }
 
-  $html.= "</table>
-  <address>Generated by SabreDAV " . Sabre_DAV_Version::VERSION ."-". Sabre_DAV_Version::STABILITY . " (c)2007-2011 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>
-</body>
-</html>";
+    /**
+     * This method takes a path/name of an asset and turns it into url
+     * suiteable for http access.
+     *
+     * @param string $assetName
+     * @return string
+     */
+    protected function getAssetUrl($assetName) {
 
-        return $html; 
+        return $this->server->getBaseUri() . '?sabreAction=asset&assetName=' . urlencode($assetName);
+
+    }
+
+    /**
+     * This method returns a local pathname to an asset.
+     *
+     * @param string $assetName
+     * @return string
+     */
+    protected function getLocalAssetPath($assetName) {
+
+        // Making sure people aren't trying to escape from the base path.
+        $assetSplit = explode('/', $assetName);
+        if (in_array('..',$assetSplit)) {
+            throw new Sabre_DAV_Exception('Incorrect asset path');
+        }
+        $path = __DIR__ . '/assets/' . $assetName;
+        return $path;
+
+    }
+
+    /**
+     * This method reads an asset from disk and generates a full http response.
+     *
+     * @param string $assetName
+     * @return void
+     */
+    protected function serveAsset($assetName) {
+
+        $assetPath = $this->getLocalAssetPath($assetName);
+        if (!file_exists($assetPath)) {
+            throw new Sabre_DAV_Exception_NotFound('Could not find an asset with this name');
+        }
+        // Rudimentary mime type detection
+        switch(strtolower(substr($assetPath,strpos($assetPath,'.')+1))) {
+
+        case 'ico' :
+            $mime = 'image/vnd.microsoft.icon';
+            break;
+
+        case 'png' :
+            $mime = 'image/png';
+            break;
+
+        default:
+            $mime = 'application/octet-stream';
+            break;
+
+        }
+
+        $this->server->httpResponse->setHeader('Content-Type', $mime);
+        $this->server->httpResponse->setHeader('Content-Length', filesize($assetPath));
+        $this->server->httpResponse->setHeader('Cache-Control', 'public, max-age=1209600');
+        $this->server->httpResponse->sendStatus(200);
+        $this->server->httpResponse->sendBody(fopen($assetPath,'r'));
 
     }
 
diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
new file mode 100755
index 0000000000000000000000000000000000000000..2b2c10a22cc7a57c4dc5d7156f184448f2bee92b
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
new file mode 100755
index 0000000000000000000000000000000000000000..c9acc84172dad59708b6b298b310b8d29eeeb671
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
new file mode 100755
index 0000000000000000000000000000000000000000..3ecd6a800a01b77ec8b53fd2ac2c1ad9be035fc0
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
new file mode 100755
index 0000000000000000000000000000000000000000..2ce954866d853edb737a7e281de221f7846846f6
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
new file mode 100755
index 0000000000000000000000000000000000000000..156fa64fd50f15d9e838326d42d68feba2c23c3b
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
new file mode 100755
index 0000000000000000000000000000000000000000..3b98551cec3a863ab120a52cf21debad6cab6748
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
new file mode 100755
index 0000000000000000000000000000000000000000..156fa64fd50f15d9e838326d42d68feba2c23c3b
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
new file mode 100755
index 0000000000000000000000000000000000000000..f8988f828e61bb1894c3ea5b848f95aac84beaa3
Binary files /dev/null and b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png differ
diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php
old mode 100644
new mode 100755
index fc6a6fff083e4ea2747d2fdb3d843c4570757c75..a8320dd978260c46a94944133f2ddae65ea815e2
--- a/3rdparty/Sabre/DAV/Client.php
+++ b/3rdparty/Sabre/DAV/Client.php
@@ -3,14 +3,14 @@
 /**
  * SabreDAV DAV client
  *
- * This client wraps around Curl to provide a convenient API to a WebDAV 
+ * This client wraps around Curl to provide a convenient API to a WebDAV
  * server.
  *
  * NOTE: This class is experimental, it's api will likely change in the future.
- * 
+ *
  * @package Sabre
  * @subpackage DAVClient
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -26,22 +26,22 @@ class Sabre_DAV_Client {
     /**
      * Constructor
      *
-     * Settings are provided through the 'settings' argument. The following 
+     * Settings are provided through the 'settings' argument. The following
      * settings are supported:
      *
      *   * baseUri
      *   * userName (optional)
      *   * password (optional)
      *   * proxy (optional)
-     * 
-     * @param array $settings 
+     *
+     * @param array $settings
      */
     public function __construct(array $settings) {
 
         if (!isset($settings['baseUri'])) {
             throw new InvalidArgumentException('A baseUri must be provided');
         }
-        
+
         $validSettings = array(
             'baseUri',
             'userName',
@@ -62,23 +62,23 @@ class Sabre_DAV_Client {
     /**
      * Does a PROPFIND request
      *
-     * The list of requested properties must be specified as an array, in clark 
-     * notation. 
+     * The list of requested properties must be specified as an array, in clark
+     * notation.
      *
-     * The returned array will contain a list of filenames as keys, and 
+     * The returned array will contain a list of filenames as keys, and
      * properties as values.
      *
-     * The properties array will contain the list of properties. Only properties 
-     * that are actually returned from the server (without error) will be 
+     * The properties array will contain the list of properties. Only properties
+     * that are actually returned from the server (without error) will be
      * returned, anything else is discarded.
      *
-     * Depth should be either 0 or 1. A depth of 1 will cause a request to be 
+     * Depth should be either 0 or 1. A depth of 1 will cause a request to be
      * made to the server to also return all child resources.
      *
-     * @param string $url 
-     * @param array $properties 
-     * @param int $depth 
-     * @return array 
+     * @param string $url
+     * @param array $properties
+     * @param int $depth
+     * @return array
      */
     public function propFind($url, array $properties, $depth = 0) {
 
@@ -132,14 +132,14 @@ class Sabre_DAV_Client {
     /**
      * Updates a list of properties on the server
      *
-     * The list of properties must have clark-notation properties for the keys, 
-     * and the actual (string) value for the value. If the value is null, an 
-     * attempt is made to delete the property. 
+     * The list of properties must have clark-notation properties for the keys,
+     * and the actual (string) value for the value. If the value is null, an
+     * attempt is made to delete the property.
      *
-     * @todo Must be building the request using the DOM, and does not yet 
-     *       support complex properties. 
-     * @param string $url 
-     * @param array $properties 
+     * @todo Must be building the request using the DOM, and does not yet
+     *       support complex properties.
+     * @param string $url
+     * @param array $properties
      * @return void
      */
     public function propPatch($url, array $properties) {
@@ -175,7 +175,7 @@ class Sabre_DAV_Client {
                     $body.="    <x:" . $elementName . " xmlns:x=\"" . $namespace . "\">";
                 }
                 // Shitty.. i know
-                $body.=htmlspecialchars($propValue, ENT_NOQUOTES, 'UTF-8'); 
+                $body.=htmlspecialchars($propValue, ENT_NOQUOTES, 'UTF-8');
                 if ($namespace === 'DAV:') {
                     $body.='</d:' . $elementName . '>' . "\n";
                 } else {
@@ -189,7 +189,7 @@ class Sabre_DAV_Client {
 
         $body.= '</d:propertyupdate>';
 
-        $response = $this->request('PROPPATCH', $url, $body, array(
+        $this->request('PROPPATCH', $url, $body, array(
             'Content-Type' => 'application/xml'
         ));
 
@@ -198,11 +198,11 @@ class Sabre_DAV_Client {
     /**
      * Performs an HTTP options request
      *
-     * This method returns all the features from the 'DAV:' header as an array. 
-     * If there was no DAV header, or no contents this method will return an 
-     * empty array. 
-     * 
-     * @return array 
+     * This method returns all the features from the 'DAV:' header as an array.
+     * If there was no DAV header, or no contents this method will return an
+     * empty array.
+     *
+     * @return array
      */
     public function options() {
 
@@ -222,20 +222,20 @@ class Sabre_DAV_Client {
     /**
      * Performs an actual HTTP request, and returns the result.
      *
-     * If the specified url is relative, it will be expanded based on the base 
+     * If the specified url is relative, it will be expanded based on the base
      * url.
      *
      * The returned array contains 3 keys:
      *   * body - the response body
      *   * httpCode - a HTTP code (200, 404, etc)
-     *   * headers - a list of response http headers. The header names have 
+     *   * headers - a list of response http headers. The header names have
      *     been lowercased.
      *
-     * @param string $method 
-     * @param string $url 
-     * @param string $body 
-     * @param array $headers 
-     * @return array 
+     * @param string $method
+     * @param string $url
+     * @param string $body
+     * @param array $headers
+     * @return array
      */
     public function request($method, $url = '', $body = null, $headers = array()) {
 
@@ -243,14 +243,37 @@ class Sabre_DAV_Client {
 
         $curlSettings = array(
             CURLOPT_RETURNTRANSFER => true,
-            CURLOPT_CUSTOMREQUEST => $method,
-            CURLOPT_POSTFIELDS => $body,
             // Return headers as part of the response
-            CURLOPT_HEADER => true
+            CURLOPT_HEADER => true,
+            CURLOPT_POSTFIELDS => $body,
+            // Automatically follow redirects
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_MAXREDIRS => 5,
         );
 
+        switch ($method) {
+            case 'PUT':
+                $curlSettings[CURLOPT_PUT] = true;
+                break;
+            case 'HEAD' :
+
+                // do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
+                // requests when the Content-Length header is given - which in turn is perfectly valid according to HTTP
+                // specs...) cURL does unfortunately return an error in this case ("transfer closed transfer closed with
+                // ... bytes remaining to read") this can be circumvented by explicitly telling cURL to ignore the
+                // response body
+                $curlSettings[CURLOPT_NOBODY] = true;
+                $curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
+                break;
+
+            default:
+                $curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
+                break;
+
+        }
+
         // Adding HTTP headers
-        $nHeaders = array(); 
+        $nHeaders = array();
         foreach($headers as $key=>$value) {
 
             $nHeaders[] = $key . ': ' . $value;
@@ -277,17 +300,17 @@ class Sabre_DAV_Client {
         $headerBlob = substr($response, 0, $curlInfo['header_size']);
         $response = substr($response, $curlInfo['header_size']);
 
-        // In the case of 100 Continue, or redirects we'll have multiple lists 
-        // of headers for each separate HTTP response. We can easily split this 
+        // In the case of 100 Continue, or redirects we'll have multiple lists
+        // of headers for each separate HTTP response. We can easily split this
         // because they are separated by \r\n\r\n
         $headerBlob = explode("\r\n\r\n", trim($headerBlob, "\r\n"));
-        
+
         // We only care about the last set of headers
         $headerBlob = $headerBlob[count($headerBlob)-1];
 
         // Splitting headers
         $headerBlob = explode("\r\n", $headerBlob);
-        
+
         $headers = array();
         foreach($headerBlob as $header) {
             $parts = explode(':', $header, 2);
@@ -304,10 +327,17 @@ class Sabre_DAV_Client {
 
         if ($curlErrNo) {
             throw new Sabre_DAV_Exception('[CURL] Error while making request: ' . $curlError . ' (error code: ' . $curlErrNo . ')');
-        } 
+        }
 
         if ($response['statusCode']>=400) {
-            throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
+            switch ($response['statusCode']) {
+                case 404:
+                    throw new Sabre_DAV_Exception_NotFound('Resource ' . $url . ' not found.');
+                    break;
+
+                default:
+                    throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
+            }
         }
 
         return $response;
@@ -317,12 +347,12 @@ class Sabre_DAV_Client {
     /**
      * Wrapper for all curl functions.
      *
-     * The only reason this was split out in a separate method, is so it 
-     * becomes easier to unittest. 
+     * The only reason this was split out in a separate method, is so it
+     * becomes easier to unittest.
      *
      * @param string $url
-     * @param array $settings 
-     * @return  
+     * @param array $settings
+     * @return array
      */
     protected function curlRequest($url, $settings) {
 
@@ -339,20 +369,20 @@ class Sabre_DAV_Client {
     }
 
     /**
-     * Returns the full url based on the given url (which may be relative). All 
-     * urls are expanded based on the base url as given by the server. 
-     * 
-     * @param string $url 
-     * @return string 
+     * Returns the full url based on the given url (which may be relative). All
+     * urls are expanded based on the base url as given by the server.
+     *
+     * @param string $url
+     * @return string
      */
     protected function getAbsoluteUrl($url) {
 
-        // If the url starts with http:// or https://, the url is already absolute. 
+        // If the url starts with http:// or https://, the url is already absolute.
         if (preg_match('/^http(s?):\/\//', $url)) {
             return $url;
         }
 
-        // If the url starts with a slash, we must calculate the url based off 
+        // If the url starts with a slash, we must calculate the url based off
         // the root of the base url.
         if (strpos($url,'/') === 0) {
             $parts = parse_url($this->baseUri);
@@ -366,7 +396,7 @@ class Sabre_DAV_Client {
 
     /**
      * Parses a WebDAV multistatus response body
-     * 
+     *
      * This method returns an array with the following structure
      *
      * array(
@@ -387,7 +417,7 @@ class Sabre_DAV_Client {
      *
      *
      * @param string $body xml body
-     * @return array 
+     * @return array
      */
     public function parseMultiStatus($body) {
 
@@ -397,14 +427,13 @@ class Sabre_DAV_Client {
         if ($responseXML===false) {
             throw new InvalidArgumentException('The passed data is not valid XML');
         }
-         
-        $responseXML->registerXPathNamespace('d','DAV:');
+
+        $responseXML->registerXPathNamespace('d', 'urn:DAV');
 
         $propResult = array();
 
         foreach($responseXML->xpath('d:response') as $response) {
-
-            $response->registerXPathNamespace('d','DAV:');
+            $response->registerXPathNamespace('d', 'urn:DAV');
             $href = $response->xpath('d:href');
             $href = (string)$href[0];
 
@@ -412,11 +441,11 @@ class Sabre_DAV_Client {
 
             foreach($response->xpath('d:propstat') as $propStat) {
 
-                $propStat->registerXPathNamespace('d','DAV:');
+                $propStat->registerXPathNamespace('d', 'urn:DAV');
                 $status = $propStat->xpath('d:status');
                 list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3);
 
-                $properties[$statusCode] = Sabre_DAV_XMLUtil::parseProperties(dom_import_simplexml($propStat), $this->propertyMap); 
+                $properties[$statusCode] = Sabre_DAV_XMLUtil::parseProperties(dom_import_simplexml($propStat), $this->propertyMap);
 
             }
 
diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php
old mode 100644
new mode 100755
index 9da04c12792fc1324e8b7a502079441a4decc714..776c22531b2485bdcabb5c47a9ae2efec75bdd1a
--- a/3rdparty/Sabre/DAV/Collection.php
+++ b/3rdparty/Sabre/DAV/Collection.php
@@ -4,12 +4,12 @@
  * Collection class
  *
  * This is a helper class, that should aid in getting collections classes setup.
- * Most of its methods are implemented, and throw permission denied exceptions 
- * 
+ * Most of its methods are implemented, and throw permission denied exceptions
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Collection extends Sabre_DAV_Node implements Sabre_DAV_ICollection {
@@ -17,12 +17,12 @@ 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
-     * 
+     *
      * @param string $name
-     * @throws Sabre_DAV_Exception_FileNotFound
-     * @return Sabre_DAV_INode 
+     * @throws Sabre_DAV_Exception_NotFound
+     * @return Sabre_DAV_INode
      */
     public function getChild($name) {
 
@@ -31,7 +31,7 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
             if ($child->getName()==$name) return $child;
 
         }
-        throw new Sabre_DAV_Exception_FileNotFound('File not found: ' . $name);
+        throw new Sabre_DAV_Exception_NotFound('File not found: ' . $name);
 
     }
 
@@ -39,9 +39,9 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
      * Checks is a child-node exists.
      *
      * It is generally a good idea to try and override this. Usually it can be optimized.
-     * 
-     * @param string $name 
-     * @return bool 
+     *
+     * @param string $name
+     * @return bool
      */
     public function childExists($name) {
 
@@ -50,7 +50,7 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
             $this->getChild($name);
             return true;
 
-        } catch(Sabre_DAV_Exception_FileNotFound $e) {
+        } catch(Sabre_DAV_Exception_NotFound $e) {
 
             return false;
 
@@ -59,12 +59,28 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
     }
 
     /**
-     * Creates a new file in the directory 
-     * 
-     * @param string $name Name of the file 
-     * @param resource $data Initial payload, passed as a readable stream resource. 
-     * @throws Sabre_DAV_Exception_Forbidden
-     * @return void
+     * Creates a new file in the directory
+     *
+     * 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
+     * of the new file here.
+     *
+     * The returned ETag must be surrounded by double-quotes (The quotes should
+     * be part of the actual string).
+     *
+     * If you cannot accurately determine the ETag, you should not return it.
+     * If you don't store the file exactly as-is (you're transforming it
+     * somehow) you should also not return an ETag.
+     *
+     * This means that if a subsequent GET to this new file does not exactly
+     * return the same contents of what was submitted here, you are strongly
+     * recommended to omit the ETag.
+     *
+     * @param string $name Name of the file
+     * @param resource|string $data Initial payload
+     * @return null|string
      */
     public function createFile($name, $data = null) {
 
@@ -73,9 +89,9 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
     }
 
     /**
-     * Creates a new subdirectory 
-     * 
-     * @param string $name 
+     * Creates a new subdirectory
+     *
+     * @param string $name
      * @throws Sabre_DAV_Exception_Forbidden
      * @return void
      */
diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php
old mode 100644
new mode 100755
index 86af4827b3edf5555142e6e875b28f060fe7f338..6db8febc02e900ceba08c74370bbffa7968fd46b
--- a/3rdparty/Sabre/DAV/Directory.php
+++ b/3rdparty/Sabre/DAV/Directory.php
@@ -8,7 +8,7 @@
  * @package Sabre
  * @subpackage DAV
  * @deprecated Use Sabre_DAV_Collection instead
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php
old mode 100644
new mode 100755
index 61f8b87c0a62f15de6cd09e90383093094f0b799..a2cd6cf5820d935bd5e843d2be95085205faec5d
--- a/3rdparty/Sabre/DAV/Exception.php
+++ b/3rdparty/Sabre/DAV/Exception.php
@@ -7,42 +7,42 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
 
 /**
- * Main Exception class. 
+ * Main Exception class.
  *
- * This class defines a getHTTPCode method, which should return the appropriate HTTP code for the Exception occured.
+ * This class defines a getHTTPCode method, which should return the appropriate HTTP code for the Exception occurred.
  * The default for this is 500.
  *
  * This class also allows you to generate custom xml data for your exceptions. This will be displayed
  * in the 'error' element in the failing response.
  */
-class Sabre_DAV_Exception extends Exception { 
+class Sabre_DAV_Exception extends Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
-    public function getHTTPCode() { 
+    public function getHTTPCode() {
 
         return 500;
 
     }
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-    
+
 
     }
 
@@ -50,14 +50,15 @@ class Sabre_DAV_Exception extends Exception {
      * This method allows the exception to return any extra HTTP response headers.
      *
      * The headers must be returned as an array.
-     * 
-     * @return array 
+     *
+     * @param Sabre_DAV_Server $server
+     * @return array
      */
     public function getHTTPHeaders(Sabre_DAV_Server $server) {
 
         return array();
 
-    } 
+    }
 
 }
 
diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php
old mode 100644
new mode 100755
index 7025bb1031745b8a94b16afc4e83fa81b11de872..b198648a7545d44972e6e54f3fe81404a8253100
--- a/3rdparty/Sabre/DAV/Exception/BadRequest.php
+++ b/3rdparty/Sabre/DAV/Exception/BadRequest.php
@@ -4,24 +4,24 @@
  * BadRequest
  *
  * The BadRequest is thrown when the user submitted an invalid HTTP request
- * BadRequest 
- * 
+ * BadRequest
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_BadRequest extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
     public function getHTTPCode() {
 
-        return 400; 
+        return 400;
 
     }
 
diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php
old mode 100644
new mode 100755
index 7eaa08178ae2f16f2417a13ef1dd6833037b871a..6b0bd1fad7302402471aac6d9df3493f64eb156d
--- a/3rdparty/Sabre/DAV/Exception/Conflict.php
+++ b/3rdparty/Sabre/DAV/Exception/Conflict.php
@@ -8,14 +8,14 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_Conflict extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
old mode 100644
new mode 100755
index 279f63dfde783a5c0fd6955f486f4d8832dfa530..6121868e69e018b073257732d6d9f0d17f4fd26d
--- a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
+++ b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
@@ -1,28 +1,28 @@
 <?php
 
 /**
- * ConflictingLock 
+ * ConflictingLock
  *
- * Similar to Exception_Locked, this exception thrown when a LOCK request 
+ * Similar to Exception_Locked, this exception thrown when a LOCK request
  * was made, on a resource which was already locked
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_ConflictingLock extends Sabre_DAV_Exception_Locked {
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-        
+
         if ($this->lock) {
             $error = $errorNode->ownerDocument->createElementNS('DAV:','d:no-conflicting-lock');
             $errorNode->appendChild($error);
diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
old mode 100644
new mode 100755
index b20e4a2fb3ff7b1bed6024700969ad415d5185a5..d76e400c93b111b64fdd15369a8fecdf8fec197a
--- a/3rdparty/Sabre/DAV/Exception/FileNotFound.php
+++ b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
@@ -3,26 +3,17 @@
 /**
  * FileNotFound
  *
- * This Exception is thrown when a Node couldn't be found. It returns HTTP error code 404
+ * Deprecated: Warning, this class is deprecated and will be removed in a 
+ * future version of SabreDAV. Please use Sabre_DAV_Exception_NotFound instead.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @deprecated Use Sabre_DAV_Exception_NotFound instead
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class Sabre_DAV_Exception_FileNotFound extends Sabre_DAV_Exception {
-
-    /**
-     * Returns the HTTP statuscode for this exception 
-     *
-     * @return int
-     */
-    public function getHTTPCode() {
-
-        return 404;
-
-    }
+class Sabre_DAV_Exception_FileNotFound extends Sabre_DAV_Exception_NotFound {
 
 }
 
diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php
old mode 100644
new mode 100755
index 167f3c2760a8b38704d19fa340fba7327882d383..20b1056e31b5f27ef13e688ff4bf8a2440e5e376
--- a/3rdparty/Sabre/DAV/Exception/Forbidden.php
+++ b/3rdparty/Sabre/DAV/Exception/Forbidden.php
@@ -4,17 +4,17 @@
  * Forbidden
  *
  * This exception is thrown whenever a user tries to do an operation he's not allowed to
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_Forbidden extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
old mode 100644
new mode 100755
index 15007cdd352524fd362c754a75bdc7b1ad84ce2e..1a15089b0a34756236781f88152e5e3c91a67781
--- a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
+++ b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
@@ -1,20 +1,20 @@
 <?php
 
 /**
- * InsufficientStorage 
+ * InsufficientStorage
  *
  * This Exception can be thrown, when for example a harddisk is full or a quota is exceeded
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_InsufficientStorage extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
old mode 100644
new mode 100755
index f06810a25ef58ba2c2b67d71f6accce60d814a7a..2230f1d081166a3cdf27552181e4223a90c22a31
--- a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
+++ b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
@@ -1,26 +1,26 @@
 <?php
 
 /**
- * InvalidResourceType 
+ * InvalidResourceType
  *
  * This exception is thrown when the user tried to create a new collection, with
  * a special resourcetype value that was not recognized by the server.
  *
  * See RFC5689 section 3.3
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbidden { 
+class Sabre_DAV_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbidden {
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
@@ -29,5 +29,5 @@ class Sabre_DAV_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbid
         $errorNode->appendChild($error);
 
     }
-    
+
 }
diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
old mode 100644
new mode 100755
index 47032cffc75de30033010bfd3a632c5de0ee6b01..80ab7aff65ae80dcdc3afb480ae57e60bc1923b6
--- a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
+++ b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
@@ -1,13 +1,13 @@
 <?php
 
 /**
- * LockTokenMatchesRequestUri 
+ * LockTokenMatchesRequestUri
+ *
+ * This exception is thrown by UNLOCK if a supplied lock-token is invalid
  *
- * This exception is thrown by UNLOCK if a supplied lock-token is invalid 
- * 
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -23,10 +23,10 @@ class Sabre_DAV_Exception_LockTokenMatchesRequestUri extends Sabre_DAV_Exception
     }
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php
old mode 100644
new mode 100755
index b4bb2e0378cc55ed509258da4a5af79b3f853efe..976365ac1f84d6c263d71019edbfa5bfc05e23f7
--- a/3rdparty/Sabre/DAV/Exception/Locked.php
+++ b/3rdparty/Sabre/DAV/Exception/Locked.php
@@ -1,32 +1,32 @@
 <?php
 
 /**
- * Locked 
+ * Locked
  *
  * The 423 is thrown when a client tried to access a resource that was locked, without supplying a valid lock token
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_Locked extends Sabre_DAV_Exception {
 
     /**
-     * Lock information 
-     * 
-     * @var Sabre_DAV_Locks_LockInfo 
+     * Lock information
+     *
+     * @var Sabre_DAV_Locks_LockInfo
      */
     protected $lock;
 
     /**
      * Creates the exception
-     * 
+     *
      * A LockInfo object should be passed if the user should be informed
      * which lock actually has the file locked.
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lock 
+     *
+     * @param Sabre_DAV_Locks_LockInfo $lock
      */
     public function __construct(Sabre_DAV_Locks_LockInfo $lock = null) {
 
@@ -35,7 +35,7 @@ class Sabre_DAV_Exception_Locked extends Sabre_DAV_Exception {
     }
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
@@ -46,14 +46,14 @@ class Sabre_DAV_Exception_Locked extends Sabre_DAV_Exception {
     }
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-        
+
         if ($this->lock) {
             $error = $errorNode->ownerDocument->createElementNS('DAV:','d:lock-token-submitted');
             $errorNode->appendChild($error);
diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
old mode 100644
new mode 100755
index 02c145ffeb635de6320a707ed191963ae8da28e9..318757515054be2edb704216e563b8bb98929857
--- a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
+++ b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
@@ -4,17 +4,17 @@
  * MethodNotAllowed
  *
  * The 405 is thrown when a client tried to create a directory on an already existing directory
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_MethodNotAllowed extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
@@ -28,8 +28,9 @@ class Sabre_DAV_Exception_MethodNotAllowed extends Sabre_DAV_Exception {
      * This method allows the exception to return any extra HTTP response headers.
      *
      * The headers must be returned as an array.
-     * 
-     * @return array 
+     *
+     * @param Sabre_DAV_Server $server
+     * @return array
      */
     public function getHTTPHeaders(Sabre_DAV_Server $server) {
 
diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
old mode 100644
new mode 100755
index 1faffddfa00d58f171ed2ac3a6de00145438110b..87ca624429f4240c1ef324a51d210b591f427f18
--- a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
+++ b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
@@ -5,22 +5,22 @@
  *
  * This exception is thrown when the client did not provide valid
  * authentication credentials.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_NotAuthenticated extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
     public function getHTTPCode() {
-        
+
         return 401;
 
     }
diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php
new file mode 100755
index 0000000000000000000000000000000000000000..2b9da560d2352a42d44a335b2d8a2e4db8c4816f
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Exception/NotFound.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * NotFound
+ *
+ * This Exception is thrown when a Node couldn't be found. It returns HTTP error code 404
+ *
+ * @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
+ */
+class Sabre_DAV_Exception_NotFound extends Sabre_DAV_Exception {
+
+    /**
+     * Returns the HTTP statuscode for this exception
+     *
+     * @return int
+     */
+    public function getHTTPCode() {
+
+        return 404;
+
+    }
+
+}
+
diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
old mode 100644
new mode 100755
index cd7f609b09df436604e39bf82528854ad349bbd3..d017a19f5593e439754a12cacfb0723d7e4b54ff
--- a/3rdparty/Sabre/DAV/Exception/NotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
@@ -4,22 +4,22 @@
  * NotImplemented
  *
  * This exception is thrown when the client tried to call an unsupported HTTP method or other feature
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_NotImplemented extends Sabre_DAV_Exception {
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
     public function getHTTPCode() {
-        
+
         return 501;
 
     }
diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
new file mode 100755
index 0000000000000000000000000000000000000000..4982f45a4b5787030c302e146e7e85e2058fcffb
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * Payment Required
+ *
+ * The PaymentRequired exception may be thrown in a case where a user must pay
+ * to access a certain resource or operation.
+ *
+ * @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
+ */
+class Sabre_DAV_Exception_PaymentRequired extends Sabre_DAV_Exception {
+
+    /**
+     * Returns the HTTP statuscode for this exception
+     *
+     * @return int
+     */
+    public function getHTTPCode() {
+
+        return 402;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
old mode 100644
new mode 100755
index ebcb9f5b9ac858e0a77907bd8785d4e4f0b582f0..213e9c52317e3be1d2f9828098b77dbfffdb9119
--- a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
+++ b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
@@ -1,15 +1,15 @@
 <?php
 
 /**
- * PreconditionFailed 
+ * PreconditionFailed
  *
- * This exception is normally thrown when a client submitted a conditional request, 
- * like for example an If, If-None-Match or If-Match header, which caused the HTTP 
+ * This exception is normally thrown when a client submitted a conditional request,
+ * like for example an If, If-None-Match or If-Match header, which caused the HTTP
  * request to not execute (the condition of the header failed)
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -17,47 +17,47 @@ class Sabre_DAV_Exception_PreconditionFailed extends Sabre_DAV_Exception {
 
     /**
      * When this exception is thrown, the header-name might be set.
-     * 
+     *
      * This allows the exception-catching code to determine which HTTP header
      * caused the exception.
-     * 
-     * @var string 
+     *
+     * @var string
      */
     public $header = null;
 
     /**
-     * Create the exception 
-     * 
-     * @param string $message 
-     * @param string $header 
+     * Create the exception
+     *
+     * @param string $message
+     * @param string $header
      */
     public function __construct($message, $header=null) {
 
         parent::__construct($message);
         $this->header = $header;
 
-    } 
+    }
 
     /**
-     * Returns the HTTP statuscode for this exception 
+     * Returns the HTTP statuscode for this exception
      *
      * @return int
      */
     public function getHTTPCode() {
 
-        return 412; 
+        return 412;
 
     }
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-        
+
         if ($this->header) {
             $prop = $errorNode->ownerDocument->createElement('s:header');
             $prop->nodeValue = $this->header;
diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
old mode 100644
new mode 100755
index e4ed601b16cd8d37d3663379a17de1a5bd29171a..e86800f30381b9baf877e39d74c0c3a75b561598
--- a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
@@ -7,17 +7,17 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Exception_ReportNotImplemented extends Sabre_DAV_Exception_NotImplemented {
 
     /**
-     * This method allows the exception to include additonal information into the WebDAV error response 
+     * This method allows the exception to include additional information into the WebDAV error response
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $errorNode 
+     * @param DOMElement $errorNode
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
old mode 100644
new mode 100755
index 37abbd729d11724077faf53b3240cf153d99b0be..29ee3654a7e776b44316769244a308154d7651de
--- a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
+++ b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
@@ -1,21 +1,21 @@
 <?php
 
 /**
- * RequestedRangeNotSatisfiable 
+ * RequestedRangeNotSatisfiable
  *
- * This exception is normally thrown when the user 
+ * This exception is normally thrown when the user
  * request a range that is out of the entity bounds.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Exception_RequestedRangeNotSatisfiable extends Sabre_DAV_Exception {
 
     /**
-     * returns the http statuscode for this exception 
+     * returns the http statuscode for this exception
      *
      * @return int
      */
diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
old mode 100644
new mode 100755
index 4c37d8997cf0a63ac09aa20091160b09bd87c092..9a4693b21a8aecfc25b153710c98bc980b4fb9d5
--- a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
+++ b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
@@ -3,19 +3,19 @@
 /**
  * UnSupportedMediaType
  *
- * The 415 Unsupported Media Type status code is generally sent back when the client 
+ * The 415 Unsupported Media Type status code is generally sent back when the client
  * tried to call an HTTP method, with a body the server didn't understand
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Exception_UnsupportedMediaType extends Sabre_DAV_Exception { 
+class Sabre_DAV_Exception_UnsupportedMediaType extends Sabre_DAV_Exception {
 
     /**
-     * returns the http statuscode for this exception 
+     * returns the http statuscode for this exception
      *
      * @return int
      */
diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php
old mode 100644
new mode 100755
index ebd6a6c505e2bd10140d963bdbb1d6829b65f9f2..3af2d755583747f2c6c3e02c51030ebe9b3cc3df
--- a/3rdparty/Sabre/DAV/FS/Directory.php
+++ b/3rdparty/Sabre/DAV/FS/Directory.php
@@ -1,24 +1,39 @@
 <?php
 
 /**
- * Directory class 
- * 
+ * Directory class
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota {
 
     /**
-     * Creates a new file in the directory 
-     * 
-     * data is a readable stream resource
+     * Creates a new file in the directory
      *
-     * @param string $name Name of the file 
-     * @param resource $data Initial payload 
-     * @return void
+     * 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
+     * of the new file here.
+     *
+     * The returned ETag must be surrounded by double-quotes (The quotes should
+     * be part of the actual string).
+     *
+     * If you cannot accurately determine the ETag, you should not return it.
+     * If you don't store the file exactly as-is (you're transforming it
+     * somehow) you should also not return an ETag.
+     *
+     * This means that if a subsequent GET to this new file does not exactly
+     * return the same contents of what was submitted here, you are strongly
+     * recommended to omit the ETag.
+     *
+     * @param string $name Name of the file
+     * @param resource|string $data Initial payload
+     * @return null|string
      */
     public function createFile($name, $data = null) {
 
@@ -28,9 +43,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Creates a new subdirectory 
-     * 
-     * @param string $name 
+     * Creates a new subdirectory
+     *
+     * @param string $name
      * @return void
      */
     public function createDirectory($name) {
@@ -41,17 +56,17 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Returns a specific child node, referenced by its name 
-     * 
-     * @param string $name 
-     * @throws Sabre_DAV_Exception_FileNotFound
-     * @return Sabre_DAV_INode 
+     * Returns a specific child node, referenced by its name
+     *
+     * @param string $name
+     * @throws Sabre_DAV_Exception_NotFound
+     * @return Sabre_DAV_INode
      */
     public function getChild($name) {
 
         $path = $this->path . '/' . $name;
 
-        if (!file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located');
+        if (!file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
 
         if (is_dir($path)) {
 
@@ -66,9 +81,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Returns an array with all the child nodes 
-     * 
-     * @return Sabre_DAV_INode[] 
+     * Returns an array with all the child nodes
+     *
+     * @return Sabre_DAV_INode[]
      */
     public function getChildren() {
 
@@ -79,10 +94,10 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Checks if a child exists. 
-     * 
-     * @param string $name 
-     * @return bool 
+     * Checks if a child exists.
+     *
+     * @param string $name
+     * @return bool
      */
     public function childExists($name) {
 
@@ -92,8 +107,8 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Deletes all files in this directory, and then itself 
-     * 
+     * Deletes all files in this directory, and then itself
+     *
      * @return void
      */
     public function delete() {
@@ -104,16 +119,16 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
     }
 
     /**
-     * Returns available diskspace information 
-     * 
-     * @return array 
+     * Returns available diskspace information
+     *
+     * @return array
      */
     public function getQuotaInfo() {
 
         return array(
             disk_total_space($this->path)-disk_free_space($this->path),
             disk_free_space($this->path)
-            ); 
+            );
 
     }
 
diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php
old mode 100644
new mode 100755
index 262187d7e8ab8c1abeb60d8b9584920d2b05fe55..6a8039fe303afbbf98364db93df3cf0c8bca987f
--- a/3rdparty/Sabre/DAV/FS/File.php
+++ b/3rdparty/Sabre/DAV/FS/File.php
@@ -1,21 +1,21 @@
 <?php
 
 /**
- * File class 
- * 
+ * File class
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
 
     /**
-     * Updates the data 
-     * 
-     * @param resource $data 
-     * @return void 
+     * Updates the data
+     *
+     * @param resource $data
+     * @return void
      */
     public function put($data) {
 
@@ -24,9 +24,9 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
     }
 
     /**
-     * Returns the data 
-     * 
-     * @return string 
+     * Returns the data
+     *
+     * @return string
      */
     public function get() {
 
@@ -37,7 +37,7 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
     /**
      * Delete the current file
      *
-     * @return void 
+     * @return void
      */
     public function delete() {
 
@@ -46,12 +46,12 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
     }
 
     /**
-     * Returns the size of the node, in bytes 
-     * 
-     * @return int 
+     * Returns the size of the node, in bytes
+     *
+     * @return int
      */
     public function getSize() {
-        
+
         return filesize($this->path);
 
     }
@@ -60,10 +60,10 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
      * Returns the ETag for a file
      *
      * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
-     * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
      *
      * Return null if the ETag can not effectively be determined
-     * 
+     *
      * @return mixed
      */
     public function getETag() {
@@ -77,8 +77,8 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
      *
      * If null is returned, we'll assume application/octet-stream
      *
-     * @return mixed 
-     */ 
+     * @return mixed
+     */
     public function getContentType() {
 
         return null;
diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php
old mode 100644
new mode 100755
index b8d7bcfe8461c11dc4448098889dacf29939aa4a..1283e9d0fdcb70c2bfc91eaaeb1bc024665ff086
--- a/3rdparty/Sabre/DAV/FS/Node.php
+++ b/3rdparty/Sabre/DAV/FS/Node.php
@@ -1,30 +1,29 @@
 <?php
 
 /**
- * Base node-class 
+ * Base node-class
+ *
+ * The node class implements the method used by both the File and the Directory classes
  *
- * The node class implements the method used by both the File and the Directory classes 
- * 
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FS_Node implements Sabre_DAV_INode {
 
     /**
      * The path to the current node
-     * 
-     * @var string 
+     *
+     * @var string
      */
-    protected $path; 
+    protected $path;
 
     /**
-     * Sets up the node, expects a full path name 
-     * 
-     * @param string $path 
-     * @return void
+     * Sets up the node, expects a full path name
+     *
+     * @param string $path
      */
     public function __construct($path) {
 
@@ -35,9 +34,9 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
 
 
     /**
-     * Returns the name of the node 
-     * 
-     * @return string 
+     * Returns the name of the node
+     *
+     * @return string
      */
     public function getName() {
 
@@ -59,7 +58,7 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
 
         $newPath = $parentPath . '/' . $newName;
         rename($this->path,$newPath);
-        
+
         $this->path = $newPath;
 
     }
@@ -67,9 +66,9 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
 
 
     /**
-     * Returns the last modification time, as a unix timestamp 
-     * 
-     * @return int 
+     * Returns the last modification time, as a unix timestamp
+     *
+     * @return int
      */
     public function getLastModified() {
 
diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php
old mode 100644
new mode 100755
index c43d4385ac7b75cb20d19857501cebef51039aa9..540057183b30380c24e8395ab6def0a792a06ff6
--- a/3rdparty/Sabre/DAV/FSExt/Directory.php
+++ b/3rdparty/Sabre/DAV/FSExt/Directory.php
@@ -1,22 +1,39 @@
 <?php
 
 /**
- * Directory class 
- * 
+ * Directory class
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota {
 
     /**
-     * Creates a new file in the directory 
-     * 
-     * @param string $name Name of the file 
-     * @param resource $data Initial payload 
-     * @return void
+     * Creates a new file in the directory
+     *
+     * 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
+     * of the new file here.
+     *
+     * The returned ETag must be surrounded by double-quotes (The quotes should
+     * be part of the actual string).
+     *
+     * If you cannot accurately determine the ETag, you should not return it.
+     * If you don't store the file exactly as-is (you're transforming it
+     * somehow) you should also not return an ETag.
+     *
+     * This means that if a subsequent GET to this new file does not exactly
+     * return the same contents of what was submitted here, you are strongly
+     * recommended to omit the ETag.
+     *
+     * @param string $name Name of the file
+     * @param resource|string $data Initial payload
+     * @return null|string
      */
     public function createFile($name, $data = null) {
 
@@ -25,12 +42,14 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
         $newPath = $this->path . '/' . $name;
         file_put_contents($newPath,$data);
 
+        return '"' . md5_file($newPath) . '"';
+
     }
 
     /**
-     * Creates a new subdirectory 
-     * 
-     * @param string $name 
+     * Creates a new subdirectory
+     *
+     * @param string $name
      * @return void
      */
     public function createDirectory($name) {
@@ -43,18 +62,18 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     }
 
     /**
-     * Returns a specific child node, referenced by its name 
-     * 
-     * @param string $name 
-     * @throws Sabre_DAV_Exception_FileNotFound
-     * @return Sabre_DAV_INode 
+     * Returns a specific child node, referenced by its name
+     *
+     * @param string $name
+     * @throws Sabre_DAV_Exception_NotFound
+     * @return Sabre_DAV_INode
      */
     public function getChild($name) {
 
         $path = $this->path . '/' . $name;
 
-        if (!file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File could not be located');
-        if ($name=='.' || $name=='..') throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..'); 
+        if (!file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File could not be located');
+        if ($name=='.' || $name=='..') throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..');
 
         if (is_dir($path)) {
 
@@ -69,10 +88,10 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     }
 
     /**
-     * Checks if a child exists. 
-     * 
-     * @param string $name 
-     * @return bool 
+     * Checks if a child exists.
+     *
+     * @param string $name
+     * @return bool
      */
     public function childExists($name) {
 
@@ -85,9 +104,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     }
 
     /**
-     * Returns an array with all the child nodes 
-     * 
-     * @return Sabre_DAV_INode[] 
+     * Returns an array with all the child nodes
+     *
+     * @return Sabre_DAV_INode[]
      */
     public function getChildren() {
 
@@ -98,9 +117,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     }
 
     /**
-     * Deletes all files in this directory, and then itself 
-     * 
-     * @return void
+     * Deletes all files in this directory, and then itself
+     *
+     * @return bool
      */
     public function delete() {
 
@@ -118,16 +137,16 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
     }
 
     /**
-     * Returns available diskspace information 
-     * 
-     * @return array 
+     * Returns available diskspace information
+     *
+     * @return array
      */
     public function getQuotaInfo() {
 
         return array(
             disk_total_space($this->path)-disk_free_space($this->path),
             disk_free_space($this->path)
-            ); 
+            );
 
     }
 
diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php
old mode 100644
new mode 100755
index 7a8e7a11f21308dd0d285670030cebd925fdd1e2..b93ce5aee2108bfbdb5bebf3a3a6619b7eda458b
--- a/3rdparty/Sabre/DAV/FSExt/File.php
+++ b/3rdparty/Sabre/DAV/FSExt/File.php
@@ -1,34 +1,35 @@
 <?php
 
 /**
- * File class 
- * 
+ * File class
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFile {
 
     /**
-     * Updates the data 
+     * Updates the data
      *
      * data is a readable stream resource.
      *
-     * @param resource $data 
-     * @return void 
+     * @param resource $data
+     * @return void
      */
     public function put($data) {
 
         file_put_contents($this->path,$data);
+        return '"' . md5_file($this->path) . '"';
 
     }
 
     /**
      * Returns the data
      *
-     * @return string 
+     * @return string
      */
     public function get() {
 
@@ -39,7 +40,7 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
     /**
      * Delete the current file
      *
-     * @return void 
+     * @return bool
      */
     public function delete() {
 
@@ -52,9 +53,11 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
      * Returns the ETag for a file
      *
      * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
-     * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
      *
      * Return null if the ETag can not effectively be determined
+     *
+     * @return string|null
      */
     public function getETag() {
 
@@ -66,7 +69,9 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
      * Returns the mime-type for a file
      *
      * If null is returned, we'll assume application/octet-stream
-     */ 
+     *
+     * @return string|null
+     */
     public function getContentType() {
 
         return null;
@@ -74,9 +79,9 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
     }
 
     /**
-     * Returns the size of the file, in bytes 
-     * 
-     * @return int 
+     * Returns the size of the file, in bytes
+     *
+     * @return int
      */
     public function getSize() {
 
diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php
old mode 100644
new mode 100755
index 9e36222bfd325a6bbe164bea5670e120fb83caf1..68ca06beb7e0930c40a20f75907baec4b1b58944
--- a/3rdparty/Sabre/DAV/FSExt/Node.php
+++ b/3rdparty/Sabre/DAV/FSExt/Node.php
@@ -1,95 +1,28 @@
 <?php
 
 /**
- * Base node-class 
+ * Base node-class
+ *
+ * The node class implements the method used by both the File and the Directory classes
  *
- * The node class implements the method used by both the File and the Directory classes 
- * 
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_DAV_ILockable, Sabre_DAV_IProperties {
-
-    /**
-     * Returns all the locks on this node
-     * 
-     * @return array 
-     */
-    function getLocks() {
-
-        $resourceData = $this->getResourceData();
-        $locks = $resourceData['locks'];
-        foreach($locks as $k=>$lock) {
-            if (time() > $lock->timeout + $lock->created) unset($locks[$k]); 
-        }
-        return $locks;
-
-    }
-
-    /**
-     * Locks this node 
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return void
-     */
-    function lock(Sabre_DAV_Locks_LockInfo $lockInfo) {
-
-        // We're making the lock timeout 30 minutes
-        $lockInfo->timeout = 1800;
-        $lockInfo->created = time();
-
-        $resourceData = $this->getResourceData();
-        if (!isset($resourceData['locks'])) $resourceData['locks'] = array();
-        $current = null;
-        foreach($resourceData['locks'] as $k=>$lock) {
-            if ($lock->token === $lockInfo->token) $current = $k;
-        }
-        if (!is_null($current)) $resourceData['locks'][$current] = $lockInfo;
-        else $resourceData['locks'][] = $lockInfo;
-
-        $this->putResourceData($resourceData);
-
-    }
-
-    /**
-     * Removes a lock from this node
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
-     */
-    function unlock(Sabre_DAV_Locks_LockInfo $lockInfo) {
-
-        //throw new Sabre_DAV_Exception('bla');
-        $resourceData = $this->getResourceData();
-        foreach($resourceData['locks'] as $k=>$lock) {
-
-            if ($lock->token === $lockInfo->token) {
-
-                unset($resourceData['locks'][$k]);
-                $this->putResourceData($resourceData);
-                return true;
-
-            }
-        }
-        return false;
-
-    }
+abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_DAV_IProperties {
 
     /**
      * Updates properties on this node,
      *
-     * @param array $mutations
+     * @param array $properties
      * @see Sabre_DAV_IProperties::updateProperties
-     * @return bool|array 
+     * @return bool|array
      */
     public function updateProperties($properties) {
 
         $resourceData = $this->getResourceData();
-        
-        $result = array();
 
         foreach($properties as $propertyName=>$propertyValue) {
 
@@ -101,11 +34,11 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
             } else {
                 $resourceData['properties'][$propertyName] = $propertyValue;
             }
-               
+
         }
 
         $this->putResourceData($resourceData);
-        return true; 
+        return true;
     }
 
     /**
@@ -114,8 +47,8 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
      * The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author
      * If the array is empty, all properties should be returned
      *
-     * @param array $properties 
-     * @return void
+     * @param array $properties
+     * @return array
      */
     function getProperties($properties) {
 
@@ -134,9 +67,9 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
     }
 
     /**
-     * Returns the path to the resource file 
-     * 
-     * @return string 
+     * Returns the path to the resource file
+     *
+     * @return string
      */
     protected function getResourceInfoPath() {
 
@@ -146,14 +79,14 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
     }
 
     /**
-     * Returns all the stored resource information 
-     * 
-     * @return array 
+     * Returns all the stored resource information
+     *
+     * @return array
      */
     protected function getResourceData() {
 
         $path = $this->getResourceInfoPath();
-        if (!file_exists($path)) return array('locks'=>array(), 'properties' => array());
+        if (!file_exists($path)) return array('properties' => array());
 
         // opening up the file, and creating a shared lock
         $handle = fopen($path,'r');
@@ -171,20 +104,19 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
         // Unserializing and checking if the resource file contains data for this file
         $data = unserialize($data);
         if (!isset($data[$this->getName()])) {
-            return array('locks'=>array(), 'properties' => array());
+            return array('properties' => array());
         }
 
         $data = $data[$this->getName()];
-        if (!isset($data['locks'])) $data['locks'] = array();
         if (!isset($data['properties'])) $data['properties'] = array();
         return $data;
 
     }
 
     /**
-     * Updates the resource information 
-     * 
-     * @param array $newData 
+     * Updates the resource information
+     *
+     * @param array $newData
      * @return void
      */
     protected function putResourceData(array $newData) {
@@ -238,6 +170,9 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
 
     }
 
+    /**
+     * @return bool
+     */
     public function deleteResourceData() {
 
         // When we're deleting this node, we also need to delete any resource information
@@ -264,6 +199,7 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
         fwrite($handle,serialize($data));
         fclose($handle);
 
+        return true;
     }
 
     public function delete() {
diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php
old mode 100644
new mode 100755
index b74bd9525b34cc8452466b260ca8be4c9fc9e16e..3126bd8d364b6c5fdd27ee8fec8fea4b90a48f9c
--- a/3rdparty/Sabre/DAV/File.php
+++ b/3rdparty/Sabre/DAV/File.php
@@ -4,12 +4,12 @@
  * File class
  *
  * This is a helper class, that should aid in getting file classes setup.
- * Most of its methods are implemented, and throw permission denied exceptions 
- * 
+ * Most of its methods are implemented, and throw permission denied exceptions
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_File extends Sabre_DAV_Node implements Sabre_DAV_IFile {
@@ -18,33 +18,33 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
      * Updates the data
      *
      * data is a readable stream resource.
-     * 
-     * @param resource $data 
-     * @return void 
+     *
+     * @param resource $data
+     * @return void
      */
-    public function put($data) { 
+    public function put($data) {
 
         throw new Sabre_DAV_Exception_Forbidden('Permission denied to change data');
 
     }
 
     /**
-     * Returns the data 
+     * Returns the data
      *
      * This method may either return a string or a readable stream resource
      *
-     * @return mixed 
+     * @return mixed
      */
-    public function get() { 
+    public function get() {
 
         throw new Sabre_DAV_Exception_Forbidden('Permission denied to read this file');
 
     }
-    
+
     /**
-     * Returns the size of the file, in bytes. 
-     * 
-     * @return int 
+     * Returns the size of the file, in bytes.
+     *
+     * @return int
      */
     public function getSize() {
 
@@ -56,9 +56,11 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
      * Returns the ETag for a file
      *
      * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
-     * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
      *
      * Return null if the ETag can not effectively be determined
+     *
+     * @return string|null
      */
     public function getETag() {
 
@@ -70,7 +72,9 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
      * Returns the mime-type for a file
      *
      * If null is returned, we'll assume application/octet-stream
-     */ 
+     *
+     * @return string|null
+     */
     public function getContentType() {
 
         return null;
diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php
old mode 100644
new mode 100755
index 0667d88899d2d307c025cc247503506f0d9311e5..4626038a66e3fcb31e211adf577b742e704cf194
--- a/3rdparty/Sabre/DAV/ICollection.php
+++ b/3rdparty/Sabre/DAV/ICollection.php
@@ -3,54 +3,70 @@
 /**
  * The ICollection Interface
  *
- * This interface should be implemented by each class that represents a collection 
- * 
+ * This interface should be implemented by each class that represents a collection
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_ICollection extends Sabre_DAV_INode {
 
     /**
-     * Creates a new file in the directory 
-     * 
-     * data is a readable stream resource
+     * Creates a new file in the directory
      *
-     * @param string $name Name of the file 
-     * @param resource $data Initial payload 
-     * @return void
+     * 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
+     * of the new file here.
+     *
+     * The returned ETag must be surrounded by double-quotes (The quotes should
+     * be part of the actual string).
+     *
+     * If you cannot accurately determine the ETag, you should not return it.
+     * If you don't store the file exactly as-is (you're transforming it
+     * somehow) you should also not return an ETag.
+     *
+     * This means that if a subsequent GET to this new file does not exactly
+     * return the same contents of what was submitted here, you are strongly
+     * recommended to omit the ETag.
+     *
+     * @param string $name Name of the file
+     * @param resource|string $data Initial payload
+     * @return null|string
      */
     function createFile($name, $data = null);
 
     /**
-     * Creates a new subdirectory 
-     * 
-     * @param string $name 
+     * Creates a new subdirectory
+     *
+     * @param string $name
      * @return void
      */
     function createDirectory($name);
 
     /**
-     * Returns a specific child node, referenced by its name 
-     * 
-     * @param string $name 
-     * @return Sabre_DAV_INode 
+     * Returns a specific child node, referenced by its name
+     *
+     * @param string $name
+     * @return Sabre_DAV_INode
      */
     function getChild($name);
 
     /**
-     * Returns an array with all the child nodes 
-     * 
-     * @return Sabre_DAV_INode[] 
+     * Returns an array with all the child nodes
+     *
+     * @return Sabre_DAV_INode[]
      */
     function getChildren();
 
     /**
-     * Checks if a child-node with the specified name exists 
-     * 
-     * @return bool 
+     * Checks if a child-node with the specified name exists
+     *
+     * @param string $name
+     * @return bool
      */
     function childExists($name);
 
diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php
old mode 100644
new mode 100755
index b8db1ab2f26917a03d5266e22ab157efc3e132bc..6ec345f9a624af16b136ef24570508e017e3e281
--- a/3rdparty/Sabre/DAV/IExtendedCollection.php
+++ b/3rdparty/Sabre/DAV/IExtendedCollection.php
@@ -5,11 +5,11 @@
  *
  * This interface can be used to create special-type of collection-resources
  * as defined by RFC 5689.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_IExtendedCollection extends Sabre_DAV_ICollection {
@@ -17,7 +17,7 @@ interface Sabre_DAV_IExtendedCollection extends Sabre_DAV_ICollection {
     /**
      * Creates a new collection
      *
-     * @param string $name 
+     * @param string $name
      * @param array $resourceType
      * @param array $properties
      * @return void
diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php
old mode 100644
new mode 100755
index 446ec86187b3a42f9770683de660b95ff87f3cfb..478f822ae712a8d4b438f61e827de6d2f84c8f9e
--- a/3rdparty/Sabre/DAV/IFile.php
+++ b/3rdparty/Sabre/DAV/IFile.php
@@ -1,34 +1,48 @@
 <?php
 
 /**
- * This interface represents a file or leaf in the tree.
+ * This interface represents a file in the directory tree
+ *
+ * A file is a bit of a broad definition. In general it implies that on
+ * this specific node a PUT or GET method may be performed, to either update,
+ * or retrieve the contents of the file.
  *
- * The nature of a file is, as you might be aware of, that it doesn't contain sub-nodes and has contents
- * 
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_IFile extends Sabre_DAV_INode {
 
     /**
-     * Updates the data 
-     * 
+     * Updates the data
+     *
      * The data argument is a readable stream resource.
      *
-     * @param resource $data 
-     * @return void 
+     * After a succesful 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.
+     *
+     * If you don't plan to store the file byte-by-byte, and you return a
+     * different object on a subsequent GET you are strongly recommended to not
+     * return an ETag, and just return null.
+     *
+     * @param resource $data
+     * @return string|null
      */
     function put($data);
 
     /**
-     * Returns the data 
-     * 
+     * Returns the data
+     *
      * This method may either return a string or a readable stream resource
      *
-     * @return mixed 
+     * @return mixed
      */
     function get();
 
@@ -36,7 +50,7 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode {
      * Returns the mime-type for a file
      *
      * If null is returned, we'll assume application/octet-stream
-     * 
+     *
      * @return void
      */
     function getContentType();
@@ -47,15 +61,15 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode {
      * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
      *
      * Return null if the ETag can not effectively be determined
-     * 
+     *
      * @return void
      */
     function getETag();
 
     /**
-     * Returns the size of the node, in bytes 
-     * 
-     * @return int 
+     * Returns the size of the node, in bytes
+     *
+     * @return int
      */
     function getSize();
 
diff --git a/3rdparty/Sabre/DAV/ILockable.php b/3rdparty/Sabre/DAV/ILockable.php
deleted file mode 100644
index f9fb3a702511eccfd4684c22c606237e1255570b..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/DAV/ILockable.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * Implement this class to support locking 
- * 
- * @package Sabre
- * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 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_ILockable extends Sabre_DAV_INode {
-
-    /**
-     * Returns an array with locks currently on the node 
-     * 
-     * @return Sabre_DAV_Locks_LockInfo[] 
-     */
-    function getLocks();
-
-    /**
-     * Creates a new lock on the file.  
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo The lock information 
-     * @return void
-     */
-    function lock(Sabre_DAV_Locks_LockInfo $lockInfo);
-
-    /**
-     * Unlocks a file 
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo The lock information 
-     * @return void 
-     */
-    function unlock(Sabre_DAV_Locks_LockInfo $lockInfo);
-
-}
-
diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php
old mode 100644
new mode 100755
index c0b96bf53775370a3374259b51196a0b26e48b1b..c57d3923105d4f0f961afb9a1c4ff28ffffcd971
--- a/3rdparty/Sabre/DAV/INode.php
+++ b/3rdparty/Sabre/DAV/INode.php
@@ -2,11 +2,11 @@
 
 /**
  * The INode interface is the base interface, and the parent class of both ICollection and IFile
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_INode {
@@ -14,14 +14,16 @@ interface Sabre_DAV_INode {
     /**
      * Deleted the current node
      *
-     * @return void 
+     * @return void
      */
     function delete();
 
     /**
-     * Returns the name of the node 
-     * 
-     * @return string 
+     * Returns the name of the node.
+     *
+     * This is used to generate the url.
+     *
+     * @return string
      */
     function getName();
 
@@ -34,9 +36,9 @@ interface Sabre_DAV_INode {
     function setName($name);
 
     /**
-     * Returns the last modification time, as a unix timestamp 
-     * 
-     * @return int 
+     * Returns the last modification time, as a unix timestamp
+     *
+     * @return int
      */
     function getLastModified();
 
diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php
old mode 100644
new mode 100755
index af17cad24affd88f1fe8633b25dae128b6b6460f..38eaab16dadb652e786429bb108785162cf6acc8
--- a/3rdparty/Sabre/DAV/IProperties.php
+++ b/3rdparty/Sabre/DAV/IProperties.php
@@ -4,11 +4,11 @@
  * IProperties interface
  *
  * Implement this interface to support custom WebDAV properties requested and sent from clients.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_IProperties extends Sabre_DAV_INode {
@@ -26,7 +26,7 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
      * If the operation was successful, true can be returned.
      * If the operation failed, false can be returned.
      *
-     * Deletion of a non-existant property is always succesful.
+     * 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
@@ -41,12 +41,12 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
      *   )
      * )
      *
-     * In this example it was forbidden to update {DAV:}displayname. 
+     * 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 array $mutations 
-     * @return bool|array 
+     * @param array $mutations
+     * @return bool|array
      */
     function updateProperties($mutations);
 
@@ -58,7 +58,7 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
      *
      * If the array is empty, it means 'all properties' were requested.
      *
-     * @param array $properties 
+     * @param array $properties
      * @return void
      */
     function getProperties($properties);
diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php
old mode 100644
new mode 100755
index 8ff1a4597f85d43610439216f9c8ecc440429a0c..3fe4c4eced4bd4e58b15408a3192d38c08a33850
--- a/3rdparty/Sabre/DAV/IQuota.php
+++ b/3rdparty/Sabre/DAV/IQuota.php
@@ -4,13 +4,13 @@
  * IQuota interface
  *
  * Implement this interface to add the ability to return quota information. The ObjectTree
- * will check for quota information on any given node. If the information is not available it will 
+ * will check for quota information on any given node. If the information is not available it will
  * attempt to fetch the information from the root node.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_IQuota extends Sabre_DAV_ICollection {
@@ -21,7 +21,7 @@ interface Sabre_DAV_IQuota extends Sabre_DAV_ICollection {
      * This method MUST return an array with 2 values, the first being the total used space,
      * the second the available space (in bytes)
      */
-    function getQuotaInfo(); 
+    function getQuotaInfo();
 
 }
 
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
old mode 100644
new mode 100755
index b09f93ddac79e41d1aa9497d7739a8a20d5d15d9..127e643a2b9658db3b19cb4024cbfbc228010291
--- a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
@@ -4,45 +4,45 @@
  * The Lock manager allows you to handle all file-locks centrally.
  *
  * This is an alternative approach to doing this on a per-node basis
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_Backend_Abstract {
 
     /**
-     * Returns a list of Sabre_DAV_Locks_LockInfo objects  
-     * 
+     * Returns a list of Sabre_DAV_Locks_LockInfo objects
+     *
      * This method should return all the locks for a particular uri, including
      * locks that might be set on a parent uri.
      *
      * If returnChildLocks is set to true, this method should also look for
      * any locks in the subtree of the uri for locks.
      *
-     * @param string $uri 
+     * @param string $uri
      * @param bool $returnChildLocks
-     * @return array 
+     * @return array
      */
     abstract function getLocks($uri, $returnChildLocks);
 
     /**
-     * Locks a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Locks a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     abstract function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo);
 
     /**
-     * Removes a lock from a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Removes a lock from a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     abstract function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo);
 
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
old mode 100644
new mode 100755
index 8653f55b1c6f9a116733392332975ff7c5a97e48..02cab87fc829e024aace719ba83c8498a5d97e0e
--- a/3rdparty/Sabre/DAV/Locks/Backend/FS.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
@@ -1,28 +1,30 @@
 <?php
 
 /**
- * The Lock manager allows you to handle all file-locks centrally.
+ * This Lock Backend stores all its data in the filesystem in separate file per
+ * node.
  *
- * This Lock Manager is now deprecated. It has a bug that allows parent 
- * collections to be deletes when children deeper in the tree are locked. 
+ * This Lock Manager is now deprecated. It has a bug that allows parent
+ * collections to be deletes when children deeper in the tree are locked.
+ *
+ * This also means that using this backend means you will not pass the Neon
+ * Litmus test.
  *
  * You are recommended to use either the PDO or the File backend instead.
  *
- * This Lock Manager stores all its data in the filesystem.
- * 
  * @package Sabre
  * @subpackage DAV
  * @deprecated
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
 
     /**
-     * The default data directory 
-     * 
-     * @var string 
+     * The default data directory
+     *
+     * @var string
      */
     private $dataDir;
 
@@ -40,17 +42,17 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
 
 
     /**
-     * Returns a list of Sabre_DAV_Locks_LockInfo objects  
-     * 
+     * Returns a list of Sabre_DAV_Locks_LockInfo objects
+     *
      * This method should return all the locks for a particular uri, including
      * locks that might be set on a parent uri.
      *
      * If returnChildLocks is set to true, this method should also look for
      * any locks in the subtree of the uri for locks.
      *
-     * @param string $uri 
+     * @param string $uri
      * @param bool $returnChildLocks
-     * @return array 
+     * @return array
      */
     public function getLocks($uri, $returnChildLocks) {
 
@@ -59,15 +61,15 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
 
         foreach(explode('/',$uri) as $uriPart) {
 
-            // weird algorithm that can probably be improved, but we're traversing the path top down 
-            if ($currentPath) $currentPath.='/'; 
+            // weird algorithm that can probably be improved, but we're traversing the path top down
+            if ($currentPath) $currentPath.='/';
             $currentPath.=$uriPart;
 
             $uriLocks = $this->getData($currentPath);
 
             foreach($uriLocks as $uriLock) {
 
-                // Unless we're on the leaf of the uri-tree we should ingore locks with depth 0
+                // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0
                 if($uri==$currentPath || $uriLock->depth!=0) {
                     $uriLock->uri = $currentPath;
                     $lockList[] = $uriLock;
@@ -79,18 +81,18 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
 
         // Checking if we can remove any of these locks
         foreach($lockList as $k=>$lock) {
-            if (time() > $lock->timeout + $lock->created) unset($lockList[$k]); 
+            if (time() > $lock->timeout + $lock->created) unset($lockList[$k]);
         }
         return $lockList;
 
     }
 
     /**
-     * Locks a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Locks a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
@@ -109,11 +111,11 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
     }
 
     /**
-     * Removes a lock from a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Removes a lock from a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
@@ -136,7 +138,7 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
      * Returns the stored data for a uri
      *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     protected function getData($uri) {
 
@@ -167,7 +169,7 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
      * Updates the lock information
      *
      * @param string $uri
-     * @param array $newData 
+     * @param array $newData
      * @return void
      */
     protected function putData($uri,array $newData) {
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php
old mode 100644
new mode 100755
index f65b20c4306728f93cd9c00968db46d6008f816c..c33f963514bef4e4ca66546479d03d9a72240e77
--- a/3rdparty/Sabre/DAV/Locks/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/File.php
@@ -3,30 +3,30 @@
 /**
  * The Lock manager allows you to handle all file-locks centrally.
  *
- * This Lock Manager stores all its data in a single file. 
+ * This Lock Manager stores all its data in a single file.
  *
  * Note that this is not nearly as robust as a database, you are encouraged
  * to use the PDO backend instead.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
 
     /**
      * The storage file
-     * 
-     * @var string 
+     *
+     * @var string
      */
     private $locksFile;
 
     /**
      * Constructor
      *
-     * @param string $locksFile path to file 
+     * @param string $locksFile path to file
      */
     public function __construct($locksFile) {
 
@@ -35,24 +35,24 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
     }
 
     /**
-     * Returns a list of Sabre_DAV_Locks_LockInfo objects  
-     * 
+     * Returns a list of Sabre_DAV_Locks_LockInfo objects
+     *
      * This method should return all the locks for a particular uri, including
      * locks that might be set on a parent uri.
      *
      * If returnChildLocks is set to true, this method should also look for
      * any locks in the subtree of the uri for locks.
      *
-     * @param string $uri 
+     * @param string $uri
      * @param bool $returnChildLocks
-     * @return array 
+     * @return array
      */
     public function getLocks($uri, $returnChildLocks) {
 
         $newLocks = array();
-        $currentPath = '';
 
         $locks = $this->getData();
+
         foreach($locks as $lock) {
 
             if ($lock->uri === $uri ||
@@ -70,29 +70,35 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
 
         // Checking if we can remove any of these locks
         foreach($newLocks as $k=>$lock) {
-            if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]); 
+            if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]);
         }
         return $newLocks;
 
     }
 
     /**
-     * Locks a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Locks a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
-    public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
+    public function lock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) {
 
         // We're making the lock timeout 30 minutes
         $lockInfo->timeout = 1800;
         $lockInfo->created = time();
         $lockInfo->uri = $uri;
 
-        $locks = $this->getLocks($uri,false);
+        $locks = $this->getData();
+
         foreach($locks as $k=>$lock) {
-            if ($lock->token == $lockInfo->token) unset($locks[$k]);
+            if (
+                ($lock->token == $lockInfo->token) ||
+                (time() > $lock->timeout + $lock->created)
+            ) {
+                unset($locks[$k]);
+            }
         }
         $locks[] = $lockInfo;
         $this->putData($locks);
@@ -101,15 +107,15 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
     }
 
     /**
-     * Removes a lock from a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Removes a lock from a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
-    public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
+    public function unlock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) {
 
-        $locks = $this->getLocks($uri,false);
+        $locks = $this->getData();
         foreach($locks as $k=>$lock) {
 
             if ($lock->token == $lockInfo->token) {
@@ -127,7 +133,7 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
     /**
      * Loads the lockdata from the filesystem.
      *
-     * @return array 
+     * @return array
      */
     protected function getData() {
 
@@ -153,7 +159,7 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
     /**
      * Saves the lockdata
      *
-     * @param array $newData 
+     * @param array $newData
      * @return void
      */
     protected function putData(array $newData) {
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
old mode 100644
new mode 100755
index c3923af19d3ea6d5eae4235711b175ef24672d71..acce80638ecb63c508c096a8e95d7b34d124a96d
--- a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
@@ -5,34 +5,34 @@
  *
  * This Lock Manager stores all its data in a database. You must pass a PDO
  * connection object in the constructor.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
 
     /**
-     * The PDO connection object 
-     * 
-     * @var pdo 
+     * The PDO connection object
+     *
+     * @var pdo
      */
     private $pdo;
 
     /**
-     * The PDO tablename this backend uses. 
-     * 
+     * The PDO tablename this backend uses.
+     *
      * @var string
      */
     protected $tableName;
 
     /**
-     * Constructor 
-     * 
+     * Constructor
+     *
      * @param PDO $pdo
-     * @param string $tableName 
+     * @param string $tableName
      */
     public function __construct(PDO $pdo, $tableName = 'locks') {
 
@@ -42,24 +42,24 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
     }
 
     /**
-     * Returns a list of Sabre_DAV_Locks_LockInfo objects  
-     * 
+     * Returns a list of Sabre_DAV_Locks_LockInfo objects
+     *
      * This method should return all the locks for a particular uri, including
      * locks that might be set on a parent uri.
      *
      * If returnChildLocks is set to true, this method should also look for
      * any locks in the subtree of the uri for locks.
      *
-     * @param string $uri 
+     * @param string $uri
      * @param bool $returnChildLocks
-     * @return array 
+     * @return array
      */
     public function getLocks($uri, $returnChildLocks) {
 
-        // NOTE: the following 10 lines or so could be easily replaced by 
-        // pure sql. MySQL's non-standard string concatination prevents us
+        // NOTE: the following 10 lines or so could be easily replaced by
+        // pure sql. MySQL's non-standard string concatenation prevents us
         // from doing this though.
-        $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM `'.$this->tableName.'` WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)';
+        $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM '.$this->tableName.' WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)';
         $params = array(time(),$uri);
 
         // We need to check locks for every part in the uri.
@@ -112,11 +112,11 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
     }
 
     /**
-     * Locks a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Locks a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
@@ -127,15 +127,15 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
 
         $locks = $this->getLocks($uri,false);
         $exists = false;
-        foreach($locks as $k=>$lock) {
+        foreach($locks as $lock) {
             if ($lock->token == $lockInfo->token) $exists = true;
         }
-        
+
         if ($exists) {
-            $stmt = $this->pdo->prepare('UPDATE `'.$this->tableName.'` SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?');
+            $stmt = $this->pdo->prepare('UPDATE '.$this->tableName.' SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?');
             $stmt->execute(array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token));
         } else {
-            $stmt = $this->pdo->prepare('INSERT INTO `'.$this->tableName.'` (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)');
+            $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)');
             $stmt->execute(array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token));
         }
 
@@ -146,15 +146,15 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
 
 
     /**
-     * Removes a lock from a uri 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return bool 
+     * Removes a lock from a uri
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
-        $stmt = $this->pdo->prepare('DELETE FROM `'.$this->tableName.'` WHERE uri = ? AND token = ?');
+        $stmt = $this->pdo->prepare('DELETE FROM '.$this->tableName.' WHERE uri = ? AND token = ?');
         $stmt->execute(array($uri,$lockInfo->token));
 
         return $stmt->rowCount()===1;
diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php
old mode 100644
new mode 100755
index 6a064466f4015303ca802b44b05d2617e33ce0ad..9df014a4281a8b192f59f85c1d50d27793fb6e3a
--- a/3rdparty/Sabre/DAV/Locks/LockInfo.php
+++ b/3rdparty/Sabre/DAV/Locks/LockInfo.php
@@ -5,11 +5,11 @@
  *
  * An object of the LockInfo class holds all the information relevant to a
  * single lock.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_LockInfo {
@@ -30,37 +30,37 @@ class Sabre_DAV_Locks_LockInfo {
     const TIMEOUT_INFINITE = -1;
 
     /**
-     * The owner of the lock 
-     * 
-     * @var string 
+     * The owner of the lock
+     *
+     * @var string
      */
     public $owner;
 
     /**
-     * The locktoken 
-     * 
-     * @var string 
+     * The locktoken
+     *
+     * @var string
      */
     public $token;
 
     /**
-     * How long till the lock is expiring 
-     * 
-     * @var int 
+     * How long till the lock is expiring
+     *
+     * @var int
      */
     public $timeout;
 
     /**
-     * UNIX Timestamp of when this lock was created 
-     * 
-     * @var int 
+     * UNIX Timestamp of when this lock was created
+     *
+     * @var int
      */
     public $created;
 
     /**
-     * Exclusive or shared lock 
-     * 
-     * @var int 
+     * Exclusive or shared lock
+     *
+     * @var int
      */
     public $scope = self::EXCLUSIVE;
 
@@ -72,7 +72,7 @@ class Sabre_DAV_Locks_LockInfo {
     /**
      * The uri this lock locks
      *
-     * TODO: This value is not always set 
+     * TODO: This value is not always set
      * @var mixed
      */
     public $uri;
diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php
old mode 100644
new mode 100755
index 461e2847e0ae8e562827294eb4d550b19b3b4530..fd956950b8af22d4260c08e5c5130717a9988f5e
--- a/3rdparty/Sabre/DAV/Locks/Plugin.php
+++ b/3rdparty/Sabre/DAV/Locks/Plugin.php
@@ -9,38 +9,37 @@
  * $lockBackend = new Sabre_DAV_Locks_Backend_File('./mylockdb');
  * $lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend);
  * $server->addPlugin($lockPlugin);
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
-     * locksBackend 
-     * 
-     * @var Sabre_DAV_Locks_Backend_Abstract 
+     * locksBackend
+     *
+     * @var Sabre_DAV_Locks_Backend_Abstract
      */
     private $locksBackend;
 
     /**
      * server
-     * 
-     * @var Sabre_DAV_Server 
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
     /**
-     * __construct 
-     * 
-     * @param Sabre_DAV_Locks_Backend_Abstract $locksBackend 
-     * @return void
+     * __construct
+     *
+     * @param Sabre_DAV_Locks_Backend_Abstract $locksBackend
      */
     public function __construct(Sabre_DAV_Locks_Backend_Abstract $locksBackend = null) {
 
-        $this->locksBackend = $locksBackend;        
+        $this->locksBackend = $locksBackend;
 
     }
 
@@ -48,8 +47,8 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * Initializes the plugin
      *
      * This method is automatically called by the Server class after addPlugin.
-     * 
-     * @param Sabre_DAV_Server $server 
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -63,11 +62,11 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a plugin name.
-     * 
+     *
      * Using this name other plugins will be able to access other plugins
-     * using Sabre_DAV_Server::getPlugin 
-     * 
-     * @return string 
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
      */
     public function getPluginName() {
 
@@ -76,20 +75,21 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This method is called by the Server if the user used an HTTP method 
+     * This method is called by the Server if the user used an HTTP method
      * the server didn't recognize.
      *
      * This plugin intercepts the LOCK and UNLOCK methods.
-     * 
-     * @param string $method 
-     * @return bool 
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function unknownMethod($method, $uri) {
 
-        switch($method) { 
+        switch($method) {
 
-            case 'LOCK'   : $this->httpLock($uri); return false; 
-            case 'UNLOCK' : $this->httpUnlock($uri); return false; 
+            case 'LOCK'   : $this->httpLock($uri); return false;
+            case 'UNLOCK' : $this->httpUnlock($uri); return false;
 
         }
 
@@ -98,26 +98,20 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * This method is called after most properties have been found
      * it allows us to add in any Lock-related properties
-     * 
-     * @param string $path 
-     * @param array $properties 
-     * @return bool 
+     *
+     * @param string $path
+     * @param array $newProperties
+     * @return bool
      */
-    public function afterGetProperties($path,&$newProperties) {
+    public function afterGetProperties($path, &$newProperties) {
 
         foreach($newProperties[404] as $propName=>$discard) {
 
-            $node = null;
-
             switch($propName) {
 
                 case '{DAV:}supportedlock' :
                     $val = false;
                     if ($this->locksBackend) $val = true;
-                    else {
-                        if (!$node) $node = $this->server->tree->getNodeForPath($path);
-                        if ($node instanceof Sabre_DAV_ILockable) $val = true;
-                    }
                     $newProperties[200][$propName] = new Sabre_DAV_Property_SupportedLock($val);
                     unset($newProperties[404][$propName]);
                     break;
@@ -141,10 +135,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * handled.
      *
      * This plugin uses that feature to intercept access to locked resources.
-     * 
+     *
      * @param string $method
      * @param string $uri
-     * @return bool 
+     * @return bool
      */
     public function beforeMethod($method, $uri) {
 
@@ -187,18 +181,17 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * 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 
+     * This method is passed a uri. It should only return HTTP methods that are
      * available for the specified uri.
      *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getHTTPMethods($uri) {
 
-        if ($this->locksBackend ||
-            $this->server->tree->getNodeForPath($uri) instanceof Sabre_DAV_ILocks) {
+        if ($this->locksBackend)
             return array('LOCK','UNLOCK');
-        }
+
         return array();
 
     }
@@ -208,8 +201,8 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * In this case this is only the number 2. The 2 in the Dav: header
      * indicates the server supports locks.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getFeatures() {
 
@@ -218,49 +211,23 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Returns all lock information on a particular uri 
-     * 
+     * Returns all lock information on a particular uri
+     *
      * This function should return an array with Sabre_DAV_Locks_LockInfo objects. If there are no locks on a file, return an empty array.
      *
-     * Additionally there is also the possibility of locks on parent nodes, so we'll need to traverse every part of the tree 
+     * Additionally there is also the possibility of locks on parent nodes, so we'll need to traverse every part of the tree
      * If the $returnChildLocks argument is set to true, we'll also traverse all the children of the object
      * for any possible locks and return those as well.
      *
-     * @param string $uri 
+     * @param string $uri
      * @param bool $returnChildLocks
-     * @return array 
+     * @return array
      */
     public function getLocks($uri, $returnChildLocks = false) {
 
         $lockList = array();
-        $currentPath = '';
-        foreach(explode('/',$uri) as $uriPart) {
 
-            $uriLocks = array();
-            if ($currentPath) $currentPath.='/'; 
-            $currentPath.=$uriPart;
-
-            try {
-
-                $node = $this->server->tree->getNodeForPath($currentPath);
-                if ($node instanceof Sabre_DAV_ILockable) $uriLocks = $node->getLocks();
-
-            } catch (Sabre_DAV_Exception_FileNotFound $e){
-                // In case the node didn't exist, this could be a lock-null request
-            }
-
-            foreach($uriLocks as $uriLock) {
-
-                // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0
-                if($uri==$currentPath || $uriLock->depth!=0) {
-                    $uriLock->uri = $currentPath;
-                    $lockList[] = $uriLock;
-                }
-
-            }
-
-        }
-        if ($this->locksBackend) 
+        if ($this->locksBackend)
             $lockList = array_merge($lockList,$this->locksBackend->getLocks($uri, $returnChildLocks));
 
         return $lockList;
@@ -271,13 +238,13 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * Locks an uri
      *
      * The WebDAV lock request can be operated to either create a new lock on a file, or to refresh an existing lock
-     * If a new lock is created, a full XML body should be supplied, containing information about the lock such as the type 
+     * If a new lock is created, a full XML body should be supplied, containing information about the lock such as the type
      * of lock (shared or exclusive) and the owner of the lock
      *
      * If a lock is to be refreshed, no body should be supplied and there should be a valid If header containing the lock
      *
-     * Additionally, a lock can be requested for a non-existant file. In these case we're obligated to create an empty file as per RFC4918:S7.3
-     * 
+     * Additionally, a lock can be requested for a non-existent file. In these case we're obligated to create an empty file as per RFC4918:S7.3
+     *
      * @param string $uri
      * @return void
      */
@@ -297,7 +264,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
         if ($body = $this->server->httpRequest->getBody(true)) {
             // This is a new lock request
             $lockInfo = $this->parseLockRequest($body);
-            $lockInfo->depth = $this->server->getHTTPDepth(); 
+            $lockInfo->depth = $this->server->getHTTPDepth();
             $lockInfo->uri = $uri;
             if($lastLock && $lockInfo->scope != Sabre_DAV_Locks_LockInfo::SHARED) throw new Sabre_DAV_Exception_ConflictingLock($lastLock);
 
@@ -306,11 +273,11 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
             // This must have been a lock refresh
             $lockInfo = $lastLock;
 
-            // The resource could have been locked through another uri. 
+            // The resource could have been locked through another uri.
             if ($uri!=$lockInfo->uri) $uri = $lockInfo->uri;
 
         } else {
-            
+
             // There was neither a lock refresh nor a new lock request
             throw new Sabre_DAV_Exception_BadRequest('An xml body is required for lock requests');
 
@@ -322,16 +289,16 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
         // If we got this far.. we should go check if this node actually exists. If this is not the case, we need to create it first
         try {
-            $node = $this->server->tree->getNodeForPath($uri);
-            
+            $this->server->tree->getNodeForPath($uri);
+
             // We need to call the beforeWriteContent event for RFC3744
             $this->server->broadcastEvent('beforeWriteContent',array($uri));
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
-            
+        } catch (Sabre_DAV_Exception_NotFound $e) {
+
             // It didn't, lets create it
-            $this->server->createFile($uri,fopen('php://memory','r')); 
-            $newFile = true; 
+            $this->server->createFile($uri,fopen('php://memory','r'));
+            $newFile = true;
 
         }
 
@@ -362,7 +329,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
         $locks = $this->getLocks($uri);
 
-        // Windows sometimes forgets to include < and > in the Lock-Token 
+        // Windows sometimes forgets to include < and > in the Lock-Token
         // header
         if ($lockToken[0]!=='<') $lockToken = '<' . $lockToken . '>';
 
@@ -370,7 +337,6 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
             if ('<opaquelocktoken:' . $lock->token . '>' == $lockToken) {
 
-                $this->server->broadcastEvent('beforeUnlock',array($uri, $lock));
                 $this->unlockNode($uri,$lock);
                 $this->server->httpResponse->setHeader('Content-Length','0');
                 $this->server->httpResponse->sendStatus(204);
@@ -390,21 +356,15 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * All the locking information is supplied in the lockInfo object. The object has a suggested timeout, but this can be safely ignored
      * It is important that if the existing timeout is ignored, the property is overwritten, as this needs to be sent back to the client
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return void
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function lockNode($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
         if (!$this->server->broadcastEvent('beforeLock',array($uri,$lockInfo))) return;
 
-        try {
-            $node = $this->server->tree->getNodeForPath($uri);
-            if ($node instanceof Sabre_DAV_ILockable) return $node->lock($lockInfo);
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
-            // In case the node didn't exist, this could be a lock-null request
-        }
         if ($this->locksBackend) return $this->locksBackend->lock($uri,$lockInfo);
         throw new Sabre_DAV_Exception_MethodNotAllowed('Locking support is not enabled for this resource. No Locking backend was found so if you didn\'t expect this error, please check your configuration.');
 
@@ -414,29 +374,22 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * Unlocks a uri
      *
      * This method removes a lock from a uri. It is assumed all the supplied information is correct and verified
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return void
+     *
+     * @param string $uri
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return bool
      */
     public function unlockNode($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
 
         if (!$this->server->broadcastEvent('beforeUnlock',array($uri,$lockInfo))) return;
-        try {
-            $node = $this->server->tree->getNodeForPath($uri);
-            if ($node instanceof Sabre_DAV_ILockable) return $node->unlock($lockInfo);
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
-            // In case the node didn't exist, this could be a lock-null request
-        }
-
         if ($this->locksBackend) return $this->locksBackend->unlock($uri,$lockInfo);
 
     }
 
 
     /**
-     * Returns the contents of the HTTP Timeout header. 
-     * 
+     * Returns the contents of the HTTP Timeout header.
+     *
      * The method formats the header into an integer.
      *
      * @return int
@@ -444,7 +397,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     public function getTimeoutHeader() {
 
         $header = $this->server->httpRequest->getHeader('Timeout');
-        
+
         if ($header) {
 
             if (stripos($header,'second-')===0) $header = (int)(substr($header,7));
@@ -462,16 +415,16 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Generates the response for successfull LOCK requests 
-     * 
-     * @param Sabre_DAV_Locks_LockInfo $lockInfo 
-     * @return string 
+     * Generates the response for successful LOCK requests
+     *
+     * @param Sabre_DAV_Locks_LockInfo $lockInfo
+     * @return string
      */
     protected function generateLockResponse(Sabre_DAV_Locks_LockInfo $lockInfo) {
 
         $dom = new DOMDocument('1.0','utf-8');
         $dom->formatOutput = true;
-        
+
         $prop = $dom->createElementNS('DAV:','d:prop');
         $dom->appendChild($prop);
 
@@ -484,10 +437,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
         return $dom->saveXML();
 
     }
-    
+
     /**
      * validateLock should be called when a write operation is about to happen
-     * It will check if the requested url is locked, and see if the correct lock tokens are passed 
+     * It will check if the requested url is locked, and see if the correct lock tokens are passed
      *
      * @param mixed $urls List of relevant urls. Can be an array, a string or nothing at all for the current request uri
      * @param mixed $lastLock This variable will be populated with the last checked lock object (Sabre_DAV_Locks_LockInfo)
@@ -511,13 +464,13 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
 
             $locks = $this->getLocks($url, $checkChildLocks);
 
-            // If there were no conditions, but there were locks, we fail 
+            // If there were no conditions, but there were locks, we fail
             if (!$conditions && $locks) {
                 reset($locks);
                 $lastLock = current($locks);
                 return false;
             }
-          
+
             // If there were no locks or conditions, we go to the next url
             if (!$locks && !$conditions) continue;
 
@@ -542,7 +495,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
                     // key 2 can contain an etag
                     if ($conditionToken[2]) {
 
-                        $uri = $conditionUri?$conditionUri:$this->server->getRequestUri(); 
+                        $uri = $conditionUri?$conditionUri:$this->server->getRequestUri();
                         $node = $this->server->tree->getNodeForPath($uri);
                         $etagValid = $node->getETag()==$conditionToken[2];
 
@@ -609,23 +562,23 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
      * This method is created to extract information from the WebDAV HTTP 'If:' header
      *
      * The If header can be quite complex, and has a bunch of features. We're using a regex to extract all relevant information
-     * The function will return an array, containg structs with the following keys
+     * The function will return an array, containing structs with the following keys
      *
-     *   * uri   - the uri the condition applies to. If this is returned as an 
+     *   * uri   - the uri the condition applies to. If this is returned as an
      *     empty string, this implies it's referring to the request url.
-     *   * tokens - The lock token. another 2 dimensional array containg 2 elements (0 = true/false.. If this is a negative condition its set to false, 1 = the actual token)
+     *   * tokens - The lock token. another 2 dimensional array containing 2 elements (0 = true/false.. If this is a negative condition its set to false, 1 = the actual token)
      *   * etag - an etag, if supplied
-     * 
-     * @return void
+     *
+     * @return array
      */
     public function getIfConditions() {
 
-        $header = $this->server->httpRequest->getHeader('If'); 
+        $header = $this->server->httpRequest->getHeader('If');
         if (!$header) return array();
 
         $matches = array();
 
-        $regex = '/(?:\<(?P<uri>.*?)\>\s)?\((?P<not>Not\s)?(?:\<(?P<token>[^\>]*)\>)?(?:\s?)(?:\[(?P<etag>[^\]]*)\])?\)/im'; 
+        $regex = '/(?:\<(?P<uri>.*?)\>\s)?\((?P<not>Not\s)?(?:\<(?P<token>[^\>]*)\>)?(?:\s?)(?:\[(?P<etag>[^\]]*)\])?\)/im';
         preg_match_all($regex,$header,$matches,PREG_SET_ORDER);
 
         $conditions = array();
@@ -636,7 +589,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
                 'uri'   => $match['uri'],
                 'tokens' => array(
                     array($match['not']?0:1,$match['token'],isset($match['etag'])?$match['etag']:'')
-                ),    
+                ),
             );
 
             if (!$condition['uri'] && count($conditions)) $conditions[count($conditions)-1]['tokens'][] = array(
@@ -655,9 +608,9 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Parses a webdav lock xml body, and returns a new Sabre_DAV_Locks_LockInfo object 
-     * 
-     * @param string $body 
+     * Parses a webdav lock xml body, and returns a new Sabre_DAV_Locks_LockInfo object
+     *
+     * @param string $body
      * @return Sabre_DAV_Locks_LockInfo
      */
     protected function parseLockRequest($body) {
diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php
old mode 100644
new mode 100755
index f93a1aa25a1f00793e848d2fdb752ab092be785d..b37a90ae9939a1315e438a4bd55d5687e12cc28b
--- a/3rdparty/Sabre/DAV/Mount/Plugin.php
+++ b/3rdparty/Sabre/DAV/Mount/Plugin.php
@@ -4,25 +4,25 @@
  * This plugin provides support for RFC4709: Mounting WebDAV servers
  *
  * Simply append ?mount to any collection to generate the davmount response.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
  */
 class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
-     * Reference to Server class 
-     * 
-     * @var Sabre_DAV_Server 
+     * Reference to Server class
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
     /**
-     * Initializes the plugin and registers event handles 
-     * 
-     * @param Sabre_DAV_Server $server 
+     * Initializes the plugin and registers event handles
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -35,9 +35,10 @@ class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * 'beforeMethod' event handles. This event handles intercepts GET requests ending
      * with ?mount
-     * 
-     * @param string $method 
-     * @return void
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function beforeMethod($method, $uri) {
 
@@ -57,13 +58,13 @@ class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Generates the davmount response 
-     * 
-     * @param string $uri absolute uri 
+     * Generates the davmount response
+     *
+     * @param string $uri absolute uri
      * @return void
      */
     public function davMount($uri) {
-       
+
         $this->server->httpResponse->sendStatus(200);
         $this->server->httpResponse->setHeader('Content-Type','application/davmount+xml');
         ob_start();
diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php
old mode 100644
new mode 100755
index 0510df5fdf28156bd1941cce78f1734992377308..070b7176afdf6ea09e47ba2c2084799028656d79
--- a/3rdparty/Sabre/DAV/Node.php
+++ b/3rdparty/Sabre/DAV/Node.php
@@ -3,22 +3,22 @@
 /**
  * Node class
  *
- * This is a helper class, that should aid in getting nodes setup. 
- * 
+ * This is a helper class, that should aid in getting nodes setup.
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Node implements Sabre_DAV_INode {
 
     /**
-     * Returns the last modification time 
+     * Returns the last modification time
      *
      * In this case, it will simply return the current time
      *
-     * @return int 
+     * @return int
      */
     public function getLastModified() {
 
@@ -30,7 +30,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
      * Deleted the current node
      *
      * @throws Sabre_DAV_Exception_Forbidden
-     * @return void 
+     * @return void
      */
     public function delete() {
 
@@ -40,7 +40,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
 
     /**
      * Renames the node
-     * 
+     *
      * @throws Sabre_DAV_Exception_Forbidden
      * @param string $name The new name
      * @return void
diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php
old mode 100644
new mode 100755
index f12a36837052c058d4a35e7ae30a0c48d4aeb13e..bce5146390026a417230243fc94be0299db93a6d
--- a/3rdparty/Sabre/DAV/ObjectTree.php
+++ b/3rdparty/Sabre/DAV/ObjectTree.php
@@ -3,27 +3,27 @@
 /**
  * ObjectTree class
  *
- * This implementation of the Tree class makes use of the INode, IFile and ICollection API's 
- * 
+ * This implementation of the Tree class makes use of the INode, IFile and ICollection API's
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_ObjectTree extends Sabre_DAV_Tree {
 
     /**
-     * The root node 
-     * 
+     * The root node
+     *
      * @var Sabre_DAV_ICollection
      */
     protected $rootNode;
 
     /**
-     * This is the node cache. Accessed nodes are stored here 
-     * 
-     * @var array 
+     * This is the node cache. Accessed nodes are stored here
+     *
+     * @var array
      */
     protected $cache = array();
 
@@ -31,9 +31,8 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
      * Creates the object
      *
      * This method expects the rootObject to be passed as a parameter
-     * 
-     * @param Sabre_DAV_ICollection $rootNode 
-     * @return void
+     *
+     * @param Sabre_DAV_ICollection $rootNode
      */
     public function __construct(Sabre_DAV_ICollection $rootNode) {
 
@@ -42,10 +41,10 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
     }
 
     /**
-     * Returns the INode object for the requested path  
-     * 
-     * @param string $path 
-     * @return Sabre_DAV_INode 
+     * Returns the INode object for the requested path
+     *
+     * @param string $path
+     * @return Sabre_DAV_INode
      */
     public function getNodeForPath($path) {
 
@@ -54,17 +53,17 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
 
         //if (!$path || $path=='.') return $this->rootNode;
         $currentNode = $this->rootNode;
-        $i=0;
-        // We're splitting up the path variable into folder/subfolder components and traverse to the correct node.. 
+
+        // We're splitting up the path variable into folder/subfolder components and traverse to the correct node..
         foreach(explode('/',$path) as $pathPart) {
 
             // If this part of the path is just a dot, it actually means we can skip it
             if ($pathPart=='.' || $pathPart=='') continue;
 
             if (!($currentNode instanceof Sabre_DAV_ICollection))
-                throw new Sabre_DAV_Exception_FileNotFound('Could not find node at path: ' . $path);
+                throw new Sabre_DAV_Exception_NotFound('Could not find node at path: ' . $path);
 
-            $currentNode = $currentNode->getChild($pathPart); 
+            $currentNode = $currentNode->getChild($pathPart);
 
         }
 
@@ -76,8 +75,8 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
     /**
      * This function allows you to check if a node exists.
      *
-     * @param string $path 
-     * @return bool 
+     * @param string $path
+     * @return bool
      */
     public function nodeExists($path) {
 
@@ -92,7 +91,7 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
             if (!$parentNode instanceof Sabre_DAV_ICollection) return false;
             return $parentNode->childExists($base);
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
 
             return false;
 
@@ -101,10 +100,10 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
     }
 
     /**
-     * Returns a list of childnodes for a given path. 
-     * 
-     * @param string $path 
-     * @return array 
+     * Returns a list of childnodes for a given path.
+     *
+     * @param string $path
+     * @return array
      */
     public function getChildren($path) {
 
@@ -127,14 +126,14 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
      *   * node creations
      *   * copy
      *   * move
-     *   * renaming nodes 
-     * 
+     *   * renaming nodes
+     *
      * If Tree classes implement a form of caching, this will allow
      * them to make sure caches will be expired.
-     * 
+     *
      * If a path is passed, it is assumed that the entire subtree is dirty
      *
-     * @param string $path 
+     * @param string $path
      * @return void
      */
     public function markDirty($path) {
@@ -145,7 +144,7 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
         foreach($this->cache as $nodePath=>$node) {
             if ($nodePath == $path || strpos($nodePath,$path.'/')===0)
                 unset($this->cache[$nodePath]);
-            
+
         }
 
     }
diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php
old mode 100644
new mode 100755
index 577535b012769b418a41f58487dd8c1718551a2e..1cfada3236c5500a64e4c343d0437db7f22dbb76
--- a/3rdparty/Sabre/DAV/Property.php
+++ b/3rdparty/Sabre/DAV/Property.php
@@ -4,16 +4,16 @@
  * Abstract property class
  *
  * Extend this class to create custom complex properties
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Property {
 
-    abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop); 
+    abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop);
 
     static function unserialize(DOMElement $prop) {
 
diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php
old mode 100644
new mode 100755
index 4a81262997148025ecc68f28d55c243c8f6e0f1a..bd63f573140a72780f215fd0af8d42f509c571b3
--- a/3rdparty/Sabre/DAV/Property/GetLastModified.php
+++ b/3rdparty/Sabre/DAV/Property/GetLastModified.php
@@ -2,33 +2,32 @@
 
 /**
  * This property represents the {DAV:}getlastmodified property.
- * 
+ *
  * Although this is normally a simple property, windows requires us to add
  * some new attributes.
  *
- * This class uses unix timestamps internally, and converts them to RFC 1123 times for 
+ * This class uses unix timestamps internally, and converts them to RFC 1123 times for
  * serialization
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_GetLastModified extends Sabre_DAV_Property {
 
     /**
-     * time 
-     * 
-     * @var int 
+     * time
+     *
+     * @var int
      */
     public $time;
 
     /**
-     * __construct 
-     * 
-     * @param int|DateTime $time 
-     * @return void
+     * __construct
+     *
+     * @param int|DateTime $time
      */
     public function __construct($time) {
 
@@ -46,9 +45,10 @@ class Sabre_DAV_Property_GetLastModified extends Sabre_DAV_Property {
     }
 
     /**
-     * serialize 
-     * 
-     * @param DOMElement $prop 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement       $prop
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
@@ -56,14 +56,14 @@ class Sabre_DAV_Property_GetLastModified extends Sabre_DAV_Property {
         $doc = $prop->ownerDocument;
         $prop->setAttribute('xmlns:b','urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/');
         $prop->setAttribute('b:dt','dateTime.rfc1123');
-        $prop->nodeValue = $this->time->format(DateTime::RFC1123);
+        $prop->nodeValue = Sabre_HTTP_Util::toHTTPDate($this->time);
 
     }
 
     /**
-     * getTime 
-     * 
-     * @return DateTime 
+     * getTime
+     *
+     * @return DateTime
      */
     public function getTime() {
 
diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php
old mode 100644
new mode 100755
index 3294ff2ac6848fcf0564af191c10c2a7e9cd010b..dac564f24d70745d18f88970fc494267bb9081c7
--- a/3rdparty/Sabre/DAV/Property/Href.php
+++ b/3rdparty/Sabre/DAV/Property/Href.php
@@ -3,36 +3,36 @@
 /**
  * Href property
  *
- * The href property represpents a url within a {DAV:}href element.
+ * The href property represents a url within a {DAV:}href element.
  * This is used by many WebDAV extensions, but not really within the WebDAV core spec
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
 
     /**
-     * href 
-     * 
-     * @var string 
+     * href
+     *
+     * @var string
      */
     private $href;
 
     /**
-     * Automatically prefix the url with the server base directory 
-     * 
-     * @var bool 
+     * Automatically prefix the url with the server base directory
+     *
+     * @var bool
      */
     private $autoPrefix = true;
 
     /**
-     * __construct 
-     * 
-     * @param string $href 
-     * @return void
+     * __construct
+     *
+     * @param string $href
+     * @param bool $autoPrefix
      */
     public function __construct($href, $autoPrefix = true) {
 
@@ -42,9 +42,9 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
     }
 
     /**
-     * Returns the uri 
-     * 
-     * @return string 
+     * Returns the uri
+     *
+     * @return string
      */
     public function getHref() {
 
@@ -56,12 +56,12 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
      * Serializes this property.
      *
      * It will additionally prepend the href property with the server's base uri.
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $dom 
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $dom
      * @return void
      */
-    public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
+    public function serialize(Sabre_DAV_Server $server, DOMElement $dom) {
 
         $prefix = $server->xmlNamespaces['DAV:'];
 
@@ -72,13 +72,13 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
     }
 
     /**
-     * Unserializes this property from a DOM Element 
+     * Unserializes this property from a DOM Element
      *
      * This method returns an instance of this class.
      * It will only decode {DAV:}href values. For non-compatible elements null will be returned.
      *
-     * @param DOMElement $dom 
-     * @return Sabre_DAV_Property_Href 
+     * @param DOMElement $dom
+     * @return Sabre_DAV_Property_Href
      */
     static function unserialize(DOMElement $dom) {
 
@@ -86,6 +86,6 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
             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 100644
new mode 100755
index 76a5512901c6ded74e7ccfc33d2f1460dfcae8d3..7a52272e8859fe9c6e17fb71a590c4678d6a4525
--- a/3rdparty/Sabre/DAV/Property/HrefList.php
+++ b/3rdparty/Sabre/DAV/Property/HrefList.php
@@ -3,35 +3,35 @@
 /**
  * HrefList property
  *
- * This property contains multiple {DAV:}href elements, each containing a url. 
- * 
+ * This property contains multiple {DAV:}href elements, each containing a url.
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_HrefList extends Sabre_DAV_Property {
 
     /**
-     * hrefs 
-     * 
-     * @var array 
+     * hrefs
+     *
+     * @var array
      */
     private $hrefs;
 
     /**
-     * Automatically prefix the url with the server base directory 
-     * 
-     * @var bool 
+     * Automatically prefix the url with the server base directory
+     *
+     * @var bool
      */
     private $autoPrefix = true;
 
     /**
-     * __construct 
-     * 
+     * __construct
+     *
      * @param array $hrefs
-     * @param bool $autoPrefix 
+     * @param bool $autoPrefix
      */
     public function __construct(array $hrefs, $autoPrefix = true) {
 
@@ -41,9 +41,9 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
     }
 
     /**
-     * Returns the uris 
-     * 
-     * @return array 
+     * Returns the uris
+     *
+     * @return array
      */
     public function getHrefs() {
 
@@ -55,9 +55,9 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
      * Serializes this property.
      *
      * It will additionally prepend the href property with the server's base uri.
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $dom 
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $dom
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
@@ -73,13 +73,13 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
     }
 
     /**
-     * Unserializes this property from a DOM Element 
+     * Unserializes this property from a DOM Element
      *
      * This method returns an instance of this class.
      * It will only decode {DAV:}href values.
      *
-     * @param DOMElement $dom 
-     * @return Sabre_DAV_Property_Href 
+     * @param DOMElement $dom
+     * @return Sabre_DAV_Property_Href
      */
     static function unserialize(DOMElement $dom) {
 
@@ -91,6 +91,6 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
         }
         return new self($hrefs, false);
 
-    } 
+    }
 
 }
diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php
old mode 100644
new mode 100755
index 29d76a44fcd3fb5cbcc143c829c72b07eeb53b3a..5c0409064cb3d69ecc3812a14f5cf3a5454ed34d
--- a/3rdparty/Sabre/DAV/Property/IHref.php
+++ b/3rdparty/Sabre/DAV/Property/IHref.php
@@ -9,16 +9,16 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_IHref {
 
     /**
-     * getHref 
-     * 
-     * @return string 
+     * getHref
+     *
+     * @return string
      */
     function getHref();
 
diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
old mode 100644
new mode 100755
index 05c7470b4ed86f61448c47f6f11f6f76b74190e7..2ded5649a44951477f0517eade2510c9f78dd992
--- a/3rdparty/Sabre/DAV/Property/LockDiscovery.php
+++ b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
@@ -4,26 +4,26 @@
  * Represents {DAV:}lockdiscovery property
  *
  * This property contains all the open locks on a given resource
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_LockDiscovery extends Sabre_DAV_Property {
 
     /**
-     * locks 
-     * 
-     * @var array 
+     * locks
+     *
+     * @var array
      */
     public $locks;
- 
+
     /**
-     * Should we show the locktoken as well? 
-     * 
-     * @var bool 
+     * Should we show the locktoken as well?
+     *
+     * @var bool
      */
     public $revealLockToken;
 
@@ -36,13 +36,12 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
     static public $hideLockRoot = false;
 
     /**
-     * __construct 
-     * 
-     * @param array $locks 
-     * @param bool $revealLockToken 
-     * @return void
+     * __construct
+     *
+     * @param array $locks
+     * @param bool $revealLockToken
      */
-    public function __construct($locks,$revealLockToken = false) {
+    public function __construct($locks, $revealLockToken = false) {
 
         $this->locks = $locks;
         $this->revealLockToken = $revealLockToken;
@@ -50,12 +49,13 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
     }
 
     /**
-     * serialize 
-     * 
-     * @param DOMElement $prop 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement       $prop
      * @return void
      */
-    public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+    public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
 
         $doc = $prop->ownerDocument;
 
@@ -74,7 +74,7 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
 
             $lockType->appendChild($doc->createElementNS('DAV:','d:write'));
 
-            /* {DAV:}lockroot */ 
+            /* {DAV:}lockroot */
             if (!self::$hideLockRoot) {
                 $lockRoot = $doc->createElementNS('DAV:','d:lockroot');
                 $activeLock->appendChild($lockRoot);
@@ -91,7 +91,7 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
                 $activeLock->appendChild($lockToken);
                 $lockToken->appendChild($doc->createElementNS('DAV:','d:href','opaquelocktoken:' . $lock->token));
             }
-           
+
             $activeLock->appendChild($doc->createElementNS('DAV:','d:owner',$lock->owner));
 
         }
diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php
old mode 100644
new mode 100755
index 2c606c22d60de7c84e4711a3e8c00f8355436ab4..f6269611e54d1b2ecc4134f2104e74cb2f6a9997
--- a/3rdparty/Sabre/DAV/Property/ResourceType.php
+++ b/3rdparty/Sabre/DAV/Property/ResourceType.php
@@ -4,28 +4,27 @@
  * This class represents the {DAV:}resourcetype property
  *
  * Normally for files this is empty, and for collection {DAV:}collection.
- * However, other specs define different values for this. 
- * 
+ * However, other specs define different values for this.
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Property_ResourceType extends Sabre_DAV_Property {
 
     /**
-     * resourceType 
-     * 
+     * resourceType
+     *
      * @var array
      */
     public $resourceType = array();
 
     /**
-     * __construct 
-     * 
-     * @param mixed $resourceType 
-     * @return void
+     * __construct
+     *
+     * @param mixed $resourceType
      */
     public function __construct($resourceType = array()) {
 
@@ -33,7 +32,7 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
             $this->resourceType = array();
         elseif ($resourceType === Sabre_DAV_Server::NODE_DIRECTORY)
             $this->resourceType = array('{DAV:}collection');
-        elseif (is_array($resourceType)) 
+        elseif (is_array($resourceType))
             $this->resourceType = $resourceType;
         else
             $this->resourceType = array($resourceType);
@@ -41,25 +40,26 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
     }
 
     /**
-     * serialize 
-     * 
-     * @param DOMElement $prop 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $prop
      * @return void
      */
-    public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+    public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
 
         $propName = null;
         $rt = $this->resourceType;
-        
+
         foreach($rt as $resourceType) {
-            if (preg_match('/^{([^}]*)}(.*)$/',$resourceType,$propName)) { 
-       
+            if (preg_match('/^{([^}]*)}(.*)$/',$resourceType,$propName)) {
+
                 if (isset($server->xmlNamespaces[$propName[1]])) {
                     $prop->appendChild($prop->ownerDocument->createElement($server->xmlNamespaces[$propName[1]] . ':' . $propName[2]));
                 } else {
                     $prop->appendChild($prop->ownerDocument->createElementNS($propName[1],'custom:' . $propName[2]));
                 }
-            
+
             }
         }
 
@@ -69,8 +69,8 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
      * Returns the values in clark-notation
      *
      * For example array('{DAV:}collection')
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getValue() {
 
@@ -79,10 +79,10 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
     }
 
     /**
-     * Checks if the principal contains a certain value 
-     * 
-     * @param string $type 
-     * @return bool 
+     * Checks if the principal contains a certain value
+     *
+     * @param string $type
+     * @return bool
      */
     public function is($type) {
 
@@ -104,10 +104,10 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
     }
 
     /**
-     * Unserializes a DOM element into a ResourceType property. 
-     * 
-     * @param DOMElement $dom 
-     * @return void
+     * Unserializes a DOM element into a ResourceType property.
+     *
+     * @param DOMElement $dom
+     * @return Sabre_DAV_Property_ResourceType
      */
     static public function unserialize(DOMElement $dom) {
 
diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php
old mode 100644
new mode 100755
index 7d3a2db0387d190966a801d0488a69f3e610be5e..88afbcfb26d4e6d8b96f27e6b6e6d2978e81ed3d
--- a/3rdparty/Sabre/DAV/Property/Response.php
+++ b/3rdparty/Sabre/DAV/Property/Response.php
@@ -1,53 +1,52 @@
 <?php
 
 /**
- * Response property 
- * 
+ * Response property
+ *
  * This class represents the {DAV:}response XML element.
- * This is used by the Server class to encode individual items within a multistatus 
+ * This is used by the Server class to encode individual items within a multistatus
  * response.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_Response extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
 
     /**
-     * Url for the response 
-     * 
-     * @var string 
+     * Url for the response
+     *
+     * @var string
      */
     private $href;
 
     /**
-     * Propertylist, ordered by HTTP status code 
-     * 
-     * @var array 
+     * Propertylist, ordered by HTTP status code
+     *
+     * @var array
      */
     private $responseProperties;
 
     /**
      * The responseProperties argument is a list of properties
      * within an array with keys representing HTTP status codes
-     * 
-     * @param string $href 
-     * @param array $responseProperties 
-     * @return void
+     *
+     * @param string $href
+     * @param array $responseProperties
      */
-    public function __construct($href,array $responseProperties) {
+    public function __construct($href, array $responseProperties) {
 
         $this->href = $href;
-        $this->responseProperties = $responseProperties; 
+        $this->responseProperties = $responseProperties;
 
     }
 
     /**
-     * Returns the url 
-     * 
-     * @return string 
+     * Returns the url
+     *
+     * @return string
      */
     public function getHref() {
 
@@ -56,9 +55,9 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
     }
 
     /**
-     * Returns the property list 
-     * 
-     * @return array 
+     * Returns the property list
+     *
+     * @return array
      */
     public function getResponseProperties() {
 
@@ -67,19 +66,19 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
     }
 
     /**
-     * serialize 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $dom 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $dom
      * @return void
      */
-    public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
+    public function serialize(Sabre_DAV_Server $server, DOMElement $dom) {
 
         $document = $dom->ownerDocument;
         $properties = $this->responseProperties;
-        
+
         $xresponse = $document->createElement('d:response');
-        $dom->appendChild($xresponse); 
+        $dom->appendChild($xresponse);
 
         $uri = Sabre_DAV_URLUtil::encodePath($this->href);
 
@@ -87,7 +86,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
         $uri = $server->getBaseUri() . $uri;
 
         $xresponse->appendChild($document->createElement('d:href',$uri));
-       
+
         // The properties variable is an array containing properties, grouped by
         // HTTP status
         foreach($properties as $httpStatus=>$propertyGroup) {
@@ -111,7 +110,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
 
                 $propName = null;
                 preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
-            
+
                 // special case for empty namespaces
                 if ($propName[1]=='') {
 
@@ -125,7 +124,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
                         $nsList[$propName[1]] = 'x' . count($nsList);
                     }
 
-                    // If the namespace was defined in the top-level xml namespaces, it means 
+                    // If the namespace was defined in the top-level xml namespaces, it means
                     // there was already a namespace declaration, and we don't have to worry about it.
                     if (isset($server->xmlNamespaces[$propName[1]])) {
                         $currentProperty = $document->createElement($nsList[$propName[1]] . ':' . $propName[2]);
diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php
old mode 100644
new mode 100755
index cd70b12861d05130f1cf0f399bdf74b2be710109..cae923afbf9d542110623023d9e87ddd98be9452
--- a/3rdparty/Sabre/DAV/Property/ResponseList.php
+++ b/3rdparty/Sabre/DAV/Property/ResponseList.php
@@ -1,33 +1,32 @@
 <?php
 
 /**
- * ResponseList property 
- * 
+ * ResponseList property
+ *
  * This class represents multiple {DAV:}response XML elements.
- * This is used by the Server class to encode items within a multistatus 
+ * This is used by the Server class to encode items within a multistatus
  * response.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_ResponseList extends Sabre_DAV_Property {
 
     /**
-     * Response objects. 
-     * 
-     * @var array 
+     * Response objects.
+     *
+     * @var array
      */
     private $responses;
 
     /**
-     * The only valid argument is a list of Sabre_DAV_Property_Response 
+     * The only valid argument is a list of Sabre_DAV_Property_Response
      * objects.
-     * 
-     * @param array $responses; 
-     * @return void
+     *
+     * @param array $responses;
      */
     public function __construct($responses) {
 
@@ -41,10 +40,10 @@ class Sabre_DAV_Property_ResponseList extends Sabre_DAV_Property {
     }
 
     /**
-     * serialize 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $dom 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $dom
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php
old mode 100644
new mode 100755
index 01e63f58d9d5136a4f4b9aa5734d8acfdfd4b231..4e3aaf23a1a6229fbc24224509238ff320534e6d
--- a/3rdparty/Sabre/DAV/Property/SupportedLock.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedLock.php
@@ -5,27 +5,26 @@
  *
  * This property contains information about what kind of locks
  * this server supports.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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_Property_SupportedLock extends Sabre_DAV_Property {
 
     /**
-     * supportsLocks 
-     * 
+     * supportsLocks
+     *
      * @var mixed
      */
     public $supportsLocks = false;
 
     /**
-     * __construct 
-     * 
-     * @param mixed $supportsLocks 
-     * @return void
+     * __construct
+     *
+     * @param mixed $supportsLocks
      */
     public function __construct($supportsLocks) {
 
@@ -34,9 +33,10 @@ class Sabre_DAV_Property_SupportedLock extends Sabre_DAV_Property {
     }
 
     /**
-     * serialize 
-     * 
-     * @param DOMElement $prop 
+     * serialize
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement       $prop
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
old mode 100644
new mode 100755
index acd9219c0f70656392622d700aebcba38f81e52c..e62699f3b5a7fc3f1fbe16b5d0cd8d8f3178546d
--- a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
@@ -5,18 +5,18 @@
  *
  * This property is defined in RFC3253, but since it's
  * so common in other webdav-related specs, it is part of the core server.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Property_SupportedReportSet extends Sabre_DAV_Property {
 
     /**
-     * List of reports 
-     * 
+     * List of reports
+     *
      * @var array
      */
     protected $reports = array();
@@ -28,13 +28,12 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
      * should be valid report-types in clark-notation.
      *
      * Either a string or an array of strings must be passed.
-     * 
-     * @param mixed $reports 
-     * @return void
+     *
+     * @param mixed $reports
      */
     public function __construct($reports = null) {
 
-        if (!is_null($reports)) 
+        if (!is_null($reports))
             $this->addReport($reports);
 
     }
@@ -44,8 +43,8 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
      *
      * The report must be a string in clark-notation.
      * Multiple reports can be specified as an array.
-     * 
-     * @param mixed $report 
+     *
+     * @param mixed $report
      * @return void
      */
     public function addReport($report) {
@@ -54,7 +53,7 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
 
         foreach($report as $r) {
 
-            if (!preg_match('/^{([^}]*)}(.*)$/',$r)) 
+            if (!preg_match('/^{([^}]*)}(.*)$/',$r))
                 throw new Sabre_DAV_Exception('Reportname must be in clark-notation');
 
             $this->reports[] = $r;
@@ -65,8 +64,8 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
 
     /**
      * Returns the list of supported reports
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getValue() {
 
@@ -75,16 +74,16 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes the node 
+     * Serializes the node
      *
      * @param Sabre_DAV_Server $server
-     * @param DOMElement $prop 
+     * @param DOMElement $prop
      * @return void
      */
-    public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+    public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
 
         foreach($this->reports as $reportName) {
-     
+
             $supportedReport = $prop->ownerDocument->createElement('d:supported-report');
             $prop->appendChild($supportedReport);
 
@@ -92,9 +91,9 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
             $supportedReport->appendChild($report);
 
             preg_match('/^{([^}]*)}(.*)$/',$reportName,$matches);
-            
+
             list(, $namespace, $element) = $matches;
-       
+
             $prefix = isset($server->xmlNamespaces[$namespace])?$server->xmlNamespaces[$namespace]:null;
 
             if ($prefix) {
diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php
old mode 100644
new mode 100755
index 3d76d4f1918e9cabff7576e6d94805d4cdd02d5d..4284c127b6e120ac33b110e5df019e0502d6d797
--- a/3rdparty/Sabre/DAV/Server.php
+++ b/3rdparty/Sabre/DAV/Server.php
@@ -2,11 +2,11 @@
 
 /**
  * Main DAV server class
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Server {
@@ -26,9 +26,6 @@ class Sabre_DAV_Server {
      */
     const NODE_DIRECTORY = 2;
 
-    const PROP_SET = 1;
-    const PROP_REMOVE = 2;
-
     /**
      * XML namespace for all SabreDAV related elements
      */
@@ -36,42 +33,42 @@ class Sabre_DAV_Server {
 
     /**
      * The tree object
-     * 
-     * @var Sabre_DAV_Tree 
+     *
+     * @var Sabre_DAV_Tree
      */
     public $tree;
 
     /**
-     * The base uri 
-     * 
-     * @var string 
+     * The base uri
+     *
+     * @var string
      */
-    protected $baseUri = null; 
+    protected $baseUri = null;
 
     /**
-     * httpResponse 
-     * 
-     * @var Sabre_HTTP_Response 
+     * httpResponse
+     *
+     * @var Sabre_HTTP_Response
      */
     public $httpResponse;
 
     /**
      * httpRequest
-     * 
-     * @var Sabre_HTTP_Request 
+     *
+     * @var Sabre_HTTP_Request
      */
     public $httpRequest;
 
     /**
-     * The list of plugins 
-     * 
-     * @var array 
+     * The list of plugins
+     *
+     * @var array
      */
     protected $plugins = array();
 
     /**
-     * This array contains a list of callbacks we should call when certain events are triggered 
-     * 
+     * This array contains a list of callbacks we should call when certain events are triggered
+     *
      * @var array
      */
     protected $eventSubscriptions = array();
@@ -81,7 +78,7 @@ class Sabre_DAV_Server {
      *
      * If you are defining your own custom namespace, add it here to reduce
      * bandwidth and improve legibility of xml bodies.
-     * 
+     *
      * @var array
      */
     public $xmlNamespaces = array(
@@ -90,9 +87,9 @@ class Sabre_DAV_Server {
     );
 
     /**
-     * The propertymap can be used to map properties from 
+     * The propertymap can be used to map properties from
      * requests to property classes.
-     * 
+     *
      * @var array
      */
     public $propertyMap = array(
@@ -125,23 +122,32 @@ class Sabre_DAV_Server {
      * This is a flag that allow or not showing file, line and code
      * of the exception in the returned XML
      *
-     * @var bool 
+     * @var bool
      */
     public $debugExceptions = false;
 
     /**
-     * This property allows you to automatically add the 'resourcetype' value 
+     * This property allows you to automatically add the 'resourcetype' value
      * based on a node's classname or interface.
      *
-     * The preset ensures that {DAV:}collection is automaticlly added for nodes 
+     * The preset ensures that {DAV:}collection is automaticlly added for nodes
      * implementing Sabre_DAV_ICollection.
-     * 
+     *
      * @var array
      */
     public $resourceTypeMapping = array(
         'Sabre_DAV_ICollection' => '{DAV:}collection',
     );
 
+    /**
+     * If this setting is turned off, SabreDAV's version number will be hidden
+     * from various places.
+     *
+     * Some people feel this is a good security measure.
+     *
+     * @var bool
+     */
+    static public $exposeVersion = true;
 
     /**
      * Sets up the server
@@ -150,14 +156,13 @@ class Sabre_DAV_Server {
      * use it as the directory tree. If a Sabre_DAV_INode is passed, it
      * will create a Sabre_DAV_ObjectTree and use the node as the root.
      *
-     * If nothing is passed, a Sabre_DAV_SimpleCollection is created in 
+     * If nothing is passed, a Sabre_DAV_SimpleCollection is created in
      * a Sabre_DAV_ObjectTree.
      *
      * 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 $tree The tree object 
-     * @return void
+     * the nodes in the array as top-level children.
+     *
+     * @param Sabre_DAV_Tree|Sabre_DAV_INode|null $treeOrNode The tree object
      */
     public function __construct($treeOrNode = null) {
 
@@ -190,7 +195,7 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * Starts the DAV Server 
+     * Starts the DAV Server
      *
      * @return void
      */
@@ -218,7 +223,9 @@ class Sabre_DAV_Server {
                 $error->appendChild($DOM->createElement('s:stacktrace',$e->getTraceAsString()));
 
             }
-            $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION));
+            if (self::$exposeVersion) {
+                $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION));
+            }
 
             if($e instanceof Sabre_DAV_Exception) {
 
@@ -233,7 +240,7 @@ class Sabre_DAV_Server {
 
             }
             $headers['Content-Type'] = 'application/xml; charset=utf-8';
-            
+
             $this->httpResponse->sendStatus($httpCode);
             $this->httpResponse->setHeaders($headers);
             $this->httpResponse->sendBody($DOM->saveXML());
@@ -244,24 +251,24 @@ class Sabre_DAV_Server {
 
     /**
      * Sets the base server uri
-     * 
+     *
      * @param string $uri
      * @return void
      */
     public function setBaseUri($uri) {
 
         // If the baseUri does not end with a slash, we must add it
-        if ($uri[strlen($uri)-1]!=='/') 
+        if ($uri[strlen($uri)-1]!=='/')
             $uri.='/';
 
-        $this->baseUri = $uri;    
+        $this->baseUri = $uri;
 
     }
 
     /**
      * Returns the base responding uri
-     * 
-     * @return string 
+     *
+     * @return string
      */
     public function getBaseUri() {
 
@@ -272,11 +279,11 @@ class Sabre_DAV_Server {
 
     /**
      * This method attempts to detect the base uri.
-     * Only the PATH_INFO variable is considered. 
-     * 
-     * If this variable is not set, the root (/) is assumed. 
+     * Only the PATH_INFO variable is considered.
      *
-     * @return void
+     * If this variable is not set, the root (/) is assumed.
+     *
+     * @return string
      */
     public function guessBaseUri() {
 
@@ -303,21 +310,21 @@ class Sabre_DAV_Server {
                 return rtrim($baseUri,'/') . '/';
             }
 
-            throw new Sabre_DAV_Exception('The REQUEST_URI ('. $uri . ') did not end with the contents of PATH_INFO (' . $pathInfo . '). This server might be misconfigured.'); 
+            throw new Sabre_DAV_Exception('The REQUEST_URI ('. $uri . ') did not end with the contents of PATH_INFO (' . $pathInfo . '). This server might be misconfigured.');
 
-        } 
+        }
 
-        // The last fallback is that we're just going to assume the server root. 
+        // The last fallback is that we're just going to assume the server root.
         return '/';
 
     }
 
     /**
      * Adds a plugin to the server
-     * 
+     *
      * For more information, console the documentation of Sabre_DAV_ServerPlugin
      *
-     * @param Sabre_DAV_ServerPlugin $plugin 
+     * @param Sabre_DAV_ServerPlugin $plugin
      * @return void
      */
     public function addPlugin(Sabre_DAV_ServerPlugin $plugin) {
@@ -333,11 +340,11 @@ class Sabre_DAV_Server {
      * This function returns null if the plugin was not found.
      *
      * @param string $name
-     * @return Sabre_DAV_ServerPlugin 
+     * @return Sabre_DAV_ServerPlugin
      */
     public function getPlugin($name) {
 
-        if (isset($this->plugins[$name])) 
+        if (isset($this->plugins[$name]))
             return $this->plugins[$name];
 
         // This is a fallback and deprecated.
@@ -350,9 +357,9 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * Returns all plugins 
-     * 
-     * @return array 
+     * Returns all plugins
+     *
+     * @return array
      */
     public function getPlugins() {
 
@@ -361,7 +368,6 @@ class Sabre_DAV_Server {
     }
 
 
-
     /**
      * Subscribe to an event.
      *
@@ -371,9 +377,9 @@ class Sabre_DAV_Server {
      *
      * This is for example used to make sure that the authentication plugin
      * is triggered before anything else. If it's not needed to change this
-     * number, it is recommended to ommit.  
-     * 
-     * @param string $event 
+     * number, it is recommended to ommit.
+     *
+     * @param string $event
      * @param callback $callback
      * @param int $priority
      * @return void
@@ -398,7 +404,7 @@ class Sabre_DAV_Server {
      *
      * @param string $eventName
      * @param array $arguments
-     * @return bool 
+     * @return bool
      */
     public function broadcastEvent($eventName,$arguments = array()) {
 
@@ -418,7 +424,7 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * Handles a http request, and execute a method based on its name 
+     * Handles a http request, and execute a method based on its name
      *
      * @param string $method
      * @param string $uri
@@ -426,7 +432,7 @@ class Sabre_DAV_Server {
      */
     public function invokeMethod($method, $uri) {
 
-        $method = strtoupper($method); 
+        $method = strtoupper($method);
 
         if (!$this->broadcastEvent('beforeMethod',array($method, $uri))) return;
 
@@ -453,7 +459,7 @@ class Sabre_DAV_Server {
 
             if ($this->broadcastEvent('unknownMethod',array($method, $uri))) {
                 // Unsupported method
-                throw new Sabre_DAV_Exception_NotImplemented();
+                throw new Sabre_DAV_Exception_NotImplemented('There was no handler found for this "' . $method . '" method');
             }
 
         }
@@ -461,9 +467,9 @@ class Sabre_DAV_Server {
     }
 
     // {{{ HTTP Method implementations
-    
+
     /**
-     * HTTP OPTIONS 
+     * HTTP OPTIONS
      *
      * @param string $uri
      * @return void
@@ -476,11 +482,13 @@ class Sabre_DAV_Server {
         $features = array('1','3', 'extended-mkcol');
 
         foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures());
-        
+
         $this->httpResponse->setHeader('DAV',implode(', ',$features));
         $this->httpResponse->setHeader('MS-Author-Via','DAV');
         $this->httpResponse->setHeader('Accept-Ranges','bytes');
-        $this->httpResponse->setHeader('X-Sabre-Version',Sabre_DAV_Version::VERSION);
+        if (self::$exposeVersion) {
+            $this->httpResponse->setHeader('X-Sabre-Version',Sabre_DAV_Version::VERSION);
+        }
         $this->httpResponse->setHeader('Content-Length',0);
         $this->httpResponse->sendStatus(200);
 
@@ -492,13 +500,13 @@ class Sabre_DAV_Server {
      * This method simply fetches the contents of a uri, like normal
      *
      * @param string $uri
-     * @return void
+     * @return bool
      */
     protected function httpGet($uri) {
 
         $node = $this->tree->getNodeForPath($uri,0);
 
-        if (!$this->checkPreconditions(true)) return false; 
+        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');
         $body = $node->get();
@@ -535,7 +543,7 @@ class Sabre_DAV_Server {
         } else {
             $nodeSize = null;
         }
-        
+
         $this->httpResponse->setHeaders($httpHeaders);
 
         $range = $this->getHTTPRange();
@@ -545,12 +553,12 @@ class Sabre_DAV_Server {
         // If ifRange is set, and range is specified, we first need to check
         // the precondition.
         if ($nodeSize && $range && $ifRange) {
-             
+
             // if IfRange is parsable as a date we'll treat it as a DateTime
             // otherwise, we must treat it as an etag.
             try {
                 $ifRangeDate = new DateTime($ifRange);
-               
+
                 // It's a date. We must check if the entity is modified since
                 // the specified date.
                 if (!isset($httpHeaders['Last-Modified'])) $ignoreRangeHeader = true;
@@ -560,8 +568,8 @@ class Sabre_DAV_Server {
                 }
 
             } catch (Exception $e) {
-               
-                // It's an entity. We can do a simple comparison. 
+
+                // It's an entity. We can do a simple comparison.
                 if (!isset($httpHeaders['ETag'])) $ignoreRangeHeader = true;
                 elseif ($httpHeaders['ETag']!==$ifRange) $ignoreRangeHeader = true;
             }
@@ -575,7 +583,7 @@ class Sabre_DAV_Server {
 
                 $start = $range[0];
                 $end = $range[1]?$range[1]:$nodeSize-1;
-                if($start >= $nodeSize) 
+                if($start >= $nodeSize)
                     throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The start offset (' . $range[0] . ') exceeded the size of the entity (' . $nodeSize . ')');
 
                 if($end < $start) throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')');
@@ -625,7 +633,7 @@ class Sabre_DAV_Server {
 
         $node = $this->tree->getNodeForPath($uri);
         /* This information is only collection for File objects.
-         * Ideally we want to throw 405 Method Not Allowed for every 
+         * Ideally we want to throw 405 Method Not Allowed for every
          * non-file, but MS Office does not like this
          */
         if ($node instanceof Sabre_DAV_IFile) {
@@ -640,7 +648,7 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * HTTP Delete 
+     * HTTP Delete
      *
      * The HTTP delete method, deletes a given uri
      *
@@ -651,6 +659,7 @@ class Sabre_DAV_Server {
 
         if (!$this->broadcastEvent('beforeUnbind',array($uri))) return;
         $this->tree->delete($uri);
+        $this->broadcastEvent('afterUnbind',array($uri));
 
         $this->httpResponse->sendStatus(204);
         $this->httpResponse->setHeader('Content-Length','0');
@@ -659,13 +668,13 @@ class Sabre_DAV_Server {
 
 
     /**
-     * WebDAV PROPFIND 
+     * WebDAV PROPFIND
      *
      * This WebDAV method requests information about an uri resource, or a list of resources
      * If a client wants to receive the properties for a single resource it will add an HTTP Depth: header with a 0 value
      * If the value is 1, it means that it also expects a list of sub-resources (e.g.: files in a directory)
      *
-     * The request body contains an XML data structure that has a list of properties the client understands 
+     * The request body contains an XML data structure that has a list of properties the client understands
      * The response body is also an xml document, containing information about every uri resource and the requested properties
      *
      * It has to return a HTTP 207 Multi-status status code
@@ -679,7 +688,7 @@ class Sabre_DAV_Server {
         $requestedProperties = $this->parsePropfindRequest($this->httpRequest->getBody(true));
 
         $depth = $this->getHTTPDepth(1);
-        // The only two options for the depth of a propfind is 0 or 1 
+        // The only two options for the depth of a propfind is 0 or 1
         if ($depth!=0) $depth = 1;
 
         $newProperties = $this->getPropertiesForPath($uri,$requestedProperties,$depth);
@@ -688,8 +697,8 @@ class Sabre_DAV_Server {
         $this->httpResponse->sendStatus(207);
         $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
 
-        // Normally this header is only needed for OPTIONS responses, however.. 
-        // iCal seems to also depend on these being set for PROPFIND. Since 
+        // Normally this header is only needed for OPTIONS responses, however..
+        // iCal seems to also depend on these being set for PROPFIND. Since
         // this is not harmful, we'll add it.
         $features = array('1','3', 'extended-mkcol');
         foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures());
@@ -712,7 +721,7 @@ class Sabre_DAV_Server {
     protected function httpPropPatch($uri) {
 
         $newProperties = $this->parsePropPatchRequest($this->httpRequest->getBody(true));
-        
+
         $result = $this->updateProperties($uri, $newProperties);
 
         $this->httpResponse->sendStatus(207);
@@ -725,14 +734,14 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * HTTP PUT method 
-     * 
+     * HTTP PUT method
+     *
      * This HTTP method updates a file, or creates a new one.
      *
-     * If a new resource was created, a 201 Created status code should be returned. If an existing resource is updated, it's a 200 Ok
+     * If a new resource was created, a 201 Created status code should be returned. If an existing resource is updated, it's a 204 No Content
      *
      * @param string $uri
-     * @return void
+     * @return bool
      */
     protected function httpPut($uri) {
 
@@ -768,13 +777,13 @@ class Sabre_DAV_Server {
 
         // Intercepting the Finder problem
         if (($expected = $this->httpRequest->getHeader('X-Expected-Entity-Length')) && $expected > 0) {
-           
+
             /**
-            Many webservers will not cooperate well with Finder PUT requests, 
+            Many webservers will not cooperate well with Finder PUT requests,
             because it uses 'Chunked' transfer encoding for the request body.
 
-            The symptom of this problem is that Finder sends files to the 
-            server, but they arrive as 0-lenght files in PHP.
+            The symptom of this problem is that Finder sends files to the
+            server, but they arrive as 0-length files in PHP.
 
             If we don't do anything, the user might think they are uploading
             files successfully, but they end up empty on the server. Instead,
@@ -808,29 +817,36 @@ class Sabre_DAV_Server {
 
         }
 
-        if ($this->tree->nodeExists($uri)) { 
+        if ($this->tree->nodeExists($uri)) {
 
             $node = $this->tree->getNodeForPath($uri);
-          
+
             // Checking If-None-Match and related headers.
             if (!$this->checkPreconditions()) return;
-            
+
             // If the node is a collection, we'll deny it
             if (!($node instanceof Sabre_DAV_IFile)) throw new Sabre_DAV_Exception_Conflict('PUT is not allowed on non-files.');
-            if (!$this->broadcastEvent('beforeWriteContent',array($this->getRequestUri()))) return false;
+            if (!$this->broadcastEvent('beforeWriteContent',array($uri, $node, &$body))) return false;
+
+            $etag = $node->put($body);
+
+            $this->broadcastEvent('afterWriteContent',array($uri, $node));
 
-            $node->put($body);
             $this->httpResponse->setHeader('Content-Length','0');
+            if ($etag) $this->httpResponse->setHeader('ETag',$etag);
             $this->httpResponse->sendStatus(204);
 
         } else {
 
+            $etag = null;
             // If we got here, the resource didn't exist yet.
-            if (!$this->createFile($this->getRequestUri(),$body)) {
+            if (!$this->createFile($this->getRequestUri(),$body,$etag)) {
                 // For one reason or another the file was not created.
                 return;
             }
+
             $this->httpResponse->setHeader('Content-Length','0');
+            if ($etag) $this->httpResponse->setHeader('ETag', $etag);
             $this->httpResponse->sendStatus(201);
 
         }
@@ -855,7 +871,7 @@ class Sabre_DAV_Server {
             $contentType = $this->httpRequest->getHeader('Content-Type');
             if (strpos($contentType,'application/xml')!==0 && strpos($contentType,'text/xml')!==0) {
 
-                // We must throw 415 for unsupport mkcol bodies
+                // We must throw 415 for unsupported mkcol bodies
                 throw new Sabre_DAV_Exception_UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type');
 
             }
@@ -863,7 +879,7 @@ class Sabre_DAV_Server {
             $dom = Sabre_DAV_XMLUtil::loadDOMDocument($requestBody);
             if (Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)!=='{DAV:}mkcol') {
 
-                // We must throw 415 for unsupport mkcol bodies
+                // We must throw 415 for unsupported mkcol bodies
                 throw new Sabre_DAV_Exception_UnsupportedMediaType('The request body for the MKCOL request must be a {DAV:}mkcol request construct.');
 
             }
@@ -875,7 +891,7 @@ class Sabre_DAV_Server {
                 $properties = array_merge($properties, Sabre_DAV_XMLUtil::parseProperties($childNode, $this->propertyMap));
 
             }
-            if (!isset($properties['{DAV:}resourcetype'])) 
+            if (!isset($properties['{DAV:}resourcetype']))
                 throw new Sabre_DAV_Exception_BadRequest('The mkcol request must include a {DAV:}resourcetype property');
 
             $resourceType = $properties['{DAV:}resourcetype']->getValue();
@@ -918,19 +934,21 @@ class Sabre_DAV_Server {
         $moveInfo = $this->getCopyAndMoveInfo();
 
         // If the destination is part of the source tree, we must fail
-        if ($moveInfo['destination']==$uri) 
+        if ($moveInfo['destination']==$uri)
             throw new Sabre_DAV_Exception_Forbidden('Source and destination uri are identical.');
 
         if ($moveInfo['destinationExists']) {
 
             if (!$this->broadcastEvent('beforeUnbind',array($moveInfo['destination']))) return false;
             $this->tree->delete($moveInfo['destination']);
+            $this->broadcastEvent('afterUnbind',array($moveInfo['destination']));
 
         }
 
         if (!$this->broadcastEvent('beforeUnbind',array($uri))) return false;
         if (!$this->broadcastEvent('beforeBind',array($moveInfo['destination']))) return false;
         $this->tree->move($uri,$moveInfo['destination']);
+        $this->broadcastEvent('afterUnbind',array($uri));
         $this->broadcastEvent('afterBind',array($moveInfo['destination']));
 
         // If a resource was overwritten we should send a 204, otherwise a 201
@@ -946,13 +964,13 @@ class Sabre_DAV_Server {
      * A lot of the actual request processing is done in getCopyMoveInfo
      *
      * @param string $uri
-     * @return void
+     * @return bool
      */
     protected function httpCopy($uri) {
 
         $copyInfo = $this->getCopyAndMoveInfo();
         // If the destination is part of the source tree, we must fail
-        if ($copyInfo['destination']==$uri) 
+        if ($copyInfo['destination']==$uri)
             throw new Sabre_DAV_Exception_Forbidden('Source and destination uri are identical.');
 
         if ($copyInfo['destinationExists']) {
@@ -998,13 +1016,13 @@ class Sabre_DAV_Server {
     }
 
     // }}}
-    // {{{ HTTP/WebDAV protocol helpers 
+    // {{{ HTTP/WebDAV protocol helpers
 
     /**
-     * Returns an array with all the supported HTTP methods for a specific uri. 
+     * Returns an array with all the supported HTTP methods for a specific uri.
      *
-     * @param string $uri 
-     * @return array 
+     * @param string $uri
+     * @return array
      */
     public function getAllowedMethods($uri) {
 
@@ -1023,13 +1041,13 @@ class Sabre_DAV_Server {
 
         // The MKCOL is only allowed on an unmapped uri
         try {
-            $node = $this->tree->getNodeForPath($uri);
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+            $this->tree->getNodeForPath($uri);
+        } catch (Sabre_DAV_Exception_NotFound $e) {
             $methods[] = 'MKCOL';
         }
 
         // We're also checking if any of the plugins register any new methods
-        foreach($this->plugins as $plugin) $methods = array_merge($methods,$plugin->getHTTPMethods($uri));
+        foreach($this->plugins as $plugin) $methods = array_merge($methods, $plugin->getHTTPMethods($uri));
         array_unique($methods);
 
         return $methods;
@@ -1037,8 +1055,8 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * Gets the uri for the request, keeping the base uri into consideration 
-     * 
+     * Gets the uri for the request, keeping the base uri into consideration
+     *
      * @return string
      */
     public function getRequestUri() {
@@ -1048,9 +1066,9 @@ class Sabre_DAV_Server {
     }
 
     /**
-     * Calculates the uri for a request, making sure that the base uri is stripped out 
-     * 
-     * @param string $uri 
+     * Calculates the uri for a request, making sure that the base uri is stripped out
+     *
+     * @param string $uri
      * @throws Sabre_DAV_Exception_Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri
      * @return string
      */
@@ -1068,9 +1086,9 @@ class Sabre_DAV_Server {
 
             return trim(Sabre_DAV_URLUtil::decodePath(substr($uri,strlen($this->getBaseUri()))),'/');
 
-        // A special case, if the baseUri was accessed without a trailing 
-        // slash, we'll accept it as well. 
-        } elseif ($uri.'/' === $this->getBaseUri()) { 
+        // A special case, if the baseUri was accessed without a trailing
+        // slash, we'll accept it as well.
+        } elseif ($uri.'/' === $this->getBaseUri()) {
 
             return '';
 
@@ -1086,10 +1104,10 @@ class Sabre_DAV_Server {
      * Returns the HTTP depth header
      *
      * This method returns the contents of the HTTP depth request header. If the depth header was 'infinity' it will return the Sabre_DAV_Server::DEPTH_INFINITY object
-     * It is possible to supply a default depth value, which is used when the depth header has invalid content, or is completely non-existant
-     * 
-     * @param mixed $default 
-     * @return int 
+     * It is possible to supply a default depth value, which is used when the depth header has invalid content, or is completely non-existent
+     *
+     * @param mixed $default
+     * @return int
      */
     public function getHTTPDepth($default = self::DEPTH_INFINITY) {
 
@@ -1100,7 +1118,7 @@ class Sabre_DAV_Server {
 
         if ($depth == 'infinity') return self::DEPTH_INFINITY;
 
-           
+
         // If its an unknown value. we'll grab the default
         if (!ctype_digit($depth)) return $default;
 
@@ -1118,14 +1136,14 @@ class Sabre_DAV_Server {
      * 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 
+     * If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity
      *
-     * return $mixed
+     * @return array|null
      */
     public function getHTTPRange() {
 
         $range = $this->httpRequest->getHeader('range');
-        if (is_null($range)) return null; 
+        if (is_null($range)) return null;
 
         // Matching "Range: bytes=1234-5678: both numbers are optional
 
@@ -1143,15 +1161,15 @@ class Sabre_DAV_Server {
 
     /**
      * Returns information about Copy and Move requests
-     * 
-     * This function is created to help getting information about the source and the destination for the 
-     * WebDAV MOVE and COPY HTTP request. It also validates a lot of information and throws proper exceptions 
-     * 
+     *
+     * This function is created to help getting information about the source and the destination for the
+     * WebDAV MOVE and COPY HTTP request. It also validates a lot of information and throws proper exceptions
+     *
      * The returned value is an array with the following keys:
      *   * destination - Destination path
-     *   * destinationExists - Wether or not the destination is an existing url (and should therefore be overwritten)
+     *   * destinationExists - Whether or not the destination is an existing url (and should therefore be overwritten)
      *
-     * @return array 
+     * @return array
      */
     public function getCopyAndMoveInfo() {
 
@@ -1170,7 +1188,7 @@ class Sabre_DAV_Server {
         try {
             $destinationParent = $this->tree->getNodeForPath($destinationDir);
             if (!($destinationParent instanceof Sabre_DAV_ICollection)) throw new Sabre_DAV_Exception_UnsupportedMediaType('The destination node is not a collection');
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
 
             // If the destination parent node is not found, we throw a 409
             throw new Sabre_DAV_Exception_Conflict('The destination node is not found');
@@ -1179,12 +1197,12 @@ class Sabre_DAV_Server {
         try {
 
             $destinationNode = $this->tree->getNodeForPath($destination);
-            
+
             // If this succeeded, it means the destination already exists
             // we'll need to throw precondition failed in case overwrite is false
             if (!$overwrite) throw new Sabre_DAV_Exception_PreconditionFailed('The destination node already exists, and the overwrite header is set to false','Overwrite');
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
 
             // Destination didn't exist, we're all good
             $destinationNode = false;
@@ -1219,23 +1237,51 @@ class Sabre_DAV_Server {
 
     }
 
+    /**
+     * A kid-friendly way to fetch properties for a node's children.
+     *
+     * The returned array will be indexed by the path of the of child node.
+     * Only properties that are actually found will be returned.
+     *
+     * The parent node will not be returned.
+     *
+     * @param string $path
+     * @param array $propertyNames
+     * @return array
+     */
+    public function getPropertiesForChildren($path, $propertyNames) {
+
+        $result = array();
+        foreach($this->getPropertiesForPath($path,$propertyNames,1) as $k=>$row) {
+
+            // Skipping the parent path
+            if ($k === 0) continue;
+
+            $result[$row['href']] = $row[200];
+
+        }
+        return $result;
+
+    }
+
     /**
      * Returns a list of HTTP headers for a particular resource
      *
-     * The generated http headers are based on properties provided by the 
+     * The generated http headers are based on properties provided by the
      * resource. The method basically provides a simple mapping between
      * DAV property and HTTP header.
      *
      * The headers are intended to be used for HEAD and GET requests.
-     * 
+     *
      * @param string $path
+     * @return array
      */
     public function getHTTPHeaders($path) {
 
         $propertyMap = array(
             '{DAV:}getcontenttype'   => 'Content-Type',
             '{DAV:}getcontentlength' => 'Content-Length',
-            '{DAV:}getlastmodified'  => 'Last-Modified', 
+            '{DAV:}getlastmodified'  => 'Last-Modified',
             '{DAV:}getetag'          => 'ETag',
         );
 
@@ -1245,40 +1291,40 @@ class Sabre_DAV_Server {
         foreach($propertyMap as $property=>$header) {
             if (!isset($properties[$property])) continue;
 
-            if (is_scalar($properties[$property])) { 
+            if (is_scalar($properties[$property])) {
                 $headers[$header] = $properties[$property];
 
-            // GetLastModified gets special cased 
+            // GetLastModified gets special cased
             } elseif ($properties[$property] instanceof Sabre_DAV_Property_GetLastModified) {
-                $headers[$header] = $properties[$property]->getTime()->format(DateTime::RFC1123);
+                $headers[$header] = Sabre_HTTP_Util::toHTTPDate($properties[$property]->getTime());
             }
 
         }
 
         return $headers;
-        
+
     }
 
     /**
      * Returns a list of properties for a given path
-     * 
+     *
      * The path that should be supplied should have the baseUrl stripped out
      * The list of properties should be supplied in Clark notation. If the list is empty
      * 'allprops' is assumed.
      *
      * If a depth of 1 is requested child elements will also be returned.
      *
-     * @param string $path 
+     * @param string $path
      * @param array $propertyNames
-     * @param int $depth 
+     * @param int $depth
      * @return array
      */
-    public function getPropertiesForPath($path,$propertyNames = array(),$depth = 0) {
+    public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) {
 
         if ($depth!=0) $depth = 1;
 
         $returnPropertyList = array();
-        
+
         $parentNode = $this->tree->getNodeForPath($path);
         $nodes = array(
             $path => $parentNode
@@ -1286,11 +1332,11 @@ class Sabre_DAV_Server {
         if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) {
             foreach($this->tree->getChildren($path) as $childNode)
                 $nodes[$path . '/' . $childNode->getName()] = $childNode;
-        }            
-       
+        }
+
         // If the propertyNames array is empty, it means all properties are requested.
         // We shouldn't actually return everything we know though, and only return a
-        // sensible list. 
+        // sensible list.
         $allProperties = count($propertyNames)==0;
 
         foreach($nodes as $myPath=>$node) {
@@ -1315,8 +1361,8 @@ class Sabre_DAV_Server {
                 );
             }
 
-            // If the resourceType was not part of the list, we manually add it 
-            // and mark it for removal. We need to know the resourcetype in order 
+            // If the resourceType was not part of the list, we manually add it
+            // and mark it for removal. We need to know the resourcetype in order
             // to make certain decisions about the entry.
             // WebDAV dictates we should add a / and the end of href's for collections
             $removeRT = false;
@@ -1326,32 +1372,39 @@ class Sabre_DAV_Server {
             }
 
             $result = $this->broadcastEvent('beforeGetProperties',array($myPath, $node, &$currentPropertyNames, &$newProperties));
-            // If this method explicitly returned false, we must ignore this 
-            // node as it is inacessible.
+            // If this method explicitly returned false, we must ignore this
+            // node as it is inaccessible.
             if ($result===false) continue;
 
             if (count($currentPropertyNames) > 0) {
 
-                if ($node instanceof Sabre_DAV_IProperties) 
+                if ($node instanceof Sabre_DAV_IProperties)
                     $newProperties['200'] = $newProperties[200] + $node->getProperties($currentPropertyNames);
 
             }
 
 
             foreach($currentPropertyNames as $prop) {
-                
+
                 if (isset($newProperties[200][$prop])) continue;
 
                 switch($prop) {
                     case '{DAV:}getlastmodified'       : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break;
-                    case '{DAV:}getcontentlength'      : if ($node instanceof Sabre_DAV_IFile) $newProperties[200][$prop] = (int)$node->getSize(); break;
-                    case '{DAV:}quota-used-bytes'      : 
+                    case '{DAV:}getcontentlength'      :
+                        if ($node instanceof Sabre_DAV_IFile) {
+                            $size = $node->getSize();
+                            if (!is_null($size)) {
+                                $newProperties[200][$prop] = (int)$node->getSize();
+                            }
+                        }
+                        break;
+                    case '{DAV:}quota-used-bytes'      :
                         if ($node instanceof Sabre_DAV_IQuota) {
                             $quotaInfo = $node->getQuotaInfo();
                             $newProperties[200][$prop] = $quotaInfo[0];
                         }
                         break;
-                    case '{DAV:}quota-available-bytes' : 
+                    case '{DAV:}quota-available-bytes' :
                         if ($node instanceof Sabre_DAV_IQuota) {
                             $quotaInfo = $node->getQuotaInfo();
                             $newProperties[200][$prop] = $quotaInfo[1];
@@ -1364,7 +1417,7 @@ class Sabre_DAV_Server {
                         foreach($this->plugins as $plugin) {
                             $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath));
                         }
-                        $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports); 
+                        $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports);
                         break;
                     case '{DAV:}resourcetype' :
                         $newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType();
@@ -1379,14 +1432,14 @@ class Sabre_DAV_Server {
                 if (!$allProperties && !isset($newProperties[200][$prop])) $newProperties[404][$prop] = null;
 
             }
-         
+
             $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties));
 
-            $newProperties['href'] = trim($myPath,'/'); 
+            $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 
+            // 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'] .='/';
 
@@ -1397,7 +1450,7 @@ class Sabre_DAV_Server {
             $returnPropertyList[] = $newProperties;
 
         }
-        
+
         return $returnPropertyList;
 
     }
@@ -1406,27 +1459,31 @@ class Sabre_DAV_Server {
      * This method is invoked by sub-systems creating a new file.
      *
      * Currently this is done by HTTP PUT and HTTP LOCK (in the Locks_Plugin).
-     * It was important to get this done through a centralized function, 
+     * It was important to get this done through a centralized function,
      * allowing plugins to intercept this using the beforeCreateFile event.
      *
      * This method will return true if the file was actually created
-     * 
-     * @param string $uri 
-     * @param resource $data 
-     * @return bool 
+     *
+     * @param string   $uri
+     * @param resource $data
+     * @param string   $etag
+     * @return bool
      */
-    public function createFile($uri,$data) {
+    public function createFile($uri,$data, &$etag = null) {
 
         list($dir,$name) = Sabre_DAV_URLUtil::splitPath($uri);
 
         if (!$this->broadcastEvent('beforeBind',array($uri))) return false;
-        if (!$this->broadcastEvent('beforeCreateFile',array($uri,$data))) return false;
 
         $parent = $this->tree->getNodeForPath($dir);
-        $parent->createFile($name,$data);
+
+        if (!$this->broadcastEvent('beforeCreateFile',array($uri, &$data, $parent))) return false;
+
+        $etag = $parent->createFile($name,$data);
         $this->tree->markDirty($dir);
 
         $this->broadcastEvent('afterBind',array($uri));
+        $this->broadcastEvent('afterCreateFile',array($uri, $parent));
 
         return true;
     }
@@ -1434,7 +1491,7 @@ class Sabre_DAV_Server {
     /**
      * This method is invoked by sub-systems creating a new directory.
      *
-     * @param string $uri 
+     * @param string $uri
      * @return void
      */
     public function createDirectory($uri) {
@@ -1447,14 +1504,14 @@ class Sabre_DAV_Server {
      * Use this method to create a new collection
      *
      * The {DAV:}resourcetype is specified using the resourceType array.
-     * At the very least it must contain {DAV:}collection. 
+     * At the very least it must contain {DAV:}collection.
      *
      * The properties array can contain a list of additional properties.
-     * 
-     * @param string $uri The new uri 
-     * @param array $resourceType The resourceType(s) 
+     *
+     * @param string $uri The new uri
+     * @param array $resourceType The resourceType(s)
      * @param array $properties A list of properties
-     * @return void
+     * @return array|null
      */
     public function createCollection($uri, array $resourceType, array $properties) {
 
@@ -1471,7 +1528,7 @@ class Sabre_DAV_Server {
 
             $parent = $this->tree->getNodeForPath($parentUri);
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
 
             throw new Sabre_DAV_Exception_Conflict('Parent node does not exist');
 
@@ -1491,14 +1548,14 @@ class Sabre_DAV_Server {
             // If we got here.. it means there's already a node on that url, and we need to throw a 405
             throw new Sabre_DAV_Exception_MethodNotAllowed('The resource you tried to create already exists');
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
             // This is correct
         }
 
-        
+
         if (!$this->broadcastEvent('beforeBind',array($uri))) return;
 
-        // There are 2 modes of operation. The standard collection 
+        // There are 2 modes of operation. The standard collection
         // creates the directory, and then updates properties
         // the extended collection can create it directly.
         if ($parent instanceof Sabre_DAV_IExtendedCollection) {
@@ -1513,7 +1570,7 @@ class Sabre_DAV_Server {
             }
 
             $parent->createDirectory($newName);
-            $rollBack = false; 
+            $rollBack = false;
             $exception = null;
             $errorResult = null;
 
@@ -1544,7 +1601,7 @@ class Sabre_DAV_Server {
 
                 return $errorResult;
             }
-                
+
         }
         $this->tree->markDirty($parentUri);
         $this->broadcastEvent('afterBind',array($uri));
@@ -1557,29 +1614,29 @@ class Sabre_DAV_Server {
      * The properties array must be a list of properties. Array-keys are
      * property names in clarknotation, array-values are it's values.
      * If a property must be deleted, the value should be null.
-     * 
-     * Note that this request should either completely succeed, or 
+     *
+     * Note that this request should either completely succeed, or
      * completely fail.
      *
      * The response is an array with statuscodes for keys, which in turn
      * contain arrays with propertynames. This response can be used
      * to generate a multistatus body.
-     * 
-     * @param string $uri 
-     * @param array $properties 
-     * @return array 
+     *
+     * @param string $uri
+     * @param array $properties
+     * @return array
      */
     public function updateProperties($uri, array $properties) {
 
         // we'll start by grabbing the node, this will throw the appropriate
-        // exceptions if it doesn't. 
+        // exceptions if it doesn't.
         $node = $this->tree->getNodeForPath($uri);
-       
+
         $result = array(
             200 => array(),
             403 => array(),
             424 => array(),
-        ); 
+        );
         $remainingProperties = $properties;
         $hasError = false;
 
@@ -1684,14 +1741,15 @@ class Sabre_DAV_Server {
      * the appropriate HTTP response headers are already set.
      *
      * Normally this method will throw 412 Precondition Failed for failures
-     * related to If-None-Match, If-Match and If-Unmodified Since. It will 
+     * related to If-None-Match, If-Match and If-Unmodified Since. It will
      * set the status to 304 Not Modified for If-Modified_since.
      *
-     * If the $handleAsGET argument is set to true, it will also return 304 
+     * If the $handleAsGET argument is set to true, it will also return 304
      * Not Modified for failure of the If-None-Match precondition. This is the
      * desired behaviour for HTTP GET and HTTP HEAD requests.
      *
-     * @return bool 
+     * @param bool $handleAsGET
+     * @return bool
      */
     public function checkPreconditions($handleAsGET = false) {
 
@@ -1708,7 +1766,7 @@ class Sabre_DAV_Server {
             // request succeed if a resource exists at that url.
             try {
                 $node = $this->tree->getNodeForPath($uri);
-            } catch (Sabre_DAV_Exception_FileNotFound $e) {
+            } catch (Sabre_DAV_Exception_NotFound $e) {
                 throw new Sabre_DAV_Exception_PreconditionFailed('An If-Match header was specified and the resource did not exist','If-Match');
             }
 
@@ -1722,7 +1780,7 @@ class Sabre_DAV_Server {
 
                     // Stripping any extra spaces
                     $ifMatchItem = trim($ifMatchItem,' ');
-                    
+
                     $etag = $node->getETag();
                     if ($etag===$ifMatchItem) {
                         $haveMatch = true;
@@ -1744,7 +1802,7 @@ class Sabre_DAV_Server {
             if (!$node) {
                 try {
                     $node = $this->tree->getNodeForPath($uri);
-                } catch (Sabre_DAV_Exception_FileNotFound $e) {
+                } catch (Sabre_DAV_Exception_NotFound $e) {
                     $nodeExists = false;
                 }
             }
@@ -1758,10 +1816,10 @@ class Sabre_DAV_Server {
                     $etag = $node->getETag();
 
                     foreach($ifNoneMatch as $ifNoneMatchItem) {
-                        
+
                         // Stripping any extra spaces
                         $ifNoneMatchItem = trim($ifNoneMatchItem,' ');
-                        
+
                         if ($etag===$ifNoneMatchItem) $haveMatch = true;
 
                     }
@@ -1781,7 +1839,7 @@ class Sabre_DAV_Server {
         }
 
         if (!$ifNoneMatch && ($ifModifiedSince = $this->httpRequest->getHeader('If-Modified-Since'))) {
-            
+
             // The If-Modified-Since header contains a date. We
             // will only return the entity if it has been changed since
             // that date. If it hasn't been changed, we return a 304
@@ -1799,23 +1857,24 @@ class Sabre_DAV_Server {
                     $lastMod = new DateTime('@' . $lastMod);
                     if ($lastMod <= $date) {
                         $this->httpResponse->sendStatus(304);
+                        $this->httpResponse->setHeader('Last-Modified', Sabre_HTTP_Util::toHTTPDate($lastMod));
                         return false;
-                    } 
+                    }
                 }
             }
         }
 
         if ($ifUnmodifiedSince = $this->httpRequest->getHeader('If-Unmodified-Since')) {
-            
+
             // The If-Unmodified-Since will allow allow the request if the
             // entity has not changed since the specified date.
             $date = Sabre_HTTP_Util::parseHTTPDate($ifUnmodifiedSince);
-           
+
             // We must only check the date if it's valid
             if ($date) {
                 if (is_null($node)) {
                     $node = $this->tree->getNodeForPath($uri);
-                }   
+                }
                 $lastMod = $node->getLastModified();
                 if ($lastMod) {
                     $lastMod = new DateTime('@' . $lastMod);
@@ -1830,16 +1889,15 @@ class Sabre_DAV_Server {
 
     }
 
-    // }}} 
-    // {{{ XML Readers & Writers  
-    
-    
+    // }}}
+    // {{{ XML Readers & Writers
+
+
     /**
-     * Generates a WebDAV propfind response body based on a list of nodes 
-     * 
+     * Generates a WebDAV propfind response body based on a list of nodes
+     *
      * @param array $fileProperties The list with nodes
-     * @param array $requestedProperties The properties that should be returned
-     * @return string 
+     * @return string
      */
     public function generateMultiStatus(array $fileProperties) {
 
@@ -1859,7 +1917,7 @@ class Sabre_DAV_Server {
 
             $href = $entry['href'];
             unset($entry['href']);
-            
+
             $response = new Sabre_DAV_Property_Response($href,$entry);
             $response->serialize($this,$multiStatus);
 
@@ -1878,7 +1936,7 @@ class Sabre_DAV_Server {
      * The keys in the returned array contain the property name (e.g.: {DAV:}displayname,
      * and the value contains the property value. If a property is to be removed the value
      * will be null.
-     * 
+     *
      * @param string $body xml body
      * @return array list of properties in need of updating or deletion
      */
@@ -1886,17 +1944,17 @@ class Sabre_DAV_Server {
 
         //We'll need to change the DAV namespace declaration to something else in order to make it parsable
         $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
-        
+
         $newProperties = array();
 
         foreach($dom->firstChild->childNodes as $child) {
 
-            if ($child->nodeType !== XML_ELEMENT_NODE) continue; 
+            if ($child->nodeType !== XML_ELEMENT_NODE) continue;
 
             $operation = Sabre_DAV_XMLUtil::toClarkNotation($child);
 
             if ($operation!=='{DAV:}set' && $operation!=='{DAV:}remove') continue;
-            
+
             $innerProperties = Sabre_DAV_XMLUtil::parseProperties($child, $this->propertyMap);
 
             foreach($innerProperties as $propertyName=>$propertyValue) {
@@ -1920,9 +1978,9 @@ class Sabre_DAV_Server {
      *
      * This will either be a list of properties, or an empty array; in which case
      * an {DAV:}allprop was requested.
-     * 
-     * @param string $body 
-     * @return array 
+     *
+     * @param string $body
+     * @return array
      */
     public function parsePropFindRequest($body) {
 
@@ -1931,7 +1989,7 @@ class Sabre_DAV_Server {
 
         $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
         $elem = $dom->getElementsByTagNameNS('urn:DAV','propfind')->item(0);
-        return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem)); 
+        return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem));
 
     }
 
diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php
old mode 100644
new mode 100755
index 6909f600c216a169df4a1cee8030d2f205063b6b..131863d13fbf3a9823282d0b9aebb5b7c4e9a760
--- a/3rdparty/Sabre/DAV/ServerPlugin.php
+++ b/3rdparty/Sabre/DAV/ServerPlugin.php
@@ -3,12 +3,12 @@
 /**
  * The baseclass for all server plugins.
  *
- * Plugins can modify or extend the servers behaviour. 
- * 
+ * Plugins can modify or extend the servers behaviour.
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_ServerPlugin {
@@ -20,18 +20,18 @@ abstract class Sabre_DAV_ServerPlugin {
      * addPlugin is called.
      *
      * This method should set up the requires event subscriptions.
-     * 
-     * @param Sabre_DAV_Server $server 
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     abstract public function initialize(Sabre_DAV_Server $server);
-    
+
     /**
-     * This method should return a list of server-features. 
+     * 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() {
@@ -44,11 +44,11 @@ abstract class Sabre_DAV_ServerPlugin {
      * 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 
+     * This method is passed a uri. It should only return HTTP methods that are
      * available for the specified uri.
      *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getHTTPMethods($uri) {
 
@@ -58,11 +58,11 @@ abstract class Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a plugin name.
-     * 
+     *
      * Using this name other plugins will be able to access other plugins
-     * using Sabre_DAV_Server::getPlugin 
-     * 
-     * @return string 
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
      */
     public function getPluginName() {
 
@@ -74,11 +74,11 @@ abstract class Sabre_DAV_ServerPlugin {
      * Returns a list of reports this plugin supports.
      *
      * This will be used in the {DAV:}supported-report-set property.
-     * Note that you still need to subscribe to the 'report' event to actually 
-     * implement them 
-     * 
+     * Note that you still need to subscribe to the 'report' event to actually
+     * implement them
+     *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getSupportedReportSet($uri) {
 
diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php
old mode 100644
new mode 100755
index 223d05fed554bbba58ed608b9fdaff4677c9fb14..4acf971caa5c457905b0a02a65bb524e12b59a60
--- a/3rdparty/Sabre/DAV/SimpleCollection.php
+++ b/3rdparty/Sabre/DAV/SimpleCollection.php
@@ -8,23 +8,23 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_SimpleCollection extends Sabre_DAV_Collection {
 
     /**
-     * List of childnodes 
+     * List of childnodes
      *
      * @var array
      */
     protected $children = array();
 
     /**
-     * Name of this resource 
-     * 
-     * @var string 
+     * Name of this resource
+     *
+     * @var string
      */
     protected $name;
 
@@ -33,10 +33,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
      *
      * The name of the node must be passed, child nodes can also be bassed.
      * This nodes must be instances of Sabre_DAV_INode
-     * 
-     * @param string $name 
-     * @param array $children 
-     * @return void
+     *
+     * @param string $name
+     * @param array $children
      */
     public function __construct($name,array $children = array()) {
 
@@ -51,9 +50,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
     }
 
     /**
-     * Adds a new childnode to this collection 
-     * 
-     * @param Sabre_DAV_INode $child 
+     * Adds a new childnode to this collection
+     *
+     * @param Sabre_DAV_INode $child
      * @return void
      */
     public function addChild(Sabre_DAV_INode $child) {
@@ -63,9 +62,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
     }
 
     /**
-     * Returns the name of the collection 
-     * 
-     * @return string 
+     * Returns the name of the collection
+     *
+     * @return string
      */
     public function getName() {
 
@@ -76,24 +75,24 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
     /**
      * 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
-     * 
+     *
      * @param string $name
-     * @throws Sabre_DAV_Exception_FileNotFound
-     * @return Sabre_DAV_INode 
+     * @throws Sabre_DAV_Exception_NotFound
+     * @return Sabre_DAV_INode
      */
     public function getChild($name) {
 
         if (isset($this->children[$name])) return $this->children[$name];
-        throw new Sabre_DAV_Exception_FileNotFound('File not found: ' . $name . ' in \'' . $this->getName() . '\'');
+        throw new Sabre_DAV_Exception_NotFound('File not found: ' . $name . ' in \'' . $this->getName() . '\'');
 
     }
 
     /**
-     * Returns a list of children for this collection 
-     * 
-     * @return array 
+     * Returns a list of children for this collection
+     *
+     * @return array
      */
     public function getChildren() {
 
diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php
old mode 100644
new mode 100755
index 516a3aa907c8d55511e7d15d421baa29e17a1738..621222ebc53a6dbfc4e3b89f1b58288cee7652bc
--- a/3rdparty/Sabre/DAV/SimpleDirectory.php
+++ b/3rdparty/Sabre/DAV/SimpleDirectory.php
@@ -11,8 +11,8 @@
  * @package Sabre
  * @subpackage DAV
  * @deprecated Use Sabre_DAV_SimpleCollection instead.
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 100644
new mode 100755
index 304dff1c5ec22f594281cbef96c36f19e4e9d347..58330d6861de476db3dbf879013166c0fd8261da
--- a/3rdparty/Sabre/DAV/SimpleFile.php
+++ b/3rdparty/Sabre/DAV/SimpleFile.php
@@ -3,47 +3,48 @@
 /**
  * SimpleFile
  *
- * The 'SimpleFile' class is used to easily add read-only immutable files to 
- * the directory structure. One usecase would be to add a 'readme.txt' to a 
+ * The 'SimpleFile' class is used to easily add read-only immutable files to
+ * the directory structure. One usecase would be to add a 'readme.txt' to a
  * root of a webserver with some standard content.
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_SimpleFile extends Sabre_DAV_File {
 
     /**
-     * File contents 
+     * File contents
      *
-     * @var string 
+     * @var string
      */
     protected $contents = array();
 
     /**
-     * Name of this resource 
-     * 
-     * @var string 
+     * Name of this resource
+     *
+     * @var string
      */
     protected $name;
 
     /**
      * A mimetype, such as 'text/plain' or 'text/html'
-     * 
-     * @var string 
+     *
+     * @var string
      */
     protected $mimeType;
 
     /**
      * Creates this node
      *
-     * The name of the node must be passed, as well as the contents of the 
+     * The name of the node must be passed, as well as the contents of the
      * file.
-     * 
-     * @param string $name 
-     * @param string $contents 
+     *
+     * @param string $name
+     * @param string $contents
+     * @param string|null $mimeType
      */
     public function __construct($name, $contents, $mimeType = null) {
 
@@ -57,8 +58,8 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
      * Returns the node name for this file.
      *
      * This name is used to construct the url.
-     * 
-     * @return string 
+     *
+     * @return string
      */
     public function getName() {
 
@@ -67,7 +68,7 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
     }
 
     /**
-     * Returns the data 
+     * Returns the data
      *
      * This method may either return a string or a readable stream resource
      *
@@ -75,14 +76,14 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
      */
     public function get() {
 
-        return $this->contents; 
+        return $this->contents;
 
     }
 
     /**
-     * Returns the size of the file, in bytes. 
-     * 
-     * @return int 
+     * Returns the size of the file, in bytes.
+     *
+     * @return int
      */
     public function getSize() {
 
@@ -94,13 +95,14 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
      * Returns the ETag for a file
      *
      * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
-     * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
      *
      * Return null if the ETag can not effectively be determined
+     * @return string
      */
     public function getETag() {
 
-        return '"' . md5($this->contents) . '"'; 
+        return '"' . md5($this->contents) . '"';
 
     }
 
@@ -108,13 +110,12 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
      * Returns the mime-type for a file
      *
      * If null is returned, we'll assume application/octet-stream
-     */ 
+     * @return string
+     */
     public function getContentType() {
 
-        return $this->mimeType; 
+        return $this->mimeType;
 
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php
old mode 100644
new mode 100755
index 440cf6866ca6a68d5b8e7f2356342db961468b27..b126a94c82579b7b7602324632c8b368e7d275da
--- a/3rdparty/Sabre/DAV/StringUtil.php
+++ b/3rdparty/Sabre/DAV/StringUtil.php
@@ -3,14 +3,14 @@
 /**
  * String utility
  *
- * This class is mainly used to implement the 'text-match' filter, used by both 
- * the CalDAV calendar-query REPORT, and CardDAV addressbook-query REPORT. 
+ * This class is mainly used to implement the 'text-match' filter, used by both
+ * the CalDAV calendar-query REPORT, and CardDAV addressbook-query REPORT.
  * Because they both need it, it was decided to put it in Sabre_DAV instead.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_StringUtil {
@@ -18,11 +18,11 @@ class Sabre_DAV_StringUtil {
     /**
      * Checks if a needle occurs in a haystack ;)
      *
-     * @param string $haystack 
-     * @param string $needle 
-     * @param string $collation 
-     * @param string $matchType 
-     * @return bool 
+     * @param string $haystack
+     * @param string $needle
+     * @param string $collation
+     * @param string $matchType
+     * @return bool
      */
     static public function textMatch($haystack, $needle, $collation, $matchType = 'contains') {
 
@@ -37,7 +37,7 @@ class Sabre_DAV_StringUtil {
 
             case 'i;octet' :
                 // Do nothing
-                break; 
+                break;
 
             case 'i;unicode-casemap' :
                 $haystack = mb_strtoupper($haystack, 'UTF-8');
@@ -63,18 +63,18 @@ class Sabre_DAV_StringUtil {
                 throw new Sabre_DAV_Exception_BadRequest('Match-type: ' . $matchType . ' is not supported');
 
         }
-        
+
     }
 
     /**
-     * This method takes an input string, checks if it's not valid UTF-8 and 
+     * This method takes an input string, checks if it's not valid UTF-8 and
      * attempts to convert it to UTF-8 if it's not.
      *
-     * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1), 
+     * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1),
      * anything else will likely fail.
      *
-     * @param string $input 
-     * @return string 
+     * @param string $input
+     * @return string
      */
     static public function ensureUTF8($input) {
 
@@ -84,7 +84,7 @@ class Sabre_DAV_StringUtil {
             return utf8_encode($input);
         } else {
             return $input;
-        } 
+        }
 
     }
 
diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
old mode 100644
new mode 100755
index e8276af5613c7815c40be5a308f10c3de52a912b..36096e677752e61fc1b62e53f3caf64c47e131aa
--- a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
+++ b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
@@ -22,8 +22,8 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
@@ -31,7 +31,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     /**
      * This is the list of patterns we intercept.
      * If new patterns are added, they must be valid patterns for preg_match.
-     * 
+     *
      * @var array
      */
     public $temporaryFilePatterns = array(
@@ -43,19 +43,19 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
         '/^\.dat(.*)$/',   // Smultron seems to create these
         '/^~lock.(.*)#$/', // Windows 7 lockfiles
     );
-    
+
     /**
      * This is the directory where this plugin
      * will store it's files.
-     * 
-     * @var string 
+     *
+     * @var string
      */
     private $dataDir;
 
     /**
      * A reference to the main Server class
-     * 
-     * @var Sabre_DAV_Server 
+     *
+     * @var Sabre_DAV_Server
      */
     private $server;
 
@@ -65,9 +65,8 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
      * Make sure you specify a directory for your files. If you don't, we
      * will use PHP's directory for session-storage instead, and you might
      * not want that.
-     * 
-     * @param string $dataDir 
-     * @return void
+     *
+     * @param string|null $dataDir
      */
     public function __construct($dataDir = null) {
 
@@ -75,15 +74,15 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
         if (!is_dir($dataDir)) mkdir($dataDir);
         $this->dataDir = $dataDir;
 
-    } 
+    }
 
     /**
      * Initialize the plugin
      *
      * This is called automatically be the Server class after this plugin is
      * added with Sabre_DAV_Server::addPlugin()
-     * 
-     * @param Sabre_DAV_Server $server 
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -97,11 +96,12 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     /**
      * This method is called before any HTTP method handler
      *
-     * This method intercepts any GET, DELETE, PUT and PROPFIND calls to 
+     * This method intercepts any GET, DELETE, PUT and PROPFIND calls to
      * filenames that are known to match the 'temporary file' regex.
-     * 
-     * @param string $method 
-     * @return bool 
+     *
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function beforeMethod($method, $uri) {
 
@@ -125,33 +125,33 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     /**
      * This method is invoked if some subsystem creates a new file.
      *
-     * This is used to deal with HTTP LOCK requests which create a new 
+     * This is used to deal with HTTP LOCK requests which create a new
      * file.
-     * 
-     * @param string $uri 
-     * @param resource $data 
-     * @return bool 
+     *
+     * @param string $uri
+     * @param resource $data
+     * @return bool
      */
     public function beforeCreateFile($uri,$data) {
 
         if ($tempPath = $this->isTempFile($uri)) {
-            
+
             $hR = $this->server->httpResponse;
             $hR->setHeader('X-Sabre-Temp','true');
             file_put_contents($tempPath,$data);
             return false;
         }
-        return true; 
+        return true;
 
     }
 
     /**
      * This method will check if the url matches the temporary file pattern
-     * if it does, it will return an path based on $this->dataDir for the 
+     * if it does, it will return an path based on $this->dataDir for the
      * temporary file storage.
-     * 
-     * @param string $path 
-     * @return boolean|string 
+     *
+     * @param string $path
+     * @return boolean|string
      */
     protected function isTempFile($path) {
 
@@ -161,7 +161,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
         foreach($this->temporaryFilePatterns as $tempFile) {
 
             if (preg_match($tempFile,$tempPath)) {
-                return $this->dataDir . '/sabredav_' . md5($path) . '.tempfile';
+                return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile';
             }
 
         }
@@ -175,9 +175,9 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
      * This method handles the GET method for temporary files.
      * If the file doesn't exist, it will return false which will kick in
      * the regular system for the GET method.
-     * 
-     * @param string $tempLocation 
-     * @return bool 
+     *
+     * @param string $tempLocation
+     * @return bool
      */
     public function httpGet($tempLocation) {
 
@@ -195,9 +195,9 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * This method handles the PUT method.
-     * 
-     * @param string $tempLocation 
-     * @return bool 
+     *
+     * @param string $tempLocation
+     * @return bool
      */
     public function httpPut($tempLocation) {
 
@@ -205,7 +205,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
         $hR->setHeader('X-Sabre-Temp','true');
 
         $newFile = !file_exists($tempLocation);
-       
+
         if (!$newFile && ($this->server->httpRequest->getHeader('If-None-Match'))) {
              throw new Sabre_DAV_Exception_PreconditionFailed('The resource already exists, and an If-None-Match header was supplied');
         }
@@ -219,11 +219,11 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     /**
      * This method handles the DELETE method.
      *
-     * If the file didn't exist, it will return false, which will make the 
+     * If the file didn't exist, it will return false, which will make the
      * standard HTTP DELETE handler kick in.
-     * 
-     * @param string $tempLocation 
-     * @return bool 
+     *
+     * @param string $tempLocation
+     * @return bool
      */
     public function httpDelete($tempLocation) {
 
@@ -238,25 +238,26 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This method handles the PROPFIND method. 
+     * This method handles the PROPFIND method.
      *
      * It's a very lazy method, it won't bother checking the request body
      * for which properties were requested, and just sends back a default
      * set of properties.
      *
-     * @param string $tempLocation 
-     * @return void
+     * @param string $tempLocation
+     * @param string $uri
+     * @return bool
      */
     public function httpPropfind($tempLocation, $uri) {
 
         if (!file_exists($tempLocation)) return true;
-       
+
         $hR = $this->server->httpResponse;
         $hR->setHeader('X-Sabre-Temp','true');
         $hR->sendStatus(207);
         $hR->setHeader('Content-Type','application/xml; charset=utf-8');
 
-        $requestedProps = $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true)); 
+        $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true));
 
         $properties = array(
             'href' => $uri,
@@ -264,7 +265,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
                 '{DAV:}getlastmodified' => new Sabre_DAV_Property_GetLastModified(filemtime($tempLocation)),
                 '{DAV:}getcontentlength' => filesize($tempLocation),
                 '{DAV:}resourcetype' => new Sabre_DAV_Property_ResourceType(null),
-                '{'.Sabre_DAV_Server::NS_SABREDAV.'}tempFile' => true, 
+                '{'.Sabre_DAV_Server::NS_SABREDAV.'}tempFile' => true,
 
             ),
          );
@@ -276,4 +277,13 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
     }
 
 
+    /**
+     * This method returns the directory where the temporary files should be stored.
+     *
+     * @return string
+     */
+    protected function getDataDir()
+    {
+        return $this->dataDir;
+    }
 }
diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php
old mode 100644
new mode 100755
index 98e6f62c9e588cb5462408884b1bbd9206abde3d..502163941555d209837c3dee0c59b76981d72ab4
--- a/3rdparty/Sabre/DAV/Tree.php
+++ b/3rdparty/Sabre/DAV/Tree.php
@@ -1,34 +1,34 @@
 <?php
 
 /**
- * Abstract tree object 
- * 
+ * Abstract tree object
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Tree {
-    
+
     /**
      * This function must return an INode object for a path
-     * If a Path doesn't exist, thrown an Exception_FileNotFound
-     * 
-     * @param string $path 
-     * @throws Exception_FileNotFound
-     * @return Sabre_DAV_INode 
+     * If a Path doesn't exist, thrown a Exception_NotFound
+     *
+     * @param string $path
+     * @throws Sabre_DAV_Exception_NotFound
+     * @return Sabre_DAV_INode
      */
     abstract function getNodeForPath($path);
 
     /**
      * This function allows you to check if a node exists.
      *
-     * Implementors of this class should override this method to make 
+     * Implementors of this class should override this method to make
      * it cheaper.
-     * 
-     * @param string $path 
-     * @return bool 
+     *
+     * @param string $path
+     * @return bool
      */
     public function nodeExists($path) {
 
@@ -37,7 +37,7 @@ abstract class Sabre_DAV_Tree {
             $this->getNodeForPath($path);
             return true;
 
-        } catch (Sabre_DAV_Exception_FileNotFound $e) {
+        } catch (Sabre_DAV_Exception_NotFound $e) {
 
             return false;
 
@@ -50,12 +50,12 @@ abstract class Sabre_DAV_Tree {
      *
      * @param string $sourcePath The source location
      * @param string $destinationPath The full destination path
-     * @return void 
+     * @return void
      */
     public function copy($sourcePath, $destinationPath) {
 
         $sourceNode = $this->getNodeForPath($sourcePath);
-       
+
         // grab the dirname and basename components
         list($destinationDir, $destinationName) = Sabre_DAV_URLUtil::splitPath($destinationPath);
 
@@ -67,9 +67,9 @@ abstract class Sabre_DAV_Tree {
     }
 
     /**
-     * Moves a file from one location to another 
-     * 
-     * @param string $sourcePath The path to the file which should be moved 
+     * Moves a file from one location to another
+     *
+     * @param string $sourcePath The path to the file which should be moved
      * @param string $destinationPath The full destination path, so not just the destination parent node
      * @return int
      */
@@ -91,26 +91,26 @@ abstract class Sabre_DAV_Tree {
     }
 
     /**
-     * Deletes a node from the tree 
-     * 
-     * @param string $path 
+     * Deletes a node from the tree
+     *
+     * @param string $path
      * @return void
      */
     public function delete($path) {
 
         $node = $this->getNodeForPath($path);
         $node->delete();
-        
+
         list($parent) = Sabre_DAV_URLUtil::splitPath($path);
         $this->markDirty($parent);
 
     }
 
     /**
-     * Returns a list of childnodes for a given path. 
-     * 
-     * @param string $path 
-     * @return array 
+     * Returns a list of childnodes for a given path.
+     *
+     * @param string $path
+     * @return array
      */
     public function getChildren($path) {
 
@@ -127,14 +127,14 @@ abstract class Sabre_DAV_Tree {
      *   * node creations
      *   * copy
      *   * move
-     *   * renaming nodes 
-     * 
+     *   * renaming nodes
+     *
      * If Tree classes implement a form of caching, this will allow
      * them to make sure caches will be expired.
-     * 
+     *
      * If a path is passed, it is assumed that the entire subtree is dirty
      *
-     * @param string $path 
+     * @param string $path
      * @return void
      */
     public function markDirty($path) {
@@ -143,10 +143,11 @@ abstract class Sabre_DAV_Tree {
     }
 
     /**
-     * copyNode 
-     * 
-     * @param Sabre_DAV_INode $source 
-     * @param Sabre_DAV_ICollection $destination 
+     * copyNode
+     *
+     * @param Sabre_DAV_INode $source
+     * @param Sabre_DAV_ICollection $destinationParent
+     * @param string $destinationName
      * @return void
      */
     protected function copyNode(Sabre_DAV_INode $source,Sabre_DAV_ICollection $destinationParent,$destinationName = null) {
@@ -163,14 +164,14 @@ abstract class Sabre_DAV_Tree {
                 fwrite($stream,$data);
                 rewind($stream);
                 $data = $stream;
-            } 
+            }
             $destinationParent->createFile($destinationName,$data);
             $destination = $destinationParent->getChild($destinationName);
 
         } elseif ($source instanceof Sabre_DAV_ICollection) {
 
             $destinationParent->createDirectory($destinationName);
-            
+
             $destination = $destinationParent->getChild($destinationName);
             foreach($source->getChildren() as $child) {
 
diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php
old mode 100644
new mode 100755
index 5c611047e073fd4c2642babf24696517c53b2201..85a9ee317be3c43daa2495908e2800d119ddc11c
--- a/3rdparty/Sabre/DAV/Tree/Filesystem.php
+++ b/3rdparty/Sabre/DAV/Tree/Filesystem.php
@@ -1,12 +1,12 @@
 <?php
 
 /**
- * Sabre_DAV_Tree_Filesystem 
- * 
+ * Sabre_DAV_Tree_Filesystem
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_Tree_Filesystem extends Sabre_DAV_Tree {
@@ -14,7 +14,7 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
     /**
      * Base url on the filesystem.
      *
-     * @var string 
+     * @var string
      */
     protected $basePath;
 
@@ -22,9 +22,8 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
      * Creates this tree
      *
      * Supply the path you'd like to share.
-     * 
-     * @param string $basePath 
-     * @return void
+     *
+     * @param string $basePath
      */
     public function __construct($basePath) {
 
@@ -33,16 +32,16 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
     }
 
     /**
-     * Returns a new node for the given path 
-     * 
-     * @param string $path 
-     * @return void
+     * Returns a new node for the given path
+     *
+     * @param string $path
+     * @return Sabre_DAV_FS_Node
      */
     public function getNodeForPath($path) {
 
         $realPath = $this->getRealPath($path);
-        if (!file_exists($realPath)) throw new Sabre_DAV_Exception_FileNotFound('File at location ' . $realPath . ' not found');
-        if (is_dir($realPath)) { 
+        if (!file_exists($realPath)) throw new Sabre_DAV_Exception_NotFound('File at location ' . $realPath . ' not found');
+        if (is_dir($realPath)) {
             return new Sabre_DAV_FS_Directory($path);
         } else {
             return new Sabre_DAV_FS_File($path);
@@ -51,10 +50,10 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
     }
 
     /**
-     * Returns the real filesystem path for a webdav url. 
-     * 
-     * @param string $publicPath 
-     * @return string 
+     * Returns the real filesystem path for a webdav url.
+     *
+     * @param string $publicPath
+     * @return string
      */
     protected function getRealPath($publicPath) {
 
@@ -67,24 +66,24 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
      *
      * This method must work recursively and delete the destination
      * if it exists
-     * 
-     * @param string $source 
-     * @param string $destination 
+     *
+     * @param string $source
+     * @param string $destination
      * @return void
      */
     public function copy($source,$destination) {
 
         $source = $this->getRealPath($source);
         $destination = $this->getRealPath($destination);
-        $this->realCopy($source,$destination); 
+        $this->realCopy($source,$destination);
 
     }
 
     /**
-     * Used by self::copy 
-     * 
-     * @param string $source 
-     * @param string $destination 
+     * Used by self::copy
+     *
+     * @param string $source
+     * @param string $destination
      * @return void
      */
     protected function realCopy($source,$destination) {
@@ -107,9 +106,9 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
      * Moves a file or directory recursively.
      *
      * If the destination exists, delete it first.
-     * 
-     * @param string $source 
-     * @param string $destination 
+     *
+     * @param string $source
+     * @param string $destination
      * @return void
      */
     public function move($source,$destination) {
diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php
old mode 100644
new mode 100755
index 8f38749264b1f5e3c5b87ec0195f05aa749dbee2..794665a44f68b0ef8fe9d8c7a15adc6841405fe3
--- a/3rdparty/Sabre/DAV/URLUtil.php
+++ b/3rdparty/Sabre/DAV/URLUtil.php
@@ -11,11 +11,11 @@
  * Specifically, it was found that GVFS (gnome's webdav client) does not like encoding of ( and
  * ). Since these are reserved, but don't have a reserved meaning in url, these characters are
  * kept as-is.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_URLUtil {
@@ -24,46 +24,42 @@ class Sabre_DAV_URLUtil {
      * Encodes the path of a url.
      *
      * slashes (/) are treated as path-separators.
-     * 
-     * @param string $path 
-     * @return string 
+     *
+     * @param string $path
+     * @return string
      */
     static function encodePath($path) {
 
-    	$valid_chars = '/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()';
-        $newStr = '';
-        for( $i=0; isset($path[$i]); ++$i ) {
-            if( strpos($valid_chars,($c=$path[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c));
-            else $newStr .= $c;
-        }
-        return $newStr;
-    	
+        return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/])/',function($match) {
+
+            return '%'.sprintf('%02x',ord($match[0]));
+
+        }, $path);
+
     }
 
     /**
      * Encodes a 1 segment of a path
      *
      * Slashes are considered part of the name, and are encoded as %2f
-     * 
-     * @param string $pathSegment 
-     * @return string 
+     *
+     * @param string $pathSegment
+     * @return string
      */
     static function encodePathSegment($pathSegment) {
 
-    	$valid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()';
-        $newStr = '';
-        for( $i=0; isset($pathSegment[$i]); ++$i ) {
-            if( strpos($valid_chars,($c=$pathSegment[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c));
-            else $newStr .= $c;
-        }
-        return $newStr;
+        return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)])/',function($match) {
+
+            return '%'.sprintf('%02x',ord($match[0]));
+
+        }, $pathSegment);
     }
 
     /**
      * Decodes a url-encoded path
      *
-     * @param string $path 
-     * @return string 
+     * @param string $path
+     * @return string
      */
     static function decodePath($path) {
 
@@ -74,17 +70,17 @@ class Sabre_DAV_URLUtil {
     /**
      * Decodes a url-encoded path segment
      *
-     * @param string $path 
-     * @return string 
+     * @param string $path
+     * @return string
      */
     static function decodePathSegment($path) {
 
-        $path = urldecode($path);
+        $path = rawurldecode($path);
         $encoding = mb_detect_encoding($path, array('UTF-8','ISO-8859-1'));
 
         switch($encoding) {
 
-            case 'ISO-8859-1' : 
+            case 'ISO-8859-1' :
                 $path = utf8_encode($path);
 
         }
@@ -94,7 +90,7 @@ class Sabre_DAV_URLUtil {
     }
 
     /**
-     * Returns the 'dirname' and 'basename' for a path. 
+     * Returns the 'dirname' and 'basename' for a path.
      *
      * The reason there is a custom function for this purpose, is because
      * basename() is locale aware (behaviour changes if C locale or a UTF-8 locale is used)
@@ -108,8 +104,8 @@ class Sabre_DAV_URLUtil {
      * If there is no dirname, it will return an empty string. Any / appearing at the end of the
      * string is stripped off.
      *
-     * @param string $path 
-     * @return array 
+     * @param string $path
+     * @return array
      */
     static function splitPath($path) {
 
diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php
old mode 100644
new mode 100755
index e42a536ad8a3feff157c8c2cebec4be534d30967..f0eebe598e5d74d0d61e403e26a9d66adaf3eecb
--- a/3rdparty/Sabre/DAV/UUIDUtil.php
+++ b/3rdparty/Sabre/DAV/UUIDUtil.php
@@ -4,13 +4,13 @@
  * UUID Utility
  *
  * This class has static methods to generate and validate UUID's.
- * UUIDs are used a decent amount within various *DAV standards, so it made 
+ * UUIDs are used a decent amount within various *DAV standards, so it made
  * sense to include it.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_UUIDUtil {
@@ -18,10 +18,10 @@ class Sabre_DAV_UUIDUtil {
     /**
      * Returns a pseudo-random v4 UUID
      *
-     * This function is based on a comment by Andrew Moore on php.net 
-     * 
+     * This function is based on a comment by Andrew Moore on php.net
+     *
      * @see http://www.php.net/manual/en/function.uniqid.php#94959
-     * @return void
+     * @return string
      */
     static function getUUID() {
 
@@ -48,9 +48,9 @@ class Sabre_DAV_UUIDUtil {
 
     /**
      * Checks if a string is a valid UUID.
-     * 
-     * @param string $uuid 
-     * @return bool 
+     *
+     * @param string $uuid
+     * @return bool
      */
     static function validateUUID($uuid) {
 
diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php
old mode 100644
new mode 100755
index 6bece1985e4e9706b7a7e41f1b738a61672e7b73..5e5d15e40397e700ab6d821c7862b3a7a026f9e5
--- a/3rdparty/Sabre/DAV/Version.php
+++ b/3rdparty/Sabre/DAV/Version.php
@@ -2,10 +2,10 @@
 
 /**
  * This class contains the SabreDAV version constants.
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,7 +14,7 @@ class Sabre_DAV_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.5.4';
+    const VERSION = '1.6.2';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php
old mode 100644
new mode 100755
index bd05be4b2297b77e36c47d62904ff964617a0516..60eff3b159ac15bf34a4f09fd0f2d7a721542785
--- a/3rdparty/Sabre/DAV/XMLUtil.php
+++ b/3rdparty/Sabre/DAV/XMLUtil.php
@@ -2,32 +2,32 @@
 
 /**
  * XML utilities for WebDAV
- * 
+ *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_XMLUtil {
 
     /**
      * Returns the 'clark notation' for an element.
-     * 
+     *
      * For example, and element encoded as:
      * <b:myelem xmlns:b="http://www.example.org/" />
      * will be returned as:
      * {http://www.example.org}myelem
      *
      * This format is used throughout the SabreDAV sourcecode.
-     * Elements encoded with the urn:DAV namespace will 
+     * 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.
      *
-     * @param DOMElement $dom 
-     * @return string 
+     * @param DOMNode $dom
+     * @return string
      */
     static function toClarkNotation(DOMNode $dom) {
 
@@ -35,21 +35,21 @@ class Sabre_DAV_XMLUtil {
 
         // Mapping back to the real namespace, in case it was dav
         if ($dom->namespaceURI=='urn:DAV') $ns = 'DAV:'; else $ns = $dom->namespaceURI;
-        
+
         // Mapping to clark notation
         return '{' . $ns . '}' . $dom->localName;
 
     }
 
     /**
-     * Parses a clark-notation string, and returns the namespace and element 
+     * Parses a clark-notation string, and returns the namespace and element
      * name components.
      *
      * If the string was invalid, it will throw an InvalidArgumentException.
-     * 
+     *
      * @param string $str
-     * @throws InvalidArgumentException 
-     * @return array 
+     * @throws InvalidArgumentException
+     * @return array
      */
     static function parseClarkNotation($str) {
 
@@ -70,6 +70,9 @@ class Sabre_DAV_XMLUtil {
      *
      * 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) {
 
@@ -83,17 +86,17 @@ class Sabre_DAV_XMLUtil {
      * 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, and it converts the DAV: namespace to urn:DAV.
+     *
      * @param string $xml
-     * @throws Sabre_DAV_Exception_BadRequest 
-     * @return DOMDocument 
+     * @throws Sabre_DAV_Exception_BadRequest
+     * @return DOMDocument
      */
     static function loadDOMDocument($xml) {
 
         if (empty($xml))
             throw new Sabre_DAV_Exception_BadRequest('Empty XML document sent');
-       
+
         // The BitKinex client sends xml documents as UTF-16. PHP 5.3.1 (and presumably lower)
         // does not support this, so we must intercept this and convert to UTF-8.
         if (substr($xml,0,12) === "\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20\x00") {
@@ -111,7 +114,7 @@ class Sabre_DAV_XMLUtil {
         // Retaining old error setting
         $oldErrorSetting =  libxml_use_internal_errors(true);
 
-        // Clearing any previous errors 
+        // Clearing any previous errors
         libxml_clear_errors();
 
         $dom = new DOMDocument();
@@ -135,7 +138,7 @@ class Sabre_DAV_XMLUtil {
     /**
      * Parses all WebDAV properties out of a DOM Element
      *
-     * Generally WebDAV properties are encloded in {DAV:}prop elements. This
+     * Generally WebDAV properties are enclosed in {DAV:}prop elements. This
      * method helps by going through all these and pulling out the actual
      * propertynames, making them array keys and making the property values,
      * well.. the array values.
@@ -145,7 +148,7 @@ class Sabre_DAV_XMLUtil {
      *
      * Complex values are supported through the propertyMap argument. The
      * propertyMap should have the clark-notation properties as it's keys, and
-     * classnames as values. 
+     * classnames as values.
      *
      * When any of these properties are found, the unserialize() method will be
      * (statically) called. The result of this method is used as the value.
@@ -168,7 +171,7 @@ class Sabre_DAV_XMLUtil {
 
                 $propertyName = Sabre_DAV_XMLUtil::toClarkNotation($propNodeData);
                 if (isset($propertyMap[$propertyName])) {
-                    $propList[$propertyName] = call_user_func(array($propertyMap[$propertyName],'unserialize'),$propNodeData); 
+                    $propList[$propertyName] = call_user_func(array($propertyMap[$propertyName],'unserialize'),$propNodeData);
                 } else {
                     $propList[$propertyName] = $propNodeData->textContent;
                 }
diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php
new file mode 100755
index 0000000000000000000000000000000000000000..6a4890677ea2bdad500410eae9e47ee89f6b914e
--- /dev/null
+++ b/3rdparty/Sabre/DAV/includes.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Sabre_DAV includes file
+ *
+ * Including this file will automatically include all files from the Sabre_DAV
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @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
+ */
+
+// Begin includes
+include __DIR__ . '/Auth/IBackend.php';
+include __DIR__ . '/Client.php';
+include __DIR__ . '/Exception.php';
+include __DIR__ . '/INode.php';
+include __DIR__ . '/IProperties.php';
+include __DIR__ . '/Locks/Backend/Abstract.php';
+include __DIR__ . '/Locks/Backend/File.php';
+include __DIR__ . '/Locks/Backend/FS.php';
+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__ . '/Server.php';
+include __DIR__ . '/ServerPlugin.php';
+include __DIR__ . '/StringUtil.php';
+include __DIR__ . '/TemporaryFileFilterPlugin.php';
+include __DIR__ . '/Tree.php';
+include __DIR__ . '/URLUtil.php';
+include __DIR__ . '/UUIDUtil.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/XMLUtil.php';
+include __DIR__ . '/Auth/Backend/AbstractBasic.php';
+include __DIR__ . '/Auth/Backend/AbstractDigest.php';
+include __DIR__ . '/Auth/Backend/Apache.php';
+include __DIR__ . '/Auth/Backend/File.php';
+include __DIR__ . '/Auth/Backend/PDO.php';
+include __DIR__ . '/Auth/Plugin.php';
+include __DIR__ . '/Browser/GuessContentType.php';
+include __DIR__ . '/Browser/MapGetToPropFind.php';
+include __DIR__ . '/Browser/Plugin.php';
+include __DIR__ . '/Exception/BadRequest.php';
+include __DIR__ . '/Exception/Conflict.php';
+include __DIR__ . '/Exception/Forbidden.php';
+include __DIR__ . '/Exception/InsufficientStorage.php';
+include __DIR__ . '/Exception/InvalidResourceType.php';
+include __DIR__ . '/Exception/Locked.php';
+include __DIR__ . '/Exception/LockTokenMatchesRequestUri.php';
+include __DIR__ . '/Exception/MethodNotAllowed.php';
+include __DIR__ . '/Exception/NotAuthenticated.php';
+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/RequestedRangeNotSatisfiable.php';
+include __DIR__ . '/Exception/UnsupportedMediaType.php';
+include __DIR__ . '/FS/Node.php';
+include __DIR__ . '/FSExt/Node.php';
+include __DIR__ . '/ICollection.php';
+include __DIR__ . '/IExtendedCollection.php';
+include __DIR__ . '/IFile.php';
+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__ . '/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';
+include __DIR__ . '/FS/Directory.php';
+include __DIR__ . '/FS/File.php';
+include __DIR__ . '/FSExt/Directory.php';
+include __DIR__ . '/FSExt/File.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 100644
new mode 100755
index a361e054610dd2251f3bb1961b879a95de39d79a..e05b7749805c8cc40306f527f54734b72d17f830
--- a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
@@ -3,53 +3,52 @@
 /**
  * Principals Collection
  *
- * This is a helper class that easily allows you to create a collection that 
+ * This is a helper class that easily allows you to create a collection that
  * has a childnode for every principal.
- * 
- * To use this class, simply implement the getChildForPrincipal method. 
+ *
+ * To use this class, simply implement the getChildForPrincipal method.
  *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collection  {
 
     /**
-     * Node or 'directory' name. 
-     * 
-     * @var string 
+     * Node or 'directory' name.
+     *
+     * @var string
      */
     protected $path;
 
     /**
-     * Principal backend 
-     * 
-     * @var Sabre_DAVACL_IPrincipalBackend 
+     * Principal backend
+     *
+     * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
      * If this value is set to true, it effectively disables listing of users
-     * it still allows user to find other users if they have an exact url. 
-     * 
-     * @var bool 
+     * it still allows user to find other users if they have an exact url.
+     *
+     * @var bool
      */
     public $disableListing = false;
 
     /**
      * Creates the object
      *
-     * This object must be passed the principal backend. This object will 
-     * filter all principals from a specfied prefix ($principalPrefix). The 
-     * default is 'principals', if your principals are stored in a different 
+     * This object must be passed the principal backend. This object will
+     * filter all principals from a specified prefix ($principalPrefix). The
+     * default is 'principals', if your principals are stored in a different
      * collection, override $principalPrefix
-     * 
-     * 
-     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend 
+     *
+     *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
      * @param string $principalPrefix
-     * @param string $nodeName
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $principalPrefix = 'principals') {
 
@@ -64,28 +63,28 @@ abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collec
      * The passed array contains principal information, and is guaranteed to
      * at least contain a uri item. Other properties may or may not be
      * supplied by the authentication backend.
-     * 
-     * @param array $principalInfo 
+     *
+     * @param array $principalInfo
      * @return Sabre_DAVACL_IPrincipal
      */
     abstract function getChildForPrincipal(array $principalInfo);
 
     /**
-     * Returns the name of this collection. 
-     * 
-     * @return string 
+     * Returns the name of this collection.
+     *
+     * @return string
      */
     public function getName() {
 
         list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalPrefix);
-        return $name; 
+        return $name;
 
     }
 
     /**
-     * Return the list of users 
-     * 
-     * @return void
+     * Return the list of users
+     *
+     * @return array
      */
     public function getChildren() {
 
@@ -99,23 +98,57 @@ abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collec
 
 
         }
-        return $children; 
+        return $children;
 
     }
 
     /**
      * Returns a child object, by its name.
-     * 
+     *
      * @param string $name
-     * @throws Sabre_DAV_Exception_FileNotFound
+     * @throws Sabre_DAV_Exception_NotFound
      * @return Sabre_DAV_IPrincipal
      */
     public function getChild($name) {
 
         $principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix . '/' . $name);
-        if (!$principalInfo) throw new Sabre_DAV_Exception_FileNotFound('Principal with name ' . $name . ' not found');
+        if (!$principalInfo) throw new Sabre_DAV_Exception_NotFound('Principal with name ' . $name . ' not found');
         return $this->getChildForPrincipal($principalInfo);
 
     }
 
+    /**
+     * This method is used to search for principals matching a set of
+     * properties.
+     *
+     * This search is specifically used by RFC3744's principal-property-search
+     * REPORT. You should at least allow searching on
+     * http://sabredav.org/ns}email-address.
+     *
+     * The actual search should be a unicode-non-case-sensitive search. The
+     * keys in searchProperties are the WebDAV property names, while the values
+     * are the property values to search on.
+     *
+     * If multiple properties are being searched on, the search should be
+     * AND'ed.
+     *
+     * This method should simply return a list of 'child names', which may be
+     * used to call $this->getChild in the future.
+     *
+     * @param array $searchProperties
+     * @return array
+     */
+    public function searchPrincipals(array $searchProperties) {
+
+        $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties);
+        $r = array();
+
+        foreach($result as $row) {
+            list(, $r[]) = Sabre_DAV_URLUtil::splitPath($row);
+        }
+
+        return $r;
+
+    }
+
 }
diff --git a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
old mode 100644
new mode 100755
index d10aeb4345c6ff2c653f139db50f904dbf779093..4b9f93b003631770b295bcd0937db863d2971383
--- a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
+++ b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
@@ -1,12 +1,12 @@
 <?php
 
 /**
- * Sabre_DAVACL_Exception_AceConflict 
- * 
+ * Sabre_DAVACL_Exception_AceConflict
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Exception_AceConflict extends Sabre_DAV_Exception_Conflict {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_AceConflict extends Sabre_DAV_Exception_Conflict {
      * Adds in extra information in the xml response.
      *
      * This method adds the {DAV:}no-ace-conflict element as defined in rfc3744
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $errorNode 
+     *
+     * @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('DAV:','d:no-ace-conflict');
         $errorNode->appendChild($np);
 
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
old mode 100644
new mode 100755
index 024ab6641f35a851aad6d01b1790482dda6e058d..9b055dd9709ec8a9db6df77c98c9523fec426f52
--- a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
@@ -1,60 +1,61 @@
 <?php
 
 /**
- * NeedPrivileges 
+ * NeedPrivileges
  *
  * The 403-need privileges is thrown when a user didn't have the appropriate
  * permissions to perform an operation
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @version $Id$
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Exception_NeedPrivileges extends Sabre_DAV_Exception_Forbidden {
 
     /**
-     * The relevant uri 
-     * 
-     * @var string 
+     * The relevant uri
+     *
+     * @var string
      */
     protected $uri;
 
     /**
-     * The privileges the user didn't have. 
-     * 
-     * @var array 
+     * The privileges the user didn't have.
+     *
+     * @var array
      */
     protected $privileges;
 
     /**
-     * Constructor 
-     * 
-     * @param string $uri 
-     * @param array $privileges 
+     * Constructor
+     *
+     * @param string $uri
+     * @param array $privileges
      */
     public function __construct($uri,array $privileges) {
 
         $this->uri = $uri;
         $this->privileges = $privileges;
 
+        parent::__construct('User did not have the required privileges (' . implode(',', $privileges) . ') for path "' . $uri . '"');
+
     }
 
     /**
      * Adds in extra information in the xml response.
      *
      * This method adds the {DAV:}need-privileges element as defined in rfc3744
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $errorNode 
+     *
+     * @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('DAV:','d:need-privileges');
         $errorNode->appendChild($np);
 
diff --git a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
old mode 100644
new mode 100755
index 60f49ebff4adec68e1eee8454628737909961310..f44e3e32281719878e0aa9819272fafaf09ff4f1
--- a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
@@ -2,11 +2,11 @@
 
 /**
  * Sabre_DAVACL_Exception_NoAbstract
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Exception_NoAbstract extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NoAbstract extends Sabre_DAV_Exception_Precondition
      * Adds in extra information in the xml response.
      *
      * This method adds the {DAV:}no-abstract element as defined in rfc3744
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $errorNode 
+     *
+     * @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('DAV:','d:no-abstract');
         $errorNode->appendChild($np);
 
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
old mode 100644
new mode 100755
index e056dc9e4f70ff2c25e2a679fdb4e4669f2db2c9..8d1e38ca1b470d84d9ce38182bf02507c423b114
--- a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
@@ -2,11 +2,11 @@
 
 /**
  * Sabre_DAVACL_Exception_NotRecognizedPrincipal
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Exception_NotRecognizedPrincipal extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NotRecognizedPrincipal extends Sabre_DAV_Exception_
      * Adds in extra information in the xml response.
      *
      * This method adds the {DAV:}recognized-principal element as defined in rfc3744
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $errorNode 
+     *
+     * @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('DAV:','d:recognized-principal');
         $errorNode->appendChild($np);
 
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
old mode 100644
new mode 100755
index 27db7cdd7dd43be716b6248a8d4acdf73505e707..3b5d012d7fa25f35d7a5b8e6ad5a6dea005238cb
--- a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
@@ -2,11 +2,11 @@
 
 /**
  * Sabre_DAVACL_Exception_NotSupportedPrivilege
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Exception_NotSupportedPrivilege extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NotSupportedPrivilege extends Sabre_DAV_Exception_P
      * Adds in extra information in the xml response.
      *
      * This method adds the {DAV:}not-supported-privilege element as defined in rfc3744
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $errorNode 
+     *
+     * @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('DAV:','d:not-supported-privilege');
         $errorNode->appendChild($np);
 
     }
 
 }
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/IACL.php b/3rdparty/Sabre/DAVACL/IACL.php
old mode 100644
new mode 100755
index 506be4248d76b8bca9facd87097c128846e4f2bd..003e69934834a3b4ef0780b51c723ab486120d40
--- a/3rdparty/Sabre/DAVACL/IACL.php
+++ b/3rdparty/Sabre/DAVACL/IACL.php
@@ -4,11 +4,11 @@
  * ACL-enabled node
  *
  * If you want to add WebDAV ACL to a node, you must implement this class
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_IACL extends Sabre_DAV_INode {
@@ -16,8 +16,8 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     function getOwner();
@@ -26,8 +26,8 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     function getGroup();
 
@@ -35,24 +35,39 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     function getACL();
 
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     function setACL(array $acl);
 
+    /**
+     * 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
+     */
+    function getSupportedPrivilegeSet();
+
+
 }
diff --git a/3rdparty/Sabre/DAVACL/IPrincipal.php b/3rdparty/Sabre/DAVACL/IPrincipal.php
old mode 100644
new mode 100755
index 7868811db76394ef6101516b627bde7d1da54929..fc7605bf625bc9e27f95aae5926d69e30554ca9f
--- a/3rdparty/Sabre/DAVACL/IPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipal.php
@@ -2,50 +2,50 @@
 
 /**
  * IPrincipal interface
- * 
+ *
  * Implement this interface to define your own principals
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_IPrincipal extends Sabre_DAV_INode {
 
     /**
-     * Returns a list of altenative urls for a principal
-     * 
+     * Returns a list of alternative urls for a principal
+     *
      * This can for example be an email address, or ldap url.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     function getAlternateUriSet();
 
     /**
-     * Returns the full principal url 
-     * 
-     * @return string 
+     * Returns the full principal url
+     *
+     * @return string
      */
     function getPrincipalUrl();
 
     /**
      * Returns the list of group members
-     * 
+     *
      * If this principal is a group, this function should return
-     * all member principal uri's for the group. 
-     * 
+     * all member principal uri's for the group.
+     *
      * @return array
      */
     function getGroupMemberSet();
 
     /**
      * Returns the list of groups this principal is member of
-     * 
+     *
      * If this principal is a member of a (list of) groups, this function
-     * should return a list of principal uri's for it's members. 
-     * 
-     * @return array 
+     * should return a list of principal uri's for it's members.
+     *
+     * @return array
      */
     function getGroupMembership();
 
@@ -54,11 +54,11 @@ interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
      *
      * If this principal is a group, this method sets all the group members.
      * The list of members is always overwritten, never appended to.
-     * 
-     * This method should throw an exception if the members could not be set. 
-     * 
-     * @param array $principals 
-     * @return void 
+     *
+     * This method should throw an exception if the members could not be set.
+     *
+     * @param array $principals
+     * @return void
      */
     function setGroupMemberSet(array $principals);
 
@@ -66,9 +66,9 @@ interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
      * Returns the displayname
      *
      * This should be a human readable name for the principal.
-     * If none is available, return the nodename. 
-     * 
-     * @return string 
+     * If none is available, return the nodename.
+     *
+     * @return string
      */
     function getDisplayName();
 
diff --git a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
old mode 100644
new mode 100755
index 8899f6f80dffda4e838cf963ec1ce6ade41660f7..e798bf890c0a1e87aba4e2fad001eb68397bf785
--- a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
@@ -3,14 +3,14 @@
 /**
  * Implement this interface to create your own principal backends.
  *
- * Creating backends for principals is entirely optional. You can also 
- * implement Sabre_DAVACL_IPrincipal directly. This interface is used solely by 
+ * Creating backends for principals is entirely optional. You can also
+ * implement Sabre_DAVACL_IPrincipal directly. This interface is used solely by
  * Sabre_DAVACL_AbstractPrincipalCollection.
  *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_IPrincipalBackend {
@@ -18,56 +18,136 @@ interface Sabre_DAVACL_IPrincipalBackend {
     /**
      * Returns a list of principals based on a prefix.
      *
-     * This prefix will often contain something like 'principals'. You are only 
+     * This prefix will often contain something like 'principals'. You are only
      * expected to return principals that are in this base path.
      *
-     * You are expected to return at least a 'uri' for every user, you can 
+     * You are expected to return at least a 'uri' for every user, you can
      * return any additional properties if you wish so. Common properties are:
-     *   {DAV:}displayname 
-     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV 
-     *     field that's actualy injected in a number of other properties. If
+     *   {DAV:}displayname
+     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV
+     *     field that's actually injected in a number of other properties. If
      *     you have an email address, use this property.
-     * 
-     * @param string $prefixPath 
-     * @return array 
+     *
+     * @param string $prefixPath
+     * @return array
      */
     function getPrincipalsByPrefix($prefixPath);
 
     /**
      * Returns a specific principal, specified by it's path.
-     * The returned structure should be the exact same as from 
-     * getPrincipalsByPrefix. 
-     * 
-     * @param string $path 
-     * @return array 
+     * The returned structure should be the exact same as from
+     * getPrincipalsByPrefix.
+     *
+     * @param string $path
+     * @return array
      */
     function getPrincipalByPath($path);
 
     /**
-     * Returns the list of members for a group-principal 
-     * 
-     * @param string $principal 
-     * @return array 
+     * Updates one ore more webdav properties on a principal.
+     *
+     * The list of mutations is supplied as an array. Each key in the array is
+     * a propertyname, such as {DAV:}displayname.
+     *
+     * Each value is the actual value to be updated. If a value is null, it
+     * must be deleted.
+     *
+     * This method should be atomic. It must either completely succeed, or
+     * completely fail. Success and failure can simply be returned as 'true' or
+     * 'false'.
+     *
+     * It is also possible to return detailed failure information. In that case
+     * an array such as this should be returned:
+     *
+     * array(
+     *   200 => array(
+     *      '{DAV:}prop1' => null,
+     *   ),
+     *   201 => array(
+     *      '{DAV:}prop2' => null,
+     *   ),
+     *   403 => array(
+     *      '{DAV:}prop3' => null,
+     *   ),
+     *   424 => array(
+     *      '{DAV:}prop4' => null,
+     *   ),
+     * );
+     *
+     * In this previous example prop1 was successfully updated or deleted, and
+     * prop2 was succesfully created.
+     *
+     * prop3 failed to update due to '403 Forbidden' and because of this prop4
+     * also could not be updated with '424 Failed dependency'.
+     *
+     * This last example was actually incorrect. While 200 and 201 could appear
+     * in 1 response, if there's any error (403) the other properties should
+     * always fail with 423 (failed dependency).
+     *
+     * But anyway, if you don't want to scratch your head over this, just
+     * return true or false.
+     *
+     * @param string $path
+     * @param array $mutations
+     * @return array|bool
+     */
+    function updatePrincipal($path, $mutations);
+
+    /**
+     * This method is used to search for principals matching a set of
+     * properties.
+     *
+     * This search is specifically used by RFC3744's principal-property-search
+     * REPORT. You should at least allow searching on
+     * http://sabredav.org/ns}email-address.
+     *
+     * The actual search should be a unicode-non-case-sensitive search. The
+     * keys in searchProperties are the WebDAV property names, while the values
+     * are the property values to search on.
+     *
+     * If multiple properties are being searched on, the search should be
+     * AND'ed.
+     *
+     * This method should simply return an array with full principal uri's.
+     *
+     * If somebody attempted to search on a property the backend does not
+     * support, you should simply return 0 results.
+     *
+     * You can also just return 0 results if you choose to not support
+     * searching at all, but keep in mind that this may stop certain features
+     * from working.
+     *
+     * @param string $prefixPath
+     * @param array $searchProperties
+     * @return array
+     */
+    function searchPrincipals($prefixPath, array $searchProperties);
+
+    /**
+     * Returns the list of members for a group-principal
+     *
+     * @param string $principal
+     * @return array
      */
     function getGroupMemberSet($principal);
 
     /**
-     * Returns the list of groups a principal is a member of 
-     * 
-     * @param string $principal 
-     * @return array 
+     * Returns the list of groups a principal is a member of
+     *
+     * @param string $principal
+     * @return array
      */
     function getGroupMembership($principal);
 
     /**
      * Updates the list of group members for a group principal.
      *
-     * The principals should be passed as a list of uri's. 
-     * 
-     * @param string $principal 
-     * @param array $members 
+     * The principals should be passed as a list of uri's.
+     *
+     * @param string $principal
+     * @param array $members
      * @return void
      */
-    function setGroupMemberSet($principal, array $members); 
+    function setGroupMemberSet($principal, array $members);
 
 }
diff --git a/3rdparty/Sabre/DAVACL/Plugin.php b/3rdparty/Sabre/DAVACL/Plugin.php
old mode 100644
new mode 100755
index b964bdb5dec84466b71002cf4cce356174b5bb97..5c828c6d97be4f0cfc1273303daacc2284c432b6
--- a/3rdparty/Sabre/DAVACL/Plugin.php
+++ b/3rdparty/Sabre/DAVACL/Plugin.php
@@ -6,14 +6,14 @@
  * This plugin provides funcitonality to enforce ACL permissions.
  * ACL is defined in RFC3744.
  *
- * In addition it also provides support for the {DAV:}current-user-principal 
- * property, defined in RFC5397 and the {DAV:}expand-property report, as 
- * defined in RFC3253. 
- * 
+ * In addition it also provides support for the {DAV:}current-user-principal
+ * property, defined in RFC5397 and the {DAV:}expand-property report, as
+ * defined in RFC3253.
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
@@ -40,16 +40,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     const R_RECURSIVEPARENTS = 3;
 
     /**
-     * Reference to server object. 
-     * 
-     * @var Sabre_DAV_Server 
+     * Reference to server object.
+     *
+     * @var Sabre_DAV_Server
      */
     protected $server;
 
     /**
      * List of urls containing principal collections.
-     * Modify this if your principals are located elsewhere. 
-     * 
+     * Modify this if your principals are located elsewhere.
+     *
      * @var array
      */
     public $principalCollectionSet = array(
@@ -57,14 +57,14 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     );
 
     /**
-     * By default ACL is only enforced for nodes that have ACL support (the 
-     * ones that implement Sabre_DAVACL_IACL). For any other node, access is 
+     * By default ACL is only enforced for nodes that have ACL support (the
+     * ones that implement Sabre_DAVACL_IACL). For any other node, access is
      * always granted.
      *
-     * To override this behaviour you can turn this setting off. This is useful 
+     * To override this behaviour you can turn this setting off. This is useful
      * if you plan to fully support ACL in the entire tree.
      *
-     * @var bool 
+     * @var bool
      */
     public $allowAccessToNodesWithoutACL = true;
 
@@ -72,28 +72,50 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * By default nodes that are inaccessible by the user, can still be seen
      * in directory listings (PROPFIND on parent with Depth: 1)
      *
-     * In certain cases it's desirable to hide inaccessible nodes. Setting this 
+     * In certain cases it's desirable to hide inaccessible nodes. Setting this
      * to true will cause these nodes to be hidden from directory listings.
-     * 
-     * @var bool 
+     *
+     * @var bool
      */
     public $hideNodesFromListings = false;
 
     /**
-     * This string is prepended to the username of the currently logged in 
-     * user. This allows the plugin to determine the principal path based on 
+     * This string is prepended to the username of the currently logged in
+     * user. This allows the plugin to determine the principal path based on
      * the username.
-     * 
+     *
      * @var string
      */
     public $defaultUsernamePath = 'principals';
 
+    /**
+     * This list of properties are the properties a client can search on using
+     * the {DAV:}principal-property-search report.
+     *
+     * The keys are the property names, values are descriptions.
+     *
+     * @var array
+     */
+    public $principalSearchPropertySet = array(
+        '{DAV:}displayname' => 'Display name',
+        '{http://sabredav.org/ns}email-address' => 'Email address',
+    );
+
+    /**
+     * 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 
+     */
+    public $adminPrincipals = array();
+
     /**
      * Returns a list of features added by this plugin.
      *
      * This list is used in the response of a HTTP OPTIONS request.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getFeatures() {
 
@@ -102,10 +124,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Returns a list of available methods for a given url 
-     * 
-     * @param string $uri 
-     * @return array 
+     * Returns a list of available methods for a given url
+     *
+     * @param string $uri
+     * @return array
      */
     public function getMethods($uri) {
 
@@ -115,11 +137,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a plugin name.
-     * 
+     *
      * Using this name other plugins will be able to access other plugins
-     * using Sabre_DAV_Server::getPlugin 
-     * 
-     * @return string 
+     * using Sabre_DAV_Server::getPlugin
+     *
+     * @return string
      */
     public function getPluginName() {
 
@@ -131,37 +153,38 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * Returns a list of reports this plugin supports.
      *
      * This will be used in the {DAV:}supported-report-set property.
-     * Note that you still need to subscribe to the 'report' event to actually 
-     * implement them 
-     * 
+     * Note that you still need to subscribe to the 'report' event to actually
+     * implement them
+     *
      * @param string $uri
-     * @return array 
+     * @return array
      */
     public function getSupportedReportSet($uri) {
 
         return array(
             '{DAV:}expand-property',
             '{DAV:}principal-property-search',
-            '{DAV:}principal-search-property-set', 
+            '{DAV:}principal-search-property-set',
         );
 
     }
 
 
     /**
-     * Checks if the current user has the specified privilege(s). 
-     * 
+     * Checks if the current user has the specified privilege(s).
+     *
      * You can specify a single privilege, or a list of privileges.
      * This method will throw an exception if the privilege is not available
      * and return true otherwise.
      *
      * @param string $uri
      * @param array|string $privileges
-     * @param bool $throwExceptions if set to false, this method won't through exceptions. 
+     * @param int $recursion
+     * @param bool $throwExceptions if set to false, this method won't through exceptions.
      * @throws Sabre_DAVACL_Exception_NeedPrivileges
-     * @return bool 
+     * @return bool
      */
-    public function checkPrivileges($uri,$privileges,$recursion = self::R_PARENT, $throwExceptions = true) {
+    public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
 
         if (!is_array($privileges)) $privileges = array($privileges);
 
@@ -171,7 +194,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             if ($this->allowAccessToNodesWithoutACL) {
                 return true;
             } else {
-                if ($throwExceptions) 
+                if ($throwExceptions)
                     throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$privileges);
                 else
                     return false;
@@ -189,7 +212,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         }
 
         if ($failed) {
-            if ($throwExceptions) 
+            if ($throwExceptions)
                 throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$failed);
             else
                 return false;
@@ -202,9 +225,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * Returns the standard users' principal.
      *
      * This is one authorative principal url for the current user.
-     * This method will return null if the user wasn't logged in. 
-     * 
-     * @return string|null 
+     * This method will return null if the user wasn't logged in.
+     *
+     * @return string|null
      */
     public function getCurrentUserPrincipal() {
 
@@ -220,9 +243,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Returns a list of principals that's associated to the current
-     * user, either directly or through group membership. 
-     * 
-     * @return array 
+     * user, either directly or through group membership.
+     *
+     * @return array
      */
     public function getCurrentUserPrincipals() {
 
@@ -236,7 +259,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         while(count($check)) {
 
             $principal = array_shift($check);
- 
+
             $node = $this->server->tree->getNodeForPath($principal);
             if ($node instanceof Sabre_DAVACL_IPrincipal) {
                 foreach($node->getGroupMembership() as $groupMember) {
@@ -262,11 +285,38 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * Returns the supported privilege structure for this ACL plugin.
      *
      * See RFC3744 for more details. Currently we default on a simple,
-     * standard structure. 
-     * 
-     * @return array 
+     * standard structure.
+     *
+     * You can either get the list of privileges by a uri (path) or by
+     * specifying a Node.
+     *
+     * @param string|Sabre_DAV_INode $node
+     * @return array
      */
-    public function getSupportedPrivilegeSet() {
+    public function getSupportedPrivilegeSet($node) {
+
+        if (is_string($node)) {
+            $node = $this->server->tree->getNodeForPath($node);
+        }
+
+        if ($node instanceof Sabre_DAVACL_IACL) {
+            $result = $node->getSupportedPrivilegeSet();
+
+            if ($result)
+                return $result;
+        }
+
+        return self::getDefaultSupportedPrivilegeSet();
+
+    }
+
+    /**
+     * Returns a fairly standard set of privileges, which may be useful for
+     * other systems to use as a basis.
+     *
+     * @return array
+     */
+    static function getDefaultSupportedPrivilegeSet() {
 
         return array(
             'privilege'  => '{DAV:}all',
@@ -314,7 +364,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
                         ),
                     ),
                 ), // {DAV:}write
-            ), 
+            ),
         ); // {DAV:}all
 
     }
@@ -329,12 +379,13 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      *   - aggregates
      *   - abstract
      *   - concrete
-     * 
-     * @return array 
+     *
+     * @param string|Sabre_DAV_INode $node
+     * @return array
      */
-    final public function getFlatPrivilegeSet() {
+    final public function getFlatPrivilegeSet($node) {
 
-        $privs = $this->getSupportedPrivilegeSet();
+        $privs = $this->getSupportedPrivilegeSet($node);
 
         $flat = array();
         $this->getFPSTraverse($privs, null, $flat);
@@ -346,9 +397,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * Traverses the privilege set tree for reordering
      *
-     * This function is solely used by getFlatPrivilegeSet, and would have been 
+     * This function is solely used by getFlatPrivilegeSet, and would have been
      * a closure if it wasn't for the fact I need to support PHP 5.2.
-     * 
+     *
+     * @param array $priv
+     * @param $concrete
+     * @param array $flat
      * @return void
      */
     final private function getFPSTraverse($priv, $concrete, &$flat) {
@@ -368,7 +422,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         if (isset($priv['aggregates'])) {
 
             foreach($priv['aggregates'] as $subPriv) {
-            
+
                 $this->getFPSTraverse($subPriv, $myPriv['concrete'], $flat);
 
             }
@@ -382,8 +436,8 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * Either a uri or a Sabre_DAV_INode may be passed.
      *
-     * null will be returned if the node doesn't support ACLs. 
-     * 
+     * null will be returned if the node doesn't support ACLs.
+     *
      * @param string|Sabre_DAV_INode $node
      * @return array
      */
@@ -392,10 +446,18 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         if (is_string($node)) {
             $node = $this->server->tree->getNodeForPath($node);
         }
-        if ($node instanceof Sabre_DAVACL_IACL) {
-            return $node->getACL();
+        if (!$node instanceof Sabre_DAVACL_IACL) {
+            return null;
         }
-        return null; 
+        $acl = $node->getACL();
+        foreach($this->adminPrincipals as $adminPrincipal) {
+            $acl[] = array(
+                'principal' => $adminPrincipal,
+                'privilege' => '{DAV:}all',
+                'protected' => true,
+            );
+        }
+        return $acl;
 
     }
 
@@ -405,10 +467,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * Either a uri or a Sabre_DAV_INode may be passed.
      *
-     * null will be returned if the node doesn't support ACLs. 
-     * 
-     * @param string|Sabre_DAV_INode $node 
-     * @return array 
+     * null will be returned if the node doesn't support ACLs.
+     *
+     * @param string|Sabre_DAV_INode $node
+     * @return array
      */
     public function getCurrentUserPrivilegeSet($node) {
 
@@ -417,6 +479,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         }
 
         $acl = $this->getACL($node);
+
         if (is_null($acl)) return null;
 
         $principals = $this->getCurrentUserPrincipals();
@@ -425,27 +488,121 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         foreach($acl as $ace) {
 
-            if (in_array($ace['principal'], $principals)) {
-                $collected[] = $ace;
+            $principal = $ace['principal'];
+
+            switch($principal) {
+
+                case '{DAV:}owner' :
+                    $owner = $node->getOwner();
+                    if ($owner && in_array($owner, $principals)) {
+                        $collected[] = $ace;
+                    }
+                    break;
+
+
+                // 'all' matches for every user
+                case '{DAV:}all' :
+
+                // 'authenticated' matched for every user that's logged in.
+                // Since it's not possible to use ACL while not being logged
+                // in, this is also always true.
+                case '{DAV:}authenticated' :
+                    $collected[] = $ace;
+                    break;
+
+                // 'unauthenticated' can never occur either, so we simply
+                // ignore these.
+                case '{DAV:}unauthenticated' :
+                    break;
+
+                default :
+                    if (in_array($ace['principal'], $principals)) {
+                        $collected[] = $ace;
+                    }
+                    break;
+
             }
 
+
+
         }
 
         // Now we deduct all aggregated privileges.
-        $flat = $this->getFlatPrivilegeSet();
+        $flat = $this->getFlatPrivilegeSet($node);
 
         $collected2 = array();
-        foreach($collected as $privilege) {
+        while(count($collected)) {
+
+            $current = array_pop($collected);
+            $collected2[] = $current['privilege'];
 
-            $collected2[] = $privilege['privilege'];
-            foreach($flat[$privilege['privilege']]['aggregates'] as $subPriv) {
-                if (!in_array($subPriv, $collected2)) 
-                    $collected2[] = $subPriv;
+            foreach($flat[$current['privilege']]['aggregates'] as $subPriv) {
+                $collected2[] = $subPriv;
+                $collected[] = $flat[$subPriv];
             }
 
         }
 
-        return $collected2;
+        return array_values(array_unique($collected2));
+
+    }
+
+    /**
+     * Principal property search
+     *
+     * This method can search for principals matching certain values in
+     * properties.
+     *
+     * This method will return a list of properties for the matched properties.
+     *
+     * @param array $searchProperties    The properties to search on. This is a
+     *                                   key-value list. The keys are property
+     *                                   names, and the values the strings to
+     *                                   match them on.
+     * @param array $requestedProperties This is the list of properties to
+     *                                   return for every match.
+     * @param string $collectionUri      The principal collection to search on.
+     *                                   If this is ommitted, the standard
+     *                                   principal collection-set will be used.
+     * @return array     This method returns an array structure similar to
+     *                  Sabre_DAV_Server::getPropertiesForPath. Returned
+     *                  properties are index by a HTTP status code.
+     *
+     */
+    public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) {
+
+        if (!is_null($collectionUri)) {
+            $uris = array($collectionUri);
+        } else {
+            $uris = $this->principalCollectionSet;
+        }
+
+        $lookupResults = array();
+        foreach($uris as $uri) {
+
+            $principalCollection = $this->server->tree->getNodeForPath($uri);
+            if (!$principalCollection instanceof Sabre_DAVACL_AbstractPrincipalCollection) {
+                // Not a principal collection, we're simply going to ignore
+                // this.
+                continue;
+            }
+
+            $results = $principalCollection->searchPrincipals($searchProperties);
+            foreach($results as $result) {
+                $lookupResults[] = rtrim($uri,'/') . '/' . $result;
+            }
+
+        }
+
+        $matches = array();
+
+        foreach($lookupResults as $lookupResult) {
+
+            list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0);
+
+        }
+
+        return $matches;
 
     }
 
@@ -453,8 +610,8 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * Sets up the plugin
      *
      * This method is automatically called by the server class.
-     * 
-     * @param Sabre_DAV_Server $server 
+     *
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     public function initialize(Sabre_DAV_Server $server) {
@@ -485,11 +642,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             '{DAV:}group'
         );
 
-        // Automatically mapping nodes implementing IPrincipal to the 
+        // Automatically mapping nodes implementing IPrincipal to the
         // {DAV:}principal resourcetype.
         $server->resourceTypeMapping['Sabre_DAVACL_IPrincipal'] = '{DAV:}principal';
 
-        // Mapping the group-member-set property to the HrefList property 
+        // Mapping the group-member-set property to the HrefList property
         // class.
         $server->propertyMap['{DAV:}group-member-set'] = 'Sabre_DAV_Property_HrefList';
 
@@ -499,10 +656,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /* {{{ Event handlers */
 
     /**
-     * Triggered before any method is handled 
-     * 
-     * @param string $method 
-     * @param string $uri 
+     * Triggered before any method is handled
+     *
+     * @param string $method
+     * @param string $uri
      * @return void
      */
     public function beforeMethod($method, $uri) {
@@ -523,14 +680,14 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
             case 'PUT' :
             case 'LOCK' :
-            case 'UNLOCK' : 
-                // This method requires the write-content priv if the node 
-                // already exists, and bind on the parent if the node is being 
-                // created. 
-                // The bind privilege is handled in the beforeBind event. 
+            case 'UNLOCK' :
+                // This method requires the write-content priv if the node
+                // already exists, and bind on the parent if the node is being
+                // created.
+                // The bind privilege is handled in the beforeBind event.
                 $this->checkPrivileges($uri,'{DAV:}write-content');
                 break;
-            
+
 
             case 'PROPPATCH' :
                 $this->checkPrivileges($uri,'{DAV:}write-properties');
@@ -543,16 +700,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             case 'COPY' :
             case 'MOVE' :
                 // Copy requires read privileges on the entire source tree.
-                // If the target exists write-content normally needs to be 
-                // checked, however, we're deleting the node beforehand and 
-                // creating a new one after, so this is handled by the 
+                // If the target exists write-content normally needs to be
+                // checked, however, we're deleting the node beforehand and
+                // creating a new one after, so this is handled by the
                 // beforeUnbind event.
-                // 
-                // The creation of the new node is handled by the beforeBind 
+                //
+                // The creation of the new node is handled by the beforeBind
                 // event.
                 //
-                // If MOVE is used beforeUnbind will also be used to check if 
-                // the sourcenode can be deleted. 
+                // If MOVE is used beforeUnbind will also be used to check if
+                // the sourcenode can be deleted.
                 $this->checkPrivileges($uri,'{DAV:}read',self::R_RECURSIVE);
 
                 break;
@@ -563,11 +720,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
     /**
      * Triggered before a new node is created.
-     * 
+     *
      * This allows us to check permissions for any operation that creates a
      * new node, such as PUT, MKCOL, MKCALENDAR, LOCK, COPY and MOVE.
-     * 
-     * @param string $uri 
+     *
+     * @param string $uri
      * @return void
      */
     public function beforeBind($uri) {
@@ -578,12 +735,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Triggered before a node is deleted 
-     * 
-     * This allows us to check permissions for any operation that will delete 
-     * an existing node. 
-     * 
-     * @param string $uri 
+     * Triggered before a node is deleted
+     *
+     * This allows us to check permissions for any operation that will delete
+     * an existing node.
+     *
+     * @param string $uri
      * @return void
      */
     public function beforeUnbind($uri) {
@@ -594,26 +751,26 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * Triggered before a node is unlocked. 
-     * 
-     * @param string $uri 
+     * Triggered before a node is unlocked.
+     *
+     * @param string $uri
      * @param Sabre_DAV_Locks_LockInfo $lock
-     * @TODO: not yet implemented 
+     * @TODO: not yet implemented
      * @return void
      */
     public function beforeUnlock($uri, Sabre_DAV_Locks_LockInfo $lock) {
-           
+
 
     }
 
     /**
-     * Triggered before properties are looked up in specific nodes. 
-     * 
-     * @param string $uri 
-     * @param Sabre_DAV_INode $node 
-     * @param array $requestedProperties 
+     * Triggered before properties are looked up in specific nodes.
+     *
+     * @param string $uri
+     * @param Sabre_DAV_INode $node
+     * @param array $requestedProperties
      * @param array $returnedProperties
-     * @TODO really should be broken into multiple methods, or even a class. 
+     * @TODO really should be broken into multiple methods, or even a class.
      * @return void
      */
     public function beforeGetProperties($uri, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) {
@@ -633,7 +790,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             }
             return;
 
-        } 
+        }
 
         /* Adding principal properties */
         if ($node instanceof Sabre_DAVACL_IPrincipal) {
@@ -692,7 +849,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         if (false !== ($index = array_search('{DAV:}supported-privilege-set', $requestedProperties))) {
 
             unset($requestedProperties[$index]);
-            $returnedProperties[200]['{DAV:}supported-privilege-set'] = new Sabre_DAVACL_Property_SupportedPrivilegeSet($this->getSupportedPrivilegeSet());
+            $returnedProperties[200]['{DAV:}supported-privilege-set'] = new Sabre_DAVACL_Property_SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node));
 
         }
         if (false !== ($index = array_search('{DAV:}current-user-privilege-set', $requestedProperties))) {
@@ -730,16 +887,24 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
+        /* The acl-restrictions property contains information on how privileges
+         * must behave.
+         */
+        if (false !== ($index = array_search('{DAV:}acl-restrictions', $requestedProperties))) {
+            unset($requestedProperties[$index]);
+            $returnedProperties[200]['{DAV:}acl-restrictions'] = new Sabre_DAVACL_Property_AclRestrictions();
+        }
+
     }
 
     /**
-     * This method intercepts PROPPATCH methods and make sure the 
-     * group-member-set is updated correctly. 
-     * 
-     * @param array $propertyDelta 
-     * @param array $result 
-     * @param Sabre_DAV_INode $node 
-     * @return void
+     * This method intercepts PROPPATCH methods and make sure the
+     * group-member-set is updated correctly.
+     *
+     * @param array $propertyDelta
+     * @param array $result
+     * @param Sabre_DAV_INode $node
+     * @return bool
      */
     public function updateProperties(&$propertyDelta, &$result, Sabre_DAV_INode $node) {
 
@@ -763,18 +928,18 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         }
 
         $node->setGroupMemberSet($memberSet);
-        
+
         $result[200]['{DAV:}group-member-set'] = null;
         unset($propertyDelta['{DAV:}group-member-set']);
 
     }
 
     /**
-     * This method handels HTTP REPORT requests 
-     * 
-     * @param string $reportName 
-     * @param DOMNode $dom 
-     * @return void
+     * This method handels HTTP REPORT requests
+     *
+     * @param string $reportName
+     * @param DOMNode $dom
+     * @return bool
      */
     public function report($reportName, $dom) {
 
@@ -785,7 +950,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
                 return false;
             case '{DAV:}principal-search-property-set' :
                 $this->principalSearchPropertySetReport($dom);
-                return false; 
+                return false;
             case '{DAV:}expand-property' :
                 $this->expandPropertyReport($dom);
                 return false;
@@ -795,12 +960,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     }
 
     /**
-     * This event is triggered for any HTTP method that is not known by the 
-     * webserver. 
+     * This event is triggered for any HTTP method that is not known by the
+     * webserver.
      *
-     * @param string $method 
-     * @param string $uri 
-     * @return void
+     * @param string $method
+     * @param string $uri
+     * @return bool
      */
     public function unknownMethod($method, $uri) {
 
@@ -817,12 +982,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * @param string $uri
      * @return void
      */
-    public function httpACL($uri) { 
+    public function httpACL($uri) {
 
         $body = $this->server->httpRequest->getBody(true);
         $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
 
-        $newAcl = 
+        $newAcl =
             Sabre_DAVACL_Property_Acl::unserialize($dom->firstChild)
             ->getPrivileges();
 
@@ -839,13 +1004,13 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         $oldAcl = $this->getACL($node);
 
-        $supportedPrivileges = $this->getFlatPrivilegeSet(); 
+        $supportedPrivileges = $this->getFlatPrivilegeSet($node);
 
-        /* Checking if protected principals from the existing principal set are 
+        /* Checking if protected principals from the existing principal set are
            not overwritten. */
-        foreach($oldAcl as $k=>$oldAce) {
+        foreach($oldAcl as $oldAce) {
 
-            if (!isset($oldAce['protected']) || !$oldAce['protected']) continue; 
+            if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
 
             $found = false;
             foreach($newAcl as $newAce) {
@@ -853,16 +1018,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
                     $newAce['privilege'] === $oldAce['privilege'] &&
                     $newAce['principal'] === $oldAce['principal'] &&
                     $newAce['protected']
-                ) 
+                )
                 $found = true;
             }
 
-            if (!$found) 
+            if (!$found)
                 throw new Sabre_DAVACL_Exception_AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
 
         }
 
-        foreach($newAcl as $k=>$newAce) {
+        foreach($newAcl as $newAce) {
 
             // Do we recognize the privilege
             if (!isset($supportedPrivileges[$newAce['privilege']])) {
@@ -876,12 +1041,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             // Looking up the principal
             try {
                 $principal = $this->server->tree->getNodeForPath($newAce['principal']);
-            } catch (Sabre_DAV_Exception_FileNotFound $e) {
+            } catch (Sabre_DAV_Exception_NotFound $e) {
                 throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
             }
             if (!($principal instanceof Sabre_DAVACL_IPrincipal)) {
                 throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
-            } 
+            }
 
         }
         $node->setACL($newAcl);
@@ -893,7 +1058,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /* Reports {{{ */
 
     /**
-     * The expand-property report is defined in RFC3253 section 3-8. 
+     * The expand-property report is defined in RFC3253 section 3-8.
      *
      * This report is very similar to a standard PROPFIND. The difference is
      * that it has the additional ability to look at properties containing a
@@ -903,7 +1068,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * Other rfc's, such as ACL rely on this report, so it made sense to put
      * it in this plugin.
      *
-     * @param DOMElement $dom 
+     * @param DOMElement $dom
      * @return void
      */
     protected function expandPropertyReport($dom) {
@@ -940,9 +1105,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * This method is used by expandPropertyReport to parse
      * out the entire HTTP request.
-     * 
-     * @param DOMElement $node 
-     * @return array 
+     *
+     * @param DOMElement $node
+     * @return array
      */
     protected function parseExpandPropertyReportRequest($node) {
 
@@ -950,9 +1115,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         do {
 
             if (Sabre_DAV_XMLUtil::toClarkNotation($node)!=='{DAV:}property') continue;
-                
+
             if ($node->firstChild) {
-                
+
                 $children = $this->parseExpandPropertyReportRequest($node->firstChild);
 
             } else {
@@ -965,7 +1130,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
             if (!$namespace) $namespace = 'DAV:';
 
             $propName = '{'.$namespace.'}' . $node->getAttribute('name');
-            $requestedProperties[$propName] = $children; 
+            $requestedProperties[$propName] = $children;
 
         } while ($node = $node->nextSibling);
 
@@ -979,11 +1144,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      *
      * @param array $path
      * @param array $requestedProperties the list of required properties
-     * @param array $depth
+     * @param int $depth
+     * @return array
      */
-    protected function expandProperties($path,array $requestedProperties,$depth) { 
+    protected function expandProperties($path, array $requestedProperties, $depth) {
 
-        $foundProperties = $this->server->getPropertiesForPath($path,array_keys($requestedProperties),$depth);
+        $foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth);
 
         $result = array();
 
@@ -993,7 +1159,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
                 // We're only traversing if sub-properties were requested
                 if(count($childRequestedProperties)===0) continue;
-                
+
                 // We only have to do the expansion if the property was found
                 // and it contains an href element.
                 if (!array_key_exists($propertyName,$node[200])) continue;
@@ -1006,7 +1172,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
                 $childProps = array();
                 foreach($hrefs as $href) {
-                    $childProps = array_merge($childProps, $this->expandProperties($href,$childRequestedProperties,0));
+                    $childProps = array_merge($childProps, $this->expandProperties($href, $childRequestedProperties, 0));
                 }
                 $node[200][$propertyName] = new Sabre_DAV_Property_ResponseList($childProps);
 
@@ -1022,27 +1188,23 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * principalSearchPropertySetReport
      *
-     * This method responsible for handing the 
+     * This method responsible for handing the
      * {DAV:}principal-search-property-set report. This report returns a list
      * of properties the client may search on, using the
      * {DAV:}principal-property-search report.
-     * 
-     * @param DOMDocument $dom 
+     *
+     * @param DOMDocument $dom
      * @return void
      */
     protected function principalSearchPropertySetReport(DOMDocument $dom) {
 
-        $searchProperties = array(
-            '{DAV:}displayname' => 'display name'
-        );
-
         $httpDepth = $this->server->getHTTPDepth(0);
         if ($httpDepth!==0) {
             throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0');
         }
-        
-        if ($dom->firstChild->hasChildNodes()) 
-            throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements'); 
+
+        if ($dom->firstChild->hasChildNodes())
+            throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements');
 
         $dom = new DOMDocument('1.0','utf-8');
         $dom->formatOutput = true;
@@ -1055,16 +1217,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
         }
 
-        $nsList = $this->server->xmlNamespaces; 
+        $nsList = $this->server->xmlNamespaces;
 
-        foreach($searchProperties as $propertyName=>$description) {
+        foreach($this->principalSearchPropertySet as $propertyName=>$description) {
 
             $psp = $dom->createElement('d:principal-search-property');
             $root->appendChild($psp);
 
             $prop = $dom->createElement('d:prop');
             $psp->appendChild($prop);
-  
+
             $propName = null;
             preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
 
@@ -1088,78 +1250,25 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
     /**
      * principalPropertySearchReport
      *
-     * This method is reponsible for handing the 
-     * {DAV:}principal-property-search report. This report can be used for 
+     * This method is responsible for handing the
+     * {DAV:}principal-property-search report. This report can be used for
      * clients to search for groups of principals, based on the value of one
      * or more properties.
-     * 
-     * @param DOMDocument $dom 
+     *
+     * @param DOMDocument $dom
      * @return void
      */
     protected function principalPropertySearchReport(DOMDocument $dom) {
 
-        $searchableProperties = array(
-            '{DAV:}displayname' => 'display name'
-
-        );
-
         list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet) = $this->parsePrincipalPropertySearchReportRequest($dom);
 
-        $result = array();
-
-        if ($applyToPrincipalCollectionSet) {
-            $uris = array();
-        } else {
-            $uris = array($this->server->getRequestUri());
-        }
-
-        $lookupResults = array();
-        foreach($uris as $uri) {
-
-            $p = array_keys($searchProperties);
-            $p[] = '{DAV:}resourcetype';
-            $r = $this->server->getPropertiesForPath($uri, $p, 1);
-
-            // The first item in the results is the parent, so we get rid of it.
-            array_shift($r);
-            $lookupResults = array_merge($lookupResults, $r);
-        } 
-
-        $matches = array();
-
-        foreach($lookupResults as $lookupResult) {
-
-            // We're only looking for principals 
-            if (!isset($lookupResult[200]['{DAV:}resourcetype']) || 
-                (!($lookupResult[200]['{DAV:}resourcetype'] instanceof Sabre_DAV_Property_ResourceType)) ||
-                !$lookupResult[200]['{DAV:}resourcetype']->is('{DAV:}principal')) continue;
-
-            foreach($searchProperties as $searchProperty=>$searchValue) {
-                if (!isset($searchableProperties[$searchProperty])) {
-                    // If a property is not 'searchable', the spec dictates 
-                    // this is not a match. 
-                    continue;
-                }
-
-                if (isset($lookupResult[200][$searchProperty]) &&
-                    mb_stripos($lookupResult[200][$searchProperty], $searchValue, 0, 'UTF-8')!==false) {
-                        $matches[] = $lookupResult['href'];
-                }
-
-            }
-
+        $uri = null;
+        if (!$applyToPrincipalCollectionSet) {
+            $uri = $this->server->getRequestUri();
         }
+        $result = $this->principalSearch($searchProperties, $requestedProperties, $uri);
 
-        $matchProperties = array();
-
-        foreach($matches as $match) {
-            
-           list($result) = $this->server->getPropertiesForPath($match, $requestedProperties, 0);
-           $matchProperties[] = $result;
-
-        }
-
-        $xml = $this->server->generateMultiStatus($matchProperties);
+        $xml = $this->server->generateMultiStatus($result);
         $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
         $this->server->httpResponse->sendStatus(207);
         $this->server->httpResponse->sendBody($xml);
@@ -1175,9 +1284,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
      * This method returns an array with two elements:
      *  1. an array with properties to search on, and their values
      *  2. a list of propertyvalues that should be returned for the request.
-     * 
-     * @param DOMDocument $dom 
-     * @return array 
+     *
+     * @param DOMDocument $dom
+     * @return array
      */
     protected function parsePrincipalPropertySearchReportRequest($dom) {
 
@@ -1193,8 +1302,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
         // Parsing the search request
         foreach($dom->firstChild->childNodes as $searchNode) {
 
-            if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set')
+            if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set') {
                 $applyToPrincipalCollectionSet = true;
+            }
 
             if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode)!=='{DAV:}property-search')
                 continue;
@@ -1208,7 +1318,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
 
                     case '{DAV:}prop' :
                         $property = Sabre_DAV_XMLUtil::parseProperties($searchNode);
-                        reset($property); 
+                        reset($property);
                         $propertyName = key($property);
                         break;
 
diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php
old mode 100644
new mode 100755
index 790603c900f33f3361bcab9cdbea308744dd1383..51c6658afd64ce3c626682208389965a1ddce361
--- a/3rdparty/Sabre/DAVACL/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Principal.php
@@ -4,17 +4,17 @@
  * Principal class
  *
  * This class is a representation of a simple principal
- * 
- * Many WebDAV specs require a user to show up in the directory 
- * structure. 
+ *
+ * Many WebDAV specs require a user to show up in the directory
+ * structure.
  *
  * This principal also has basic ACL settings, only allowing the principal
- * access it's own principal. 
- * 
+ * access it's own principal.
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPrincipal, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
@@ -22,20 +22,21 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
     /**
      * Struct with principal information.
      *
-     * @var array 
+     * @var array
      */
     protected $principalProperties;
 
     /**
-     * Principal backend 
-     * 
-     * @var Sabre_DAVACL_IPrincipalBackend 
+     * Principal backend
+     *
+     * @var Sabre_DAVACL_IPrincipalBackend
      */
     protected $principalBackend;
 
     /**
-     * Creates the principal object 
+     * Creates the principal object
      *
+     * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
      * @param array $principalProperties
      */
     public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalProperties = array()) {
@@ -49,22 +50,22 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
     }
 
     /**
-     * Returns the full principal url 
-     * 
-     * @return string 
+     * Returns the full principal url
+     *
+     * @return string
      */
     public function getPrincipalUrl() {
 
         return $this->principalProperties['uri'];
 
-    } 
+    }
 
     /**
-     * Returns a list of altenative urls for a principal
-     * 
+     * Returns a list of alternative urls for a principal
+     *
      * This can for example be an email address, or ldap url.
-     * 
-     * @return array 
+     *
+     * @return array
      */
     public function getAlternateUriSet() {
 
@@ -79,16 +80,16 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
             $uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
         }
 
-        return array_unique($uris); 
+        return array_unique($uris);
 
     }
 
     /**
      * Returns the list of group members
-     * 
+     *
      * If this principal is a group, this function should return
-     * all member principal uri's for the group. 
-     * 
+     * all member principal uri's for the group.
+     *
      * @return array
      */
     public function getGroupMemberSet() {
@@ -99,11 +100,11 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
 
     /**
      * Returns the list of groups this principal is member of
-     * 
+     *
      * If this principal is a member of a (list of) groups, this function
-     * should return a list of principal uri's for it's members. 
-     * 
-     * @return array 
+     * should return a list of principal uri's for it's members.
+     *
+     * @return array
      */
     public function getGroupMembership() {
 
@@ -117,11 +118,11 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
      *
      * If this principal is a group, this method sets all the group members.
      * The list of members is always overwritten, never appended to.
-     * 
-     * This method should throw an exception if the members could not be set. 
-     * 
-     * @param array $principals 
-     * @return void 
+     *
+     * This method should throw an exception if the members could not be set.
+     *
+     * @param array $groupMembers
+     * @return void
      */
     public function setGroupMemberSet(array $groupMembers) {
 
@@ -132,22 +133,21 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
 
     /**
      * Returns this principals name.
-     * 
-     * @return string 
+     *
+     * @return string
      */
     public function getName() {
 
         $uri = $this->principalProperties['uri'];
         list(, $name) = Sabre_DAV_URLUtil::splitPath($uri);
-
         return $name;
 
     }
 
     /**
-     * Returns the name of the user 
-     * 
-     * @return void
+     * Returns the name of the user
+     *
+     * @return string
      */
     public function getDisplayName() {
 
@@ -160,16 +160,16 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
     }
 
     /**
-     * Returns a list of properties 
-     * 
-     * @param array $requestedProperties 
-     * @return void
+     * Returns a list of properties
+     *
+     * @param array $requestedProperties
+     * @return array
      */
     public function getProperties($requestedProperties) {
 
         $newProperties = array();
         foreach($requestedProperties as $propName) {
-            
+
             if (isset($this->principalProperties[$propName])) {
                 $newProperties[$propName] = $this->principalProperties[$propName];
             }
@@ -177,29 +177,27 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
         }
 
         return $newProperties;
-        
+
     }
 
     /**
      * Updates this principals properties.
-     *
-     * Currently this is not supported
      * 
-     * @param array $properties
+     * @param array $mutations
      * @see Sabre_DAV_IProperties::updateProperties
-     * @return bool|array 
+     * @return bool|array
      */
-    public function updateProperties($properties) {
+    public function updateProperties($mutations) {
 
-        return false;
+        return $this->principalBackend->updatePrincipal($this->principalProperties['uri'], $mutations);
 
     }
 
     /**
      * Returns the owner principal
      *
-     * This must be a url to a principal, or null if there's no owner 
-     * 
+     * This must be a url to a principal, or null if there's no owner
+     *
      * @return string|null
      */
     public function getOwner() {
@@ -213,8 +211,8 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
      * Returns a group principal
      *
      * This must be a url to a principal, or null if there's no owner
-     * 
-     * @return string|null 
+     *
+     * @return string|null
      */
     public function getGroup() {
 
@@ -226,20 +224,20 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
      * 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 
+     *   * '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 
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
      */
     public function getACL() {
 
         return array(
             array(
                 'privilege' => '{DAV:}read',
-                'principal' => $this->principalProperties['uri'],
+                'principal' => $this->getPrincipalUrl(),
                 'protected' => true,
             ),
         );
@@ -249,9 +247,9 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
     /**
      * Updates the ACL
      *
-     * This method will receive a list of new ACE's. 
-     * 
-     * @param array $acl 
+     * This method will receive a list of new ACE's.
+     *
+     * @param array $acl
      * @return void
      */
     public function setACL(array $acl) {
@@ -260,4 +258,22 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
 
     }
 
+    /**
+     * 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/DAVACL/PrincipalBackend/PDO.php b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
old mode 100644
new mode 100755
index 55bd1903c9bfe5a626524bcf9f6d01b17eeca78a..a76b4a9d7279dcaf47e7286eb718c237b6ca4d5a
--- a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
@@ -3,46 +3,80 @@
 /**
  * PDO principal backend
  *
- * This is a simple principal backend that maps exactly to the users table, as 
+ * This is a simple principal backend that maps exactly to the users table, as
  * used by Sabre_DAV_Auth_Backend_PDO.
  *
- * It assumes all principals are in a single collection. The default collection 
+ * It assumes all principals are in a single collection. The default collection
  * is 'principals/', but this can be overriden.
  *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBackend {
 
     /**
-     * pdo 
-     * 
-     * @var PDO 
+     * pdo
+     *
+     * @var PDO
      */
     protected $pdo;
 
     /**
-     * PDO table name for 'principals' 
-     * 
-     * @var string 
+     * PDO table name for 'principals'
+     *
+     * @var string
      */
     protected $tableName;
 
     /**
-     * PDO table name for 'group members' 
-     * 
-     * @var string 
+     * PDO table name for 'group members'
+     *
+     * @var string
      */
     protected $groupMembersTableName;
 
+    /**
+     * A list of additional fields to support
+     *
+     * @var array
+     */
+    protected $fieldMap = array(
+
+        /**
+         * This property can be used to display the users' real name.
+         */
+        '{DAV:}displayname' => array(
+            'dbField' => 'displayname',
+        ),
+
+        /**
+         * This property is actually used by the CardDAV plugin, where it gets
+         * mapped to {http://calendarserver.orgi/ns/}me-card.
+         *
+         * The reason we don't straight-up use that property, is because
+         * me-card is defined as a property on the users' addressbook
+         * collection.
+         */
+        '{http://sabredav.org/ns}vcard-url' => array(
+            'dbField' => 'vcardurl',
+        ),
+        /**
+         * This is the users' primary email-address.
+         */
+        '{http://sabredav.org/ns}email-address' => array(
+            'dbField' => 'email',
+        ),
+    );
+
     /**
      * Sets up the backend.
-     * 
+     *
      * @param PDO $pdo
-     * @param string $tableName 
+     * @param string $tableName
+     * @param string $groupMembersTableName
      */
     public function __construct(PDO $pdo, $tableName = 'principals', $groupMembersTableName = 'groupmembers') {
 
@@ -50,27 +84,35 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
         $this->tableName = $tableName;
         $this->groupMembersTableName = $groupMembersTableName;
 
-    } 
+    }
 
 
     /**
      * Returns a list of principals based on a prefix.
      *
-     * This prefix will often contain something like 'principals'. You are only 
+     * This prefix will often contain something like 'principals'. You are only
      * expected to return principals that are in this base path.
      *
-     * You are expected to return at least a 'uri' for every user, you can 
+     * You are expected to return at least a 'uri' for every user, you can
      * return any additional properties if you wish so. Common properties are:
-     *   {DAV:}displayname 
-     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV 
+     *   {DAV:}displayname
+     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV
      *     field that's actualy injected in a number of other properties. If
      *     you have an email address, use this property.
-     * 
-     * @param string $prefixPath 
-     * @return array 
+     *
+     * @param string $prefixPath
+     * @return array
      */
     public function getPrincipalsByPrefix($prefixPath) {
-        $result = $this->pdo->query('SELECT uri, email, displayname FROM `'. $this->tableName . '`');
+
+        $fields = array(
+            'uri',
+        );
+
+        foreach($this->fieldMap as $key=>$value) {
+            $fields[] = $value['dbField'];
+        }
+        $result = $this->pdo->query('SELECT '.implode(',', $fields).'  FROM '. $this->tableName);
 
         $principals = array();
 
@@ -80,11 +122,15 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
             list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
             if ($rowPrefix !== $prefixPath) continue;
 
-            $principals[] = array(
+            $principal = array(
                 'uri' => $row['uri'],
-                '{DAV:}displayname' => $row['displayname']?$row['displayname']:basename($row['uri']),
-                '{http://sabredav.org/ns}email-address' => $row['email'],
             );
+            foreach($this->fieldMap as $key=>$value) {
+                if ($row[$value['dbField']]) {
+                    $principal[$key] = $row[$value['dbField']];
+                }
+            }
+            $principals[] = $principal;
 
         }
 
@@ -94,43 +140,218 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
 
     /**
      * Returns a specific principal, specified by it's path.
-     * The returned structure should be the exact same as from 
-     * getPrincipalsByPrefix. 
-     * 
-     * @param string $path 
-     * @return array 
+     * The returned structure should be the exact same as from
+     * getPrincipalsByPrefix.
+     *
+     * @param string $path
+     * @return array
      */
     public function getPrincipalByPath($path) {
 
-        $stmt = $this->pdo->prepare('SELECT id, uri, email, displayname FROM `'.$this->tableName.'` WHERE uri = ?');
-        $stmt->execute(array($path));
+        $fields = array(
+            'id',
+            'uri',
+        );
 
-        $users = array();
+        foreach($this->fieldMap as $key=>$value) {
+            $fields[] = $value['dbField'];
+        }
+        $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).'  FROM '. $this->tableName . ' WHERE uri = ?');
+        $stmt->execute(array($path));
 
         $row = $stmt->fetch(PDO::FETCH_ASSOC);
         if (!$row) return;
 
-        return array(
+        $principal = array(
             'id'  => $row['id'],
             'uri' => $row['uri'],
-            '{DAV:}displayname' => $row['displayname']?$row['displayname']:basename($row['uri']),
-            '{http://sabredav.org/ns}email-address' => $row['email'],
         );
+        foreach($this->fieldMap as $key=>$value) {
+            if ($row[$value['dbField']]) {
+                $principal[$key] = $row[$value['dbField']];
+            }
+        }
+        return $principal;
+
+    }
+
+    /**
+     * Updates one ore more webdav properties on a principal.
+     *
+     * The list of mutations is supplied as an array. Each key in the array is
+     * a propertyname, such as {DAV:}displayname.
+     *
+     * Each value is the actual value to be updated. If a value is null, it
+     * must be deleted.
+     *
+     * This method should be atomic. It must either completely succeed, or
+     * completely fail. Success and failure can simply be returned as 'true' or
+     * 'false'.
+     *
+     * It is also possible to return detailed failure information. In that case
+     * an array such as this should be returned:
+     *
+     * array(
+     *   200 => array(
+     *      '{DAV:}prop1' => null,
+     *   ),
+     *   201 => array(
+     *      '{DAV:}prop2' => null,
+     *   ),
+     *   403 => array(
+     *      '{DAV:}prop3' => null,
+     *   ),
+     *   424 => array(
+     *      '{DAV:}prop4' => null,
+     *   ),
+     * );
+     *
+     * In this previous example prop1 was successfully updated or deleted, and
+     * prop2 was succesfully created.
+     *
+     * prop3 failed to update due to '403 Forbidden' and because of this prop4
+     * also could not be updated with '424 Failed dependency'.
+     *
+     * This last example was actually incorrect. While 200 and 201 could appear
+     * in 1 response, if there's any error (403) the other properties should
+     * always fail with 423 (failed dependency).
+     *
+     * But anyway, if you don't want to scratch your head over this, just
+     * return true or false.
+     *
+     * @param string $path
+     * @param array $mutations
+     * @return array|bool
+     */
+    public function updatePrincipal($path, $mutations) {
+
+        $updateAble = array();
+        foreach($mutations as $key=>$value) {
+
+            // We are not aware of this field, we must fail.
+            if (!isset($this->fieldMap[$key])) {
+
+                $response = array(
+                    403 => array(
+                        $key => null,
+                    ),
+                    424 => array(),
+                );
+
+                // Adding the rest to the response as a 424
+                foreach($mutations as $subKey=>$subValue) {
+                    if ($subKey !== $key) {
+                        $response[424][$subKey] = null;
+                    }
+                }
+                return $response;
+            }
+
+            $updateAble[$this->fieldMap[$key]['dbField']] = $value;
+
+        }
+
+        // No fields to update
+        $query = "UPDATE " . $this->tableName . " SET ";
+
+        $first = true;
+        foreach($updateAble as $key => $value) {
+            if (!$first) {
+                $query.= ', ';
+            }
+            $first = false;
+            $query.= "$key = :$key ";
+        }
+        $query.='WHERE uri = :uri';
+        $stmt = $this->pdo->prepare($query);
+        $updateAble['uri'] =  $path;
+        $stmt->execute($updateAble);
+
+        return true;
 
     }
 
     /**
-     * Returns the list of members for a group-principal 
-     * 
-     * @param string $principal 
-     * @return array 
+     * This method is used to search for principals matching a set of
+     * properties.
+     *
+     * This search is specifically used by RFC3744's principal-property-search
+     * REPORT. You should at least allow searching on
+     * http://sabredav.org/ns}email-address.
+     *
+     * The actual search should be a unicode-non-case-sensitive search. The
+     * keys in searchProperties are the WebDAV property names, while the values
+     * are the property values to search on.
+     *
+     * If multiple properties are being searched on, the search should be
+     * AND'ed.
+     *
+     * This method should simply return an array with full principal uri's.
+     *
+     * If somebody attempted to search on a property the backend does not
+     * support, you should simply return 0 results.
+     *
+     * You can also just return 0 results if you choose to not support
+     * searching at all, but keep in mind that this may stop certain features
+     * from working.
+     *
+     * @param string $prefixPath
+     * @param array $searchProperties
+     * @return array
+     */
+    public function searchPrincipals($prefixPath, array $searchProperties) {
+
+        $query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 ';
+        $values = array();
+        foreach($searchProperties as $property => $value) {
+
+            switch($property) {
+
+                case '{DAV:}displayname' :
+                    $query.=' AND displayname LIKE ?';
+                    $values[] = '%' . $value . '%';
+                    break;
+                case '{http://sabredav.org/ns}email-address' :
+                    $query.=' AND email LIKE ?';
+                    $values[] = '%' . $value . '%';
+                    break;
+                default :
+                    // Unsupported property
+                    return array();
+
+            }
+
+        }
+        $stmt = $this->pdo->prepare($query);
+        $stmt->execute($values);
+
+        $principals = array();
+        while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+            // Checking if the principal is in the prefix
+            list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
+            if ($rowPrefix !== $prefixPath) continue;
+
+            $principals[] = $row['uri'];
+
+        }
+
+        return $principals;
+
+    }
+
+    /**
+     * Returns the list of members for a group-principal
+     *
+     * @param string $principal
+     * @return array
      */
     public function getGroupMemberSet($principal) {
 
         $principal = $this->getPrincipalByPath($principal);
         if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
 
-        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM `'.$this->groupMembersTableName.'` AS groupmembers LEFT JOIN `'.$this->tableName.'` AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
+        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
         $stmt->execute(array($principal['id']));
 
         $result = array();
@@ -138,21 +359,21 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
             $result[] = $row['uri'];
         }
         return $result;
-    
+
     }
 
     /**
-     * Returns the list of groups a principal is a member of 
-     * 
-     * @param string $principal 
-     * @return array 
+     * Returns the list of groups a principal is a member of
+     *
+     * @param string $principal
+     * @return array
      */
     public function getGroupMembership($principal) {
 
         $principal = $this->getPrincipalByPath($principal);
         if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
 
-        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM `'.$this->groupMembersTableName.'` AS groupmembers LEFT JOIN `'.$this->tableName.'` AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
+        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
         $stmt->execute(array($principal['id']));
 
         $result = array();
@@ -166,16 +387,16 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
     /**
      * Updates the list of group members for a group principal.
      *
-     * The principals should be passed as a list of uri's. 
-     * 
-     * @param string $principal 
-     * @param array $members 
+     * The principals should be passed as a list of uri's.
+     *
+     * @param string $principal
+     * @param array $members
      * @return void
      */
     public function setGroupMemberSet($principal, array $members) {
 
         // Grabbing the list of principal id's.
-        $stmt = $this->pdo->prepare('SELECT id, uri FROM `'.$this->tableName.'` WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
+        $stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
         $stmt->execute(array_merge(array($principal), $members));
 
         $memberIds = array();
@@ -191,12 +412,12 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
         if (!$principalId) throw new Sabre_DAV_Exception('Principal not found');
 
         // Wiping out old members
-        $stmt = $this->pdo->prepare('DELETE FROM `'.$this->groupMembersTableName.'` WHERE principal_id = ?;');
+        $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;');
         $stmt->execute(array($principalId));
 
         foreach($memberIds as $memberId) {
 
-            $stmt = $this->pdo->prepare('INSERT INTO `'.$this->groupMembersTableName.'` (principal_id, member_id) VALUES (?, ?);');
+            $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);');
             $stmt->execute(array($principalId, $memberId));
 
         }
diff --git a/3rdparty/Sabre/DAVACL/PrincipalCollection.php b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
old mode 100644
new mode 100755
index 4d22bf8aa7509b5e6d153e8f4788ffa3bbf80df6..c3e4cb83f23c4d004b15c884f0a5253a70c5fbf1
--- a/3rdparty/Sabre/DAVACL/PrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
@@ -7,11 +7,11 @@
  * Sabre_DAV_Auth_Backend to determine which users are available on the list.
  *
  * The users are instances of Sabre_DAV_Auth_Principal
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_PrincipalCollection extends Sabre_DAVACL_AbstractPrincipalCollection {
@@ -22,9 +22,9 @@ class Sabre_DAVACL_PrincipalCollection extends Sabre_DAVACL_AbstractPrincipalCol
      * The passed array contains principal information, and is guaranteed to
      * at least contain a uri item. Other properties may or may not be
      * supplied by the authentication backend.
-     * 
-     * @param array $principal 
-     * @return Sabre_DAV_INode 
+     *
+     * @param array $principal
+     * @return Sabre_DAV_INode
      */
     public function getChildForPrincipal(array $principal) {
 
diff --git a/3rdparty/Sabre/DAVACL/Property/Acl.php b/3rdparty/Sabre/DAVACL/Property/Acl.php
old mode 100644
new mode 100755
index e41e7411310af9e7286da705c45ae587ad9431bc..05e1a690b3cb23c1fdb3ba05ce19b18aa41f9fd7
--- a/3rdparty/Sabre/DAVACL/Property/Acl.php
+++ b/3rdparty/Sabre/DAVACL/Property/Acl.php
@@ -1,47 +1,47 @@
 <?php
 
 /**
- * This class represents the {DAV:}acl property 
- * 
+ * This class represents the {DAV:}acl property
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Property_Acl extends Sabre_DAV_Property {
 
     /**
-     * List of privileges 
-     * 
-     * @var array 
+     * List of privileges
+     *
+     * @var array
      */
     private $privileges;
 
     /**
-     * Wether or not the server base url is required to be prefixed when 
-     * serializing the property. 
-     * 
-     * @var boolean 
+     * Whether or not the server base url is required to be prefixed when
+     * serializing the property.
+     *
+     * @var boolean
      */
     private $prefixBaseUrl;
 
     /**
      * Constructor
      *
-     * This object requires a structure similar to the return value from 
+     * This object requires a structure similar to the return value from
      * Sabre_DAVACL_Plugin::getACL().
      *
-     * Each privilege is a an array with at least a 'privilege' property, and a 
-     * 'principal' property. A privilege may have a 'protected' property as 
-     * well. 
+     * Each privilege is a an array with at least a 'privilege' property, and a
+     * 'principal' property. A privilege may have a 'protected' property as
+     * well.
      *
-     * The prefixBaseUrl should be set to false, if the supplied principal urls 
-     * are already full urls. If this is kept to true, the servers base url 
-     * will automatically be prefixed. 
+     * The prefixBaseUrl should be set to false, if the supplied principal urls
+     * are already full urls. If this is kept to true, the servers base url
+     * will automatically be prefixed.
      *
-     * @param bool $prefixBaseUrl 
-     * @param array $privileges 
+     * @param bool $prefixBaseUrl
+     * @param array $privileges
      */
     public function __construct(array $privileges, $prefixBaseUrl = true) {
 
@@ -51,9 +51,9 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
     }
 
     /**
-     * Returns the list of privileges for this property 
-     * 
-     * @return array 
+     * Returns the list of privileges for this property
+     *
+     * @return array
      */
     public function getPrivileges() {
 
@@ -62,10 +62,10 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes the property into a DOMElement 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * Serializes the property into a DOMElement
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -80,10 +80,10 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
     }
 
     /**
-     * Unserializes the {DAV:}acl xml element. 
-     * 
-     * @param DOMElement $dom 
-     * @return Sabre_DAVACL_Property_Acl 
+     * Unserializes the {DAV:}acl xml element.
+     *
+     * @param DOMElement $dom
+     * @return Sabre_DAVACL_Property_Acl
      */
     static public function unserialize(DOMElement $dom) {
 
@@ -98,11 +98,22 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
             }
             $principal = Sabre_DAVACL_Property_Principal::unserialize($principal->item(0));
 
-            if ($principal->getType()!==Sabre_DAVACL_Property_Principal::HREF) {
-                throw new Sabre_DAV_Exception_NotImplemented('Currently only uri based principals are support, {DAV:}all, {DAV:}unauthenticated and {DAV:}authenticated are not implemented yet');
+            switch($principal->getType()) {
+                case Sabre_DAVACL_Property_Principal::HREF :
+                    $principal = $principal->getHref();
+                    break;
+                case Sabre_DAVACL_Property_Principal::AUTHENTICATED :
+                    $principal = '{DAV:}authenticated';
+                    break;
+                case Sabre_DAVACL_Property_Principal::UNAUTHENTICATED :
+                    $principal = '{DAV:}unauthenticated';
+                    break;
+                case Sabre_DAVACL_Property_Principal::ALL :
+                    $principal = '{DAV:}all';
+                    break;
+
             }
 
-            $principal = $principal->getHref();
             $protected = false;
 
             if ($xace->getElementsByTagNameNS('urn:DAV','protected')->length > 0) {
@@ -140,7 +151,7 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
                     'privilege' => $privilegeName,
                 );
 
-            } 
+            }
 
         }
 
@@ -149,12 +160,12 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes a single access control entry. 
-     * 
-     * @param DOMDocument $doc 
-     * @param DOMElement $node 
+     * Serializes a single access control entry.
+     *
+     * @param DOMDocument $doc
+     * @param DOMElement $node
      * @param array $ace
-     * @param Sabre_DAV_Server $server 
+     * @param Sabre_DAV_Server $server
      * @return void
      */
     private function serializeAce($doc,$node,$ace, $server) {
@@ -164,7 +175,19 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
 
         $principal = $doc->createElementNS('DAV:','d:principal');
         $xace->appendChild($principal);
-        $principal->appendChild($doc->createElementNS('DAV:','d:href',($this->prefixBaseUrl?$server->getBaseUri():'') . $ace['principal'] . '/'));
+        switch($ace['principal']) {
+            case '{DAV:}authenticated' :
+                $principal->appendChild($doc->createElementNS('DAV:','d:authenticated'));
+                break;
+            case '{DAV:}unauthenticated' :
+                $principal->appendChild($doc->createElementNS('DAV:','d:unauthenticated'));
+                break;
+            case '{DAV:}all' :
+                $principal->appendChild($doc->createElementNS('DAV:','d:all'));
+                break;
+            default:
+                $principal->appendChild($doc->createElementNS('DAV:','d:href',($this->prefixBaseUrl?$server->getBaseUri():'') . $ace['principal'] . '/'));
+        }
 
         $grant = $doc->createElementNS('DAV:','d:grant');
         $xace->appendChild($grant);
diff --git a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
new file mode 100755
index 0000000000000000000000000000000000000000..a8b054956ddc705eb1e6b01c9610199ae02199d7
--- /dev/null
+++ b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * AclRestrictions property
+ *
+ * This property represents {DAV:}acl-restrictions, as defined in RFC3744.
+ *
+ * @package Sabre
+ * @subpackage DAVACL
+ * @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_DAVACL_Property_AclRestrictions extends Sabre_DAV_Property {
+
+    /**
+     * Serializes the property into a DOMElement
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $elem
+     * @return void
+     */
+    public function serialize(Sabre_DAV_Server $server,DOMElement $elem) {
+
+        $doc = $elem->ownerDocument;
+
+        $elem->appendChild($doc->createElementNS('DAV:','d:grant-only'));
+        $elem->appendChild($doc->createElementNS('DAV:','d:no-invert'));
+
+    }
+
+}
diff --git a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
old mode 100644
new mode 100755
index 72274597b3194c5309039799b9cad51417b83cb8..94a29640615ecdb4229d8a8971b8811edb33933e
--- a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
@@ -2,31 +2,31 @@
 
 /**
  * CurrentUserPrivilegeSet
- * 
- * This class represents the current-user-privilege-set property. When 
- * requested, it contain all the privileges a user has on a specific node. 
- * 
+ *
+ * This class represents the current-user-privilege-set property. When
+ * requested, it contain all the privileges a user has on a specific node.
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
 
     /**
-     * List of privileges 
-     * 
-     * @var array 
+     * List of privileges
+     *
+     * @var array
      */
     private $privileges;
 
     /**
      * Creates the object
      *
-     * Pass the privileges in clark-notation 
-     * 
-     * @param array $privileges 
+     * Pass the privileges in clark-notation
+     *
+     * @param array $privileges
      */
     public function __construct(array $privileges) {
 
@@ -35,10 +35,10 @@ class Sabre_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes the property in the DOM 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * Serializes the property in the DOM
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -53,11 +53,11 @@ class Sabre_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes one privilege 
-     * 
-     * @param DOMDocument $doc 
-     * @param DOMElement $node 
-     * @param string $privName 
+     * Serializes one privilege
+     *
+     * @param DOMDocument $doc
+     * @param DOMElement $node
+     * @param string $privName
      * @return void
      */
     protected function serializePriv($doc,$node,$privName) {
diff --git a/3rdparty/Sabre/DAVACL/Property/Principal.php b/3rdparty/Sabre/DAVACL/Property/Principal.php
old mode 100644
new mode 100755
index dad9a3550fb5678f493d74dd8efcaacc6d77ca53..c36328a58e0b877086d43bb34f02050f5a0a1c8e
--- a/3rdparty/Sabre/DAVACL/Property/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Property/Principal.php
@@ -4,12 +4,12 @@
  * Principal property
  *
  * The principal property represents a principal from RFC3744 (ACL).
- * The property can be used to specify a principal or pseudo principals. 
+ * The property can be used to specify a principal or pseudo principals.
  *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
@@ -25,16 +25,21 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
     const AUTHENTICATED = 2;
 
     /**
-     * Specific princpals can be specified with the HREF
+     * Specific principals can be specified with the HREF
      */
     const HREF = 3;
 
+    /**
+     * Everybody, basically
+     */
+    const ALL = 4;
+
     /**
      * Principal-type
      *
      * Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
-     * 
-     * @var int 
+     *
+     * @var int
      */
     private $type;
 
@@ -42,8 +47,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
      * Url to principal
      *
      * This value is only used for the HREF principal type.
-     * 
-     * @var string 
+     *
+     * @var string
      */
     private $href;
 
@@ -53,10 +58,9 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
      * The 'type' argument must be one of the type constants defined in this class.
      *
      * 'href' is only required for the HREF type.
-     * 
-     * @param int $type 
-     * @param string $href 
-     * @return void
+     *
+     * @param int $type
+     * @param string|null $href
      */
     public function __construct($type, $href = null) {
 
@@ -70,9 +74,9 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
     }
 
     /**
-     * Returns the principal type 
-     * 
-     * @return int 
+     * Returns the principal type
+     *
+     * @return int
      */
     public function getType() {
 
@@ -81,8 +85,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
     }
 
     /**
-     * Returns the principal uri. 
-     * 
+     * Returns the principal uri.
+     *
      * @return string
      */
     public function getHref() {
@@ -92,10 +96,10 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
     }
 
     /**
-     * Serializes the property into a DOMElement. 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * Serializes the property into a DOMElement.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server, DOMElement $node) {
@@ -124,10 +128,10 @@ 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 
+     * Deserializes a DOM element into a property object.
+     *
+     * @param DOMElement $dom
+     * @return Sabre_DAV_Property_Principal
      */
     static public function unserialize(DOMElement $dom) {
 
@@ -144,6 +148,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
                 return new self(self::AUTHENTICATED);
             case '{DAV:}href':
                 return new self(self::HREF, $parent->textContent);
+            case '{DAV:}all':
+                return new self(self::ALL);
             default :
                 throw new Sabre_DAV_Exception_BadRequest('Unexpected element (' . Sabre_DAV_XMLUtil::toClarkNotation($parent) . '). Could not deserialize');
 
diff --git a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
old mode 100644
new mode 100755
index 93c3895035d0a44c115ce095a0b3e4bda0406380..276d57ae0938fca6cde2f195a2cbbece0ed1c8df
--- a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
@@ -3,32 +3,32 @@
 /**
  * SupportedPrivilegeSet property
  *
- * This property encodes the {DAV:}supported-privilege-set property, as defined 
+ * This property encodes the {DAV:}supported-privilege-set property, as defined
  * in rfc3744. Please consult the rfc for details about it's structure.
  *
- * This class expects a structure like the one given from 
- * Sabre_DAVACL_Plugin::getSupportedPrivilegeSet as the argument in its 
+ * This class expects a structure like the one given from
+ * Sabre_DAVACL_Plugin::getSupportedPrivilegeSet as the argument in its
  * constructor.
- *   
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
 
     /**
-     * privileges 
-     * 
-     * @var array 
+     * privileges
+     *
+     * @var array
      */
     private $privileges;
 
     /**
-     * Constructor 
-     * 
-     * @param array $privileges 
+     * Constructor
+     *
+     * @param array $privileges
      */
     public function __construct(array $privileges) {
 
@@ -37,10 +37,10 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
     }
 
     /**
-     * Serializes the property into a domdocument. 
-     * 
-     * @param Sabre_DAV_Server $server 
-     * @param DOMElement $node 
+     * Serializes the property into a domdocument.
+     *
+     * @param Sabre_DAV_Server $server
+     * @param DOMElement $node
      * @return void
      */
     public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -53,11 +53,11 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
     /**
      * Serializes a property
      *
-     * This is a recursive function. 
-     * 
-     * @param DOMDocument $doc 
-     * @param DOMElement $node 
-     * @param array $privilege 
+     * This is a recursive function.
+     *
+     * @param DOMDocument $doc
+     * @param DOMElement $node
+     * @param array $privilege
      * @return void
      */
     private function serializePriv($doc,$node,$privilege) {
@@ -81,7 +81,7 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
             $xsp->appendChild($doc->createElementNS('DAV:','d:description',$privilege['description']));
         }
 
-        if (isset($privilege['aggregates'])) { 
+        if (isset($privilege['aggregates'])) {
             foreach($privilege['aggregates'] as $subPrivilege) {
                 $this->serializePriv($doc,$xsp,$subPrivilege);
             }
diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php
old mode 100644
new mode 100755
index 124463e311e1c04d01acbc1f9da56e5d6d38bc4e..9950f748741b150087c6504afb6a65df5a005aef
--- a/3rdparty/Sabre/DAVACL/Version.php
+++ b/3rdparty/Sabre/DAVACL/Version.php
@@ -2,10 +2,10 @@
 
 /**
  * This class contains the SabreDAV version constants.
- * 
+ *
  * @package Sabre
  * @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,7 +14,7 @@ class Sabre_DAVACL_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.5.2';
+    const VERSION = '1.6.0';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAVACL/includes.php b/3rdparty/Sabre/DAVACL/includes.php
new file mode 100755
index 0000000000000000000000000000000000000000..28fa3eed2258e771e831e02e2c57f652435049f1
--- /dev/null
+++ b/3rdparty/Sabre/DAVACL/includes.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Sabre_DAVACL includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_DAVACL package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage DAVACL
+ * @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
+ */
+
+// Begin includes
+include __DIR__ . '/AbstractPrincipalCollection.php';
+include __DIR__ . '/Exception/AceConflict.php';
+include __DIR__ . '/Exception/NeedPrivileges.php';
+include __DIR__ . '/Exception/NoAbstract.php';
+include __DIR__ . '/Exception/NotRecognizedPrincipal.php';
+include __DIR__ . '/Exception/NotSupportedPrivilege.php';
+include __DIR__ . '/IACL.php';
+include __DIR__ . '/IPrincipal.php';
+include __DIR__ . '/IPrincipalBackend.php';
+include __DIR__ . '/Plugin.php';
+include __DIR__ . '/Principal.php';
+include __DIR__ . '/PrincipalBackend/PDO.php';
+include __DIR__ . '/PrincipalCollection.php';
+include __DIR__ . '/Property/Acl.php';
+include __DIR__ . '/Property/AclRestrictions.php';
+include __DIR__ . '/Property/CurrentUserPrivilegeSet.php';
+include __DIR__ . '/Property/Principal.php';
+include __DIR__ . '/Property/SupportedPrivilegeSet.php';
+include __DIR__ . '/Version.php';
+// End includes
diff --git a/3rdparty/Sabre/HTTP/AWSAuth.php b/3rdparty/Sabre/HTTP/AWSAuth.php
old mode 100644
new mode 100755
index 5e4668cd94d8ff35589282aa4af9d9cba2d828bd..fb8245c8cbf71d15b0aac05a2953387382842b32
--- a/3rdparty/Sabre/HTTP/AWSAuth.php
+++ b/3rdparty/Sabre/HTTP/AWSAuth.php
@@ -4,34 +4,34 @@
  * HTTP AWS Authentication handler
  *
  * Use this class to leverage amazon's AWS authentication header
- * 
+ *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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
  */
 class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
 
     /**
-     * The signature supplied by the HTTP client 
-     * 
-     * @var string 
+     * The signature supplied by the HTTP client
+     *
+     * @var string
      */
     private $signature = null;
 
     /**
-     * The accesskey supplied by the HTTP client 
-     * 
-     * @var string 
+     * The accesskey supplied by the HTTP client
+     *
+     * @var string
      */
     private $accessKey = null;
 
     /**
      * An error code, if any
      *
-     * This value will be filled with one of the ERR_* contants
-     * 
+     * This value will be filled with one of the ERR_* constants
+     *
      * @var int
      */
     public $errorCode = 0;
@@ -46,8 +46,8 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
      * Gathers all information from the headers
      *
      * This method needs to be called prior to anything else.
-     * 
-     * @return bool 
+     *
+     * @return bool
      */
     public function init() {
 
@@ -66,9 +66,9 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Returns the username for the request 
-     * 
-     * @return string 
+     * Returns the username for the request
+     *
+     * @return string
      */
     public function getAccessKey() {
 
@@ -78,8 +78,9 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
 
     /**
      * Validates the signature based on the secretKey
-     * 
-     * @return bool 
+     *
+     * @param string $secretKey
+     * @return bool
      */
     public function validate($secretKey) {
 
@@ -89,7 +90,7 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
             // We need to validate the integrity of the request
             $body = $this->httpRequest->getBody(true);
             $this->httpRequest->setBody($body,true);
-           
+
             if ($contentMD5!=base64_encode(md5($body,true))) {
                 // content-md5 header did not match md5 signature of body
                 $this->errorCode = self::ERR_MD5CHECKSUMWRONG;
@@ -98,10 +99,10 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
 
         }
 
-        if (!$requestDate = $this->httpRequest->getHeader('x-amz-date')) 
+        if (!$requestDate = $this->httpRequest->getHeader('x-amz-date'))
             $requestDate = $this->httpRequest->getHeader('Date');
 
-        if (!$this->validateRFC2616Date($requestDate)) 
+        if (!$this->validateRFC2616Date($requestDate))
             return false;
 
         $amzHeaders = $this->getAmzHeaders();
@@ -109,10 +110,10 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
         $signature = base64_encode(
             $this->hmacsha1($secretKey,
                 $this->httpRequest->getMethod() . "\n" .
-                $contentMD5 . "\n" . 
+                $contentMD5 . "\n" .
                 $this->httpRequest->getHeader('Content-type') . "\n" .
                 $requestDate . "\n" .
-                $amzHeaders . 
+                $amzHeaders .
                 $this->httpRequest->getURI()
             )
         );
@@ -146,14 +147,14 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
     /**
      * Makes sure the supplied value is a valid RFC2616 date.
      *
-     * If we would just use strtotime to get a valid timestamp, we have no way of checking if a 
+     * If we would just use strtotime to get a valid timestamp, we have no way of checking if a
      * user just supplied the word 'now' for the date header.
      *
-     * This function also makes sure the Date header is within 15 minutes of the operating 
+     * This function also makes sure the Date header is within 15 minutes of the operating
      * system date, to prevent replay attacks.
-     * 
-     * @param string $dateHeader 
-     * @return bool 
+     *
+     * @param string $dateHeader
+     * @return bool
      */
     protected function validateRFC2616Date($dateHeader) {
 
@@ -177,11 +178,11 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
         return $date;
 
     }
-    
+
     /**
-     * Returns a list of AMZ headers 
-     * 
-     * @return void
+     * Returns a list of AMZ headers
+     *
+     * @return string
      */
     protected function getAmzHeaders() {
 
@@ -193,7 +194,7 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
             }
         }
         ksort($amzHeaders);
-       
+
         $headerStr = '';
         foreach($amzHeaders as $h=>$v) {
             $headerStr.=$h.':'.$v;
@@ -204,11 +205,11 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Generates an HMAC-SHA1 signature 
-     * 
-     * @param string $key 
-     * @param string $message 
-     * @return string 
+     * Generates an HMAC-SHA1 signature
+     *
+     * @param string $key
+     * @param string $message
+     * @return string
      */
     private function hmacsha1($key, $message) {
 
diff --git a/3rdparty/Sabre/HTTP/AbstractAuth.php b/3rdparty/Sabre/HTTP/AbstractAuth.php
old mode 100644
new mode 100755
index eb528f6fdee56dd507f63eb511952ff6298d49d2..3bccabcd1c17833aded522cc77214f84175337f3
--- a/3rdparty/Sabre/HTTP/AbstractAuth.php
+++ b/3rdparty/Sabre/HTTP/AbstractAuth.php
@@ -4,10 +4,10 @@
  * HTTP Authentication baseclass
  *
  * This class has the common functionality for BasicAuth and DigestAuth
- * 
+ *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -17,29 +17,29 @@ abstract class Sabre_HTTP_AbstractAuth {
      * The realm will be displayed in the dialog boxes
      *
      * This identifier can be changed through setRealm()
-     * 
+     *
      * @var string
      */
     protected $realm = 'SabreDAV';
 
     /**
-     * HTTP response helper 
-     * 
-     * @var Sabre_HTTP_Response 
+     * HTTP response helper
+     *
+     * @var Sabre_HTTP_Response
      */
     protected $httpResponse;
 
 
     /**
-     * HTTP request helper 
-     * 
-     * @var Sabre_HTTP_Request 
+     * HTTP request helper
+     *
+     * @var Sabre_HTTP_Request
      */
     protected $httpRequest;
 
     /**
-     * __construct 
-     * 
+     * __construct
+     *
      */
     public function __construct() {
 
@@ -49,9 +49,9 @@ abstract class Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Sets an alternative HTTP response object 
-     * 
-     * @param Sabre_HTTP_Response $response 
+     * Sets an alternative HTTP response object
+     *
+     * @param Sabre_HTTP_Response $response
      * @return void
      */
     public function setHTTPResponse(Sabre_HTTP_Response $response) {
@@ -61,9 +61,9 @@ abstract class Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Sets an alternative HTTP request object 
-     * 
-     * @param Sabre_HTTP_Request $request 
+     * Sets an alternative HTTP request object
+     *
+     * @param Sabre_HTTP_Request $request
      * @return void
      */
     public function setHTTPRequest(Sabre_HTTP_Request $request) {
@@ -78,8 +78,8 @@ abstract class Sabre_HTTP_AbstractAuth {
      *
      * The realm is often displayed in authentication dialog boxes
      * Commonly an application name displayed here
-     * 
-     * @param string $realm 
+     *
+     * @param string $realm
      * @return void
      */
     public function setRealm($realm) {
@@ -91,7 +91,7 @@ abstract class Sabre_HTTP_AbstractAuth {
     /**
      * Returns the realm
      *
-     * @return string 
+     * @return string
      */
     public function getRealm() {
 
@@ -106,6 +106,6 @@ abstract class Sabre_HTTP_AbstractAuth {
      *
      * @return void
      */
-    abstract public function requireLogin(); 
+    abstract public function requireLogin();
 
 }
diff --git a/3rdparty/Sabre/HTTP/BasicAuth.php b/3rdparty/Sabre/HTTP/BasicAuth.php
old mode 100644
new mode 100755
index 35c22d22dc3837dcd51fe7d87f654b9ff3c1ce18..a747cc6a31bf134e2b409d4d39d002d12e38c6f9
--- a/3rdparty/Sabre/HTTP/BasicAuth.php
+++ b/3rdparty/Sabre/HTTP/BasicAuth.php
@@ -4,11 +4,11 @@
  * HTTP Basic Authentication handler
  *
  * Use this class for easy http authentication setup
- * 
+ *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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
  */
 class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
@@ -22,7 +22,7 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
      *
      * If nothing was supplied, 'false' will be returned
      *
-     * @return mixed 
+     * @return mixed
      */
     public function getUserPass() {
 
@@ -33,12 +33,18 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
 
         }
 
-        // Most other webservers 
+        // Most other webservers
         $auth = $this->httpRequest->getHeader('Authorization');
 
+        // Apache could prefix environment variables with REDIRECT_ when urls
+        // are passed through mod_rewrite
+        if (!$auth) {
+            $auth = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
+        }
+
         if (!$auth) return false;
 
-        if (strpos(strtolower($auth),'basic')!==0) return false; 
+        if (strpos(strtolower($auth),'basic')!==0) return false;
 
         return explode(':', base64_decode(substr($auth, 6)));
 
diff --git a/3rdparty/Sabre/HTTP/DigestAuth.php b/3rdparty/Sabre/HTTP/DigestAuth.php
old mode 100644
new mode 100755
index 5e7559295710025ba5bd86f777f75b68a1fac17e..ee7f05c08ed848d61945d938200de5908bb6929d
--- a/3rdparty/Sabre/HTTP/DigestAuth.php
+++ b/3rdparty/Sabre/HTTP/DigestAuth.php
@@ -10,18 +10,18 @@
  *  2. Call the setRealm() method with the realm you plan to use
  *  3. Call the init method function.
  *  4. Call the getUserName() function. This function may return false if no
- *     authentication information was supplied. Based on the username you 
+ *     authentication information was supplied. Based on the username you
  *     should check your internal database for either the associated password,
  *     or the so-called A1 hash of the digest.
  *  5. Call either validatePassword() or validateA1(). This will return true
- *     or false. 
+ *     or false.
  *  6. To make sure an authentication prompt is displayed, call the
  *     requireLogin() method.
- * 
- * 
+ *
+ *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -40,7 +40,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
     protected $qop = self::QOP_AUTH;
 
     /**
-     * Initializes the object 
+     * Initializes the object
      */
     public function __construct() {
 
@@ -54,7 +54,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
      * Gathers all information from the headers
      *
      * This method needs to be called prior to anything else.
-     * 
+     *
      * @return void
      */
     public function init() {
@@ -73,11 +73,11 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
      *
      * Multiple values can be specified using logical OR.
      *
-     * QOP_AUTHINT ensures integrity of the request body, but this is not 
-     * supported by most HTTP clients. QOP_AUTHINT also requires the entire 
+     * QOP_AUTHINT ensures integrity of the request body, but this is not
+     * supported by most HTTP clients. QOP_AUTHINT also requires the entire
      * request body to be md5'ed, which can put strains on CPU and memory.
      *
-     * @param int $qop 
+     * @param int $qop
      * @return void
      */
     public function setQOP($qop) {
@@ -91,8 +91,8 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
      *
      * The A1 parameter should be md5($username . ':' . $realm . ':' . $password);
      *
-     * @param string $A1 
-     * @return bool 
+     * @param string $A1
+     * @return bool
      */
     public function validateA1($A1) {
 
@@ -104,9 +104,9 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
     /**
      * Validates authentication through a password. The actual password must be provided here.
      * It is strongly recommended not store the password in plain-text and use validateA1 instead.
-     * 
-     * @param string $password 
-     * @return bool 
+     *
+     * @param string $password
+     * @return bool
      */
     public function validatePassword($password) {
 
@@ -116,9 +116,9 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Returns the username for the request 
-     * 
-     * @return string 
+     * Returns the username for the request
+     *
+     * @return string
      */
     public function getUsername() {
 
@@ -127,14 +127,14 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
     }
 
     /**
-     * Validates the digest challenge 
-     * 
-     * @return bool 
+     * Validates the digest challenge
+     *
+     * @return bool
      */
     protected function validate() {
 
         $A2 = $this->httpRequest->getMethod() . ':' . $this->digestParts['uri'];
-    
+
         if ($this->digestParts['qop']=='auth-int') {
             // Making sure we support this qop value
             if (!($this->qop & self::QOP_AUTHINT)) return false;
@@ -144,16 +144,16 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
             $A2 .= ':' . md5($body);
         } else {
 
-            // We need to make sure we support this qop value 
-            if (!($this->qop & self::QOP_AUTH)) return false; 
+            // We need to make sure we support this qop value
+            if (!($this->qop & self::QOP_AUTH)) return false;
         }
 
         $A2 = md5($A2);
 
-        $validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}"); 
+        $validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}");
 
         return $this->digestParts['response']==$validResponse;
-        
+
 
     }
 
@@ -186,7 +186,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
      *
      * If the header could not be found, null will be returned
      *
-     * @return mixed 
+     * @return mixed
      */
     public function getDigest() {
 
@@ -197,6 +197,12 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
         // most other servers
         $digest = $this->httpRequest->getHeader('Authorization');
 
+        // Apache could prefix environment variables with REDIRECT_ when urls
+        // are passed through mod_rewrite
+        if (!$digest) {
+            $digest = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
+        }
+
         if ($digest && strpos(strtolower($digest),'digest')===0) {
             return substr($digest,7);
         } else {
@@ -208,11 +214,11 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
 
     /**
      * Parses the different pieces of the digest string into an array.
-     * 
+     *
      * This method returns false if an incomplete digest was supplied
      *
-     * @param string $digest 
-     * @return mixed 
+     * @param string $digest
+     * @return mixed
      */
     protected function parseDigest($digest) {
 
@@ -227,7 +233,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
             unset($needed_parts[$m[1]]);
         }
 
-        return $needed_parts ? false : $data; 
+        return $needed_parts ? false : $data;
 
     }
 
diff --git a/3rdparty/Sabre/HTTP/Request.php b/3rdparty/Sabre/HTTP/Request.php
old mode 100644
new mode 100755
index 95a64171aab612faed7a2459f7bbedb4d983d3a7..4746ef777047e06b4b3c3ec0dd01267c749f7460
--- a/3rdparty/Sabre/HTTP/Request.php
+++ b/3rdparty/Sabre/HTTP/Request.php
@@ -6,74 +6,85 @@
  * This object can be used to easily access information about an HTTP request.
  * It can additionally be used to create 'mock' requests.
  *
- * This class mostly operates indepentend, but because of the nature of a single 
- * request per run it can operate as a singleton. For more information check out 
+ * This class mostly operates independent, but because of the nature of a single
+ * request per run it can operate as a singleton. For more information check out
  * the behaviour around 'defaultInputStream'.
  *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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
  */
 class Sabre_HTTP_Request {
 
     /**
      * PHP's $_SERVER data
-     * 
-     * @var string 
+     *
+     * @var array
      */
     protected $_SERVER;
 
+    /**
+     * PHP's $_POST data
+     *
+     * @var array
+     */
+    protected $_POST;
+
     /**
      * The request body, if any.
      *
      * This is stored in the form of a stream resource.
      *
-     * @var resource 
+     * @var resource
      */
     protected $body = null;
 
     /**
      * This will be set as the 'default' inputStream for a specific HTTP request
-     * We sometimes need to retain, or rebuild this if we need multiple runs 
+     * We sometimes need to retain, or rebuild this if we need multiple runs
      * of parsing the original HTTP request.
-     * 
-     * @var resource 
+     *
+     * @var resource
      */
     static $defaultInputStream=null;
 
     /**
      * Sets up the object
      *
-     * The serverData array can be used to override usage of PHP's 
-     * global _SERVER variable. 
-     * 
-     * @param array $serverData 
+     * The serverData and postData array can be used to override usage of PHP's
+     * global _SERVER and _POST variable respectively.
+     *
+     * @param array $serverData
+     * @param array $postData
      */
-    public function __construct($serverData = null) {
+    public function __construct(array $serverData = null, array $postData = null) {
 
        if ($serverData) $this->_SERVER = $serverData;
        else $this->_SERVER =& $_SERVER;
 
+       if ($postData) $this->_POST = $postData;
+       else $this->_POST =& $_POST;
+
     }
 
     /**
      * Returns the value for a specific http header.
      *
      * This method returns null if the header did not exist.
-     * 
-     * @param string $name 
-     * @return string 
+     *
+     * @param string $name
+     * @return string
      */
     public function getHeader($name) {
 
         $name = strtoupper(str_replace(array('-'),array('_'),$name));
         if (isset($this->_SERVER['HTTP_' . $name])) {
             return $this->_SERVER['HTTP_' . $name];
-        } 
+        }
 
-        // There's a few headers that seem to end up in the top-level 
+        // There's a few headers that seem to end up in the top-level
         // server array.
         switch($name) {
             case 'CONTENT_TYPE' :
@@ -92,9 +103,9 @@ class Sabre_HTTP_Request {
      * Returns all (known) HTTP headers.
      *
      * All headers are converted to lower-case, and additionally all underscores
-     * are automatically converted to dashes 
-     * 
-     * @return array 
+     * are automatically converted to dashes
+     *
+     * @return array
      */
     public function getHeaders() {
 
@@ -122,9 +133,9 @@ class Sabre_HTTP_Request {
     /**
      * Returns the HTTP request method
      *
-     * This is for example POST or GET 
+     * This is for example POST or GET
      *
-     * @return string 
+     * @return string
      */
     public function getMethod() {
 
@@ -135,18 +146,18 @@ class Sabre_HTTP_Request {
     /**
      * Returns the requested uri
      *
-     * @return string 
+     * @return string
      */
     public function getUri() {
-       
+
         return $this->_SERVER['REQUEST_URI'];
 
     }
 
     /**
-     * Will return protocol + the hostname + the uri 
-     * 
-     * @return void
+     * Will return protocol + the hostname + the uri
+     *
+     * @return string
      */
     public function getAbsoluteUri() {
 
@@ -157,9 +168,9 @@ class Sabre_HTTP_Request {
     }
 
     /**
-     * Returns everything after the ? from the current url 
-     * 
-     * @return string 
+     * Returns everything after the ? from the current url
+     *
+     * @return string
      */
     public function getQueryString() {
 
@@ -168,13 +179,13 @@ class Sabre_HTTP_Request {
     }
 
     /**
-     * Returns the HTTP request body body 
+     * Returns the HTTP request body body
      *
      * This method returns a readable stream resource.
-     * If the asString parameter is set to true, a string is sent instead. 
+     * If the asString parameter is set to true, a string is sent instead.
      *
      * @param bool asString
-     * @return resource 
+     * @return resource
      */
     public function getBody($asString = false) {
 
@@ -196,14 +207,14 @@ class Sabre_HTTP_Request {
     }
 
     /**
-     * Sets the contents of the HTTP request body 
-     * 
+     * Sets the contents of the HTTP request body
+     *
      * This method can either accept a string, or a readable stream resource.
      *
-     * If the setAsDefaultInputStream is set to true, it means for this run of the 
+     * If the setAsDefaultInputStream is set to true, it means for this run of the
      * script the supplied body will be used instead of php://input.
      *
-     * @param mixed $body 
+     * @param mixed $body
      * @param bool $setAsDefaultInputStream
      * @return void
      */
@@ -226,12 +237,26 @@ class Sabre_HTTP_Request {
     }
 
     /**
-     * Returns a specific item from the _SERVER array. 
+     * Returns PHP's _POST variable.
+     *
+     * The reason this is in a method is so it can be subclassed and
+     * overridden.
+     *
+     * @return array
+     */
+    public function getPostVars() {
+
+        return $this->_POST;
+
+    }
+
+    /**
+     * Returns a specific item from the _SERVER array.
      *
      * Do not rely on this feature, it is for internal use only.
      *
-     * @param string $field 
-     * @return string 
+     * @param string $field
+     * @return string
      */
     public function getRawServerValue($field) {
 
diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php
old mode 100644
new mode 100755
index dce6feac55336bab4e20ac6ed00c3ed5edd48c5f..ffe9bda2082d5fd65395038fae36cfa179da0062
--- a/3rdparty/Sabre/HTTP/Response.php
+++ b/3rdparty/Sabre/HTTP/Response.php
@@ -1,20 +1,20 @@
 <?php
 
 /**
- * Sabre_HTTP_Response 
- * 
+ * Sabre_HTTP_Response
+ *
  * @package Sabre
  * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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_HTTP_Response {
 
     /**
-     * Returns a full HTTP status message for an HTTP status code 
-     * 
-     * @param int $code 
+     * Returns a full HTTP status message for an HTTP status code
+     *
+     * @param int $code
      * @return string
      */
     public function getStatusMessage($code) {
@@ -64,6 +64,9 @@ class Sabre_HTTP_Response {
             423 => 'Locked', // RFC 4918
             424 => 'Failed Dependency', // RFC 4918
             426 => 'Upgrade required',
+            428 => 'Precondition required', // draft-nottingham-http-new-status
+            429 => 'Too Many Requests', // draft-nottingham-http-new-status
+            431 => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
             500 => 'Internal Server Error',
             501 => 'Not Implemented',
             502 => 'Bad Gateway',
@@ -71,25 +74,26 @@ class Sabre_HTTP_Response {
             504 => 'Gateway Timeout',
             505 => 'HTTP Version not supported',
             506 => 'Variant Also Negotiates',
-            507 => 'Unsufficient Storage', // RFC 4918
+            507 => 'Insufficient Storage', // RFC 4918
             508 => 'Loop Detected', // RFC 5842
             509 => 'Bandwidth Limit Exceeded', // non-standard
             510 => 'Not extended',
-       ); 
+            511 => 'Network Authentication Required', // draft-nottingham-http-new-status
+       );
 
        return 'HTTP/1.1 ' . $code . ' ' . $msg[$code];
 
     }
 
     /**
-     * Sends an HTTP status header to the client 
-     * 
-     * @param int $code HTTP status code 
-     * @return void
+     * Sends an HTTP status header to the client
+     *
+     * @param int $code HTTP status code
+     * @return bool
      */
     public function sendStatus($code) {
 
-        if (!headers_sent()) 
+        if (!headers_sent())
             return header($this->getStatusMessage($code));
         else return false;
 
@@ -97,15 +101,16 @@ class Sabre_HTTP_Response {
 
     /**
      * Sets an HTTP header for the response
-     * 
-     * @param string $name 
-     * @param string $value 
-     * @return void
+     *
+     * @param string $name
+     * @param string $value
+     * @param bool $replace
+     * @return bool
      */
     public function setHeader($name, $value, $replace = true) {
 
         $value = str_replace(array("\r","\n"),array('\r','\n'),$value);
-        if (!headers_sent()) 
+        if (!headers_sent())
             return header($name . ': ' . $value, $replace);
         else return false;
 
@@ -115,8 +120,8 @@ class Sabre_HTTP_Response {
      * Sets a bunch of HTTP Headers
      *
      * headersnames are specified as keys, value in the array value
-     * 
-     * @param array $headers 
+     *
+     * @param array $headers
      * @return void
      */
     public function setHeaders(array $headers) {
@@ -130,14 +135,14 @@ class Sabre_HTTP_Response {
      * Sends the entire response body
      *
      * This method can accept either an open filestream, or a string.
-     * 
-     * @param mixed $body 
+     *
+     * @param mixed $body
      * @return void
      */
     public function sendBody($body) {
 
         if (is_resource($body)) {
-        
+
             fpassthru($body);
 
         } else {
diff --git a/3rdparty/Sabre/HTTP/Util.php b/3rdparty/Sabre/HTTP/Util.php
old mode 100644
new mode 100755
index 8a6bd7df487bd297982d0a8a00d4e0692fd07aba..67bdd489e1e5f654c4d9c41d34292bcbfefe0c39
--- a/3rdparty/Sabre/HTTP/Util.php
+++ b/3rdparty/Sabre/HTTP/Util.php
@@ -1,11 +1,11 @@
 <?php
 
 /**
- * HTTP utility methods 
- * 
+ * HTTP utility methods
+ *
  * @package Sabre
  * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @author Paul Voegler
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
@@ -16,9 +16,9 @@ class Sabre_HTTP_Util {
      * Parses a RFC2616-compatible date string
      *
      * This method returns false if the date is invalid
-     * 
-     * @param string $dateHeader 
-     * @return bool|DateTime 
+     *
+     * @param string $dateHeader
+     * @return bool|DateTime
      */
     static function parseHTTPDate($dateHeader) {
 
@@ -42,7 +42,7 @@ class Sabre_HTTP_Util {
         $rfc1123_date = $wkday . ', ' . $date1 . ' ' . $time . ' GMT';
         //allowed date formats by RFC 2616
         $HTTP_date = "($rfc1123_date|$rfc850_date|$asctime_date)";
-        
+
         //allow for space around the string and strip it
         $dateHeader = trim($dateHeader, ' ');
         if (!preg_match('/^' . $HTTP_date . '$/', $dateHeader))
@@ -58,7 +58,24 @@ class Sabre_HTTP_Util {
         if ($realDate !== false && $realDate >= 0)
             return new DateTime('@' . $realDate, new DateTimeZone('UTC'));
 
-        return false;
+    }
+
+    /**
+     * Transforms a DateTime object to HTTP's most common date format.
+     *
+     * We're serializing it as the RFC 1123 date, which, for HTTP must be
+     * specified as GMT.
+     *
+     * @param DateTime $dateTime
+     * @return string
+     */
+    static function toHTTPDate(DateTime $dateTime) {
+
+        // We need to clone it, as we don't want to affect the existing
+        // DateTime.
+        $dateTime = clone $dateTime;
+        $dateTime->setTimeZone(new DateTimeZone('GMT'));
+        return $dateTime->format('D, d M Y H:i:s \G\M\T');
 
     }
 
diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php
old mode 100644
new mode 100755
index 67be232fc26b4ce1ec0519775995ebf25bb4ff2b..23dc7f8a7a17d9de217836a293c09e01645d5af0
--- a/3rdparty/Sabre/HTTP/Version.php
+++ b/3rdparty/Sabre/HTTP/Version.php
@@ -2,10 +2,10 @@
 
 /**
  * This class contains the Sabre_HTTP version constants.
- * 
+ *
  * @package Sabre
- * @subpackage HTTP 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,7 +14,7 @@ class Sabre_HTTP_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.5.3';
+    const VERSION = '1.6.2';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/HTTP/includes.php b/3rdparty/Sabre/HTTP/includes.php
new file mode 100755
index 0000000000000000000000000000000000000000..9d34bf3a8becc8946c4759b71457e76b39cf5da1
--- /dev/null
+++ b/3rdparty/Sabre/HTTP/includes.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * Sabre_HTTP includes file
+ *
+ * Including this file will automatically include all files from the Sabre_HTTP
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @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
+ */
+
+// Begin includes
+include __DIR__ . '/AbstractAuth.php';
+include __DIR__ . '/AWSAuth.php';
+include __DIR__ . '/BasicAuth.php';
+include __DIR__ . '/DigestAuth.php';
+include __DIR__ . '/Request.php';
+include __DIR__ . '/Response.php';
+include __DIR__ . '/Util.php';
+include __DIR__ . '/Version.php';
+// End includes
diff --git a/3rdparty/Sabre/LICENCE b/3rdparty/Sabre/LICENCE
deleted file mode 100644
index 3d07eaace836198ab96fe64cc329c02872516ca4..0000000000000000000000000000000000000000
--- a/3rdparty/Sabre/LICENCE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (C) 2007-2011 Rooftop Solutions.
-Copyright (C) 2007-2009 FileMobile inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of the SabreDAV nor the names of its contributors
-      may be used to endorse or promote products derived from this software
-      without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-    POSSIBILITY OF SUCH DAMAGE. 
diff --git a/3rdparty/Sabre/VObject/Component.php b/3rdparty/Sabre/VObject/Component.php
old mode 100644
new mode 100755
index 47cf9f3d8125b889cdf16ac9c49199c22cc38170..b78a26133fa19e1f9e9dc19c333b7744188da190
--- a/3rdparty/Sabre/VObject/Component.php
+++ b/3rdparty/Sabre/VObject/Component.php
@@ -4,39 +4,73 @@
  * VObject Component
  *
  * This class represents a VCALENDAR/VCARD component. A component is for example
- * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and 
+ * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
  * ends with END:COMPONENTNAME
  *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * Name, for example VEVENT 
-     * 
-     * @var string 
+     * Name, for example VEVENT
+     *
+     * @var string
      */
     public $name;
 
     /**
-     * Children properties and components 
-     * 
+     * Children properties and components
+     *
      * @var array
      */
     public $children = array();
 
+    /**
+     * If coponents 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',
+    );
+
+    /**
+     * Creates the new component by name, but in addition will also see if
+     * there's a class mapped to the property name.
+     *
+     * @param string $name
+     * @param string $value
+     * @return Sabre_VObject_Component
+     */
+    static public function create($name, $value = null) {
+
+        $name = strtoupper($name);
+
+        if (isset(self::$classMap[$name])) {
+            return new self::$classMap[$name]($name, $value);
+        } else {
+            return new self($name, $value);
+        }
+
+    }
 
     /**
      * Creates a new component.
      *
-     * By default this object will iterate over its own children, but this can 
+     * By default this object will iterate over its own children, but this can
      * be overridden with the iterator argument
-     * 
-     * @param string $name 
+     *
+     * @param string $name
      * @param Sabre_VObject_ElementList $iterator
      */
     public function __construct($name, Sabre_VObject_ElementList $iterator = null) {
@@ -47,23 +81,65 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     }
 
     /**
-     * Turns the object back into a serialized blob. 
-     * 
-     * @return string 
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
      */
     public function serialize() {
 
         $str = "BEGIN:" . $this->name . "\r\n";
+
+        /**
+         * Gives a component a 'score' for sorting purposes.
+         *
+         * This is solely used by the childrenSort method.
+         *
+         * A higher score means the item will be higher in the list
+         *
+         * @param Sabre_VObject_Node $n
+         * @return int
+         */
+        $sortScore = function($n) {
+
+            if ($n instanceof Sabre_VObject_Component) {
+                // We want to encode VTIMEZONE first, this is a personal
+                // preference.
+                if ($n->name === 'VTIMEZONE') {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            } else {
+                // VCARD version 4.0 wants the VERSION property to appear first
+                if ($n->name === 'VERSION') {
+                    return 3;
+                } else {
+                    return 2;
+                }
+            }
+
+        };
+
+        usort($this->children, function($a, $b) use ($sortScore) {
+
+            $sA = $sortScore($a);
+            $sB = $sortScore($b);
+
+            if ($sA === $sB) return 0;
+
+            return ($sA > $sB) ? -1 : 1;
+
+        });
+
         foreach($this->children as $child) $str.=$child->serialize();
         $str.= "END:" . $this->name . "\r\n";
-        
+
         return $str;
 
     }
 
-
     /**
-     * Adds a new componenten or element
+     * Adds a new component or element
      *
      * You can call this method with the following syntaxes:
      *
@@ -71,10 +147,10 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      * add(string $name, $value)
      *
      * The first version adds an Element
-     * The second adds a property as a string. 
-     * 
-     * @param mixed $item 
-     * @param mixed $itemValue 
+     * The second adds a property as a string.
+     *
+     * @param mixed $item
+     * @param mixed $itemValue
      * @return void
      */
     public function add($item, $itemValue = null) {
@@ -90,12 +166,12 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
             if (!is_scalar($itemValue)) {
                 throw new InvalidArgumentException('The second argument must be scalar');
             }
-            $item = new Sabre_VObject_Property($item,$itemValue);
+            $item = Sabre_VObject_Property::create($item,$itemValue);
             $item->parent = $this;
             $this->children[] = $item;
 
         } else {
-            
+
             throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
 
         }
@@ -103,9 +179,9 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     }
 
     /**
-     * Returns an iterable list of children 
-     * 
-     * @return Sabre_VObject_ElementList 
+     * Returns an iterable list of children
+     *
+     * @return Sabre_VObject_ElementList
      */
     public function children() {
 
@@ -116,18 +192,18 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     /**
      * Returns an array with elements that match the specified name.
      *
-     * This function is also aware of MIME-Directory groups (as they appear in 
-     * vcards). This means that if a property is grouped as "HOME.EMAIL", it 
-     * will also be returned when searching for just "EMAIL". If you want to 
-     * search for a property in a specific group, you can select on the entire 
-     * string ("HOME.EMAIL"). If you want to search on a specific property that 
+     * This function is also aware of MIME-Directory groups (as they appear in
+     * vcards). This means that if a property is grouped as "HOME.EMAIL", it
+     * will also be returned when searching for just "EMAIL". If you want to
+     * search for a property in a specific group, you can select on the entire
+     * string ("HOME.EMAIL"). If you want to search on a specific property that
      * has not been assigned a group, specify ".EMAIL".
      *
-     * Keys are retained from the 'children' array, which may be confusing in 
-     * certain cases. 
+     * Keys are retained from the 'children' array, which may be confusing in
+     * certain cases.
      *
-     * @param string $name 
-     * @return array 
+     * @param string $name
+     * @return array
      */
     public function select($name) {
 
@@ -144,7 +220,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
                 strtoupper($child->name) === $name &&
                 (is_null($group) || ( $child instanceof Sabre_VObject_Property && strtoupper($child->group) === $group))
             ) {
-                
+
                 $result[$key] = $child;
 
             }
@@ -155,16 +231,35 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
 
     }
 
+    /**
+     * This method only returns a list of sub-components. Properties are
+     * ignored.
+     *
+     * @return array
+     */
+    public function getComponents() {
+
+        $result = array();
+        foreach($this->children as $child) {
+            if ($child instanceof Sabre_VObject_Component) {
+                $result[] = $child;
+            }
+        }
+
+        return $result;
+
+    }
+
     /* Magic property accessors {{{ */
 
     /**
-     * Using 'get' you will either get a propery or component, 
+     * Using 'get' you will either get a property or component,
      *
      * If there were no child-elements found with the specified name,
      * null is returned.
-     * 
-     * @param string $name 
-     * @return void
+     *
+     * @param string $name
+     * @return Sabre_VObject_Property
      */
     public function __get($name) {
 
@@ -173,6 +268,7 @@ 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)));
             return $firstMatch;
         }
@@ -180,10 +276,10 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     }
 
     /**
-     * This method checks if a sub-element with the specified name exists. 
-     * 
-     * @param string $name 
-     * @return bool 
+     * This method checks if a sub-element with the specified name exists.
+     *
+     * @param string $name
+     * @return bool
      */
     public function __isset($name) {
 
@@ -200,7 +296,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
      *
      * If the item already exists, it will be removed. If you want to add
      * a new item with the same name, always use the add() method.
-     * 
+     *
      * @param string $name
      * @param mixed $value
      * @return void
@@ -218,7 +314,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
                 $this->children[] = $value;
             }
         } elseif (is_scalar($value)) {
-            $property = new Sabre_VObject_Property($name,$value);
+            $property = Sabre_VObject_Property::create($name,$value);
             $property->parent = $this;
             if (!is_null($overWrite)) {
                 $this->children[$overWrite] = $property;
@@ -232,9 +328,9 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
     }
 
     /**
-     * Removes all properties and components within this component. 
-     * 
-     * @param string $name 
+     * Removes all properties and components within this component.
+     *
+     * @param string $name
      * @return void
      */
     public function __unset($name) {
@@ -251,4 +347,19 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
 
     /* }}} */
 
+    /**
+     * This method is automatically called when the object is cloned.
+     * Specifically, this will ensure all child elements are also cloned.
+     *
+     * @return void
+     */
+    public function __clone() {
+
+        foreach($this->children as $key=>$child) {
+            $this->children[$key] = clone $child;
+            $this->children[$key]->parent = $this;
+        }
+
+    }
+
 }
diff --git a/3rdparty/Sabre/VObject/Component/VAlarm.php b/3rdparty/Sabre/VObject/Component/VAlarm.php
new file mode 100755
index 0000000000000000000000000000000000000000..ebb4a9b18f69962a0446a6f4dece59ea2db1605a
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VAlarm.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Returns a DateTime object when this alarm is going to trigger.
+     *
+     * This ignores repeated alarm, only the first trigger is returned.
+     *
+     * @return DateTime
+     */
+    public function getEffectiveTriggerTime() {
+
+        $trigger = $this->TRIGGER;
+        if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
+            $triggerDuration = Sabre_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();
+                $effectiveTrigger->add($triggerDuration);
+            } else {
+                if ($parentComponent->name === 'VTODO') {
+                    $endProp = 'DUE';
+                } 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');
+                }
+
+                if (isset($parentComponent->$endProp)) {
+                    $effectiveTrigger = clone $parentComponent->$endProp->getDateTime();
+                    $effectiveTrigger->add($triggerDuration);
+                } elseif (isset($parentComponent->DURATION)) {
+                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+                    $duration = Sabre_VObject_DateTimeParser::parseDuration($parentComponent->DURATION);
+                    $effectiveTrigger->add($duration);
+                    $effectiveTrigger->add($triggerDuration);
+                } else {
+                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+                    $effectiveTrigger->add($triggerDuration);
+                }
+            }
+        } else {
+            $effectiveTrigger = $trigger->getDateTime();
+        }
+        return $effectiveTrigger;
+
+    }
+
+    /**
+     * Returns true or false depending on if the event falls in the specified
+     * time-range. This is used for filtering purposes.
+     *
+     * 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
+     * @return bool
+     */
+    public function isInTimeRange(DateTime $start, DateTime $end) {
+
+        $effectiveTrigger = $this->getEffectiveTriggerTime();
+
+        if (isset($this->DURATION)) {
+            $duration = Sabre_VObject_DateTimeParser::parseDuration($this->DURATION);
+            $repeat = (string)$this->repeat;
+            if (!$repeat) {
+                $repeat = 1;
+            }
+
+            $period = new DatePeriod($effectiveTrigger, $duration, (int)$repeat);
+
+            foreach($period as $occurrence) {
+
+                if ($start <= $occurrence && $end > $occurrence) {
+                    return true;
+                }
+            }
+            return false;
+        } else {
+            return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
+        }
+
+    }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VCalendar.php b/3rdparty/Sabre/VObject/Component/VCalendar.php
new file mode 100755
index 0000000000000000000000000000000000000000..f3be29afdbb492c16b7fe28f0e04888c3291fd43
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VCalendar.php
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Returns a list of all 'base components'. For instance, if an Event has 
+     * a recurrence rule, and one instance is overridden, the overridden event 
+     * will have the same UID, but will be excluded from this list.
+     *
+     * VTIMEZONE components will always be excluded. 
+     *
+     * @param string $componentName filter by component name 
+     * @return array 
+     */
+    public function getBaseComponents($componentName = null) {
+
+        $components = array();
+        foreach($this->children as $component) {
+
+            if (!$component instanceof Sabre_VObject_Component)
+                continue;
+
+            if (isset($component->{'RECURRENCE-ID'})) 
+                continue;
+
+            if ($componentName && $component->name !== strtoupper($componentName)) 
+                continue;
+
+            if ($component->name === 'VTIMEZONE')
+                continue;
+
+            $components[] = $component;
+
+        }
+
+        return $components;
+
+    }
+
+    /**
+     * If this calendar object, has events with recurrence rules, this method 
+     * can be used to expand the event into multiple sub-events.
+     *
+     * Each event will be stripped from it's recurrence information, and only 
+     * the instances of the event in the specified timerange will be left 
+     * alone.
+     *
+     * In addition, this method will cause timezone information to be stripped, 
+     * and normalized to UTC.
+     *
+     * This method will alter the VCalendar. This cannot be reversed.
+     *
+     * This functionality is specifically used by the CalDAV standard. It is 
+     * possible for clients to request expand events, if they are rather simple 
+     * clients and do not have the possibility to calculate recurrences.
+     *
+     * @param DateTime $start
+     * @param DateTime $end 
+     * @return void
+     */
+    public function expand(DateTime $start, DateTime $end) {
+
+        $newEvents = array();
+
+        foreach($this->select('VEVENT') as $key=>$vevent) {
+
+            if (isset($vevent->{'RECURRENCE-ID'})) {
+                unset($this->children[$key]);
+                continue;
+            } 
+
+
+            if (!$vevent->rrule) {
+                unset($this->children[$key]);
+                if ($vevent->isInTimeRange($start, $end)) {
+                    $newEvents[] = $vevent;
+                }
+                continue;
+            }
+
+            $uid = (string)$vevent->uid;
+            if (!$uid) {
+                throw new LogicException('Event did not have a UID!');
+            }
+
+            $it = new Sabre_VObject_RecurrenceIterator($this, $vevent->uid);
+            $it->fastForward($start);
+
+            while($it->valid() && $it->getDTStart() < $end) {
+
+                if ($it->getDTEnd() > $start) {
+
+                    $newEvents[] = $it->getEventObject();
+
+                }
+                $it->next();
+
+            }
+            unset($this->children[$key]);
+
+        }
+
+        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);
+                    }
+            }
+
+            $this->add($newEvent);
+
+        }
+
+        // Removing all VTIMEZONE components
+        unset($this->VTIMEZONE);
+
+    } 
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Component/VEvent.php b/3rdparty/Sabre/VObject/Component/VEvent.php
new file mode 100755
index 0000000000000000000000000000000000000000..4cc1e36d7d6b6175fd61122bab3dc6c58447d058
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VEvent.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Returns true or false depending on if the event falls in the specified
+     * time-range. This is used for filtering purposes.
+     *
+     * 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
+     * @return bool
+     */
+    public function isInTimeRange(DateTime $start, DateTime $end) {
+
+        if ($this->RRULE) {
+            $it = new Sabre_VObject_RecurrenceIterator($this);
+            $it->fastForward($start);
+
+            // We fast-forwarded to a spot where the end-time of the
+            // recurrence instance exceeded the start of the requested
+            // time-range.
+            //
+            // If the starttime of the recurrence did not exceed the
+            // end of the time range as well, we have a match.
+            return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
+
+        }
+
+        $effectiveStart = $this->DTSTART->getDateTime();
+        if (isset($this->DTEND)) {
+            $effectiveEnd = $this->DTEND->getDateTime();
+            // If this was an all-day event, we should just increase the
+            // end-date by 1. Otherwise the event will last until the second
+            // the date changed, by increasing this by 1 day the event lasts
+            // all of the last day as well.
+            if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+                $effectiveEnd->modify('+1 day');
+            }
+        } 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 = clone $effectiveStart;
+            $effectiveEnd->modify('+1 day');
+        } else {
+            $effectiveEnd = clone $effectiveStart;
+        }
+        return (
+            ($start <= $effectiveEnd) && ($end > $effectiveStart)
+        );
+
+    }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VJournal.php b/3rdparty/Sabre/VObject/Component/VJournal.php
new file mode 100755
index 0000000000000000000000000000000000000000..22b3ec921e5a1b6e67dbdb0253ba5d6fece53cb8
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VJournal.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Returns true or false depending on if the event falls in the specified 
+     * time-range. This is used for filtering purposes. 
+     *
+     * 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 
+     * @return bool 
+     */
+    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) {
+                $effectiveEnd->modify('+1 day');
+            }
+
+            return ($start <= $effectiveEnd && $end > $dtstart);
+
+        }
+        return false;
+
+
+    }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VTodo.php b/3rdparty/Sabre/VObject/Component/VTodo.php
new file mode 100755
index 0000000000000000000000000000000000000000..79d06298d7f864ea5953f51f714906c3119feef8
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VTodo.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Returns true or false depending on if the event falls in the specified 
+     * time-range. This is used for filtering purposes. 
+     *
+     * 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 
+     * @return bool 
+     */
+    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;
+        $due = isset($this->DUE)?$this->DUE->getDateTime():null;
+        $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
+        $created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
+
+        if ($dtstart) {
+            if ($duration) {
+                $effectiveEnd = clone $dtstart;
+                $effectiveEnd->add($duration);
+                return $start <= $effectiveEnd && $end > $dtstart;
+            } elseif ($due) {
+                return
+                    ($start < $due || $start <= $dtstart) &&
+                    ($end > $dtstart || $end >= $due);
+            } else {
+                return $start <= $dtstart && $end > $dtstart;
+            }
+        }
+        if ($due) {
+            return ($start < $due && $end >= $due);
+        }
+        if ($completed && $created) {
+            return
+                ($start <= $created || $start <= $completed) &&
+                ($end >= $created || $end >= $completed);
+        }
+        if ($completed) {
+            return ($start <= $completed && $end >= $completed);
+        }
+        if ($created) {
+            return ($end > $created);
+        }
+        return true;
+
+    }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/DateTimeParser.php b/3rdparty/Sabre/VObject/DateTimeParser.php
new file mode 100755
index 0000000000000000000000000000000000000000..1e2d54ef3a9b3e115dd608e5e7a91c3b6c4ae74a
--- /dev/null
+++ b/3rdparty/Sabre/VObject/DateTimeParser.php
@@ -0,0 +1,177 @@
+<?php
+
+/**
+ * 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 {
+
+    /**
+     * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
+     *
+     * Specifying a reference timezone is optional. It will only be used
+     * if the non-UTC format is used. The argument is used as a reference, the
+     * returned DateTime object will still be in the UTC timezone.
+     *
+     * @param string $dt
+     * @param DateTimeZone $tz
+     * @return DateTime
+     */
+    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);
+
+        if (!$result) {
+            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
+        }
+
+        if ($matches[7]==='Z' || is_null($tz)) {
+            $tz = new DateTimeZone('UTC');
+        }
+        $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'));
+        return $date;
+
+    }
+
+    /**
+     * Parses an iCalendar (rfc5545) formatted date and returns a DateTime object
+     *
+     * @param string $date
+     * @return DateTime
+     */
+    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);
+
+        if (!$result) {
+            throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar date value is incorrect: ' . $date);
+        }
+
+        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
+        return $date;
+
+    }
+
+    /**
+     * Parses an iCalendar (RFC5545) formatted duration value.
+     *
+     * This method will either return a DateTimeInterval object, or a string
+     * suitable for strtotime or DateTime::modify.
+     *
+     * @param string $duration
+     * @param bool $asString
+     * @return DateInterval|string
+     */
+    static public function parseDuration($duration, $asString = false) {
+
+        $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);
+        }
+
+        if (!$asString) {
+            $invert = false;
+            if ($matches['plusminus']==='-') {
+                $invert = true;
+            }
+
+
+            $parts = array(
+                'week',
+                'day',
+                'hour',
+                'minute',
+                'second',
+            );
+            foreach($parts as $part) {
+                $matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
+            }
+
+
+            // We need to re-construct the $duration string, because weeks and
+            // days are not supported by DateInterval in the same string.
+            $duration = 'P';
+            $days = $matches['day'];
+            if ($matches['week']) {
+                $days+=$matches['week']*7;
+            }
+            if ($days)
+                $duration.=$days . 'D';
+
+            if ($matches['minute'] || $matches['second'] || $matches['hour']) {
+                $duration.='T';
+
+                if ($matches['hour'])
+                    $duration.=$matches['hour'].'H';
+
+                if ($matches['minute'])
+                    $duration.=$matches['minute'].'M';
+
+                if ($matches['second'])
+                    $duration.=$matches['second'].'S';
+
+            }
+
+            $iv = new DateInterval($duration);
+            if ($invert) $iv->invert = true;
+
+            return $iv;
+
+        }
+
+
+
+        $parts = array(
+            'week',
+            'day',
+            'hour',
+            'minute',
+            'second',
+        );
+
+        $newDur = '';
+        foreach($parts as $part) {
+            if (isset($matches[$part]) && $matches[$part]) {
+                $newDur.=' '.$matches[$part] . ' ' . $part . 's';
+            }
+        }
+
+        $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
+        return $newDur;
+
+    }
+
+    /**
+     * Parses either a Date or DateTime, or Duration value.
+     *
+     * @param string $date
+     * @param DateTimeZone|string $referenceTZ
+     * @return DateTime|DateInterval
+     */
+    static public function parse($date, $referenceTZ = null) {
+
+        if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
+            return self::parseDuration($date);
+        } elseif (strlen($date)===8) {
+            return self::parseDate($date);
+        } else {
+            return self::parseDateTime($date, $referenceTZ);
+        }
+
+    }
+
+
+}
diff --git a/3rdparty/Sabre/VObject/Element.php b/3rdparty/Sabre/VObject/Element.php
old mode 100644
new mode 100755
index 8d2b0aaacd1ee5ce9bde985eb00b058f8151da55..e20ff0b353c4491cd166ccad47a39c16a7f46c4f
--- a/3rdparty/Sabre/VObject/Element.php
+++ b/3rdparty/Sabre/VObject/Element.php
@@ -2,14 +2,15 @@
 
 /**
  * Base class for all elements
- * 
+ *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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
old mode 100644
new mode 100755
index 3350ec02c88a9b00705790e338a1e3c9e9303fb3..5e5eb7ab6f2e8a96485d33b9173c9a1726648edf
--- a/3rdparty/Sabre/VObject/Element/DateTime.php
+++ b/3rdparty/Sabre/VObject/Element/DateTime.php
@@ -1,25 +1,18 @@
 <?php
 
 /**
- * DateTime property 
+ * DateTime property
  *
- * This element is used for iCalendar properties such as the DTSTART property. 
- * It basically provides a few helper functions that make it easier to deal 
- * with these. It supports both DATE-TIME and DATE values.
+ * this class got renamed to Sabre_VObject_Property_DateTime
  *
- * In order to use this correctly, you must call setDateTime and getDateTime to 
- * retrieve and modify dates respectively.
- *
- * 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-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
+class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property_DateTime {
 
     /**
      * Local 'floating' time
@@ -41,205 +34,4 @@ class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property {
      */
     const DATE = 4;
 
-    /**
-     * DateTime representation
-     *
-     * @var DateTime
-     */
-    protected $dateTime;
-
-    /**
-     * dateType 
-     * 
-     * @var int 
-     */
-    protected $dateType;
-
-    /**
-     * Updates the Date and Time. 
-     * 
-     * @param DateTime $dt 
-     * @param int $dateType 
-     * @return void
-     */
-    public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
-
-        switch($dateType) {
-
-            case self::LOCAL :
-                $this->setValue($dt->format('Ymd\\THis'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME'); 
-                break;
-            case self::UTC :
-                $dt->setTimeZone(new DateTimeZone('UTC'));
-                $this->setValue($dt->format('Ymd\\THis\\Z'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case self::LOCALTZ :
-                $this->setValue($dt->format('Ymd\\THis'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME');
-                $this->offsetSet('TZID', $dt->getTimeZone()->getName());
-                break; 
-            case self::DATE :
-                $this->setValue($dt->format('Ymd'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE');
-                break;
-            default :
-                throw new InvalidArgumentException('You must pass a valid dateType constant');
-
-        }
-        $this->dateTime = $dt;
-        $this->dateType = $dateType;
-
-    }
-
-    /**
-     * Returns the current DateTime value.
-     *
-     * If no value was set, this method returns null.
-     *
-     * @return DateTime|null 
-     */
-    public function getDateTime() {
-
-        if ($this->dateTime)
-            return $this->dateTime;
-
-        list(
-            $this->dateType,
-            $this->dateTime
-        ) = self::parseData($this->value, $this);
-        return $this->dateTime;
-
-    }
-
-    /**
-     * Returns the type of Date format.
-     *
-     * This method returns one of the format constants. If no date was set, 
-     * this method will return null.
-     *
-     * @return int|null
-     */
-    public function getDateType() {
-
-        if ($this->dateType)
-            return $this->dateType;
-
-        list(
-            $this->dateType,
-            $this->dateTime,
-        ) = self::parseData($this->value, $this);
-        return $this->dateType;
-
-    }
-
-    /**
-     * Parses the internal data structure to figure out what the current date 
-     * and time is.
-     *
-     * The returned array contains two elements:
-     *   1. A 'DateType' constant (as defined on this class), or null. 
-     *   2. A DateTime object (or null)
-     *
-     * @param string|null $propertyValue The string to parse (yymmdd or 
-     *                                   ymmddThhmmss, etc..)
-     * @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) {
-
-        if (is_null($propertyValue)) {
-            return array(null, null);
-        }
-
-        $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
-        $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
-        $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');
-        }
-
-        if (!isset($matches['hour'])) {
-            // Date-only
-            return array(
-                self::DATE,
-                new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
-            );
-        }
-
-        $dateStr = 
-            $matches['year'] .'-' . 
-            $matches['month'] . '-' . 
-            $matches['date'] . ' ' .
-            $matches['hour'] . ':' .
-            $matches['minute'] . ':' .
-            $matches['second']; 
-
-        if (isset($matches['isutc'])) {
-            $dt = new DateTime($dateStr,new DateTimeZone('UTC'));
-            $dt->setTimeZone(new DateTimeZone('UTC'));
-            return array(
-                self::UTC,
-                $dt
-            );
-        }
-
-        // Finding the timezone.
-        $tzid = $property['TZID'];
-        if (!$tzid) {
-            return array(
-                self::LOCAL,
-                new DateTime($dateStr)
-            );
-        }
-
-        try {
-            $tz = new DateTimeZone($tzid->value);
-        } catch (Exception $e) {
-
-            // The id was invalid, 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'})) {
-                            $tzid = (string)$vtimezone->{'X-LIC-LOCATION'};
-                        }
-                    }
-                }
-            }
-
-            $tz = new DateTimeZone($tzid);
-            
-        }
-        $dt = new DateTime($dateStr, $tz);
-        $dt->setTimeZone($tz);
-
-        return array(
-            self::LOCALTZ,
-            $dt
-        );
-
-    }
-
 }
-
-?>
diff --git a/3rdparty/Sabre/VObject/Element/MultiDateTime.php b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
old mode 100644
new mode 100755
index dc6ca5abb8021e90300f97176c05ec0686fd6530..8a12ced94a80418c2c3640bd975c948cab75672c
--- a/3rdparty/Sabre/VObject/Element/MultiDateTime.php
+++ b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
@@ -1,168 +1,17 @@
 <?php
 
 /**
- * Multi-DateTime property 
+ * Multi-DateTime property
  *
- * This element is used for iCalendar properties such as the EXDATE property. 
- * It basically provides a few helper functions that make it easier to deal 
- * with these. It supports both DATE-TIME and DATE values.
+ * This class got renamed to Sabre_VObject_Property_MultiDateTime
  *
- * In order to use this correctly, you must call setDateTimes and getDateTimes 
- * to retrieve and modify dates respectively.
- *
- * 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-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
-
-    /**
-     * DateTime representation
-     *
-     * @var DateTime[]
-     */
-    protected $dateTimes;
-
-    /**
-     * dateType
-     *
-     * This is one of the Sabre_VObject_Element_DateTime constants.
-     *
-     * @var int 
-     */
-    protected $dateType;
-
-    /**
-     * Updates the value 
-     * 
-     * @param array $dt Must be an array of DateTime objects. 
-     * @param int $dateType 
-     * @return void
-     */
-    public function setDateTimes(array $dt, $dateType = Sabre_VObject_Element_DateTime::LOCALTZ) {
-
-        foreach($dt as $i) 
-            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_Element_DateTime::LOCAL :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd\\THis');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME'); 
-                break;
-            case Sabre_VObject_Element_DateTime::UTC :
-                $val = array();
-                foreach($dt as $i) {
-                    $i->setTimeZone(new DateTimeZone('UTC'));
-                    $val[] = $i->format('Ymd\\THis\\Z');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case Sabre_VObject_Element_DateTime::LOCALTZ :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd\\THis');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME');
-                $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
-                break; 
-            case Sabre_VObject_Element_DateTime::DATE :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE');
-                break;
-            default :
-                throw new InvalidArgumentException('You must pass a valid dateType constant');
-
-        }
-        $this->dateTimes = $dt;
-        $this->dateType = $dateType;
-
-    }
-
-    /**
-     * Returns the current DateTime value.
-     *
-     * If no value was set, this method returns null.
-     *
-     * @return array|null 
-     */
-    public function getDateTimes() {
-
-        if ($this->dateTimes)
-            return $this->dateTimes;
-
-        $dts = array();
-    
-        if (!$this->value) {
-            $this->dateTimes = null;
-            $this->dateType = null;
-            return null;
-        }
-
-        foreach(explode(',',$this->value) as $val) {
-            list(
-                $type,
-                $dt
-            ) = Sabre_VObject_Element_DateTime::parseData($val, $this);
-            $dts[] = $dt;
-            $this->dateType = $type;
-        }
-        $this->dateTimes = $dts;
-        return $this->dateTimes;
-
-    }
-
-    /**
-     * Returns the type of Date format.
-     *
-     * This method returns one of the format constants. If no date was set, 
-     * this method will return null.
-     *
-     * @return int|null
-     */
-    public function getDateType() {
-
-        if ($this->dateType)
-            return $this->dateType;
-    
-        if (!$this->value) {
-            $this->dateTimes = null;
-            $this->dateType = null;
-            return null;
-        }
-
-        $dts = array();
-        foreach(explode(',',$this->value) as $val) {
-            list(
-                $type,
-                $dt
-            ) = Sabre_VObject_Element_DateTime::parseData($val, $this);
-            $dts[] = $dt;
-            $this->dateType = $type; 
-        }
-        $this->dateTimes = $dts;
-        return $this->dateType;
-
-    }
+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 100644
new mode 100755
index 9922cd587bcdaa3603dc574c130c8bf0faa9a34d..7e508db20f0841ff3f26b4300fe2ca85bdb19f90
--- a/3rdparty/Sabre/VObject/ElementList.php
+++ b/3rdparty/Sabre/VObject/ElementList.php
@@ -8,15 +8,15 @@
  *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * Inner elements 
-     * 
+     * Inner elements
+     *
      * @var array
      */
     protected $elements = array();
@@ -24,37 +24,37 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     /**
      * Creates the element list.
      *
-     * @param array $elements 
+     * @param array $elements
      */
     public function __construct(array $elements) {
 
         $this->elements = $elements;
 
-    } 
+    }
 
     /* {{{ Iterator interface */
 
     /**
-     * Current position  
-     * 
-     * @var int 
+     * Current position
+     *
+     * @var int
      */
     private $key = 0;
 
     /**
-     * Returns current item in iteration 
-     * 
-     * @return Sabre_VObject_Element 
+     * Returns current item in iteration
+     *
+     * @return Sabre_VObject_Element
      */
     public function current() {
 
         return $this->elements[$this->key];
 
     }
-   
+
     /**
-     * To the next item in the iterator 
-     * 
+     * To the next item in the iterator
+     *
      * @return void
      */
     public function next() {
@@ -64,8 +64,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     }
 
     /**
-     * Returns the current iterator key 
-     * 
+     * Returns the current iterator key
+     *
      * @return int
      */
     public function key() {
@@ -75,9 +75,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     }
 
     /**
-     * Returns true if the current position in the iterator is a valid one 
-     * 
-     * @return bool 
+     * Returns true if the current position in the iterator is a valid one
+     *
+     * @return bool
      */
     public function valid() {
 
@@ -86,9 +86,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     }
 
     /**
-     * Rewinds the iterator 
-     * 
-     * @return void 
+     * Rewinds the iterator
+     *
+     * @return void
      */
     public function rewind() {
 
@@ -101,9 +101,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     /* {{{ Countable interface */
 
     /**
-     * Returns the number of elements 
-     * 
-     * @return int 
+     * Returns the number of elements
+     *
+     * @return int
      */
     public function count() {
 
@@ -115,12 +115,12 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
 
     /* {{{ ArrayAccess Interface */
 
-    
+
     /**
      * Checks if an item exists through ArrayAccess.
      *
-     * @param int $offset 
-     * @return bool 
+     * @param int $offset
+     * @return bool
      */
     public function offsetExists($offset) {
 
@@ -131,8 +131,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     /**
      * Gets an item through ArrayAccess.
      *
-     * @param int $offset 
-     * @return mixed 
+     * @param int $offset
+     * @return mixed
      */
     public function offsetGet($offset) {
 
@@ -143,8 +143,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
     /**
      * Sets an item through ArrayAccess.
      *
-     * @param int $offset 
-     * @param mixed $value 
+     * @param int $offset
+     * @param mixed $value
      * @return void
      */
     public function offsetSet($offset,$value) {
@@ -158,7 +158,7 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
      *
      * This method just forwards the request to the inner iterator
      *
-     * @param int $offset 
+     * @param int $offset
      * @return void
      */
     public function offsetUnset($offset) {
diff --git a/3rdparty/Sabre/VObject/FreeBusyGenerator.php b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
new file mode 100755
index 0000000000000000000000000000000000000000..1c96a64a004b6a7055c0568f80903c122de6d9dd
--- /dev/null
+++ b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
@@ -0,0 +1,297 @@
+<?php
+
+/**
+ * This class helps with generating FREEBUSY reports based on existing sets of
+ * objects.
+ *
+ * It only looks at VEVENT and VFREEBUSY objects from the sourcedata, and
+ * generates a single VFREEBUSY object.
+ *
+ * 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 {
+
+    /**
+     * Input objects
+     *
+     * @var array
+     */
+    protected $objects;
+
+    /**
+     * Start of range
+     *
+     * @var DateTime|null
+     */
+    protected $start;
+
+    /**
+     * End of range
+     *
+     * @var DateTime|null
+     */
+    protected $end;
+
+    /**
+     * VCALENDAR object
+     *
+     * @var Sabre_VObject_Component
+     */
+    protected $baseObject;
+
+    /**
+     * Sets the VCALENDAR object.
+     *
+     * If this is set, it will not be generated for you. You are responsible
+     * for setting things like the METHOD, CALSCALE, VERSION, etc..
+     *
+     * The VFREEBUSY object will be automatically added though.
+     *
+     * @param Sabre_VObject_Component $vcalendar
+     * @return void
+     */
+    public function setBaseObject(Sabre_VObject_Component $vcalendar) {
+
+        $this->baseObject = $vcalendar;
+
+    }
+
+    /**
+     * Sets the input objects
+     *
+     * Every object must either be a string or a Sabre_VObject_Component.
+     *
+     * @param array $objects
+     * @return void
+     */
+    public function setObjects(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[] = $object;
+            } else {
+                throw new InvalidArgumentException('You can only pass strings or Sabre_VObject_Component arguments to setObjects');
+            }
+
+        }
+
+    }
+
+    /**
+     * Sets the time range
+     *
+     * Any freebusy object falling outside of this time range will be ignored.
+     *
+     * @param DateTime $start
+     * @param DateTime $end
+     * @return void
+     */
+    public function setTimeRange(DateTime $start = null, DateTime $end = null) {
+
+        $this->start = $start;
+        $this->end = $end;
+
+    }
+
+    /**
+     * Parses the input data and returns a correct VFREEBUSY object, wrapped in
+     * a VCALENDAR.
+     *
+     * @return Sabre_VObject_Component
+     */
+    public function getResult() {
+
+        $busyTimes = array();
+
+        foreach($this->objects as $object) {
+
+            foreach($object->getBaseComponents() as $component) {
+
+                switch($component->name) {
+
+                    case 'VEVENT' :
+
+                        $FBTYPE = 'BUSY';
+                        if (isset($component->TRANSP) && (strtoupper($component->TRANSP) === 'TRANSPARENT')) {
+                            break;
+                        }
+                        if (isset($component->STATUS)) {
+                            $status = strtoupper($component->STATUS);
+                            if ($status==='CANCELLED') {
+                                break;
+                            }
+                            if ($status==='TENTATIVE') {
+                                $FBTYPE = 'BUSY-TENTATIVE';
+                            }
+                        }
+
+                        $times = array();
+
+                        if ($component->RRULE) {
+
+                            $iterator = new Sabre_VObject_RecurrenceIterator($object, (string)$component->uid);
+                            if ($this->start) {
+                                $iterator->fastForward($this->start);
+                            }
+
+                            $maxRecurrences = 200;
+
+                            while($iterator->valid() && --$maxRecurrences) {
+
+                                $startTime = $iterator->getDTStart();
+                                if ($this->end && $startTime > $this->end) {
+                                    break;
+                                }
+                                $times[] = array(
+                                    $iterator->getDTStart(),
+                                    $iterator->getDTEnd(),
+                                );
+
+                                $iterator->next();
+
+                            }
+
+                        } else {
+
+                            $startTime = $component->DTSTART->getDateTime();
+                            if ($this->end && $startTime > $this->end) {
+                                break;
+                            }
+                            $endTime = null;
+                            if (isset($component->DTEND)) {
+                                $endTime = $component->DTEND->getDateTime();
+                            } elseif (isset($component->DURATION)) {
+                                $duration = Sabre_VObject_DateTimeParser::parseDuration((string)$component->DURATION);
+                                $endTime = clone $startTime;
+                                $endTime->add($duration);
+                            } elseif ($component->DTSTART->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
+                                $endTime = clone $startTime;
+                                $endTime->modify('+1 day');
+                            } else {
+                                // The event had no duration (0 seconds)
+                                break;
+                            }
+
+                            $times[] = array($startTime, $endTime);
+
+                        }
+
+                        foreach($times as $time) {
+
+                            if ($this->end && $time[0] > $this->end) break;
+                            if ($this->start && $time[1] < $this->start) break;
+
+                            $busyTimes[] = array(
+                                $time[0],
+                                $time[1],
+                                $FBTYPE,
+                            );
+                        }
+                        break;
+
+                    case 'VFREEBUSY' :
+                        foreach($component->FREEBUSY as $freebusy) {
+
+                            $fbType = isset($freebusy['FBTYPE'])?strtoupper($freebusy['FBTYPE']):'BUSY';
+
+                            // Skipping intervals marked as 'free'
+                            if ($fbType==='FREE')
+                                continue;
+
+                            $values = explode(',', $freebusy);
+                            foreach($values as $value) {
+                                list($startTime, $endTime) = explode('/', $value);
+                                $startTime = Sabre_VObject_DateTimeParser::parseDateTime($startTime);
+
+                                if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
+                                    $duration = Sabre_VObject_DateTimeParser::parseDuration($endTime);
+                                    $endTime = clone $startTime;
+                                    $endTime->add($duration);
+                                } else {
+                                    $endTime = Sabre_VObject_DateTimeParser::parseDateTime($endTime);
+                                }
+
+                                if($this->start && $this->start > $endTime) continue;
+                                if($this->end && $this->end < $startTime) continue;
+                                $busyTimes[] = array(
+                                    $startTime,
+                                    $endTime,
+                                    $fbType
+                                );
+
+                            }
+
+
+                        }
+                        break;
+
+
+
+                }
+
+
+            }
+
+        }
+
+        if ($this->baseObject) {
+            $calendar = $this->baseObject;
+        } else {
+            $calendar = new Sabre_VObject_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->calscale = 'GREGORIAN';
+        }
+
+        $vfreebusy = new Sabre_VObject_Component('VFREEBUSY');
+        $calendar->add($vfreebusy);
+
+        if ($this->start) {
+            $dtstart = new Sabre_VObject_Property_DateTime('DTSTART');
+            $dtstart->setDateTime($this->start,Sabre_VObject_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);
+            $vfreebusy->add($dtend);
+        }
+        $dtstamp = new Sabre_VObject_Property_DateTime('DTSTAMP');
+        $dtstamp->setDateTime(new DateTime('now'), Sabre_VObject_Property_DateTime::UTC);
+        $vfreebusy->add($dtstamp);
+
+        foreach($busyTimes as $busyTime) {
+
+            $busyTime[0]->setTimeZone(new DateTimeZone('UTC'));
+            $busyTime[1]->setTimeZone(new DateTimeZone('UTC'));
+
+            $prop = new Sabre_VObject_Property(
+                'FREEBUSY',
+                $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
+            );
+            $prop['FBTYPE'] = $busyTime[2];
+            $vfreebusy->add($prop);
+
+        }
+
+        return $calendar;
+
+    }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Node.php b/3rdparty/Sabre/VObject/Node.php
old mode 100644
new mode 100755
index 7100b62f1cb2a916f43bb64190fae8734539172a..d89e01b56c69e60904bbdc9496611951128b618a
--- a/3rdparty/Sabre/VObject/Node.php
+++ b/3rdparty/Sabre/VObject/Node.php
@@ -1,47 +1,47 @@
 <?php
 
 /**
- * Base class for all nodes 
- * 
+ * Base class for all nodes
+ *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * Turns the object back into a serialized blob. 
-     * 
-     * @return string 
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
      */
     abstract function serialize();
 
     /**
-     * Iterator override 
-     * 
-     * @var Sabre_VObject_ElementList 
+     * Iterator override
+     *
+     * @var Sabre_VObject_ElementList
      */
     protected $iterator = null;
 
     /**
      * A link to the parent node
-     * 
-     * @var Sabre_VObject_Node 
+     *
+     * @var Sabre_VObject_Node
      */
-    protected $parent = null;
+    public $parent = null;
 
     /* {{{ IteratorAggregator interface */
 
     /**
-     * Returns the iterator for this object 
-     * 
-     * @return Sabre_VObject_ElementList 
+     * Returns the iterator for this object
+     *
+     * @return Sabre_VObject_ElementList
      */
     public function getIterator() {
 
-        if (!is_null($this->iterator)) 
+        if (!is_null($this->iterator))
             return $this->iterator;
 
         return new Sabre_VObject_ElementList(array($this));
@@ -52,8 +52,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
      * Sets the overridden iterator
      *
      * Note that this is not actually part of the iterator interface
-     * 
-     * @param Sabre_VObject_ElementList $iterator 
+     *
+     * @param Sabre_VObject_ElementList $iterator
      * @return void
      */
     public function setIterator(Sabre_VObject_ElementList $iterator) {
@@ -67,9 +67,9 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
     /* {{{ Countable interface */
 
     /**
-     * Returns the number of elements 
-     * 
-     * @return int 
+     * Returns the number of elements
+     *
+     * @return int
      */
     public function count() {
 
@@ -82,14 +82,14 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
 
     /* {{{ ArrayAccess Interface */
 
-    
+
     /**
      * Checks if an item exists through ArrayAccess.
      *
      * This method just forwards the request to the inner iterator
-     * 
-     * @param int $offset 
-     * @return bool 
+     *
+     * @param int $offset
+     * @return bool
      */
     public function offsetExists($offset) {
 
@@ -103,8 +103,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
      *
      * This method just forwards the request to the inner iterator
      *
-     * @param int $offset 
-     * @return mixed 
+     * @param int $offset
+     * @return mixed
      */
     public function offsetGet($offset) {
 
@@ -118,8 +118,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
      *
      * This method just forwards the request to the inner iterator
      *
-     * @param int $offset 
-     * @param mixed $value 
+     * @param int $offset
+     * @param mixed $value
      * @return void
      */
     public function offsetSet($offset,$value) {
@@ -134,7 +134,7 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
      *
      * This method just forwards the request to the inner iterator
      *
-     * @param int $offset 
+     * @param int $offset
      * @return void
      */
     public function offsetUnset($offset) {
diff --git a/3rdparty/Sabre/VObject/Parameter.php b/3rdparty/Sabre/VObject/Parameter.php
old mode 100644
new mode 100755
index 9ebab6ec69ba89d929efd85a7f5544d48444c126..2e39af5f78ab1788067335f7b3f703845e26f4e8
--- a/3rdparty/Sabre/VObject/Parameter.php
+++ b/3rdparty/Sabre/VObject/Parameter.php
@@ -5,51 +5,54 @@
  *
  * This class represents a parameter. A parameter is always tied to a property.
  * In the case of:
- *   DTSTART;VALUE=DATE:20101108 
+ *   DTSTART;VALUE=DATE:20101108
  * VALUE=DATE would be the parameter name and value.
- * 
+ *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * Parameter name 
-     * 
-     * @var string 
+     * Parameter name
+     *
+     * @var string
      */
     public $name;
 
     /**
-     * Parameter value 
-     * 
-     * @var string 
+     * Parameter value
+     *
+     * @var string
      */
     public $value;
 
     /**
-     * Sets up the object 
-     * 
-     * @param string $name 
-     * @param string $value 
+     * Sets up the object
+     *
+     * @param string $name
+     * @param string $value
      */
     public function __construct($name, $value = null) {
 
         $this->name = strtoupper($name);
         $this->value = $value;
 
-    } 
+    }
 
     /**
-     * Turns the object back into a serialized blob. 
-     * 
-     * @return string 
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
      */
     public function serialize() {
 
+        if (is_null($this->value)) {
+            return $this->name;
+        }
         $src = array(
             '\\',
             "\n",
@@ -68,9 +71,9 @@ class Sabre_VObject_Parameter extends Sabre_VObject_Node {
     }
 
     /**
-     * Called when this object is being cast to a string 
-     * 
-     * @return string 
+     * Called when this object is being cast to a string
+     *
+     * @return string
      */
     public function __toString() {
 
diff --git a/3rdparty/Sabre/VObject/ParseException.php b/3rdparty/Sabre/VObject/ParseException.php
old mode 100644
new mode 100755
index ed4ef2e859275a5e3bf24015bf5870b632a35b2c..1b5e95bf16e49b5184b5fc089ec063457c5d3bab
--- a/3rdparty/Sabre/VObject/ParseException.php
+++ b/3rdparty/Sabre/VObject/ParseException.php
@@ -2,11 +2,11 @@
 
 /**
  * Exception thrown by Sabre_VObject_Reader if an invalid object was attempted to be parsed.
- * 
+ *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 { }
diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php
old mode 100644
new mode 100755
index 060582290438d8dd520960c54b79a108305eb2e9..ce74fe3865b86d38d0fa9a8a05d9363116d926f4
--- a/3rdparty/Sabre/VObject/Property.php
+++ b/3rdparty/Sabre/VObject/Property.php
@@ -4,58 +4,103 @@
  * VObject Property
  *
  * A property in VObject is usually in the form PARAMNAME:paramValue.
- * An example is : SUMMARY:Weekly meeting 
+ * An example is : SUMMARY:Weekly meeting
  *
  * Properties can also have parameters:
  * SUMMARY;LANG=en:Weekly meeting.
  *
- * Parameters can be accessed using the ArrayAccess interface. 
+ * Parameters can be accessed using the ArrayAccess interface.
  *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * Propertyname 
-     * 
-     * @var string 
+     * Propertyname
+     *
+     * @var string
      */
     public $name;
 
     /**
      * Group name
-     * 
+     *
      * This may be something like 'HOME' for vcards.
      *
-     * @var string 
+     * @var string
      */
     public $group;
 
     /**
-     * Property parameters 
-     * 
-     * @var array 
+     * Property parameters
+     *
+     * @var array
      */
     public $parameters = array();
 
     /**
-     * Property value 
-     * 
-     * @var string 
+     * Property value
+     *
+     * @var string
      */
     public $value;
 
+    /**
+     * If properties 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(
+        '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',
+    );
+
+    /**
+     * Creates the new property by name, but in addition will also see if
+     * there's a class mapped to the property name.
+     *
+     * @param string $name
+     * @param string $value
+     * @return void
+     */
+    static public function create($name, $value = null) {
+
+        $name = strtoupper($name);
+        $shortName = $name;
+        $group = null;
+        if (strpos($shortName,'.')!==false) {
+            list($group, $shortName) = explode('.', $shortName);
+        }
+
+        if (isset(self::$classMap[$shortName])) {
+            return new self::$classMap[$shortName]($name, $value);
+        } else {
+            return new self($name, $value);
+        }
+
+    }
+
     /**
      * Creates a new property object
-     * 
-     * By default this object will iterate over its own children, but this can 
+     *
+     * By default this object will iterate over its own children, but this can
      * be overridden with the iterator argument
-     * 
-     * @param string $name 
+     *
+     * @param string $name
      * @param string $value
      * @param Sabre_VObject_ElementList $iterator
      */
@@ -73,10 +118,12 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
 
     }
 
+
+
     /**
-     * Updates the internal value 
-     * 
-     * @param string $value 
+     * Updates the internal value
+     *
+     * @param string $value
      * @return void
      */
     public function setValue($value) {
@@ -86,9 +133,9 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     }
 
     /**
-     * Turns the object back into a serialized blob. 
-     * 
-     * @return string 
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
      */
     public function serialize() {
 
@@ -97,7 +144,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
 
         if (count($this->parameters)) {
             foreach($this->parameters as $param) {
-                
+
                 $str.=';' . $param->serialize();
 
             }
@@ -115,8 +162,8 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         $out = '';
         while(strlen($str)>0) {
             if (strlen($str)>75) {
-                $out.= substr($str,0,75) . "\r\n";
-                $str = ' ' . substr($str,75);
+                $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
+                $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
             } else {
                 $out.=$str . "\r\n";
                 $str='';
@@ -136,11 +183,11 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
      * add(Sabre_VObject_Parameter $element)
      * add(string $name, $value)
      *
-     * The first version adds an Parameter 
-     * The second adds a property as a string. 
-     * 
-     * @param mixed $item 
-     * @param mixed $itemValue 
+     * The first version adds an Parameter
+     * The second adds a property as a string.
+     *
+     * @param mixed $item
+     * @param mixed $itemValue
      * @return void
      */
     public function add($item, $itemValue = null) {
@@ -153,7 +200,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
             $this->parameters[] = $item;
         } elseif(is_string($item)) {
 
-            if (!is_scalar($itemValue)) {
+            if (!is_scalar($itemValue) && !is_null($itemValue)) {
                 throw new InvalidArgumentException('The second argument must be scalar');
             }
             $parameter = new Sabre_VObject_Parameter($item,$itemValue);
@@ -161,21 +208,20 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
             $this->parameters[] = $parameter;
 
         } else {
-            
+
             throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
 
         }
 
     }
 
-
     /* ArrayAccess interface {{{ */
 
     /**
      * Checks if an array element exists
-     * 
-     * @param mixed $name 
-     * @return bool 
+     *
+     * @param mixed $name
+     * @return bool
      */
     public function offsetExists($name) {
 
@@ -191,16 +237,16 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     }
 
     /**
-     * Returns a parameter, or parameter list. 
-     * 
-     * @param string $name 
-     * @return Sabre_VObject_Element 
+     * Returns a parameter, or parameter list.
+     *
+     * @param string $name
+     * @return Sabre_VObject_Element
      */
     public function offsetGet($name) {
 
         if (is_int($name)) return parent::offsetGet($name);
         $name = strtoupper($name);
-        
+
         $result = array();
         foreach($this->parameters as $parameter) {
             if ($parameter->name == $name)
@@ -219,8 +265,8 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     }
 
     /**
-     * Creates a new parameter 
-     * 
+     * Creates a new parameter
+     *
      * @param string $name
      * @param mixed $value
      * @return void
@@ -230,7 +276,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
         if (is_int($name)) return parent::offsetSet($name, $value);
 
         if (is_scalar($value)) {
-            if (!is_string($name)) 
+            if (!is_string($name))
                 throw new InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
 
             $this->offsetUnset($name);
@@ -242,7 +288,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
             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.');
 
-            $value->parent = $this; 
+            $value->parent = $this;
             $this->parameters[] = $value;
         } else {
             throw new InvalidArgumentException('You can only add parameters to the property object');
@@ -251,17 +297,16 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     }
 
     /**
-     * Removes one or more parameters with the specified name 
-     * 
-     * @param string $name 
-     * @return void 
+     * Removes one or more parameters with the specified name
+     *
+     * @param string $name
+     * @return void
      */
     public function offsetUnset($name) {
 
-        if (is_int($name)) return parent::offsetUnset($name, $value);
+        if (is_int($name)) return parent::offsetUnset($name);
         $name = strtoupper($name);
-        
-        $result = array();
+
         foreach($this->parameters as $key=>$parameter) {
             if ($parameter->name == $name) {
                 $parameter->parent = null;
@@ -275,15 +320,29 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
     /* }}} */
 
     /**
-     * Called when this object is being cast to a string 
-     * 
-     * @return string 
+     * Called when this object is being cast to a string
+     *
+     * @return string
      */
     public function __toString() {
 
-        return $this->value;
+        return (string)$this->value;
 
     }
 
+    /**
+     * This method is automatically called when the object is cloned.
+     * Specifically, this will ensure all child elements are also cloned.
+     *
+     * @return void
+     */
+    public function __clone() {
+
+        foreach($this->parameters as $key=>$child) {
+            $this->parameters[$key] = clone $child;
+            $this->parameters[$key]->parent = $this;
+        }
+
+    }
 
 }
diff --git a/3rdparty/Sabre/VObject/Property/DateTime.php b/3rdparty/Sabre/VObject/Property/DateTime.php
new file mode 100755
index 0000000000000000000000000000000000000000..fe2372caa81cade8eb1aa149ea923e7fd62206dc
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Property/DateTime.php
@@ -0,0 +1,260 @@
+<?php
+
+/**
+ * DateTime property
+ *
+ * This element is used for iCalendar properties such as the DTSTART property.
+ * It basically provides a few helper functions that make it easier to deal
+ * with these. It supports both DATE-TIME and DATE values.
+ *
+ * In order to use this correctly, you must call setDateTime and getDateTime to
+ * retrieve and modify dates respectively.
+ *
+ * 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 {
+
+    /**
+     * 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;
+
+    /**
+     * DateTime representation
+     *
+     * @var DateTime
+     */
+    protected $dateTime;
+
+    /**
+     * dateType
+     *
+     * @var int
+     */
+    protected $dateType;
+
+    /**
+     * Updates the Date and Time.
+     *
+     * @param DateTime $dt
+     * @param int $dateType
+     * @return void
+     */
+    public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
+
+        switch($dateType) {
+
+            case self::LOCAL :
+                $this->setValue($dt->format('Ymd\\THis'));
+                $this->offsetUnset('VALUE');
+                $this->offsetUnset('TZID');
+                $this->offsetSet('VALUE','DATE-TIME');
+                break;
+            case self::UTC :
+                $dt->setTimeZone(new DateTimeZone('UTC'));
+                $this->setValue($dt->format('Ymd\\THis\\Z'));
+                $this->offsetUnset('VALUE');
+                $this->offsetUnset('TZID');
+                $this->offsetSet('VALUE','DATE-TIME');
+                break;
+            case self::LOCALTZ :
+                $this->setValue($dt->format('Ymd\\THis'));
+                $this->offsetUnset('VALUE');
+                $this->offsetUnset('TZID');
+                $this->offsetSet('VALUE','DATE-TIME');
+                $this->offsetSet('TZID', $dt->getTimeZone()->getName());
+                break;
+            case self::DATE :
+                $this->setValue($dt->format('Ymd'));
+                $this->offsetUnset('VALUE');
+                $this->offsetUnset('TZID');
+                $this->offsetSet('VALUE','DATE');
+                break;
+            default :
+                throw new InvalidArgumentException('You must pass a valid dateType constant');
+
+        }
+        $this->dateTime = $dt;
+        $this->dateType = $dateType;
+
+    }
+
+    /**
+     * Returns the current DateTime value.
+     *
+     * If no value was set, this method returns null.
+     *
+     * @return DateTime|null
+     */
+    public function getDateTime() {
+
+        if ($this->dateTime)
+            return $this->dateTime;
+
+        list(
+            $this->dateType,
+            $this->dateTime
+        ) = self::parseData($this->value, $this);
+        return $this->dateTime;
+
+    }
+
+    /**
+     * Returns the type of Date format.
+     *
+     * This method returns one of the format constants. If no date was set,
+     * this method will return null.
+     *
+     * @return int|null
+     */
+    public function getDateType() {
+
+        if ($this->dateType)
+            return $this->dateType;
+
+        list(
+            $this->dateType,
+            $this->dateTime,
+        ) = self::parseData($this->value, $this);
+        return $this->dateType;
+
+    }
+
+    /**
+     * Parses the internal data structure to figure out what the current date
+     * and time is.
+     *
+     * The returned array contains two elements:
+     *   1. A 'DateType' constant (as defined on this class), or null.
+     *   2. A DateTime object (or null)
+     *
+     * @param string|null $propertyValue The string to parse (yymmdd or
+     *                                   ymmddThhmmss, etc..)
+     * @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) {
+
+        if (is_null($propertyValue)) {
+            return array(null, null);
+        }
+
+        $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
+        $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
+        $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');
+        }
+
+        if (!isset($matches['hour'])) {
+            // Date-only
+            return array(
+                self::DATE,
+                new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
+            );
+        }
+
+        $dateStr =
+            $matches['year'] .'-' .
+            $matches['month'] . '-' .
+            $matches['date'] . ' ' .
+            $matches['hour'] . ':' .
+            $matches['minute'] . ':' .
+            $matches['second'];
+
+        if (isset($matches['isutc'])) {
+            $dt = new DateTime($dateStr,new DateTimeZone('UTC'));
+            $dt->setTimeZone(new DateTimeZone('UTC'));
+            return array(
+                self::UTC,
+                $dt
+            );
+        }
+
+        // Finding the timezone.
+        $tzid = $property['TZID'];
+        if (!$tzid) {
+            return array(
+                self::LOCAL,
+                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()); 
+            }
+        }
+        $dt = new DateTime($dateStr, $tz);
+        $dt->setTimeZone($tz);
+
+        return array(
+            self::LOCALTZ,
+            $dt
+        );
+
+    }
+
+}
diff --git a/3rdparty/Sabre/VObject/Property/MultiDateTime.php b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
new file mode 100755
index 0000000000000000000000000000000000000000..ae53ab6a6173a87922c90f8a5bb129ab8a341d92
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
@@ -0,0 +1,166 @@
+<?php
+
+/**
+ * Multi-DateTime property
+ *
+ * This element is used for iCalendar properties such as the EXDATE property.
+ * It basically provides a few helper functions that make it easier to deal
+ * with these. It supports both DATE-TIME and DATE values.
+ *
+ * In order to use this correctly, you must call setDateTimes and getDateTimes
+ * to retrieve and modify dates respectively.
+ *
+ * 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 {
+
+    /**
+     * DateTime representation
+     *
+     * @var DateTime[]
+     */
+    protected $dateTimes;
+
+    /**
+     * dateType
+     *
+     * This is one of the Sabre_VObject_Property_DateTime constants.
+     *
+     * @var int
+     */
+    protected $dateType;
+
+    /**
+     * Updates the value
+     *
+     * @param array $dt Must be an array of DateTime objects.
+     * @param int $dateType
+     * @return void
+     */
+    public function setDateTimes(array $dt, $dateType = Sabre_VObject_Property_DateTime::LOCALTZ) {
+
+        foreach($dt as $i)
+            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 :
+                $val = array();
+                foreach($dt as $i) {
+                    $val[] = $i->format('Ymd\\THis');
+                }
+                $this->setValue(implode(',',$val));
+                $this->offsetSet('VALUE','DATE-TIME');
+                break;
+            case Sabre_VObject_Property_DateTime::UTC :
+                $val = array();
+                foreach($dt as $i) {
+                    $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 :
+                $val = array();
+                foreach($dt as $i) {
+                    $val[] = $i->format('Ymd\\THis');
+                }
+                $this->setValue(implode(',',$val));
+                $this->offsetSet('VALUE','DATE-TIME');
+                $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
+                break;
+            case Sabre_VObject_Property_DateTime::DATE :
+                $val = array();
+                foreach($dt as $i) {
+                    $val[] = $i->format('Ymd');
+                }
+                $this->setValue(implode(',',$val));
+                $this->offsetSet('VALUE','DATE');
+                break;
+            default :
+                throw new InvalidArgumentException('You must pass a valid dateType constant');
+
+        }
+        $this->dateTimes = $dt;
+        $this->dateType = $dateType;
+
+    }
+
+    /**
+     * Returns the current DateTime value.
+     *
+     * If no value was set, this method returns null.
+     *
+     * @return array|null
+     */
+    public function getDateTimes() {
+
+        if ($this->dateTimes)
+            return $this->dateTimes;
+
+        $dts = array();
+
+        if (!$this->value) {
+            $this->dateTimes = null;
+            $this->dateType = null;
+            return null;
+        }
+
+        foreach(explode(',',$this->value) as $val) {
+            list(
+                $type,
+                $dt
+            ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+            $dts[] = $dt;
+            $this->dateType = $type;
+        }
+        $this->dateTimes = $dts;
+        return $this->dateTimes;
+
+    }
+
+    /**
+     * Returns the type of Date format.
+     *
+     * This method returns one of the format constants. If no date was set,
+     * this method will return null.
+     *
+     * @return int|null
+     */
+    public function getDateType() {
+
+        if ($this->dateType)
+            return $this->dateType;
+
+        if (!$this->value) {
+            $this->dateTimes = null;
+            $this->dateType = null;
+            return null;
+        }
+
+        $dts = array();
+        foreach(explode(',',$this->value) as $val) {
+            list(
+                $type,
+                $dt
+            ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+            $dts[] = $dt;
+            $this->dateType = $type;
+        }
+        $this->dateTimes = $dts;
+        return $this->dateType;
+
+    }
+
+}
diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php
old mode 100644
new mode 100755
index 7d1c282838e84e09cccaa4e57f540537e5f3b74d..eea73fa3dcee68163a42e9703a748feb783007fb
--- a/3rdparty/Sabre/VObject/Reader.php
+++ b/3rdparty/Sabre/VObject/Reader.php
@@ -5,40 +5,22 @@
  *
  * This class reads the vobject file, and returns a full element tree.
  *
+ * TODO: this class currently completely works 'statically'. This is pointless,
+ * and defeats OOP principals. Needs refactoring in a future version.
  *
- * TODO: this class currently completely works 'statically'. This is pointless, 
- * and defeats OOP principals. Needs refaxtoring in a future version.
- * 
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 {
 
     /**
-     * This array contains a list of Property names that are automatically 
-     * mapped to specific class names.
+     * Parses the file and returns the top component
      *
-     * Adding to this list allows you to specify custom property classes, 
-     * adding extra functionality. 
-     * 
-     * @var array
-     */
-    static public $elementMap = array(
-        'DTSTART'   => 'Sabre_VObject_Element_DateTime',
-        'DTEND'     => 'Sabre_VObject_Element_DateTime',
-        'COMPLETED' => 'Sabre_VObject_Element_DateTime',
-        'DUE'       => 'Sabre_VObject_Element_DateTime',
-        'EXDATE'    => 'Sabre_VObject_Element_MultiDateTime',
-    );
-
-    /**
-     * Parses the file and returns the top component 
-     * 
-     * @param string $data 
-     * @return Sabre_VObject_Element 
+     * @param string $data
+     * @return Sabre_VObject_Element
      */
     static function read($data) {
 
@@ -63,11 +45,11 @@ class Sabre_VObject_Reader {
         }
 
         unset($lines);
-        
+
         reset($lines2);
 
         return self::readLine($lines2);
-       
+
     }
 
     /**
@@ -75,9 +57,9 @@ class Sabre_VObject_Reader {
      *
      * This method receives the full array of lines. The array pointer is used
      * to traverse.
-     * 
-     * @param array $lines 
-     * @return Sabre_VObject_Element 
+     *
+     * @param array $lines
+     * @return Sabre_VObject_Element
      */
     static private function readLine(&$lines) {
 
@@ -88,22 +70,23 @@ class Sabre_VObject_Reader {
         // Components
         if (stripos($line,"BEGIN:")===0) {
 
-            // This is a component
-            $obj = new Sabre_VObject_Component(strtoupper(substr($line,6)));
+            $componentName = strtoupper(substr($line,6));
+            $obj = Sabre_VObject_Component::create($componentName);
 
             $nextLine = current($lines);
 
             while(stripos($nextLine,"END:")!==0) {
 
                 $obj->add(self::readLine($lines));
+
                 $nextLine = current($lines);
 
-                if ($nextLine===false) 
+                if ($nextLine===false)
                     throw new Sabre_VObject_ParseException('Invalid VObject. Document ended prematurely.');
 
             }
 
-            // Checking component name of the 'END:' line. 
+            // 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 . '"');
             }
@@ -117,7 +100,7 @@ class Sabre_VObject_Reader {
         //$result = preg_match('/(?P<name>[A-Z0-9-]+)(?:;(?P<parameters>^(?<!:):))(.*)$/',$line,$matches);
 
 
-        $token = '[A-Z0-9-\/\.]+';
+        $token = '[A-Z0-9-\.]+';
         $parameters = "(?:;(?P<parameters>([^:^\"]|\"([^\"]*)\")*))?";
         $regex = "/^(?P<name>$token)$parameters:(?P<value>.*)$/i";
 
@@ -128,22 +111,23 @@ class Sabre_VObject_Reader {
         }
 
         $propertyName = strtoupper($matches['name']);
-        $propertyValue = stripcslashes($matches['value']);
-
-        if (isset(self::$elementMap[$propertyName])) {
-            $className = self::$elementMap[$propertyName];
-        } else {
-            $className = 'Sabre_VObject_Property';
-        }
+        $propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
+            if ($matches[2]==='n' || $matches[2]==='N') {
+                return "\n";
+            } else {
+                return $matches[2];
+            }
+        }, $matches['value']);
 
-        $obj = new $className($propertyName, $propertyValue);
+        $obj = Sabre_VObject_Property::create($propertyName, $propertyValue);
 
         if ($matches['parameters']) {
 
             foreach(self::readParameters($matches['parameters']) as $param) {
                 $obj->add($param);
             }
-        } 
+
+        }
 
         return $obj;
 
@@ -151,12 +135,12 @@ class Sabre_VObject_Reader {
     }
 
     /**
-     * Reads a parameter list from a property 
+     * Reads a parameter list from a property
      *
      * This method returns an array of Sabre_VObject_Parameter
      *
-     * @param string $parameters 
-     * @return array 
+     * @param string $parameters
+     * @return array
      */
     static private function readParameters($parameters) {
 
@@ -179,7 +163,15 @@ class Sabre_VObject_Reader {
                 $value = '';
             }
 
-            $params[] = new Sabre_VObject_Parameter($match['paramName'], stripcslashes($value));
+            $value = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
+                if ($matches[2]==='n' || $matches[2]==='N') {
+                    return "\n";
+                } else {
+                    return $matches[2];
+                }
+            }, $value);
+
+            $params[] = new Sabre_VObject_Parameter($match['paramName'], $value);
 
         }
 
diff --git a/3rdparty/Sabre/VObject/RecurrenceIterator.php b/3rdparty/Sabre/VObject/RecurrenceIterator.php
new file mode 100755
index 0000000000000000000000000000000000000000..833aa091ab759cb0a0f7d290ddd6471c7ff99df8
--- /dev/null
+++ b/3rdparty/Sabre/VObject/RecurrenceIterator.php
@@ -0,0 +1,1009 @@
+<?php
+
+/**
+ * This class is used to determine new for a recurring event, when the next
+ * events occur.
+ *
+ * This iterator may loop infinitely in the future, therefore it is important
+ * that if you use this class, you set hard limits for the amount of iterations
+ * you want to handle.
+ *
+ * Note that currently there is not full support for the entire iCalendar
+ * specification, as it's very complex and contains a lot of permutations
+ * that's not yet used very often in software.
+ *
+ * For the focus has been on features as they actually appear in Calendaring
+ * software, but this may well get expanded as needed / on demand
+ *
+ * The following RRULE properties are supported
+ *   * UNTIL
+ *   * INTERVAL
+ *   * COUNT
+ *   * FREQ=DAILY
+ *     * BYDAY
+ *   * FREQ=WEEKLY
+ *     * BYDAY
+ *     * WKST
+ *   * FREQ=MONTHLY
+ *     * BYMONTHDAY
+ *     * BYDAY
+ *     * BYSETPOS
+ *   * FREQ=YEARLY
+ *     * BYMONTH
+ *     * BYMONTHDAY (only if BYMONTH is also set)
+ *     * BYDAY (only if BYMONTH is also set)
+ *
+ * Anything beyond this is 'undefined', which means that it may get ignored, or
+ * 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 {
+
+    /**
+     * The initial event date
+     *
+     * @var DateTime
+     */
+    public $startDate;
+
+    /**
+     * The end-date of the initial event
+     *
+     * @var DateTime
+     */
+    public $endDate;
+
+    /**
+     * The 'current' recurrence.
+     *
+     * This will be increased for every iteration.
+     *
+     * @var DateTime
+     */
+    public $currentDate;
+
+
+    /**
+     * List of dates that are excluded from the rules.
+     *
+     * This list contains the items that have been overriden by the EXDATE
+     * property.
+     *
+     * @var array
+     */
+    public $exceptionDates = array();
+
+    /**
+     * Base event
+     *
+     * @var Sabre_VObject_Component_VEvent
+     */
+    public $baseEvent;
+
+    /**
+     * List of dates that are overridden by other events.
+     * Similar to $overriddenEvents, but this just contains the original dates.
+     *
+     * @var array
+     */
+    public $overriddenDates = array();
+
+    /**
+     * list of events that are 'overridden'.
+     *
+     * This is an array of Sabre_VObject_Component_VEvent objects.
+     *
+     * @var array
+     */
+    public $overriddenEvents = array();
+
+
+    /**
+     * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
+     * yearly.
+     *
+     * @var string
+     */
+    public $frequency;
+
+    /**
+     * The last instance of this recurrence, inclusively
+     *
+     * @var DateTime|null
+     */
+    public $until;
+
+    /**
+     * The number of recurrences, or 'null' if infinitely recurring.
+     *
+     * @var int
+     */
+    public $count;
+
+    /**
+     * The interval.
+     *
+     * If for example frequency is set to daily, interval = 2 would mean every
+     * 2 days.
+     *
+     * @var int
+     */
+    public $interval = 1;
+
+    /**
+     * Which seconds to recur.
+     *
+     * This is an array of integers (between 0 and 60)
+     *
+     * @var array
+     */
+    public $bySecond;
+
+    /**
+     * Which minutes to recur
+     *
+     * This is an array of integers (between 0 and 59)
+     *
+     * @var array
+     */
+    public $byMinute;
+
+    /**
+     * Which hours to recur
+     *
+     * This is an array of integers (between 0 and 23)
+     *
+     * @var array
+     */
+    public $byHour;
+
+    /**
+     * Which weekdays to recur.
+     *
+     * This is an array of weekdays
+     *
+     * This may also be preceeded by a positive or negative integer. If present,
+     * this indicates the nth occurrence of a specific day within the monthly or
+     * yearly rrule. For instance, -2TU indicates the second-last tuesday of
+     * the month, or year.
+     *
+     * @var array
+     */
+    public $byDay;
+
+    /**
+     * Which days of the month to recur
+     *
+     * This is an array of days of the months (1-31). The value can also be
+     * negative. -5 for instance means the 5th last day of the month.
+     *
+     * @var array
+     */
+    public $byMonthDay;
+
+    /**
+     * Which days of the year to recur.
+     *
+     * This is an array with days of the year (1 to 366). The values can also
+     * be negative. For instance, -1 will always represent the last day of the
+     * year. (December 31st).
+     *
+     * @var array
+     */
+    public $byYearDay;
+
+    /**
+     * Which week numbers to recur.
+     *
+     * This is an array of integers from 1 to 53. The values can also be
+     * negative. -1 will always refer to the last week of the year.
+     *
+     * @var array
+     */
+    public $byWeekNo;
+
+    /**
+     * Which months to recur
+     *
+     * This is an array of integers from 1 to 12.
+     *
+     * @var array
+     */
+    public $byMonth;
+
+    /**
+     * Which items in an existing st to recur.
+     *
+     * These numbers work together with an existing by* rule. It specifies
+     * exactly which items of the existing by-rule to filter.
+     *
+     * Valid values are 1 to 366 and -1 to -366. As an example, this can be
+     * used to recur the last workday of the month.
+     *
+     * This would be done by setting frequency to 'monthly', byDay to
+     * 'MO,TU,WE,TH,FR' and bySetPos to -1.
+     *
+     * @var array
+     */
+    public $bySetPos;
+
+    /**
+     * When a week starts
+     *
+     * @var string
+     */
+    public $weekStart = 'MO';
+
+    /**
+     * The current item in the list
+     *
+     * @var int
+     */
+    public $counter = 0;
+
+    /**
+     * Simple mapping from iCalendar day names to day numbers
+     *
+     * @var array
+     */
+    private $dayMap = array(
+        'SU' => 0,
+        'MO' => 1,
+        'TU' => 2,
+        'WE' => 3,
+        'TH' => 4,
+        'FR' => 5,
+        'SA' => 6,
+    );
+
+    /**
+     * Mappings between the day number and english day name.
+     *
+     * @var array
+     */
+    private $dayNames = array(
+        0 => 'Sunday',
+        1 => 'Monday',
+        2 => 'Tuesday',
+        3 => 'Wednesday',
+        4 => 'Thursday',
+        5 => 'Friday',
+        6 => 'Saturday',
+    );
+
+    /**
+     * If the current iteration of the event is an overriden event, this
+     * property will hold the VObject
+     *
+     * @var Sabre_Component_VObject
+     */
+    private $currentOverriddenEvent;
+
+    /**
+     * This property may contain the date of the next not-overridden event.
+     * This date is calculated sometimes a bit early, before overridden events
+     * are evaluated.
+     *
+     * @var DateTime
+     */
+    private $nextDate;
+
+    /**
+     * Creates the 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 string|null $uid
+     */
+    public function __construct(Sabre_VObject_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');
+            }
+            $components = array($vcal);
+            $uid = (string)$vcal->uid;
+        } else {
+            $components = $vcal->select('VEVENT');
+        }
+        foreach($components as $component) {
+            if ((string)$component->uid == $uid) {
+                if (isset($component->{'RECURRENCE-ID'})) {
+                    $this->overriddenEvents[$component->DTSTART->getDateTime()->getTimeStamp()] = $component;
+                    $this->overriddenDates[] = $component->{'RECURRENCE-ID'}->getDateTime();
+                } else {
+                    $this->baseEvent = $component;
+                }
+            }
+        }
+        if (!$this->baseEvent) {
+            throw new InvalidArgumentException('Could not find a base event with uid: ' . $uid);
+        }
+
+        $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
+
+        $this->endDate = null;
+        if (isset($this->baseEvent->DTEND)) {
+            $this->endDate = clone $this->baseEvent->DTEND->getDateTime();
+        } else {
+            $this->endDate = clone $this->startDate;
+            if (isset($this->baseEvent->DURATION)) {
+                $this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value));
+            }
+        }
+        $this->currentDate = clone $this->startDate;
+
+        $rrule = (string)$this->baseEvent->RRULE;
+
+        $parts = explode(';', $rrule);
+
+        foreach($parts as $part) {
+
+            list($key, $value) = explode('=', $part, 2);
+
+            switch(strtoupper($key)) {
+
+                case 'FREQ' :
+                    if (!in_array(
+                        strtolower($value),
+                        array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
+                    )) {
+                        throw new InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
+
+                    }
+                    $this->frequency = strtolower($value);
+                    break;
+
+                case 'UNTIL' :
+                    $this->until = Sabre_VObject_DateTimeParser::parse($value);
+                    break;
+
+                case 'COUNT' :
+                    $this->count = (int)$value;
+                    break;
+
+                case 'INTERVAL' :
+                    $this->interval = (int)$value;
+                    break;
+
+                case 'BYSECOND' :
+                    $this->bySecond = explode(',', $value);
+                    break;
+
+                case 'BYMINUTE' :
+                    $this->byMinute = explode(',', $value);
+                    break;
+
+                case 'BYHOUR' :
+                    $this->byHour = explode(',', $value);
+                    break;
+
+                case 'BYDAY' :
+                    $this->byDay = explode(',', strtoupper($value));
+                    break;
+
+                case 'BYMONTHDAY' :
+                    $this->byMonthDay = explode(',', $value);
+                    break;
+
+                case 'BYYEARDAY' :
+                    $this->byYearDay = explode(',', $value);
+                    break;
+
+                case 'BYWEEKNO' :
+                    $this->byWeekNo = explode(',', $value);
+                    break;
+
+                case 'BYMONTH' :
+                    $this->byMonth = explode(',', $value);
+                    break;
+
+                case 'BYSETPOS' :
+                    $this->bySetPos = explode(',', $value);
+                    break;
+
+                case 'WKST' :
+                    $this->weekStart = strtoupper($value);
+                    break;
+
+            }
+
+        }
+
+        // Parsing exception dates
+        if (isset($this->baseEvent->EXDATE)) {
+            foreach($this->baseEvent->EXDATE as $exDate) {
+
+                foreach(explode(',', (string)$exDate) as $exceptionDate) {
+
+                    $this->exceptionDates[] =
+                        Sabre_VObject_DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
+
+                }
+
+            }
+
+        }
+
+    }
+
+    /**
+     * Returns the current item in the list
+     *
+     * @return DateTime
+     */
+    public function current() {
+
+        if (!$this->valid()) return null;
+        return clone $this->currentDate;
+
+    }
+
+    /**
+     * This method returns the startdate for the current iteration of the
+     * event.
+     *
+     * @return DateTime
+     */
+    public function getDtStart() {
+
+        if (!$this->valid()) return null;
+        return clone $this->currentDate;
+
+    }
+
+    /**
+     * This method returns the enddate for the current iteration of the
+     * event.
+     *
+     * @return DateTime
+     */
+    public function getDtEnd() {
+
+        if (!$this->valid()) return null;
+        $dtEnd = clone $this->currentDate;
+        $dtEnd->add( $this->startDate->diff( $this->endDate ) );
+        return clone $dtEnd;
+
+    }
+
+    /**
+     * Returns a VEVENT object with the updated start and end date.
+     *
+     * Any recurrence information is removed, and this function may return an
+     * 'overridden' event instead.
+     *
+     * This method always returns a cloned instance.
+     *
+     * @return void
+     */
+    public function getEventObject() {
+
+        if ($this->currentOverriddenEvent) {
+            return clone $this->currentOverriddenEvent;
+        }
+        $event = clone $this->baseEvent;
+        unset($event->RRULE);
+        unset($event->EXDATE);
+        unset($event->RDATE);
+        unset($event->EXRULE);
+
+        $event->DTSTART->setDateTime($this->getDTStart(), $event->DTSTART->getDateType());
+        if (isset($event->DTEND)) {
+            $event->DTEND->setDateTime($this->getDtEnd(), $event->DTSTART->getDateType());
+        }
+        if ($this->counter > 0) {
+            $event->{'RECURRENCE-ID'} = (string)$event->DTSTART;
+        }
+
+        return $event;
+
+    }
+
+    /**
+     * Returns the current item number
+     *
+     * @return int
+     */
+    public function key() {
+
+        return $this->counter;
+
+    }
+
+    /**
+     * Whether or not there is a 'next item'
+     *
+     * @return bool
+     */
+    public function valid() {
+
+        if (!is_null($this->count)) {
+            return $this->counter < $this->count;
+        }
+        if (!is_null($this->until)) {
+            return $this->currentDate <= $this->until;
+        }
+        return true;
+
+    }
+
+    /**
+     * Resets the iterator
+     *
+     * @return void
+     */
+    public function rewind() {
+
+        $this->currentDate = clone $this->startDate;
+        $this->counter = 0;
+
+    }
+
+    /**
+     * This method allows you to quickly go to the next occurrence after the
+     * specified date.
+     *
+     * Note that this checks the current 'endDate', not the 'stardDate'. This
+     * means that if you forward to January 1st, the iterator will stop at the
+     * first event that ends *after* January 1st.
+     *
+     * @param DateTime $dt
+     * @return void
+     */
+    public function fastForward(DateTime $dt) {
+
+        while($this->valid() && $this->getDTEnd() < $dt) {
+            $this->next();
+        }
+
+    }
+
+    /**
+     * Goes on to the next iteration
+     *
+     * @return void
+     */
+    public function next() {
+
+        /*
+        if (!is_null($this->count) && $this->counter >= $this->count) {
+            $this->currentDate = null;
+        }*/
+
+
+        $previousStamp = $this->currentDate->getTimeStamp();
+
+        while(true) {
+
+            $this->currentOverriddenEvent = null;
+
+            // If we have a next date 'stored', we use that
+            if ($this->nextDate) {
+                $this->currentDate = $this->nextDate;
+                $currentStamp = $this->currentDate->getTimeStamp();
+                $this->nextDate = null;
+            } else {
+
+                // Otherwise, we calculate it
+                switch($this->frequency) {
+
+                    case 'daily' :
+                        $this->nextDaily();
+                        break;
+
+                    case 'weekly' :
+                        $this->nextWeekly();
+                        break;
+
+                    case 'monthly' :
+                        $this->nextMonthly();
+                        break;
+
+                    case 'yearly' :
+                        $this->nextYearly();
+                        break;
+
+                }
+                $currentStamp = $this->currentDate->getTimeStamp();
+
+                // Checking exception dates
+                foreach($this->exceptionDates as $exceptionDate) {
+                    if ($this->currentDate == $exceptionDate) {
+                        $this->counter++;
+                        continue 2;
+                    }
+                }
+                foreach($this->overriddenDates as $overriddenDate) {
+                    if ($this->currentDate == $overriddenDate) {
+                        continue 2;
+                    }
+                }
+
+            }
+
+            // Checking overriden events
+            foreach($this->overriddenEvents as $index=>$event) {
+                if ($index > $previousStamp && $index <= $currentStamp) {
+
+                    // We're moving the 'next date' aside, for later use.
+                    $this->nextDate = clone $this->currentDate;
+
+                    $this->currentDate = $event->DTSTART->getDateTime();
+                    $this->currentOverriddenEvent = $event;
+
+                    break;
+                }
+            }
+
+            break;
+
+        }
+
+        /*
+        if (!is_null($this->until)) {
+            if($this->currentDate > $this->until) {
+                $this->currentDate = null;
+            }
+        }*/
+
+        $this->counter++;
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for daily frequency.
+     *
+     * @return void
+     */
+    protected function nextDaily() {
+
+        if (!$this->byDay) {
+            $this->currentDate->modify('+' . $this->interval . ' days');
+            return;
+        }
+
+        $recurrenceDays = array();
+        foreach($this->byDay as $byDay) {
+
+            // The day may be preceeded with a positive (+n) or
+            // negative (-n) integer. However, this does not make
+            // sense in 'weekly' so we ignore it here.
+            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+        }
+
+        do {
+
+            $this->currentDate->modify('+' . $this->interval . ' days');
+
+            // Current day of the week
+            $currentDay = $this->currentDate->format('w');
+
+        } while (!in_array($currentDay, $recurrenceDays));
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for weekly frequency.
+     *
+     * @return void
+     */
+    protected function nextWeekly() {
+
+        if (!$this->byDay) {
+            $this->currentDate->modify('+' . $this->interval . ' weeks');
+            return;
+        }
+
+        $recurrenceDays = array();
+        foreach($this->byDay as $byDay) {
+
+            // The day may be preceeded with a positive (+n) or
+            // negative (-n) integer. However, this does not make
+            // sense in 'weekly' so we ignore it here.
+            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+        }
+
+        // Current day of the week
+        $currentDay = $this->currentDate->format('w');
+
+        // First day of the week:
+        $firstDay = $this->dayMap[$this->weekStart];
+
+        $time = array(
+            $this->currentDate->format('H'),
+            $this->currentDate->format('i'),
+            $this->currentDate->format('s')
+        );
+
+        // Increasing the 'current day' until we find our next
+        // occurrence.
+        while(true) {
+
+            $currentDay++;
+
+            if ($currentDay>6) {
+                $currentDay = 0;
+            }
+
+            // We need to roll over to the next week
+            if ($currentDay === $firstDay) {
+                $this->currentDate->modify('+' . $this->interval . ' weeks');
+
+                // We need to go to the first day of this week, but only if we
+                // are not already on this first day of this week.
+                if($this->currentDate->format('w') != $firstDay) {
+                    $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
+                    $this->currentDate->setTime($time[0],$time[1],$time[2]);
+                }
+            }
+
+            // We have a match
+            if (in_array($currentDay ,$recurrenceDays)) {
+                $this->currentDate->modify($this->dayNames[$currentDay]);
+                $this->currentDate->setTime($time[0],$time[1],$time[2]);
+                break;
+            }
+
+        }
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for monthly frequency.
+     *
+     * @return void
+     */
+    protected function nextMonthly() {
+
+        $currentDayOfMonth = $this->currentDate->format('j');
+        if (!$this->byMonthDay && !$this->byDay) {
+
+            // If the current day is higher than the 28th, rollover can
+            // occur to the next month. We Must skip these invalid
+            // entries.
+            if ($currentDayOfMonth < 29) {
+                $this->currentDate->modify('+' . $this->interval . ' months');
+            } else {
+                $increase = 0;
+                do {
+                    $increase++;
+                    $tempDate = clone $this->currentDate;
+                    $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
+                } while ($tempDate->format('j') != $currentDayOfMonth);
+                $this->currentDate = $tempDate;
+            }
+            return;
+        }
+
+        while(true) {
+
+            $occurrences = $this->getMonthlyOccurrences();
+
+            foreach($occurrences as $occurrence) {
+
+                // The first occurrence thats higher than the current
+                // day of the month wins.
+                if ($occurrence > $currentDayOfMonth) {
+                    break 2;
+                }
+
+            }
+
+            // If we made it all the way here, it means there were no
+            // valid occurrences, and we need to advance to the next
+            // month.
+            $this->currentDate->modify('first day of this month');
+            $this->currentDate->modify('+ ' . $this->interval . ' months');
+
+            // This goes to 0 because we need to start counting at hte
+            // beginning.
+            $currentDayOfMonth = 0;
+
+        }
+
+        $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for yearly frequency.
+     *
+     * @return void
+     */
+    protected function nextYearly() {
+
+        if (!$this->byMonth) {
+            $this->currentDate->modify('+' . $this->interval . ' years');
+            return;
+        }
+
+        $currentMonth = $this->currentDate->format('n');
+        $currentYear = $this->currentDate->format('Y');
+        $currentDayOfMonth = $this->currentDate->format('j');
+
+        $advancedToNewMonth = false;
+
+        // If we got a byDay or getMonthDay filter, we must first expand
+        // further.
+        if ($this->byDay || $this->byMonthDay) {
+
+            while(true) {
+
+                $occurrences = $this->getMonthlyOccurrences();
+
+                foreach($occurrences as $occurrence) {
+
+                    // 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.
+                    if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
+                        break 2;
+                    }
+
+                }
+
+                // If we made it here, it means we need to advance to
+                // the next month or year.
+                $currentDayOfMonth = 1;
+                $advancedToNewMonth = true;
+                do {
+
+                    $currentMonth++;
+                    if ($currentMonth>12) {
+                        $currentYear+=$this->interval;
+                        $currentMonth = 1;
+                    }
+                } while (!in_array($currentMonth, $this->byMonth));
+
+                $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+
+            }
+
+            // If we made it here, it means we got a valid occurrence
+            $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
+            return;
+
+        } else {
+
+            // no byDay or byMonthDay, so we can just loop through the
+            // months.
+            do {
+
+                $currentMonth++;
+                if ($currentMonth>12) {
+                    $currentYear+=$this->interval;
+                    $currentMonth = 1;
+                }
+            } while (!in_array($currentMonth, $this->byMonth));
+            $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+            return;
+
+        }
+
+    }
+
+    /**
+     * Returns all the occurrences for a monthly frequency with a 'byDay' or
+     * 'byMonthDay' expansion for the current month.
+     *
+     * The returned list is an array of integers with the day of month (1-31).
+     *
+     * @return array
+     */
+    protected function getMonthlyOccurrences() {
+
+        $startDate = clone $this->currentDate;
+
+        $byDayResults = array();
+
+        // Our strategy is to simply go through the byDays, advance the date to
+        // that point and add it to the results.
+        if ($this->byDay) foreach($this->byDay as $day) {
+
+            $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
+
+            // Dayname will be something like 'wednesday'. Now we need to find
+            // all wednesdays in this month.
+            $dayHits = array();
+
+            $checkDate = clone $startDate;
+            $checkDate->modify('first day of this month');
+            $checkDate->modify($dayName);
+
+            do {
+                $dayHits[] = $checkDate->format('j');
+                $checkDate->modify('next ' . $dayName);
+            } while ($checkDate->format('n') === $startDate->format('n'));
+
+            // So now we have 'all wednesdays' for month. It is however
+            // possible that the user only really wanted the 1st, 2nd or last
+            // wednesday.
+            if (strlen($day)>2) {
+                $offset = (int)substr($day,0,-2);
+
+                if ($offset>0) {
+                    // It is possible that the day does not exist, such as a
+                    // 5th or 6th wednesday of the month.
+                    if (isset($dayHits[$offset-1])) {
+                        $byDayResults[] = $dayHits[$offset-1];
+                    }
+                } else {
+
+                    // if it was negative we count from the end of the array
+                    $byDayResults[] = $dayHits[count($dayHits) + $offset];
+                }
+            } else {
+                // There was no counter (first, second, last wednesdays), so we
+                // just need to add the all to the list).
+                $byDayResults = array_merge($byDayResults, $dayHits);
+
+            }
+
+        }
+
+        $byMonthDayResults = array();
+        if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
+
+            // Removing values that are out of range for this month
+            if ($monthDay > $startDate->format('t') ||
+                $monthDay < 0-$startDate->format('t')) {
+                    continue;
+            }
+            if ($monthDay>0) {
+                $byMonthDayResults[] = $monthDay;
+            } else {
+                // Negative values
+                $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
+            }
+        }
+
+        // If there was just byDay or just byMonthDay, they just specify our
+        // (almost) final list. If both were provided, then byDay limits the
+        // list.
+        if ($this->byMonthDay && $this->byDay) {
+            $result = array_intersect($byMonthDayResults, $byDayResults);
+        } elseif ($this->byMonthDay) {
+            $result = $byMonthDayResults;
+        } else {
+            $result = $byDayResults;
+        }
+        $result = array_unique($result);
+        sort($result, SORT_NUMERIC);
+
+        // The last thing that needs checking is the BYSETPOS. If it's set, it
+        // means only certain items in the set survive the filter.
+        if (!$this->bySetPos) {
+            return $result;
+        }
+
+        $filteredResult = array();
+        foreach($this->bySetPos as $setPos) {
+
+            if ($setPos<0) {
+                $setPos = count($result)-($setPos+1);
+            }
+            if (isset($result[$setPos-1])) {
+                $filteredResult[] = $result[$setPos-1];
+            }
+        }
+
+        sort($filteredResult, SORT_NUMERIC);
+        return $filteredResult;
+
+    }
+
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php
old mode 100644
new mode 100755
index 937c367e222afa447e57a3628519d860939e21e9..00110febc075802e5e595460530ba9f68f08a3a5
--- a/3rdparty/Sabre/VObject/Version.php
+++ b/3rdparty/Sabre/VObject/Version.php
@@ -2,10 +2,10 @@
 
 /**
  * This class contains the version number for the VObject package
- * 
+ *
  * @package Sabre
- * @subpackage VObject 
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @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
  */
@@ -14,7 +14,7 @@ class Sabre_VObject_Version {
     /**
      * Full version number
      */
-    const VERSION = '1.2.4';
+    const VERSION = '1.3.2';
 
     /**
      * Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
new file mode 100755
index 0000000000000000000000000000000000000000..5e1cc5d479bf9e4f28a27bcd1f0911e5ffeaec1d
--- /dev/null
+++ b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
@@ -0,0 +1,128 @@
+<?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 100644
new mode 100755
index f21010fb275a84ea9a672e2c2dd6a26a184e37cb..0177a8f1ba69089c467da2f6dbe67a14c2914fa6
--- a/3rdparty/Sabre/VObject/includes.php
+++ b/3rdparty/Sabre/VObject/includes.php
@@ -1,29 +1,41 @@
 <?php
 
 /**
- * VObject includes 
+ * Sabre_VObject includes file
  *
- * This file automatically includes all VObject classes 
+ * Including this file will automatically include all files from the VObject
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
  *
  * @package Sabre
  * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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 dirname(__FILE__) . '/ParseException.php';
-
-include dirname(__FILE__) . '/Node.php';
-include dirname(__FILE__) . '/Element.php';
-include dirname(__FILE__) . '/ElementList.php';
-include dirname(__FILE__) . '/Parameter.php';
-include dirname(__FILE__) . '/Property.php';
-include dirname(__FILE__) . '/Component.php';
-
-include dirname(__FILE__) . '/Element/DateTime.php';
-include dirname(__FILE__) . '/Element/MultiDateTime.php';
-
-include dirname(__FILE__) . '/Reader.php';
-include dirname(__FILE__) . '/Version.php';
+// Begin includes
+include __DIR__ . '/DateTimeParser.php';
+include __DIR__ . '/ElementList.php';
+include __DIR__ . '/FreeBusyGenerator.php';
+include __DIR__ . '/Node.php';
+include __DIR__ . '/Parameter.php';
+include __DIR__ . '/ParseException.php';
+include __DIR__ . '/Reader.php';
+include __DIR__ . '/RecurrenceIterator.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/WindowsTimezoneMap.php';
+include __DIR__ . '/Element.php';
+include __DIR__ . '/Property.php';
+include __DIR__ . '/Component.php';
+include __DIR__ . '/Property/DateTime.php';
+include __DIR__ . '/Property/MultiDateTime.php';
+include __DIR__ . '/Component/VAlarm.php';
+include __DIR__ . '/Component/VCalendar.php';
+include __DIR__ . '/Component/VEvent.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 100644
new mode 100755
index 0649df655b028c91f6229fe475e04e0df7865faa..c7b537d83d34ef7b0ea97ceb1cda770560bd5a66
--- a/3rdparty/Sabre/autoload.php
+++ b/3rdparty/Sabre/autoload.php
@@ -8,11 +8,15 @@
  *
  * @package Sabre
  * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @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
+ */
 function Sabre_autoload($className) {
 
     if(strpos($className,'Sabre_')===0) {
diff --git a/apps/calendar/ajax/event/edit.form.php b/apps/calendar/ajax/event/edit.form.php
index ec50b78be6fa7209cd18347ba6f038383a9fd1a6..e963da32958b9be327909fa6f1713daa4926fe07 100644
--- a/apps/calendar/ajax/event/edit.form.php
+++ b/apps/calendar/ajax/event/edit.form.php
@@ -27,15 +27,15 @@ $vevent = $object->VEVENT;
 $dtstart = $vevent->DTSTART;
 $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
 switch($dtstart->getDateType()) {
-	case Sabre_VObject_Element_DateTime::LOCALTZ:
-	case Sabre_VObject_Element_DateTime::LOCAL:
+	case Sabre_VObject_Property_DateTime::LOCALTZ:
+	case Sabre_VObject_Property_DateTime::LOCAL:
 		$startdate = $dtstart->getDateTime()->format('d-m-Y');
 		$starttime = $dtstart->getDateTime()->format('H:i');
 		$enddate = $dtend->getDateTime()->format('d-m-Y');
 		$endtime = $dtend->getDateTime()->format('H:i');
 		$allday = false;
 		break;
-	case Sabre_VObject_Element_DateTime::DATE:
+	case Sabre_VObject_Property_DateTime::DATE:
 		$startdate = $dtstart->getDateTime()->format('d-m-Y');
 		$starttime = '';
 		$dtend->getDateTime()->modify('-1 day');
diff --git a/apps/calendar/ajax/event/move.php b/apps/calendar/ajax/event/move.php
index 0552c7bbc5b8c679c8cf9a9cf8c7b68a2299ed71..75d174c13e1df42fc45b318de6740733e4c5f50b 100644
--- a/apps/calendar/ajax/event/move.php
+++ b/apps/calendar/ajax/event/move.php
@@ -27,19 +27,19 @@ $dtstart = $vevent->DTSTART;
 $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
 $start_type = $dtstart->getDateType();
 $end_type = $dtend->getDateType();
-if ($allday && $start_type != Sabre_VObject_Element_DateTime::DATE){
-	$start_type = $end_type = Sabre_VObject_Element_DateTime::DATE;
+if ($allday && $start_type != Sabre_VObject_Property_DateTime::DATE){
+	$start_type = $end_type = Sabre_VObject_Property_DateTime::DATE;
 	$dtend->setDateTime($dtend->getDateTime()->modify('+1 day'), $end_type);
 }
-if (!$allday && $start_type == Sabre_VObject_Element_DateTime::DATE){
-	$start_type = $end_type = Sabre_VObject_Element_DateTime::LOCALTZ;
+if (!$allday && $start_type == Sabre_VObject_Property_DateTime::DATE){
+	$start_type = $end_type = Sabre_VObject_Property_DateTime::LOCALTZ;
 }
 $dtstart->setDateTime($dtstart->getDateTime()->add($delta), $start_type);
 $dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
 unset($vevent->DURATION);
 
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
 
 $result = OC_Calendar_Object::edit($id, $vcalendar->serialize());
 $lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/event/resize.php b/apps/calendar/ajax/event/resize.php
index 593835d86c5b037b90a6f90b50089c48b1f78a5b..260b69144268ccf0c6173588cea1a7cf2488d056 100644
--- a/apps/calendar/ajax/event/resize.php
+++ b/apps/calendar/ajax/event/resize.php
@@ -30,8 +30,8 @@ $end_type = $dtend->getDateType();
 $dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
 unset($vevent->DURATION);
 
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
 
 OC_Calendar_Object::edit($id, $vcalendar->serialize());
 $lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php
index 3aa487fd2310d23f6ab194048376b70a5340f746..8adaa4c98f395a6e8f26a8f05db624818d582a1c 100755
--- a/apps/calendar/ajax/events.php
+++ b/apps/calendar/ajax/events.php
@@ -20,7 +20,6 @@ $events = OC_Calendar_App::getrequestedEvents($_GET['calendar_id'], $start, $end
 $output = array();
 foreach($events as $event){
 	$output[] = OC_Calendar_App::generateEventOutput($event, $start, $end);
-	
 }
 OC_JSON::encodedPrint($output);
 ?>
diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php
index 825977c17c55efdc3f36eb57fe0709eb1546f430..ae6fce3c842c5b25bb05581a51c520a49c45b84d 100644
--- a/apps/calendar/lib/object.php
+++ b/apps/calendar/lib/object.php
@@ -590,7 +590,7 @@ class OC_Calendar_Object{
 		$vevent = new OC_VObject('VEVENT');
 		$vcalendar->add($vevent);
 
-		$vevent->setDateTime('CREATED', 'now', Sabre_VObject_Element_DateTime::UTC);
+		$vevent->setDateTime('CREATED', 'now', Sabre_VObject_Property_DateTime::UTC);
 
 		$vevent->setUID();
 		return self::updateVCalendarFromRequest($request, $vcalendar);
@@ -751,22 +751,22 @@ class OC_Calendar_Object{
 		}
 
 
-		$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-		$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+		$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+		$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
 		$vevent->setString('SUMMARY', $title);
 
 		if($allday){
 			$start = new DateTime($from);
 			$end = new DateTime($to.' +1 day');
-			$vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::DATE);
-			$vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::DATE);
+			$vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::DATE);
+			$vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::DATE);
 		}else{
 			$timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
 			$timezone = new DateTimeZone($timezone);
 			$start = new DateTime($from.' '.$fromtime, $timezone);
 			$end = new DateTime($to.' '.$totime, $timezone);
-			$vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::LOCALTZ);
-			$vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::LOCALTZ);
+			$vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::LOCALTZ);
+			$vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::LOCALTZ);
 		}
 		unset($vevent->DURATION);
 
diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php
index da5fa35bc21caa6830b91a39b45d78458fc0b46e..0e1a9032666c4fcddcb2fb8e53ca46956de53ac6 100644
--- a/apps/calendar/lib/search.php
+++ b/apps/calendar/lib/search.php
@@ -26,7 +26,7 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
 					$start_dt->setTimezone(new DateTimeZone($user_timezone));
 					$end_dt = $dtend->getDateTime();
 					$end_dt->setTimezone(new DateTimeZone($user_timezone));
-					if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
+					if ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE){
 						$end_dt->modify('-1 sec');
 						if($start_dt->format('d.m.Y') != $end_dt->format('d.m.Y')){
 							$info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y') . ' - ' . $end_dt->format('d.m.Y');
diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php
index ab680c8823f7744d1a3b5aa5af983bfd687f044b..f44335a961e237256a239388fad838b3ca370ae3 100644
--- a/apps/contacts/ajax/uploadimport.php
+++ b/apps/contacts/ajax/uploadimport.php
@@ -34,17 +34,52 @@ function debug($msg) {
 	OC_Log::write('contacts','ajax/uploadimport.php: '.$msg, OC_Log::DEBUG);
 }
 
+$view = OC_App::getStorage('contacts');
+$tmpfile = md5(rand());
+
 // If it is a Drag'n'Drop transfer it's handled here.
 $fn = (isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : false);
 if($fn) {
-	$view = OC_App::getStorage('contacts');
-	$tmpfile = md5(rand());
 	if($view->file_put_contents('/'.$tmpfile, file_get_contents('php://input'))) {
 		debug($fn.' uploaded');
 		OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+		exit();
 	} else {
 		bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
 	}
 }
 
+// File input transfers are handled here
+if (!isset($_FILES['importfile'])) {
+	OC_Log::write('contacts','ajax/uploadphoto.php: No file was uploaded. Unknown error.', OC_Log::DEBUG);
+	OC_JSON::error(array('data' => array( 'message' => 'No file was uploaded. Unknown error' )));
+	exit();
+}
+$error = $_FILES['importfile']['error'];
+if($error !== UPLOAD_ERR_OK) {
+	$errors = array(
+		0=>OC_Contacts_App::$l10n->t("There is no error, the file uploaded with success"),
+		1=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
+		2=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
+		3=>OC_Contacts_App::$l10n->t("The uploaded file was only partially uploaded"),
+		4=>OC_Contacts_App::$l10n->t("No file was uploaded"),
+		6=>OC_Contacts_App::$l10n->t("Missing a temporary folder")
+	);
+	bailOut($errors[$error]);
+}
+$file=$_FILES['importfile'];
+
+$tmpfname = tempnam("/tmp", "occOrig");
+if(file_exists($file['tmp_name'])) {
+	if($view->file_put_contents('/'.$tmpfile, file_get_contents($file['tmp_name']))) {
+		debug($fn.' uploaded');
+		OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+	} else {
+		bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
+	}
+} else {
+	bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?');
+}
+
+
 ?>
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 0bb9f975fc5f73824fdbf212826ada1e52c306be..e3d2cfbdd66be9eaa003d7d4a542d1dc73e53d40 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -100,4 +100,4 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
 .propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 20px; height: 20px; vertical-align: middle; }
 .propertylist li > select { float: left; max-width: 8em; }
 .typelist { float: left; max-width: 10em; } /* for multiselect */
-.addresslist { clear: both; }
\ No newline at end of file
+.addresslist { clear: both; }
diff --git a/apps/contacts/import.php b/apps/contacts/import.php
index ca2c1e1605daa1cd7285806f21d93ed8fb7cea06..8e0a427399b008c56730df781bf2a6686e5a9530 100644
--- a/apps/contacts/import.php
+++ b/apps/contacts/import.php
@@ -24,6 +24,11 @@ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
 } else {
 	$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
 }
+if(!$file) {
+	OC_JSON::error(array('message' => 'Import file was empty.'));
+	exit();
+}
+error_log('File: '.$file);
 if(isset($_POST['method']) && $_POST['method'] == 'new'){
 	$id = OC_Contacts_Addressbook::add(OC_User::getUser(), $_POST['addressbookname']);
 	OC_Contacts_Addressbook::setActive($id, 1);
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 18edb40a3cbb303cb48e9175a3e94652b0cfef02..7e0fe8b41cf6dc551b033dad6f3fa81e703df51c 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -1287,6 +1287,7 @@ Contacts={
 		},
 		Addressbooks:{
 			droptarget:undefined,
+			droptext:t('contacts', 'Drop a VCF file to import contacts.'),
 			overview:function(){
 				if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
 					$('#chooseaddressbook_dialog').dialog('moveToTop');
@@ -1345,8 +1346,16 @@ Contacts={
 				}
 			},
 			loadImportHandlers:function() {
+				$('#import_upload_start').change(function(){
+					Contacts.UI.Addressbooks.uploadImport(this.files);
+				});
+				$('#importaddressbook_dialog').find('.upload').click(function() {
+					Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Uploading...'));
+					Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
+					$('#import_upload_start').trigger('click');
+				});
+				$('#importaddressbook_dialog').find('.upload').tipsy();
 				this.droptarget = $('#import_drop_target');
-				console.log($('#import_drop_target').html());
 				$(this.droptarget).bind('dragover',function(event){
 					$(event.target).addClass('droppable');
 					event.stopPropagation();
@@ -1371,13 +1380,13 @@ Contacts={
 					console.log('size: '+file.size+', type: '+file.type);
 					if(file.size > $('#max_upload').val()){
 						OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts','Upload too large'));
-						$(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+						$(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
 						Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
 						return;
 					}
 					if(file.type.indexOf('text') != 0) {
 						OC.dialogs.alert(t('contacts','You have dropped a file type that cannot be imported: ') + file.type, t('contacts','Wrong file type'));
-						$(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+						$(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
 						Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
 						return;
 					}
@@ -1392,11 +1401,9 @@ Contacts={
 							response = $.parseJSON(xhr.responseText);
 							if(response.status == 'success') {
 								if(xhr.status == 200) {
-									$(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
-									Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
 									Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
 								} else {
-									$(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+									$(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
 									Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
 									OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
 								}
@@ -1405,7 +1412,7 @@ Contacts={
 							}
 						}
 					};
-					xhr.open("POST", 'ajax/uploadimport.php?file='+encodeURIComponent(file.name), true);
+					xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name), true);
 					xhr.setRequestHeader('Cache-Control', 'no-cache');
 					xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
 					xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1414,12 +1421,39 @@ Contacts={
 					xhr.send(file);
 				}
 			},
+			uploadImport:function(filelist) {
+				if(!filelist) {
+					OC.dialogs.alert(t('contacts','No files selected for upload.'), t('contacts', 'Error'));
+					return;
+				}
+				//var file = filelist.item(0);
+				var file = filelist[0];
+				var target = $('#import_upload_target');
+				var form = $('#import_upload_form');
+				var totalSize=0;
+				if(file.size > $('#max_upload').val()){
+					OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts', 'Error'));
+					return;
+				} else {
+					target.load(function(){
+						var response=jQuery.parseJSON(target.contents().text());
+						if(response != undefined && response.status == 'success'){
+							Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
+						}else{
+							OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
+						}
+					});
+					form.submit();
+				}
+			},
 			importAddressbook:function(object){
 				var tr = $(document.createElement('tr'))
 					.load(OC.filePath('contacts', 'ajax', 'importaddressbook.php'));
 				$(object).closest('tr').after(tr).hide();
 			},
 			doImport:function(path, file){
+				$(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
+				Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
 				var id = $('#importaddressbook_dialog').find('#book').val();
 				console.log('Selected book: ' + id);
 				$.post(OC.filePath('contacts', '', 'import.php'), { id: id, path: path, file: file, fstype: 'OC_FilesystemView' },
@@ -1428,6 +1462,10 @@ Contacts={
 							Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Import done. Success/Failure: ')+jsondata.data.imported+'/'+jsondata.data.failed);
 							$('#chooseaddressbook_dialog').find('#close_button').val(t('contacts', 'OK'));
 							Contacts.UI.Contacts.update();
+							setTimeout(
+									function() {
+										$(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
+									}, 5000);
 						} else {
 							OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
 						}
@@ -1590,7 +1628,7 @@ $(document).ready(function(){
 	 * Profile picture upload handling
 	 */
 	// New profile picture selected
-	$('#file_upload_start').live('change',function(){
+	$('#file_upload_start').change(function(){
 		Contacts.UI.Card.uploadPhoto(this.files);
 	});
 	$('#contacts_details_photo_wrapper').bind('dragover',function(event){
@@ -1662,7 +1700,7 @@ $(document).ready(function(){
 		};
 		// Start loading indicator.
 		//$('#contacts_details_photo_progress').show()();
-		xhr.open("POST", OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
+		xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
 		xhr.setRequestHeader('Cache-Control', 'no-cache');
 		xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
 		xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1691,4 +1729,4 @@ $(document).ready(function(){
 		Contacts.UI.Card.addProperty(type);
 		$('#contacts_propertymenu').hide();
 	});
-});
\ No newline at end of file
+});
diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php
index dec081a9b8930b5d6966fdc920c4562873a6e230..64a024c0926d56cdfdf1dcc348761c84f3d7ae8d 100644
--- a/apps/contacts/templates/part.contact.php
+++ b/apps/contacts/templates/part.contact.php
@@ -24,7 +24,6 @@ $id = isset($_['id']) ? $_['id'] : '';
 	<div id="contact_photo" class="contactsection">
 
 	<form class="float" id="file_upload_form" action="ajax/uploadphoto.php" method="post" enctype="multipart/form-data" target="file_upload_target">
-	<fieldset id="photo">
 		<div class="tip propertycontainer" id="contacts_details_photo_wrapper" title="<?php echo $l->t('Click or drop to upload picture'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)" data-element="PHOTO">
 		<!-- img style="padding: 1em;" id="contacts_details_photo" alt="Profile picture"  src="photo.php?id=<?php echo $_['id']; ?>" / -->
 		<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress>
@@ -34,7 +33,6 @@ $id = isset($_['id']) ? $_['id'] : '';
 		<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
 		<input id="file_upload_start" type="file" accept="image/*" name="imagefile" />
 		<iframe name="file_upload_target" id='file_upload_target' src=""></iframe>
-	</fieldset>
 	</form>
 	</div> <!-- contact_photo -->
 
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index 488f68e6b3c0f1abf699e03171a315477adfcc3d..a227dcc3ffc93a5bef7a30896eeb83effc25e7ed 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -3,6 +3,7 @@
 set_time_limit(0);//scanning can take ages
 
 $force=isset($_GET['force']) and $_GET['force']=='true';
+$dir=isset($_GET['dir'])?$_GET['dir']:'';
 $checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true';
 
 if(!$checkOnly){
@@ -14,7 +15,7 @@ if(!$checkOnly){
 if($force or !OC_FileCache::inCache('')){
 	if(!$checkOnly){
 		OC_DB::beginTransaction();
-		OC_FileCache::scan('',$eventSource);
+		OC_FileCache::scan($dir,$eventSource);
 		OC_FileCache::clean();
 		OC_DB::commit();
 		$eventSource->send('success',true);
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 99623b6355ef9c9219f0066ac79323fa62bd9f79..a135f7ded5b689a9e8b842f7d6eaf01e99286527 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -30,6 +30,8 @@
 .file_upload_filename { position: relative; z-index:100; padding-left: 0.8em; padding-right: 0.8em; cursor:pointer; border-top-left-radius:0; border-bottom-left-radius:0; }
 .file_upload_filename img { position: absolute; top: 0.4em; left: 0.4em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
 
+#upload { position:absolute; right:13.5em; top:0em; }
+#upload #uploadprogressbar { position:relative; display:inline-block; width:10em; height:1.5em; top:.4em; }
 
 .file_upload_form, .file_upload_wrapper, .file_upload_start, .file_upload_filename, #file_upload_submit { cursor:pointer; }
 
@@ -41,7 +43,7 @@ tbody tr { background-color:#fff; height:2.5em; }
 tbody tr:hover, tbody tr:active, tbody tr.selected { background-color:#f8f8f8; }
 tbody tr.selected { background-color:#eee; }
 tbody a { color:#000; }
-span.extension, td.date { color:#999; }
+span.extension, span.uploading, td.date { color:#999; }
 span.extension { text-transform:lowercase; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; }
 tr:hover span.extension { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; color:#777; }
 div.crumb { float:left; display:block; background:no-repeat right 0; padding:.75em 1.5em 0 1em; height:2.9em; }
@@ -60,8 +62,10 @@ table td.filename a.name { display:block; height:1.5em; vertical-align:middle; m
 table tr[data-type="dir"] td.filename a.name span.nametext {font-weight:bold; }
 table td.filename a.name input, table td.filename a.name form { width:100%; cursor:text; }
 table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:.2em .5em .5em 0; }
-table td.filename .nametext, .modified { float:left; padding:.3em 0; }
+table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0; }
+// TODO fix usability bug (accidental file/folder selection)
 table td.filename .nametext { width:70%; overflow:hidden; }
+table td.filename .uploadtext { font-weight:normal; margin-left:.5em; }
 table td.filename form { float:left; font-size:.85em; }
 table thead.fixed tr{ position:fixed; top:6.5em; z-index:49; -moz-box-shadow:0 -3px 7px #ddd; -webkit-box-shadow:0 -3px 7px #ddd; box-shadow:0 -3px 7px #ddd; }
 table thead.fixed { height:2em; }
diff --git a/apps/files/index.php b/apps/files/index.php
index 46b511d66eb95a9909e72f9342f69b4e3d511465..8464db30f0156caa1ff672a234a63358ede5a3ae 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -26,6 +26,8 @@ OC_Util::checkLoggedIn();
 
 // Load the files we need
 OC_Util::addStyle( "files", "files" );
+OC_Util::addScript( "files", "jquery.iframe-transport" );
+OC_Util::addScript( "files", "jquery.fileupload" );
 OC_Util::addScript( "files", "files" );
 OC_Util::addScript( 'files', 'filelist' );
 OC_Util::addScript( 'files', 'fileactions' );
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 481802e0d63a258c8e97ddfc4df5ff3d08d1c4d0..68268a7d3a9ce0e8dd2a8870a6d4e915d7aaf365 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -140,7 +140,20 @@ $(document).ready(function(){
 });
 
 FileActions.register('all','Delete',function(){return OC.imagePath('core','actions/delete')},function(filename){
-	FileList.do_delete(filename);
+	if(Files.cancelUpload(filename)) {
+		if(filename.substr){
+			filename=[filename];
+		}
+		$.each(filename,function(index,file){
+			var filename = $('tr').filterAttr('data-file',file);
+			filename.hide();
+			filename.find('input[type="checkbox"]').removeAttr('checked');
+			filename.removeClass('selected');
+		});
+		procesSelection();
+	}else{
+		FileList.do_delete(filename);
+	}
 });
 
 FileActions.register('all','Rename',function(){return OC.imagePath('core','actions/rename')},function(filename){
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 5bd85fc29ef5f49d10105f7715e3d978ada0e960..febdfc473b1be76eb004aa1ab2e2c8197737d3d4 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -43,6 +43,7 @@ FileList={
 		td.append('<input type="checkbox" />');
 		var link_elem = $('<a></a>').attr({ "class": "name", "href": "index.php?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/') });
 		link_elem.append($('<span></span>').addClass('nametext').text(name));
+		link_elem.append($('<span></span>').attr({'class': 'uploadtext', 'currentUploads': 0}));
 		td.append(link_elem);
 		html.append(td);
 		if(size!='Pending'){
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 9d83e5e6d268d2ad81770744d3bd5e64ea045400..2dce00035e162fe0195c035ea21f2dc6ab41547f 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -1,3 +1,32 @@
+var uploadingFiles = {};
+Files={
+	cancelUpload:function(filename) {
+		if(uploadingFiles[filename]) {
+			uploadingFiles[filename].abort();
+			delete uploadingFiles[filename];
+			return true;
+		}
+		return false;
+	},
+	cancelUploads:function() {
+		$.each(uploadingFiles,function(index,file) {
+			if(typeof file['abort'] === 'function') {
+				file.abort();
+				var filename = $('tr').filterAttr('data-file',index);
+				filename.hide();
+				filename.find('input[type="checkbox"]').removeAttr('checked');
+				filename.removeClass('selected');
+			} else {
+				$.each(file,function(i,f) {
+					f.abort();
+					delete file[i];
+				});
+			}
+			delete uploadingFiles[index];
+		});
+		procesSelection();
+	}
+}
 $(document).ready(function() {
 	$('#fileList tr').each(function(){
 		//little hack to set unescape filenames in attribute
@@ -151,83 +180,205 @@ $(document).ready(function() {
 		return false;
 	});
 
-	$('.file_upload_start').live('change',function(){
-		var form=$(this).closest('form');
-		var that=this;
-		var uploadId=form.attr('data-upload-id');
-		var files=this.files;
-		var target=form.children('iframe');
-		var totalSize=0;
-		if(files){
-			for(var i=0;i<files.length;i++){
-				totalSize+=files[i].size;
-				if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
-					FileList.finishDelete(function(){
-						$(that).change();
-					});
-					return;
-				}
-			}
-		}
-		if(totalSize>$('#max_upload').val()){
-			$( "#uploadsize-message" ).dialog({
-				modal: true,
-				buttons: {
-					Close: function() {
-						$( this ).dialog( "close" );
+	// drag&drop support using jquery.fileupload
+	// TODO use OC.dialogs
+	$(document).bind('drop dragover', function (e) {
+			e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
+	});
+
+	$(function() {
+		$('.file_upload_start').fileupload({
+			dropZone: $('#content'), // restrict dropZone to content div
+			add: function(e, data) {
+				var files = data.files;
+				var totalSize=0;
+				if(files){
+					for(var i=0;i<files.length;i++){
+						totalSize+=files[i].size;
+						if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
+							FileList.finishDelete(function(){
+								$('.file_upload_start').change();
+							});
+							return;
+						}
 					}
 				}
-			});
-		}else{
-			target.load(function(){
-				var response=jQuery.parseJSON(target.contents().find('body').text());
-				//set mimetype and if needed filesize
-				if(response){
-					if(response[0] != undefined && response[0].status == 'success'){
-						for(var i=0;i<response.length;i++){
-							var file=response[i];
+				if(totalSize>$('#max_upload').val()){
+					$( '#uploadsize-message' ).dialog({
+						modal: true,
+						buttons: {
+							Close: function() {
+								$( this ).dialog( 'close' );
+							}
+						}
+					});
+				}else{
+				if($.support.xhrFileUpload) {
+					for(var i=0;i<files.length;i++){
+						var fileName = files[i].name
+						var dropTarget = $(e.originalEvent.target).closest('tr');
+						if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
+							var dirName = dropTarget.attr('data-file')
+							var jqXHR =  $('.file_upload_start').fileupload('send', {files: files[i],
+									formData: function(form) {
+										var formArray = form.serializeArray();
+										formArray[1]['value'] = dirName;
+										return formArray;
+									}}).success(function(result, textStatus, jqXHR) {
+										var response;
+										response=jQuery.parseJSON(result);
+										if(response[0] == undefined || response[0].status != 'success') {
+											$('#notification').text(t('files', response.data.message));
+											$('#notification').fadeIn();
+										}
+										var file=response[0];
+										delete uploadingFiles[dirName][file.name];
+										var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+										currentUploads -= 1;
+										uploadtext.attr('currentUploads', currentUploads);
+										if(currentUploads === 0) {
+											var img = OC.imagePath('core', 'filetypes/folder.png');
+											var tr=$('tr').filterAttr('data-file',dirName);
+											tr.find('td.filename').attr('style','background-image:url('+img+')');
+											uploadtext.text('');
+											uploadtext.hide();
+										} else {
+											uploadtext.text(currentUploads + ' files uploading')
+										}
+									})
+							.error(function(jqXHR, textStatus, errorThrown) {
+								if(errorThrown === 'abort') {
+									var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+									currentUploads -= 1;
+									uploadtext.attr('currentUploads', currentUploads);
+									if(currentUploads === 0) {
+										var img = OC.imagePath('core', 'filetypes/folder.png');
+										var tr=$('tr').filterAttr('data-file',dirName);
+										tr.find('td.filename').attr('style','background-image:url('+img+')');
+										uploadtext.text('');
+										uploadtext.hide();
+									} else {
+										uploadtext.text(currentUploads + ' files uploading')
+									}
+									$('#notification').hide();
+									$('#notification').text(t('files', 'Upload cancelled.'));
+									$('#notification').fadeIn();
+								}
+							});
+							//TODO test with filenames containing slashes
+							if(uploadingFiles[dirName] === undefined) {
+								uploadingFiles[dirName] = {};
+							}
+							uploadingFiles[dirName][fileName] = jqXHR;
+						} else {
+							var jqXHR =  $('.file_upload_start').fileupload('send', {files: files[i]})
+									.success(function(result, textStatus, jqXHR) {
+										var response;
+										response=jQuery.parseJSON(result);
+										if(response[0] != undefined && response[0].status == 'success') {
+											var file=response[0];
+											delete uploadingFiles[file.name];
+											$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
+											var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+											if(size==t('files','Pending')){
+												$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
+											}
+											FileList.loadingDone(file.name);
+										} else {
+											$('#notification').text(t('files', response.data.message));
+											$('#notification').fadeIn();
+											$('#fileList > tr').not('[data-mime]').fadeOut();
+											$('#fileList > tr').not('[data-mime]').remove();
+										}
+									})
+							.error(function(jqXHR, textStatus, errorThrown) {
+								if(errorThrown === 'abort') {
+									$('#notification').hide();
+									$('#notification').text(t('files', 'Upload cancelled.'));
+									$('#notification').fadeIn();
+								}
+							});
+							uploadingFiles[files[i].name] = jqXHR;
+						}
+					}
+				}else{
+					data.submit().success(function(data, status) {
+						response = jQuery.parseJSON(data[0].body.innerText);
+						if(response[0] != undefined && response[0].status == 'success') {
+							var file=response[0];
+							delete uploadingFiles[file.name];
 							$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
-							if(size=='Pending'){
+							var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+							if(size==t('files','Pending')){
 								$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
 							}
 							FileList.loadingDone(file.name);
+						} else {
+							$('#notification').text(t('files', response.data.message));
+							$('#notification').fadeIn();
+							$('#fileList > tr').not('[data-mime]').fadeOut();
+							$('#fileList > tr').not('[data-mime]').remove();
 						}
-					}
-					else{
-						$('#notification').text(t('files',response.data.message));
-						$('#notification').fadeIn();
-						$('#fileList > tr').not('[data-mime]').fadeOut();
-						$('#fileList > tr').not('[data-mime]').remove();
-					}
+					});
 				}
-			});
-			form.submit();
-			var date=new Date();
-			if(files){
-				for(var i=0;i<files.length;i++){
-					if(files[i].size>0){
-						var size=files[i].size;
-					}else{
-						var size=t('files','Pending');
-					}
+									
+					var date=new Date();
 					if(files){
+						for(var i=0;i<files.length;i++){
+							if(files[i].size>0){
+								var size=files[i].size;
+							}else{
+								var size=t('files','Pending');
+							}
+							if(files && !dirName){
 						FileList.addFile(getUniqueName(files[i].name),size,date,true);
+							} else if(dirName) {
+								var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
+								var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+								currentUploads += 1;
+								uploadtext.attr('currentUploads', currentUploads);
+								if(currentUploads === 1) {
+									var img = OC.imagePath('core', 'loading.gif');
+									var tr=$('tr').filterAttr('data-file',dirName);
+									tr.find('td.filename').attr('style','background-image:url('+img+')');
+									uploadtext.text('1 file uploading');
+									uploadtext.show();
+								} else {
+									uploadtext.text(currentUploads + ' files uploading')
+								}
+							}
+						}
+					}else{
+						var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
+				FileList.addFile(getUniqueName(filename),'Pending',date,true);
 					}
 				}
-			}else{
-				var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
-				FileList.addFile(getUniqueName(filename),'Pending',date,true);
+			},
+			fail: function(e, data) {
+				// TODO: cancel upload & display error notification
+			},
+			progress: function(e, data) {
+				// TODO: show nice progress bar in file row
+			},
+			progressall: function(e, data) {
+				var progress = (data.loaded/data.total)*100;
+				$('#uploadprogressbar').progressbar('value',progress);
+			},
+			start: function(e, data) {
+				$('#uploadprogressbar').progressbar({value:0});
+				$('#uploadprogressbar').fadeIn();
+				if(data.dataType != 'iframe ') {
+					$('#upload input.stop').show();
+				}
+			},
+			stop: function(e, data) {
+				if(data.dataType != 'iframe ') {
+					$('#upload input.stop').hide();
+				}	
+				$('#uploadprogressbar').progressbar('value',100);
+				$('#uploadprogressbar').fadeOut();
 			}
-
-			//clone the upload form and hide the new one to allow users to start a new upload while the old one is still uploading
-			var clone=form.clone();
-			uploadId++;
-			clone.attr('data-upload-id',uploadId);
-			clone.attr('target','file_upload_target_'+uploadId);
-			clone.children('iframe').attr('name','file_upload_target_'+uploadId)
-			clone.insertBefore(form);
-			form.hide();
-		}
+		})
 	});
 
 	//add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
@@ -370,12 +521,15 @@ $(document).ready(function() {
 	}, "json");
 });
 
-function scanFiles(force){
+function scanFiles(force,dir){
+	if(!dir){
+		dir='';
+	}
 	force=!!force; //cast to bool
 	scanFiles.scanning=true;
 	$('#scanning-message').show();
 	$('#fileList').remove();
-	var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force});
+	var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
 	scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
 	scannerEventSource.listen('scanning',function(data){
 		$('#scan-count').text(data.count+' files scanned');
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index 3571950467e01be19a187d8960705b573ea7a67b..fc385e1ed3ad78083ce970123ce030986186ed47 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -22,6 +22,11 @@
 					<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:?>
diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php
index 5a5941fc7ae8f13ec6843c10407a331e64e71913..b2db4cbb8df00127ae7d5e6236500705a6af7e40 100644
--- a/apps/files/templates/part.list.php
+++ b/apps/files/templates/part.list.php
@@ -21,6 +21,10 @@
 							<?php echo htmlspecialchars($file['basename']);?><span class='extension'><?php echo $file['extension'];?></span>
 						<?php endif;?>
 					</span>
+					<?php if($file['type'] == 'dir'):?>
+						<span class="uploadtext" currentUploads="0">
+						</span>
+					<?php endif;?>
 					</a>
 				</td>
 				<td class="filesize" title="<?php echo human_file_size($file['size']); ?>" style="color:rgb(<?php echo $simple_size_color.','.$simple_size_color.','.$simple_size_color ?>)"><?php echo $simple_file_size; ?></td>
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
index 21fa38e4b5989699cac69deabac9feaf41d9c89c..07a2e523a4292f080ef895cc2ca3e169595f074f 100644
--- a/apps/files_encryption/lib/cryptstream.php
+++ b/apps/files_encryption/lib/cryptstream.php
@@ -33,6 +33,7 @@ class OC_CryptStream{
 	private $path;
 	private $readBuffer;//for streams that dont support seeking
 	private $meta=array();//header/meta for source stream
+	private $count;
 
 	public function stream_open($path, $mode, $options, &$opened_path){
 		$path=str_replace('crypt://','',$path);
@@ -92,16 +93,6 @@ class OC_CryptStream{
 			$data=substr($block,0,$currentPos%8192).$data;
 		}
 		while(strlen($data)>0){
-			if(strlen($data)<8192){
-				//fetch the current data in that block and append it to the input so we always write entire blocks
-				$oldPos=ftell($this->source);
-				$encryptedBlock=fread($this->source,8192);
-				fseek($this->source,$oldPos);
-				if($encryptedBlock){
-					$block=OC_Crypt::decrypt($encryptedBlock);
-					$data.=substr($block,strlen($data));
-				}
-			}
 			$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
 			fwrite($this->source,$encrypted);
 			$data=substr($data,8192);
@@ -139,7 +130,9 @@ class OC_CryptStream{
 	}
 
 	public function stream_close(){
-		OC_FileCache::put($this->path,array('encrypted'=>true));
+		if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
+			OC_FileCache::put($this->path,array('encrypted'=>true));
+		}
 		return fclose($this->source);
 	}
 }
\ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index e3a106d0d04ac67aef8bbe7619a5e82440fe21ca..d65bcba8bfa1dc80056921b14d46a9ed43a073dd 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -27,7 +27,6 @@
 
 class OC_FileProxy_Encryption extends OC_FileProxy{
 	private static $blackList=null; //mimetypes blacklisted from encryption
-	private static $metaData=array(); //metadata cache
 	private static $enableEncryption=null;
 	
 	/**
@@ -60,13 +59,8 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
 	 * @return bool
 	 */
 	private static function isEncrypted($path){
-		if(isset(self::$metaData[$path])){
-			$metadata=self::$metaData[$path];
-		}else{
-			$metadata=OC_FileCache::getCached($path);
-			self::$metaData[$path]=$metadata;
-		}
-		return (bool)$metadata['encrypted'];
+		$metadata=OC_FileCache::getCached($path);
+		return isset($metadata['encrypted']) and (bool)$metadata['encrypted'];
 	}
 	
 	public function preFile_put_contents($path,&$data){
@@ -98,12 +92,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
 				//first encrypt the target file so we don't end up with a half encrypted file
 				OC_Log::write('files_encryption','Decrypting '.$path.' before writing',OC_Log::DEBUG);
 				$tmp=fopen('php://temp');
-				while(!feof($result)){
-					$chunk=fread($result,8192);
-					if($chunk){
-						fwrite($tmp,$chunk);
-					}
-				}
+				OC_Helper::streamCopy($result,$tmp);
 				fclose($result);
 				OC_Filesystem::file_put_contents($path,$tmp);
 				fclose($tmp);
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index e53eb1ff3b6fd1d92a9befaed1612f8b9222a1fd..a987d17d799c49bfa741e698c4a3deedcf9ba8ec 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -28,6 +28,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 	private $rootContainer;
 
 	private static $tempFiles=array();
+	private $objects=array();
+	private $containers=array();
 
 	const SUBCONTAINER_FILE='.subcontainers';
 
@@ -38,7 +40,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 	 */
 	private function getContainerName($path){
 		$path=trim($this->root.$path,'/');
-		return md5($path);
+		return str_replace('/','\\',$path);
 	}
 
 	/**
@@ -50,8 +52,12 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 		if($path=='' or $path=='/'){
 			return $this->rootContainer;
 		}
+		if(isset($this->containers[$path])){
+			return $this->containers[$path];
+		}
 		try{
 			$container=$this->conn->get_container($this->getContainerName($path));
+			$this->containers[$path]=$container;
 			return $container;
 		}catch(NoSuchContainerException $e){
 			return null;
@@ -87,12 +93,16 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 	 * @return CF_Object
 	 */
 	private function getObject($path){
+		if(isset($this->objects[$path])){
+			return $this->objects[$path];
+		}
 		$container=$this->getContainer(dirname($path));
 		if(is_null($container)){
 			return null;
 		}else{
 			try{
 				$obj=$container->get_object(basename($path));
+				$this->objects[$path]=$obj;
 				return $obj;
 			}catch(NoSuchObjectException $e){
 				return null;
@@ -295,6 +305,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 			}
 			
 			$this->conn->delete_container($this->getContainerName($path));
+			unset($this->containers[$path]);
 			return true;
 		}
 	}
@@ -309,12 +320,14 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 			if($sub){
 				$this->emptyContainer($path.'/'.$sub);
 				$this->conn->delete_container($this->getContainerName($path.'/'.$sub));
+				unset($this->containers[$path.'/'.$sub]);
 			}
 		}
 
 		$objects=$this->getObjects($container);
 		foreach($objects as $object){
 			$container->delete_object($object);
+			unset($this->objects[$path.'/'.$object]);
 		}
 	}
 
@@ -381,6 +394,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 		if($this->objectExists($path)){
 			$container=$this->getContainer(dirname($path));
 			$container->delete_object(basename($path));
+			unset($this->objects[$path]);
 		}else{
 			return false;
 		}
@@ -447,6 +461,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
 		$sourceContainer=$this->getContainer(dirname($path1));
 		$targetContainer=$this->getContainer(dirname($path2));
 		$result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2));
+		unset($this->objects[$path1]);
 		if($result){
 			$targetObj=$this->getObject($path2);
 			$this->resetMTime($targetObj);
diff --git a/apps/files_sharing/ajax/email.php b/apps/files_sharing/ajax/email.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6d53c49bff853f7c1d580a209f578653af3f41f
--- /dev/null
+++ b/apps/files_sharing/ajax/email.php
@@ -0,0 +1,15 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('files_sharing');
+$user = OC_User::getUser();
+// TODO translations
+$subject = $user + ' ' + 'shared a file with you';
+$link = $_POST['link'] + '&f=' + $_POST['f'];
+$text = $user + ' ' + 'shared the file' + ' ' + $_POST['f'] + ' ' + 'with you.' + ' ' + 'It is available for download here:' + ' ' + $link;
+$fromaddress = OC_Preferences::getValue($user, 'settings', 'email', 'owncloud.org');
+OC_Mail::send($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user);
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/ajax/toggleresharing.php b/apps/files_sharing/ajax/toggleresharing.php
new file mode 100644
index 0000000000000000000000000000000000000000..72af1eedec119bc8cd86c89fda352033aa65918f
--- /dev/null
+++ b/apps/files_sharing/ajax/toggleresharing.php
@@ -0,0 +1,13 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkAppEnabled('files_sharing');
+OC_JSON::checkAdminUser();
+if ($_POST['resharing'] == true) {
+	OC_Appconfig::setValue('files_sharing', 'resharing', 'yes');
+} else {
+	OC_Appconfig::setValue('files_sharing', 'resharing', 'no');
+}
+
+?>
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 8049e9b0ae3cbcde3564f008c351ff8087642953..645f4f5e4f23de8fb3bf3f5f9928c7c8ba2eb0e7 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -3,10 +3,17 @@
 require_once('apps/files_sharing/sharedstorage.php');
 
 OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
+OC_APP::registerAdmin('files_sharing', 'settings');
 OC_Hook::connect("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
 OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
 OC_Hook::connect("OC_Filesystem", "post_write", "OC_Share", "updateItem");
-OC_Util::addScript("files_sharing", "share");
+OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_Share', 'removeUser');
+OC_Hook::connect('OC_User', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
+OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '/';
+if ($dir != '/Shared' || OC_Appconfig::getValue('files_sharing', 'resharing', 'yes') == 'yes') {
+	OC_Util::addScript("files_sharing", "share");
+}
 OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min");
 OC_Util::addStyle( 'files_sharing', 'sharing' );
 OC_Util::addStyle("3rdparty", "chosen/chosen");
diff --git a/apps/files_sharing/js/settings.js b/apps/files_sharing/js/settings.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb7d79fecbb24a2de090c0424c6a183b15018f97
--- /dev/null
+++ b/apps/files_sharing/js/settings.js
@@ -0,0 +1,9 @@
+$(document).ready(function() {
+	$('#allowResharing').bind('change', function() {
+		var checked = 1;
+		if (!this.checked) {
+			checked = 0;
+		}
+		$.post(OC.filePath('files_sharing','ajax','toggleresharing.php'), 'resharing='+checked);
+	});
+});
\ No newline at end of file
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 54d749d833e5e7c94d5e6ee3b3dada6e866b04bc..4125fd14d2584ea5cd9ef532ddb4c7f91dbd51a9 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -163,6 +163,9 @@ $(document).ready(function() {
 				data: data,
 				success: function(){
 					$('#link').hide('blind');
+					$('#emailBreak').remove();
+					$('#email').hide('blind');
+					$('#emailButton').hide('blind');
 				}
 			});
 		}
@@ -172,6 +175,14 @@ $(document).ready(function() {
 		$(this).focus();
 		$(this).select();
 	});
+
+	$('#emailButton').live('click', function() {
+		$('#email').css('font-weight', 'bold');
+		$('#email').animate({ fontWeight: 'normal' }, 2000, function() {
+			$(this).val('');
+		}).val('Email sent');
+		$.post(OC.filePath('files_sharing','ajax','email.php'), 'toaddress='+$('#email').val()+'&link='+$('#link').val());
+	});
 });
 
 function createDropdown(filename, files) {
@@ -183,10 +194,12 @@ function createDropdown(filename, files) {
 	html += '<ul id="shared_list"></ul>';
 	html += '</div>';
 	html += '<div id="public">';
-	html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">make public</label>';
+	html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">Share with private link</label>';
 	//html += '<input type="checkbox" name="public_link_write" id="public_link_write" value="1" /><label for="public_link_write">allow upload</label>';
 	html += '<br />';
 	html += '<input id="link" style="display:none; width:90%;" />';
+	html += '<input id="email" style="display:none; width:65%;" value="" placeholder="Email link to person" />';
+	html += '<input id="emailButton" style="display:none;" type="submit" value="Send" />';
 	html += '</div>';
 	if (filename) {
 		$('tr').filterAttr('data-file',filename).addClass('mouseOver');
@@ -241,5 +254,9 @@ function showPublicLink(token, file) {
 	$('#makelink').attr('checked', true);
 	$('#link').data('token', token);
 	$('#link').val(parent.location.protocol+'//'+location.host+OC.linkTo('files_sharing','get.php')+'?token='+token+'&f='+file);
-	$('#link').show('blind');
+	$('#link').show('blind', function() {
+		$('#link').after('<br id="emailBreak" />');
+		$('#email').show('blind');
+		$('#emailButton').show('blind');
+	});
 }
diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php
index 673984f393b6fe28f20f7983c6f6ec9f21c899fb..62ac05a59529c1da8a27345ab7455cf9fc398dad 100644
--- a/apps/files_sharing/lib_share.php
+++ b/apps/files_sharing/lib_share.php
@@ -436,6 +436,34 @@ class OC_Share {
 		}
 	}
 
+	public static function removeUser($arguments) {
+		$query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_owner = ? OR uid_shared_with '.self::getUsersAndGroups($arguments['uid']));
+		$query->execute(array($arguments['uid']));
+	}
+
+	public static function addToGroupShare($arguments) {
+		$length = -strlen($arguments['gid']) - 1;
+		$query = OC_DB::prepare('SELECT uid_owner, source, permissions FROM *PREFIX*sharing WHERE SUBSTR(uid_shared_with, '.$length.') = ?');
+		$gid = '@'.$arguments['gid'];
+		$result = $query->execute(array($gid))->fetchAll();
+		if (count($result) > 0) {
+			$query = OC_DB::prepare('INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)');
+			$sharedFolder = '/'.$arguments['uid'].'/files/Shared/';
+			$lastSource = '';
+			for ($i = 0; $i < count($result) - 1; $i++) {
+				if ($result[$i]['source'] != $lastSource) {
+					$query->execute(array($result[$i]['uid_owner'], $arguments['uid'].'@'.$arguments['gid'], $result[$i]['source'], $sharedFolder.basename($result[$i]['source']), $result[$i]['permissions']));
+					$lastSource = $result[$i]['source'];
+				}
+			}
+		}
+	}
+
+	public static function removeFromGroupShare($arguments) {
+		$query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?');
+		$query->execute(array($arguments['uid'].'@'.$arguments['gid']));
+	}
+
 }
 
 ?>
diff --git a/apps/files_sharing/settings.php b/apps/files_sharing/settings.php
new file mode 100644
index 0000000000000000000000000000000000000000..b30c4f45cde49d05da2dc568a6fe15b1445c2f71
--- /dev/null
+++ b/apps/files_sharing/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+OC_Util::checkAdminUser();
+OC_Util::addScript('files_sharing', 'settings');
+$tmpl = new OC_Template('files_sharing', 'settings');
+$tmpl->assign('allowResharing', OC_Appconfig::getValue('files_sharing', 'resharing', 'yes'));
+return $tmpl->fetchPage();
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/templates/settings.php b/apps/files_sharing/templates/settings.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b6ba5f33ee1d0766e7da1adfdaf0ff640602a42
--- /dev/null
+++ b/apps/files_sharing/templates/settings.php
@@ -0,0 +1,6 @@
+<form id="resharing">
+	<fieldset class="personalblock">
+	<input type="checkbox" name="allowResharing" id="allowResharing" value="1" <?php if ($_['allowResharing'] == 'yes') echo ' checked="checked"'; ?> /> <label for="allowResharing"><?php echo $l->t('Enable Resharing'); ?></label> <br/>
+	<em><?php echo $l->t('Allow users to reshare files they don\'t own');?></em>
+	</fieldset>
+</form>
\ No newline at end of file
diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php
index 6e7a803252e4610a110fc710b7380273b6fc0d1e..32e4c0ce81be2e42d70fe30575740f52485f18fa 100644
--- a/apps/files_versions/appinfo/app.php
+++ b/apps/files_versions/appinfo/app.php
@@ -9,6 +9,7 @@ OC_App::register( array(
   'name' => 'Versioning' ));
 
 OC_APP::registerAdmin('files_versions', 'settings');
+OC_UTIL::addScript('files_versions', 'versions');
 
 // Listen to write signals
 OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OCA_Versions\Storage", "write_hook");
diff --git a/apps/files_versions/css/versions.css b/apps/files_versions/css/versions.css
index 139597f9cb07c5d48bed18984ec4747f4b4f3438..b2279e9b05ac9662e48249ed6345722209fcaaf5 100644
--- a/apps/files_versions/css/versions.css
+++ b/apps/files_versions/css/versions.css
@@ -1,2 +1,3 @@
-
-
+#history {
+    margin: 2em 2em 0;
+}
\ No newline at end of file
diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php
index 6c7626ca4edc9ae0363fd00185eeeec64ebce357..b0aa8fdc9820733a6baeb4f3479ef892b4b42ebd 100644
--- a/apps/files_versions/history.php
+++ b/apps/files_versions/history.php
@@ -20,40 +20,41 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  * 
  */
-require_once('../../lib/base.php');
+require_once( '../../lib/base.php' );
 
-OC_Util::checkLoggedIn();
+OC_Util::checkLoggedIn( );
+OC_Util::addStyle('files_versions','versions');
 
-if (isset($_GET['path'])) {
+if ( isset( $_GET['path'] ) ) {
 
 	$path = $_GET['path'];
-	$path = strip_tags($path);
+	$path = strip_tags( $path);
 
 	// roll back to old version if button clicked
-        if(isset($_GET['revert'])) {
-        	\OCA_Versions\Storage::rollback($path,$_GET['revert']);
+        if( isset( $_GET['revert'] ) ) {
+        	\OCA_Versions\Storage::rollback( $path, $_GET['revert'] );
 	}
 
 	// show the history only if there is something to show
-        if(OCA_Versions\Storage::isversioned($path)) {
+        if( OCA_Versions\Storage::isversioned( $path ) ) {
 
 		$count=5; //show the newest revisions
-	        $versions=OCA_Versions\Storage::getversions($path,$count);
+	        $versions=OCA_Versions\Storage::getversions( $path, $count);
 
-		$tmpl = new OC_Template('files_versions', 'history', 'user');
-		$tmpl->assign('path', $path);
-		$tmpl->assign('versions', array_reverse($versions));
-		$tmpl->printPage();
+		$tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+		$tmpl->assign( 'path', $path);
+		$tmpl->assign( 'versions', array_reverse( $versions) );
+		$tmpl->printPage( );
 	}else{
-		$tmpl = new OC_Template('files_versions', 'history', 'user');
-		$tmpl->assign('path', $path);
-		$tmpl->assign('message', 'No old versions available');
-		$tmpl->printPage();
+		$tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+		$tmpl->assign( 'path', $path);
+		$tmpl->assign( 'message', 'No old versions available' );
+		$tmpl->printPage( );
 	}
 }else{
-	$tmpl = new OC_Template('files_versions', 'history', 'user');
-	$tmpl->assign('message', 'No path specified');
-	$tmpl->printPage();
+	$tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+	$tmpl->assign( 'message', 'No path specified' );
+	$tmpl->printPage( );
 }
 
 
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index 139597f9cb07c5d48bed18984ec4747f4b4f3438..325ef823a9c152e1ba979dacc4ef0e8e324d9354 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -1,2 +1,67 @@
+$(document).ready(function(){
+	
+	// Add history button to files/index.php
+	FileActions.register('file','History',function(){return OC.imagePath('core','actions/history')},function(filename){
+		
+		if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback
+		
+		var file = $('#dir').val()+'/'+filename;
+		
+		createVersionsDropdown(filename, file)
 
+		//window.location='../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
 
+		
+	});
+	
+});
+
+function createVersionsDropdown(filename, files) {
+	var historyUrl = '../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
+	//alert( historyUrl );
+	var html = '<div id="dropdown" class="drop" data-file="'+files+'">';
+	html += '<div id="private">';
+	html += '<select data-placeholder="File Version" id="share_with" class="chzen-select">';
+	html += '<option value=""></option>';
+	html += '</select>';
+	html += '<ul id="shared_list"></ul>';
+	html += '</div>';
+	html += '<div id="public">';
+	html += '<input type="button" name="makelink" id="makelink" value="Revert file" />';
+	html += '<input type="button" onclick="window.location=\''+historyUrl+'\'" name="makelink" id="makelink" value="More..." />';
+	html += '<br />';
+	html += '<input id="link" style="display:none; width:90%;" />';
+	html += '</div>';
+	
+	if (filename) {
+		$('tr').filterAttr('data-file',filename).addClass('mouseOver');
+		$(html).appendTo($('tr').filterAttr('data-file',filename).find('td.filename'));
+	} else {
+		$(html).appendTo($('thead .share'));
+	}
+// 			$.getJSON(OC.linkTo('files_sharing', 'ajax/userautocomplete.php'), function(users) {
+// 				if (users) {
+// 					$.each(users, function(index, row) {
+// 						$(row).appendTo('#share_with');
+// 					});
+// 					$('#share_with').trigger('liszt:updated');
+// 				}
+// 			});
+// 			$.getJSON(OC.linkTo('files_sharing', 'ajax/getitem.php'), { source: files }, function(users) {
+// 				if (users) {
+// 					$.each(users, function(index, row) {
+// 						if (row.uid_shared_with == 'public') {
+// 							showPublicLink(row.token, '/'+filename);
+// 						} else if (isNaN(index)) {
+// 							addUser(row.uid_shared_with, row.permissions, index.substr(0, index.lastIndexOf('-')));
+// 						} else {
+// 							addUser(row.uid_shared_with, row.permissions, false);
+// 						}
+// 					});
+// 				}
+// 			});
+
+	$('#dropdown').show('blind');
+	$('#share_with').chosen();
+	
+}
\ No newline at end of file
diff --git a/apps/files_versions/templates/history.php b/apps/files_versions/templates/history.php
index 1b3de9ce77c0d7cf75525ff223f6d0983e809b26..d33d2b0f68b7814ccd1f3184aaafbe54ae2f33de 100644
--- a/apps/files_versions/templates/history.php
+++ b/apps/files_versions/templates/history.php
@@ -1,3 +1,4 @@
+<div id="history">
 <?php
 	if(isset($_['message'])){
 
@@ -10,9 +11,10 @@
 	        echo('<strong>Versions of '.$_['path']).'</strong><br>';
 	        echo('<p><em>You can click on the revert button to revert to the specific verson.</em></p><br />');
 	        foreach ($_['versions'] as $v){
-			echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">revert</a><br /><br />');
+			echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">Revert</a><br /><br />');
 		}
 
 	}
 
 ?>
+</div>
diff --git a/apps/files_versions/versions.php b/apps/files_versions/versions.php
index 156a4f59c73bed478d9e540900bf53111c8ecdff..167c64a4345562b811ed9653ae1115fab11b6ff7 100644
--- a/apps/files_versions/versions.php
+++ b/apps/files_versions/versions.php
@@ -36,7 +36,7 @@ class Storage {
 	const DEFAULTFOLDER='versions'; 
 	const DEFAULTBLACKLIST='avi mp3 mpg mp4'; 
 	const DEFAULTMAXFILESIZE=1048576; // 10MB 
-	const DEFAULTMININTERVAL=300; // 5 min
+	const DEFAULTMININTERVAL=1; // 5 min
 	const DEFAULTMAXVERSIONS=50; 
 
 	/**
diff --git a/apps/user_ldap/appinfo/database.xml b/apps/user_ldap/appinfo/database.xml
new file mode 100644
index 0000000000000000000000000000000000000000..74c56fcf7435952fd189ffaefa4e5fab0a881f73
--- /dev/null
+++ b/apps/user_ldap/appinfo/database.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+ <charset>utf8</charset>
+
+ <table>
+
+  <name>*dbprefix*ldap_user_mapping</name>
+
+  <declaration>
+
+   <field>
+    <name>ldap_dn</name>
+    <type>text</type>
+    <notnull>true</notnull>
+	<length>255</length>
+	<default></default>
+   </field>
+
+   <field>
+    <name>owncloud_name</name>
+    <type>text</type>
+    <notnull>true</notnull>
+    <length>255</length>
+	<default></default>
+   </field>
+
+   <index>
+    <name>ldap_dn</name>
+    <unique>true</unique>
+    <field>
+     <name>ldap_dn</name>
+    </field>
+   </index>
+
+   <index>
+    <name>owncloud_name</name>
+    <unique>true</unique>
+    <field>
+     <name>owncloud_name</name>
+	 <sorting>ascending</sorting>
+    </field>
+   </index>
+
+  </declaration>
+
+ </table>
+
+ <table>
+
+  <name>*dbprefix*ldap_group_mapping</name>
+
+  <declaration>
+
+   <field>
+    <name>ldap_dn</name>
+    <type>text</type>
+    <notnull>true</notnull>
+    <length>255</length>
+    <default></default>
+   </field>
+
+   <field>
+    <name>owncloud_name</name>
+    <type>text</type>
+    <notnull>true</notnull>
+    <length>255</length>
+    <default></default>
+   </field>
+
+   <index>
+    <name>ldap_dn</name>
+    <unique>true</unique>
+    <field>
+     <name>ldap_dn</name>
+    </field>
+   </index>
+
+   <index>
+    <name>owncloud_name</name>
+    <unique>true</unique>
+    <field>
+     <name>owncloud_name</name>
+     <sorting>ascending</sorting>
+    </field>
+   </index>
+
+  </declaration>
+
+ </table>
+
+</database>
\ No newline at end of file
diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version
index ceab6e11ece0bcec917c12e11d350946f085d549..a0d78bd347e089e143f3ded0ecfb6dd6ba382545 100644
--- a/apps/user_ldap/appinfo/version
+++ b/apps/user_ldap/appinfo/version
@@ -1 +1 @@
-0.1
\ No newline at end of file
+0.1.90
\ No newline at end of file
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index fe0789cdeb7743fd58d50c8ebd5f96e11c1af2be..7773968e208678f896032c256231d1d10ef18392 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -24,13 +24,9 @@
 class OC_GROUP_LDAP extends OC_Group_Backend {
 // 	//group specific settings
 	protected $ldapGroupFilter;
-	protected $ldapGroupDisplayName;
-	protected $ldapGroupMemberAttr;
 
 	public function __construct() {
 		$this->ldapGroupFilter      = OC_Appconfig::getValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)');
-		$this->ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', 'cn');
-		$this->ldapGroupMemberAttr  = OC_Appconfig::getValue('user_ldap', 'ldap_group_member_attr', 'memberUid');
 	}
 
 	/**
@@ -42,18 +38,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * Checks whether the user is member of a group or not.
 	 */
 	public function inGroup($uid, $gid) {
-		$filter = OC_LDAP::combineFilterWithAnd(array(
-			$this->ldapGroupFilter,
-			LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid,
-			$this->ldapGroupDisplayName.'='.$gid
-		));
-		$groups = $this->retrieveList($filter, $this->ldapGroupDisplayName);
-
-		if(count($groups) > 0) {
-			return true;
-		} else {
+		$dn_user = OC_LDAP::username2dn($uid);
+		$dn_group = OC_LDAP::groupname2dn($gid);
+// 	if($dn_group == 'c')	{echo('#sdfsdgfds');die($gid);}
+		// just in case
+		if(!$dn_group || !$dn_user) {
 			return false;
 		}
+// 		var_dump($dn_group);
+		$members = OC_LDAP::readAttribute($dn_group, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+
+		return in_array($dn_user, $members);
 	}
 
 	/**
@@ -65,12 +60,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * if the user exists at all.
 	 */
 	public function getUserGroups($uid) {
+		$userDN = OC_LDAP::username2dn($uid);
+		if(!$userDN) {
+			return array();
+		}
+
 		$filter = OC_LDAP::combineFilterWithAnd(array(
 			$this->ldapGroupFilter,
-			LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid
+			LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$userDN
 		));
+		$groups = $this->retrieveList($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
+		$userGroups = OC_LDAP::ownCloudGroupNames($groups);
 
-		return $this->retrieveList($filter, $this->ldapGroupDisplayName);
+		return array_unique($userGroups, SORT_LOCALE_STRING);
 	}
 
 	/**
@@ -78,12 +80,16 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * @returns array with user ids
 	 */
 	public function usersInGroup($gid) {
-		$filter = OC_LDAP::combineFilterWithAnd(array(
-			$this->ldapGroupFilter,
-			$this->ldapGroupDisplayName.'='.$gid
-		));
-
-		return $this->retrieveList($filter, $this->ldapGroupMemberAttr, false);
+		$groupDN = OC_LDAP::groupname2dn($gid);
+		if(!$groupDN) {
+			return array();
+		}
+		$members = OC_LDAP::readAttribute($groupDN, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+		$result = array();
+		foreach($members as $member) {
+		    $result[] = OC_LDAP::dn2username($member);
+		}
+		return array_unique($result, SORT_LOCALE_STRING);
 	}
 
 	/**
@@ -93,7 +99,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * Returns a list with all groups
 	 */
 	public function getGroups() {
-		return $this->retrieveList($this->ldapGroupFilter, $this->ldapGroupDisplayName);
+		$ldap_groups = $this->retrieveList($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
+		$groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+		return $groups;
 	}
 
 	/**
@@ -112,13 +120,18 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 			$list = OC_LDAP::searchUsers($filter, $attr);
 		}
 
-
 		if(is_array($list)) {
-			return array_unique($list, SORT_LOCALE_STRING);
+			if(count($attr) > 1){
+				return $list;
+			} else {
+				return array_unique($list, SORT_LOCALE_STRING);
+			}
 		}
 
 		//error cause actually, maybe throw an exception in future.
 		return array();
 	}
 
+
+
 }
\ No newline at end of file
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
new file mode 100644
index 0000000000000000000000000000000000000000..cae9655e3df5354529c5514ae105808bb8bf505e
--- /dev/null
+++ b/apps/user_ldap/js/settings.js
@@ -0,0 +1,3 @@
+$(document).ready(function() {
+	$('#ldapSettings').tabs();
+});
\ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
index 752ac4f22896ead44605f084fafd866ce40bf435..4efcf0c5a0d332707480fc2128bb38bf3a255584 100644
--- a/apps/user_ldap/lib_ldap.php
+++ b/apps/user_ldap/lib_ldap.php
@@ -21,7 +21,8 @@
  *
  */
 
-define('LDAP_GROUP_MEMBER_ASSOC_ATTR','memberUid');
+define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember');
+define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn');
 
 //needed to unbind, because we use OC_LDAP only statically
 class OC_LDAP_DESTRUCTOR {
@@ -45,7 +46,9 @@ class OC_LDAP {
 	static protected $ldapTLS;
 	static protected $ldapNoCase;
 	// user and group settings, that are needed in both backends
-	static public $ldapUserDisplayName;
+	static protected $ldapUserDisplayName;
+	static protected $ldapUserFilter;
+	static protected $ldapGroupDisplayName;
 
 	static public function init() {
 		self::readConfiguration();
@@ -56,14 +59,345 @@ class OC_LDAP {
 		@ldap_unbind(self::$ldapConnectionRes);
 	}
 
+	/**
+	 * @brief returns a read-only configuration value
+	 * @param $key the name of the configuration value
+	 * @returns the value on success, otherwise null
+	 *
+	 * returns a read-only configuration values
+	 *
+	 * we cannot work with getters, because it is a static class
+	 */
 	static public function conf($key) {
+		if(!self::$configured) {
+			self::init();
+		}
+
 		$availableProperties = array(
 			'ldapUserDisplayName',
+			'ldapGroupDisplayName',
 		);
 
 		if(in_array($key, $availableProperties)) {
 			return self::$$key;
 		}
+
+		return null;
+	}
+
+	/**
+	 * gives back the database table for the query
+	 */
+	static private function getMapTable($isUser) {
+		if($isUser) {
+			return '*PREFIX*ldap_user_mapping';
+		} else {
+			return '*PREFIX*ldap_group_mapping';
+		}
+	}
+
+	/**
+	 * @brief returns the LDAP DN for the given internal ownCloud name of the group
+	 * @param $name the ownCloud name in question
+	 * @returns string with the LDAP DN on success, otherwise false
+	 *
+	 * returns the LDAP DN for the given internal ownCloud name of the group
+	 */
+	static public function groupname2dn($name) {
+		return self::ocname2dn($name, false);
+	}
+
+	/**
+	 * @brief returns the LDAP DN for the given internal ownCloud name of the user
+	 * @param $name the ownCloud name in question
+	 * @returns string with the LDAP DN on success, otherwise false
+	 *
+	 * returns the LDAP DN for the given internal ownCloud name of the user
+	 */
+	static public function username2dn($name) {
+		$dn = self::ocname2dn($name, true);
+		if($dn) {
+			return $dn;
+		} else {
+			//fallback: user is not mapped
+			$filter = self::combineFilterWithAnd(array(
+				self::$ldapUserFilter,
+				self::$ldapUserDisplayName . '=' . $name,
+			));
+			$result = self::searchUsers($filter, 'dn');
+			if(isset($result[0]['dn'])) {
+				self::mapUser($result[0], $name);
+				return $result[0];
+			}
+		}
+
+		return false;
+	}
+
+	static private function ocname2dn($name, $isUser) {
+		$table = self::getMapTable($isUser);
+
+		$query = OC_DB::prepare('
+			SELECT ldap_dn
+			FROM '.$table.'
+			WHERE owncloud_name = ?
+		');
+
+		$record = $query->execute(array($name))->fetchOne();
+		return $record;
+		if($name=='Coyotes') {
+			echo("adsfasdf ");
+			var_dump($record);
+			die();
+		}
+		if(isset($record['ldap_dn'])) {
+			return $record['ldap_dn'];
+		}
+
+		return false;
+	}
+
+	/**
+	 * @brief returns the internal ownCloud name for the given LDAP DN of the group
+	 * @param $dn the dn of the group object
+	 * @param $ldapname optional, the display name of the object
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * returns the internal ownCloud name for the given LDAP DN of the group
+	 */
+	static public function dn2groupname($dn, $ldapname = null) {
+		return self::dn2ocname($dn, $ldapname, false);
+	}
+
+	/**
+	 * @brief returns the internal ownCloud name for the given LDAP DN of the user
+	 * @param $dn the dn of the user object
+	 * @param $ldapname optional, the display name of the object
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * returns the internal ownCloud name for the given LDAP DN of the user
+	 */
+	static public function dn2username($dn, $ldapname = null) {
+		return self::dn2ocname($dn, $ldapname, true);
+	}
+
+	static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+		$table = self::getMapTable($isUser);
+		if($isUser) {
+			$nameAttribute = self::conf('ldapUserDisplayName');
+		} else {
+			$nameAttribute = self::conf('ldapGroupDisplayName');
+		}
+
+		$query = OC_DB::prepare('
+			SELECT owncloud_name
+			FROM '.$table.'
+			WHERE ldap_dn = ?
+		');
+
+		$component = $query->execute(array($dn))->fetchOne();
+		if($component) {
+			return $component;
+		}
+
+		if(is_null($ldapname)) {
+			$ldapname = self::readAttribute($dn, $nameAttribute);
+			$ldapname = $ldapname[0];
+		}
+
+		//a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
+		if(self::mapComponent($dn, $ldapname, $isUser)) {
+			return $ldapname;
+		}
+
+		//doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
+		$oc_name = self::alternateOwnCloudName($ldapname, $dn);
+		if(self::mapComponent($dn, $oc_name, $isUser)) {
+			return $oc_name;
+		}
+
+		//and this of course should never been thrown :)
+		throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+	}
+
+	/**
+	 * @brief gives back the user names as they are used ownClod internally
+	 * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
+	 * @returns an array with the user names to use in ownCloud
+	 *
+	 * gives back the user names as they are used ownClod internally
+	 */
+	static public function ownCloudUserNames($ldapUsers) {
+		return self::ldap2ownCloudNames($ldapUsers, true);
+	}
+
+	/**
+	 * @brief gives back the group names as they are used ownClod internally
+	 * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
+	 * @returns an array with the group names to use in ownCloud
+	 *
+	 * gives back the group names as they are used ownClod internally
+	 */
+	static public function ownCloudGroupNames($ldapGroups) {
+		return self::ldap2ownCloudNames($ldapGroups, false);
+	}
+
+	static private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+		if($isUsers) {
+			$knownObjects = self::mappedUsers();
+			$nameAttribute = self::conf('ldapUserDisplayName');
+		} else {
+			$knownObjects = self::mappedGroups();
+			$nameAttribute = self::conf('ldapGroupDisplayName');
+		}
+		$ownCloudNames = array();
+
+		foreach($ldapObjects as $ldapObject) {
+			$key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+			//everything is fine when we know the group
+			if($key) {
+				$ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
+				continue;
+			}
+
+			//a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict
+			if(self::mapComponent($ldapObject['dn'], $ldapObject[$nameAttribute], $isUsers)) {
+				$ownCloudNames[] = $ldapObject[$nameAttribute];
+				continue;
+			}
+
+			//doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
+			$oc_name = self::alternateOwnCloudName($ldapObject[$nameAttribute], $ldapObject['dn']);
+			if(self::mapComponent($ldapObject['dn'], $oc_name, $isUsers)) {
+				$ownCloudNames[] = $oc_name;
+				continue;
+			}
+
+			//and this of course should never been thrown :)
+			throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+		}
+		return $ownCloudNames;
+	}
+
+	/**
+	 * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+	 * @param $name the display name of the object
+	 * @param $dn the dn of the object
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+	 */
+	static private function alternateOwnCloudName($name, $dn) {
+		$ufn = ldap_dn2ufn($dn);
+		return $name . ' (' . trim(substr_replace($ufn, '', 0, strpos($ufn, ','))) . ')';
+	}
+
+	/**
+	 * @brief retrieves all known groups from the mappings table
+	 * @returns array with the results
+	 *
+	 * retrieves all known groups from the mappings table
+	 */
+	static private function mappedGroups() {
+		return self::mappedComponents(false);
+	}
+
+	/**
+	 * @brief retrieves all known users from the mappings table
+	 * @returns array with the results
+	 *
+	 * retrieves all known users from the mappings table
+	 */
+	static private function mappedUsers() {
+		return self::mappedComponents(true);
+	}
+
+	static private function mappedComponents($isUsers) {
+		$table = self::getMapTable($isUsers);
+
+		$query = OC_DB::prepare('
+			SELECT ldap_dn, owncloud_name
+			FROM '. $table
+		);
+
+		return $query->execute()->fetchAll();
+	}
+
+	/**
+	 * @brief inserts a new group into the mappings table
+	 * @param $dn the record in question
+	 * @param $ocname the name to use in ownCloud
+	 * @returns true on success, false otherwise
+	 *
+	 * inserts a new group into the mappings table
+	 */
+	static private function mapGroup($dn, $ocname) {
+		return self::mapComponent($dn, $ocname, false);
+	}
+
+	/**
+	 * @brief inserts a new user into the mappings table
+	 * @param $dn the record in question
+	 * @param $ocname the name to use in ownCloud
+	 * @returns true on success, false otherwise
+	 *
+	 * inserts a new user into the mappings table
+	 */
+	static private function mapUser($dn, $ocname) {
+		return self::mapComponent($dn, $ocname, true);
+	}
+
+	/**
+	 * @brief inserts a new user or group into the mappings table
+	 * @param $dn the record in question
+	 * @param $ocname the name to use in ownCloud
+	 * @param $isUser is it a user or a group?
+	 * @returns true on success, false otherwise
+	 *
+	 * inserts a new user or group into the mappings table
+	 */
+	static private function mapComponent($dn, $ocname, $isUser = true) {
+		$table = self::getMapTable($isUser);
+
+		$insert = OC_DB::prepare('
+			INSERT IGNORE INTO '.$table.'
+			(ldap_dn, owncloud_name)
+			VALUES (?,?)
+		');
+
+		$res = $insert->execute(array($dn, $ocname));
+
+		return !OC_DB::isError($res);
+	}
+
+	/**
+	 * @brief reads a given attribute for an LDAP record identified by a DN
+	 * @param $dn the record in question
+	 * @param $attr the attribute that shall be retrieved
+	 * @returns the values in an array on success, false otherwise
+	 *
+	 * Reads an attribute from an LDAP entry
+	 */
+	static public function readAttribute($dn, $attr) {
+		$cr = self::getConnectionResource();
+// echo("<pre>");var_dump($dn);
+		$rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
+		if(!$rr) {
+			echo('<pre>###RA ');var_dump($dn);var_dump(debug_backtrace());die();
+		}
+		$er = ldap_first_entry($cr, $rr);
+		$result = ldap_get_attributes($cr, $er);
+
+// 		if($dn == 'cn=Coyotes,cn=groups,dc=blizzz-oc,dc=bzoc') die((var_dump($result)));
+		if($result[$attr]['count'] > 0){
+			$values = array();
+			for($i=0;$i<$result[$attr]['count'];$i++) {
+				$values[] = $result[$attr][$i];
+			}
+			return $values;
+		}
+		return false;
 	}
 
 	/**
@@ -100,15 +434,38 @@ class OC_LDAP {
 	 * Executes an LDAP search
 	 */
 	static private function search($filter, $base, $attr = null) {
-		$sr = ldap_search(self::getConnectionResource(), $base, $filter, array($attr));
+		if(!is_null($attr) && !is_array($attr)) {
+			$attr = array(strtolower($attr));
+		}
+		$sr = ldap_search(self::getConnectionResource(), $base, $filter, $attr);
 		$findings = ldap_get_entries(self::getConnectionResource(), $sr );
 
 		if(!is_null($attr)) {
 			$selection = array();
+			$multiarray = false;
+			if(count($attr) > 1) {
+				$multiarray = true;
+				$i = 0;
+			}
 			foreach($findings as $item) {
-				if(isset($item[strtolower($attr)])) {
-					$selection[] = $item[strtolower($attr)][0];
+				if($multiarray) {
+					foreach($attr as $key) {
+						if(isset($item[$key])) {
+							if($key != 'dn'){
+								$selection[$i][$key] = $item[$key][0];
+							} else {
+								$selection[$i][$key] = $item[$key];
+							}
+						}
+
+					}
+					$i++;
+				} else {
+					if(isset($item[$attr[0]])) {
+						$selection[] = $item[$attr[0]];
+					}
 				}
+
 			}
 			return $selection;
 		}
@@ -173,16 +530,18 @@ class OC_LDAP {
 	 */
 	static private function readConfiguration() {
 		if(!self::$configured) {
-			self::$ldapHost            = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
-			self::$ldapPort            = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
-			self::$ldapAgentName       = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
-			self::$ldapAgentPassword   = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
-			self::$ldapBase            = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
-			self::$ldapBaseUsers       = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
-			self::$ldapBaseGroups      = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
-			self::$ldapTLS             = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
-			self::$ldapNoCase          = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
-			self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+			self::$ldapHost             = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
+			self::$ldapPort             = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
+			self::$ldapAgentName        = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
+			self::$ldapAgentPassword    = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
+			self::$ldapBase             = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
+			self::$ldapBaseUsers        = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
+			self::$ldapBaseGroups       = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
+			self::$ldapTLS              = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
+			self::$ldapNoCase           = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
+			self::$ldapUserDisplayName  = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+			self::$ldapUserFilter       = OC_Appconfig::getValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
+			self::$ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR);
 
 			if(
 				   !empty(self::$ldapHost)
@@ -226,5 +585,23 @@ class OC_LDAP {
 		}
 	}
 
+	/**
+	* taken from http://www.php.net/manual/en/function.array-search.php#97645
+	* TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
+	*/
+	static public function recursiveArraySearch($haystack, $needle, $index = null) {
+		$aIt = new RecursiveArrayIterator($haystack);
+		$it = new RecursiveIteratorIterator($aIt);
+
+		while($it->valid()) {
+			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
+				return $aIt->key();
+			}
+
+			$it->next();
+		}
+
+		return false;
+	}
 
  }
\ No newline at end of file
diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php
index ad44fe95f9ecf3ef151387a3b58348c3be22a49b..2226c74609d5b6b09112b6f5b37f0bb7ff07e1d0 100644
--- a/apps/user_ldap/settings.php
+++ b/apps/user_ldap/settings.php
@@ -20,7 +20,10 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+
+OC_Util::addScript('user_ldap', 'settings');
+OC_Util::addStyle('user_ldap', 'settings');
 
 if ($_POST) {
 	foreach($params as $param){
@@ -45,10 +48,8 @@ foreach($params as $param){
 		$tmpl->assign($param, $value);
 }
 
-// ldap_port has a default value
+// settings with default values
 $tmpl->assign( 'ldap_port', OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT));
-
-// ldap_display_name has a default value
 $tmpl->assign( 'ldap_display_name', OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME));
 
 return $tmpl->fetchPage();
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 828c72cba97e4187427a0c5099aa7de21f68d12f..7e327bb0701925069b034f8ef7392b8d8237daf5 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -1,21 +1,30 @@
 <form id="ldap" action="#" method="post">
-	<fieldset class="personalblock">
-		<legend><strong>LDAP</strong></legend>
-		<p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label>
-		<label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+	<div id="ldapSettings" class="personalblock">
+	<ul>
+		<li><a href="#ldapSettings-1">LDAP Basic</a></li>
+		<li><a href="#ldapSettings-2">Advanced</a></li>
+	</ul>
+	<fieldset id="ldapSettings-1">
+		<p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label> <label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
 		<p><label for="ldap_dn"><?php echo $l->t('Name');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" />
 		<label for="ldap_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_password" name="ldap_password" value="<?php echo $_['ldap_password']; ?>" />
 		<small><?php echo $l->t('Leave both empty for anonymous bind for search, then bind with users credentials.');?></small></p>
-		<p><label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
 		<p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" /><small><?php echo $l->t('use %%uid placeholder, e.g. uid=%%uid');?></small></p>
-		<p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?>	</p>
-		<p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
-		<small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
+		<p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?></small></p>
+	</fieldset>
+	<fieldset id="ldapSettings-2">
+		<p><label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+		<p><label for="ldap_base_users"><?php echo $l->t('Base User Tree');?></label><input type="text" id="ldap_base_users" name="ldap_base_users" value="<?php echo $_['ldap_base_users']; ?>" /></p>
+		<p><label for="ldap_base_groups"><?php echo $l->t('Base Group Tree');?></label><input type="text" id="ldap_base_groups" name="ldap_base_groups" value="<?php echo $_['ldap_base_groups']; ?>" /></p>
 		<p><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?>><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label></p>
 		<p><input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if ($_['ldap_nocase']) echo ' checked'; ?>><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label></p>
+		<p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
+		<small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
 		<p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" />
-                <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
-                <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
-		<input type="submit" value="Save" />
+		<label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
+		<p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
 	</fieldset>
+	<input type="submit" value="Save" />
+	</div>
+
 </form>
diff --git a/core/img/actions/history.png b/core/img/actions/history.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1e743651f827e9fa0b34dfdc0c7537f612b36d1
Binary files /dev/null and b/core/img/actions/history.png differ
diff --git a/core/img/actions/history.svg b/core/img/actions/history.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9c2838d565b6a93f399581c3ff3272a5b6747649
--- /dev/null
+++ b/core/img/actions/history.svg
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="17"
+   height="17"
+   id="svg3972"
+   version="1.1"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="backup.svg"
+   inkscape:export-filename="/home/ronny/persoenliches/Programme/JBackpack/jbackpack/src/ch/fhnw/jbackpack/icons/16x16/icon.png"
+   inkscape:export-xdpi="2.8099999"
+   inkscape:export-ydpi="2.8099999">
+  <defs
+     id="defs3974">
+    <linearGradient
+       id="linearGradient3820">
+      <stop
+         style="stop-color:#7399ab;stop-opacity:1;"
+         offset="0"
+         id="stop3822" />
+      <stop
+         style="stop-color:#fffeff;stop-opacity:1;"
+         offset="1"
+         id="stop3824" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5144">
+      <stop
+         style="stop-color:#ab7392;stop-opacity:1;"
+         offset="0"
+         id="stop5146" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.02909091"
+         offset="1"
+         id="stop5148" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5130">
+      <stop
+         id="stop5140"
+         offset="0"
+         style="stop-color:#a08f82;stop-opacity:0.74901961;" />
+      <stop
+         id="stop5138"
+         offset="0.5"
+         style="stop-color:#ab7392;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ab7392;stop-opacity:0;"
+         offset="1"
+         id="stop5134" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4519"
+       osb:paint="gradient">
+      <stop
+         style="stop-color:#5d879d;stop-opacity:1;"
+         offset="0"
+         id="stop4521" />
+      <stop
+         style="stop-color:#5d879d;stop-opacity:0;"
+         offset="1"
+         id="stop4523" />
+    </linearGradient>
+    <filter
+       id="filter4697"
+       inkscape:label="Drop shadow"
+       width="1.5"
+       height="1.5"
+       x="-0.25"
+       y="-0.25"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur4699"
+         in="SourceAlpha"
+         stdDeviation="2"
+         result="blur" />
+      <feColorMatrix
+         id="feColorMatrix4701"
+         result="bluralpha"
+         type="matrix"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
+      <feOffset
+         id="feOffset4703"
+         in="bluralpha"
+         dx="4"
+         dy="4"
+         result="offsetBlur" />
+      <feMerge
+         id="feMerge4705">
+        <feMergeNode
+           id="feMergeNode4707"
+           in="offsetBlur" />
+        <feMergeNode
+           id="feMergeNode4709"
+           in="SourceGraphic" />
+      </feMerge>
+    </filter>
+    <filter
+       id="filter5086"
+       inkscape:label="Drop shadow"
+       width="1.5"
+       height="1.5"
+       x="-0.25"
+       y="-0.25"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur5088"
+         in="SourceAlpha"
+         stdDeviation="5"
+         result="blur" />
+      <feColorMatrix
+         id="feColorMatrix5090"
+         result="bluralpha"
+         type="matrix"
+         values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
+      <feOffset
+         id="feOffset5092"
+         in="bluralpha"
+         dx="10"
+         dy="10"
+         result="offsetBlur" />
+      <feMerge
+         id="feMerge5094">
+        <feMergeNode
+           id="feMergeNode5096"
+           in="offsetBlur" />
+        <feMergeNode
+           id="feMergeNode5098"
+           in="SourceGraphic" />
+      </feMerge>
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5130"
+       id="linearGradient5136"
+       x1="119.76609"
+       y1="431.36642"
+       x2="631.76611"
+       y2="431.36642"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5144"
+       id="radialGradient5150"
+       cx="294.02567"
+       cy="300.53604"
+       fx="294.02567"
+       fy="300.53604"
+       r="183.84033"
+       gradientTransform="matrix(0.66691196,0.43225768,-0.44145763,0.68110633,230.61036,-24.143353)"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       inkscape:collect="always"
+       id="filter4381"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="2.5"
+         id="feGaussianBlur4383" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3820"
+       id="linearGradient3575"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.06875313,0,0,0.06875313,2.829762,444.82336)"
+       x1="339.43503"
+       y1="370.08636"
+       x2="66.978798"
+       y2="135.09288" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="45.254834"
+     inkscape:cx="12.081283"
+     inkscape:cy="8.5032287"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1033"
+     inkscape:window-x="-3"
+     inkscape:window-y="-3"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4447"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata3977">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(93.42207,-466.65551)">
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       d="m -83.896989,468.73997 c -3.950245,0 -6.534942,3.44694 -6.364259,6.72133 l -2.160822,0 3.904021,3.91738 4.081269,-3.87222 -2.148938,0 c -0.237051,-1.70092 1.163456,-3.1145 2.688727,-3.0921 1.596496,0.0235 2.800571,1.22922 2.800571,2.73336 0.08961,1.59378 -1.629405,3.4279 -3.965431,2.53172 -8.3e-5,1.22806 0.0027,2.54389 0,3.76397 4.189434,0.82896 7.639781,-2.50953 7.639781,-6.25087 0,-3.56212 -2.9188,-6.45252 -6.474921,-6.45252 z"
+       id="path4438"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccscccccc"
+       inkscape:export-filename="/home/samtuke/owncloud/git/owncloud/core/img/actions/history.png"
+       inkscape:export-xdpi="89.929733"
+       inkscape:export-ydpi="89.929733" />
+  </g>
+</svg>
diff --git a/files/js/jquery.fileupload.js b/files/js/jquery.fileupload.js
new file mode 100644
index 0000000000000000000000000000000000000000..a89e9dc2c4498fe50c7d8a4985bd952c639310f1
--- /dev/null
+++ b/files/js/jquery.fileupload.js
@@ -0,0 +1,866 @@
+/*
+ * jQuery File Upload Plugin 5.9
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint nomen: true, unparam: true, regexp: true */
+/*global define, window, document, Blob, FormData, location */
+
+(function (factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        // Register as an anonymous AMD module:
+        define([
+            'jquery',
+            'jquery.ui.widget'
+        ], factory);
+    } else {
+        // Browser globals:
+        factory(window.jQuery);
+    }
+}(function ($) {
+    'use strict';
+
+    // The FileReader API is not actually used, but works as feature detection,
+    // as e.g. Safari supports XHR file uploads via the FormData API,
+    // but not non-multipart XHR file uploads:
+    $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
+    $.support.xhrFormDataFileUpload = !!window.FormData;
+
+    // The fileupload widget listens for change events on file input fields defined
+    // via fileInput setting and paste or drop events of the given dropZone.
+    // In addition to the default jQuery Widget methods, the fileupload widget
+    // exposes the "add" and "send" methods, to add or directly send files using
+    // the fileupload API.
+    // By default, files added via file input selection, paste, drag & drop or
+    // "add" method are uploaded immediately, but it is possible to override
+    // the "add" callback option to queue file uploads.
+    $.widget('blueimp.fileupload', {
+
+        options: {
+            // The namespace used for event handler binding on the dropZone and
+            // fileInput collections.
+            // If not set, the name of the widget ("fileupload") is used.
+            namespace: undefined,
+            // The drop target collection, by the default the complete document.
+            // Set to null or an empty collection to disable drag & drop support:
+            dropZone: $(document),
+            // The file input field collection, that is listened for change events.
+            // If undefined, it is set to the file input fields inside
+            // of the widget element on plugin initialization.
+            // Set to null or an empty collection to disable the change listener.
+            fileInput: undefined,
+            // By default, the file input field is replaced with a clone after
+            // each input field change event. This is required for iframe transport
+            // queues and allows change events to be fired for the same file
+            // selection, but can be disabled by setting the following option to false:
+            replaceFileInput: true,
+            // The parameter name for the file form data (the request argument name).
+            // If undefined or empty, the name property of the file input field is
+            // used, or "files[]" if the file input name property is also empty:
+            paramName: undefined,
+            // By default, each file of a selection is uploaded using an individual
+            // request for XHR type uploads. Set to false to upload file
+            // selections in one request each:
+            singleFileUploads: true,
+            // To limit the number of files uploaded with one XHR request,
+            // set the following option to an integer greater than 0:
+            limitMultiFileUploads: undefined,
+            // Set the following option to true to issue all file upload requests
+            // in a sequential order:
+            sequentialUploads: false,
+            // To limit the number of concurrent uploads,
+            // set the following option to an integer greater than 0:
+            limitConcurrentUploads: undefined,
+            // Set the following option to true to force iframe transport uploads:
+            forceIframeTransport: false,
+            // Set the following option to the location of a redirect url on the
+            // origin server, for cross-domain iframe transport uploads:
+            redirect: undefined,
+            // The parameter name for the redirect url, sent as part of the form
+            // data and set to 'redirect' if this option is empty:
+            redirectParamName: undefined,
+            // Set the following option to the location of a postMessage window,
+            // to enable postMessage transport uploads:
+            postMessage: undefined,
+            // By default, XHR file uploads are sent as multipart/form-data.
+            // The iframe transport is always using multipart/form-data.
+            // Set to false to enable non-multipart XHR uploads:
+            multipart: true,
+            // To upload large files in smaller chunks, set the following option
+            // to a preferred maximum chunk size. If set to 0, null or undefined,
+            // or the browser does not support the required Blob API, files will
+            // be uploaded as a whole.
+            maxChunkSize: undefined,
+            // When a non-multipart upload or a chunked multipart upload has been
+            // aborted, this option can be used to resume the upload by setting
+            // it to the size of the already uploaded bytes. This option is most
+            // useful when modifying the options object inside of the "add" or
+            // "send" callbacks, as the options are cloned for each file upload.
+            uploadedBytes: undefined,
+            // By default, failed (abort or error) file uploads are removed from the
+            // global progress calculation. Set the following option to false to
+            // prevent recalculating the global progress data:
+            recalculateProgress: true,
+
+            // Additional form data to be sent along with the file uploads can be set
+            // using this option, which accepts an array of objects with name and
+            // value properties, a function returning such an array, a FormData
+            // object (for XHR file uploads), or a simple object.
+            // The form of the first fileInput is given as parameter to the function:
+            formData: function (form) {
+                return form.serializeArray();
+            },
+
+            // The add callback is invoked as soon as files are added to the fileupload
+            // widget (via file input selection, drag & drop, paste or add API call).
+            // If the singleFileUploads option is enabled, this callback will be
+            // called once for each file in the selection for XHR file uplaods, else
+            // once for each file selection.
+            // The upload starts when the submit method is invoked on the data parameter.
+            // The data object contains a files property holding the added files
+            // and allows to override plugin options as well as define ajax settings.
+            // Listeners for this callback can also be bound the following way:
+            // .bind('fileuploadadd', func);
+            // data.submit() returns a Promise object and allows to attach additional
+            // handlers using jQuery's Deferred callbacks:
+            // data.submit().done(func).fail(func).always(func);
+            add: function (e, data) {
+                data.submit();
+            },
+
+            // Other callbacks:
+            // Callback for the submit event of each file upload:
+            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
+            // Callback for the start of each file upload request:
+            // send: function (e, data) {}, // .bind('fileuploadsend', func);
+            // Callback for successful uploads:
+            // done: function (e, data) {}, // .bind('fileuploaddone', func);
+            // Callback for failed (abort or error) uploads:
+            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
+            // Callback for completed (success, abort or error) requests:
+            // always: function (e, data) {}, // .bind('fileuploadalways', func);
+            // Callback for upload progress events:
+            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
+            // Callback for global upload progress events:
+            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
+            // Callback for uploads start, equivalent to the global ajaxStart event:
+            // start: function (e) {}, // .bind('fileuploadstart', func);
+            // Callback for uploads stop, equivalent to the global ajaxStop event:
+            // stop: function (e) {}, // .bind('fileuploadstop', func);
+            // Callback for change events of the fileInput collection:
+            // change: function (e, data) {}, // .bind('fileuploadchange', func);
+            // Callback for paste events to the dropZone collection:
+            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
+            // Callback for drop events of the dropZone collection:
+            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
+            // Callback for dragover events of the dropZone collection:
+            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
+
+            // The plugin options are used as settings object for the ajax calls.
+            // The following are jQuery ajax settings required for the file uploads:
+            processData: false,
+            contentType: false,
+            cache: false
+        },
+
+        // A list of options that require a refresh after assigning a new value:
+        _refreshOptionsList: [
+            'namespace',
+            'dropZone',
+            'fileInput',
+            'multipart',
+            'forceIframeTransport'
+        ],
+
+        _isXHRUpload: function (options) {
+            return !options.forceIframeTransport &&
+                ((!options.multipart && $.support.xhrFileUpload) ||
+                $.support.xhrFormDataFileUpload);
+        },
+
+        _getFormData: function (options) {
+            var formData;
+            if (typeof options.formData === 'function') {
+                return options.formData(options.form);
+            } else if ($.isArray(options.formData)) {
+                return options.formData;
+            } else if (options.formData) {
+                formData = [];
+                $.each(options.formData, function (name, value) {
+                    formData.push({name: name, value: value});
+                });
+                return formData;
+            }
+            return [];
+        },
+
+        _getTotal: function (files) {
+            var total = 0;
+            $.each(files, function (index, file) {
+                total += file.size || 1;
+            });
+            return total;
+        },
+
+        _onProgress: function (e, data) {
+            if (e.lengthComputable) {
+                var total = data.total || this._getTotal(data.files),
+                    loaded = parseInt(
+                        e.loaded / e.total * (data.chunkSize || total),
+                        10
+                    ) + (data.uploadedBytes || 0);
+                this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
+                data.lengthComputable = true;
+                data.loaded = loaded;
+                data.total = total;
+                // Trigger a custom progress event with a total data property set
+                // to the file size(s) of the current upload and a loaded data
+                // property calculated accordingly:
+                this._trigger('progress', e, data);
+                // Trigger a global progress event for all current file uploads,
+                // including ajax calls queued for sequential file uploads:
+                this._trigger('progressall', e, {
+                    lengthComputable: true,
+                    loaded: this._loaded,
+                    total: this._total
+                });
+            }
+        },
+
+        _initProgressListener: function (options) {
+            var that = this,
+                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
+            // Accesss to the native XHR object is required to add event listeners
+            // for the upload progress event:
+            if (xhr.upload) {
+                $(xhr.upload).bind('progress', function (e) {
+                    var oe = e.originalEvent;
+                    // Make sure the progress event properties get copied over:
+                    e.lengthComputable = oe.lengthComputable;
+                    e.loaded = oe.loaded;
+                    e.total = oe.total;
+                    that._onProgress(e, options);
+                });
+                options.xhr = function () {
+                    return xhr;
+                };
+            }
+        },
+
+        _initXHRData: function (options) {
+            var formData,
+                file = options.files[0],
+                // Ignore non-multipart setting if not supported:
+                multipart = options.multipart || !$.support.xhrFileUpload;
+            if (!multipart || options.blob) {
+                // For non-multipart uploads and chunked uploads,
+                // file meta data is not part of the request body,
+                // so we transmit this data as part of the HTTP headers.
+                // For cross domain requests, these headers must be allowed
+                // via Access-Control-Allow-Headers or removed using
+                // the beforeSend callback:
+                options.headers = $.extend(options.headers, {
+                    'X-File-Name': file.name,
+                    'X-File-Type': file.type,
+                    'X-File-Size': file.size
+                });
+                if (!options.blob) {
+                    // Non-chunked non-multipart upload:
+                    options.contentType = file.type;
+                    options.data = file;
+                } else if (!multipart) {
+                    // Chunked non-multipart upload:
+                    options.contentType = 'application/octet-stream';
+                    options.data = options.blob;
+                }
+            }
+            if (multipart && $.support.xhrFormDataFileUpload) {
+                if (options.postMessage) {
+                    // window.postMessage does not allow sending FormData
+                    // objects, so we just add the File/Blob objects to
+                    // the formData array and let the postMessage window
+                    // create the FormData object out of this array:
+                    formData = this._getFormData(options);
+                    if (options.blob) {
+                        formData.push({
+                            name: options.paramName,
+                            value: options.blob
+                        });
+                    } else {
+                        $.each(options.files, function (index, file) {
+                            formData.push({
+                                name: options.paramName,
+                                value: file
+                            });
+                        });
+                    }
+                } else {
+                    if (options.formData instanceof FormData) {
+                        formData = options.formData;
+                    } else {
+                        formData = new FormData();
+                        $.each(this._getFormData(options), function (index, field) {
+                            formData.append(field.name, field.value);
+                        });
+                    }
+                    if (options.blob) {
+                        formData.append(options.paramName, options.blob, file.name);
+                    } else {
+                        $.each(options.files, function (index, file) {
+                            // File objects are also Blob instances.
+                            // This check allows the tests to run with
+                            // dummy objects:
+                            if (file instanceof Blob) {
+                                formData.append(options.paramName, file, file.name);
+                            }
+                        });
+                    }
+                }
+                options.data = formData;
+            }
+            // Blob reference is not needed anymore, free memory:
+            options.blob = null;
+        },
+
+        _initIframeSettings: function (options) {
+            // Setting the dataType to iframe enables the iframe transport:
+            options.dataType = 'iframe ' + (options.dataType || '');
+            // The iframe transport accepts a serialized array as form data:
+            options.formData = this._getFormData(options);
+            // Add redirect url to form data on cross-domain uploads:
+            if (options.redirect && $('<a></a>').prop('href', options.url)
+                    .prop('host') !== location.host) {
+                options.formData.push({
+                    name: options.redirectParamName || 'redirect',
+                    value: options.redirect
+                });
+            }
+        },
+
+        _initDataSettings: function (options) {
+            if (this._isXHRUpload(options)) {
+                if (!this._chunkedUpload(options, true)) {
+                    if (!options.data) {
+                        this._initXHRData(options);
+                    }
+                    this._initProgressListener(options);
+                }
+                if (options.postMessage) {
+                    // Setting the dataType to postmessage enables the
+                    // postMessage transport:
+                    options.dataType = 'postmessage ' + (options.dataType || '');
+                }
+            } else {
+                this._initIframeSettings(options, 'iframe');
+            }
+        },
+
+        _initFormSettings: function (options) {
+            // Retrieve missing options from the input field and the
+            // associated form, if available:
+            if (!options.form || !options.form.length) {
+                options.form = $(options.fileInput.prop('form'));
+            }
+            if (!options.paramName) {
+                options.paramName = options.fileInput.prop('name') ||
+                    'files[]';
+            }
+            if (!options.url) {
+                options.url = options.form.prop('action') || location.href;
+            }
+            // The HTTP request method must be "POST" or "PUT":
+            options.type = (options.type || options.form.prop('method') || '')
+                .toUpperCase();
+            if (options.type !== 'POST' && options.type !== 'PUT') {
+                options.type = 'POST';
+            }
+        },
+
+        _getAJAXSettings: function (data) {
+            var options = $.extend({}, this.options, data);
+            this._initFormSettings(options);
+            this._initDataSettings(options);
+            return options;
+        },
+
+        // Maps jqXHR callbacks to the equivalent
+        // methods of the given Promise object:
+        _enhancePromise: function (promise) {
+            promise.success = promise.done;
+            promise.error = promise.fail;
+            promise.complete = promise.always;
+            return promise;
+        },
+
+        // Creates and returns a Promise object enhanced with
+        // the jqXHR methods abort, success, error and complete:
+        _getXHRPromise: function (resolveOrReject, context, args) {
+            var dfd = $.Deferred(),
+                promise = dfd.promise();
+            context = context || this.options.context || promise;
+            if (resolveOrReject === true) {
+                dfd.resolveWith(context, args);
+            } else if (resolveOrReject === false) {
+                dfd.rejectWith(context, args);
+            }
+            promise.abort = dfd.promise;
+            return this._enhancePromise(promise);
+        },
+
+        // Uploads a file in multiple, sequential requests
+        // by splitting the file up in multiple blob chunks.
+        // If the second parameter is true, only tests if the file
+        // should be uploaded in chunks, but does not invoke any
+        // upload requests:
+        _chunkedUpload: function (options, testOnly) {
+            var that = this,
+                file = options.files[0],
+                fs = file.size,
+                ub = options.uploadedBytes = options.uploadedBytes || 0,
+                mcs = options.maxChunkSize || fs,
+                // Use the Blob methods with the slice implementation
+                // according to the W3C Blob API specification:
+                slice = file.webkitSlice || file.mozSlice || file.slice,
+                upload,
+                n,
+                jqXHR,
+                pipe;
+            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
+                    options.data) {
+                return false;
+            }
+            if (testOnly) {
+                return true;
+            }
+            if (ub >= fs) {
+                file.error = 'uploadedBytes';
+                return this._getXHRPromise(
+                    false,
+                    options.context,
+                    [null, 'error', file.error]
+                );
+            }
+            // n is the number of blobs to upload,
+            // calculated via filesize, uploaded bytes and max chunk size:
+            n = Math.ceil((fs - ub) / mcs);
+            // The chunk upload method accepting the chunk number as parameter:
+            upload = function (i) {
+                if (!i) {
+                    return that._getXHRPromise(true, options.context);
+                }
+                // Upload the blobs in sequential order:
+                return upload(i -= 1).pipe(function () {
+                    // Clone the options object for each chunk upload:
+                    var o = $.extend({}, options);
+                    o.blob = slice.call(
+                        file,
+                        ub + i * mcs,
+                        ub + (i + 1) * mcs
+                    );
+                    // Store the current chunk size, as the blob itself
+                    // will be dereferenced after data processing:
+                    o.chunkSize = o.blob.size;
+                    // Process the upload data (the blob and potential form data):
+                    that._initXHRData(o);
+                    // Add progress listeners for this chunk upload:
+                    that._initProgressListener(o);
+                    jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
+                        .done(function () {
+                            // Create a progress event if upload is done and
+                            // no progress event has been invoked for this chunk:
+                            if (!o.loaded) {
+                                that._onProgress($.Event('progress', {
+                                    lengthComputable: true,
+                                    loaded: o.chunkSize,
+                                    total: o.chunkSize
+                                }), o);
+                            }
+                            options.uploadedBytes = o.uploadedBytes +=
+                                o.chunkSize;
+                        });
+                    return jqXHR;
+                });
+            };
+            // Return the piped Promise object, enhanced with an abort method,
+            // which is delegated to the jqXHR object of the current upload,
+            // and jqXHR callbacks mapped to the equivalent Promise methods:
+            pipe = upload(n);
+            pipe.abort = function () {
+                return jqXHR.abort();
+            };
+            return this._enhancePromise(pipe);
+        },
+
+        _beforeSend: function (e, data) {
+            if (this._active === 0) {
+                // the start callback is triggered when an upload starts
+                // and no other uploads are currently running,
+                // equivalent to the global ajaxStart event:
+                this._trigger('start');
+            }
+            this._active += 1;
+            // Initialize the global progress values:
+            this._loaded += data.uploadedBytes || 0;
+            this._total += this._getTotal(data.files);
+        },
+
+        _onDone: function (result, textStatus, jqXHR, options) {
+            if (!this._isXHRUpload(options)) {
+                // Create a progress event for each iframe load:
+                this._onProgress($.Event('progress', {
+                    lengthComputable: true,
+                    loaded: 1,
+                    total: 1
+                }), options);
+            }
+            options.result = result;
+            options.textStatus = textStatus;
+            options.jqXHR = jqXHR;
+            this._trigger('done', null, options);
+        },
+
+        _onFail: function (jqXHR, textStatus, errorThrown, options) {
+            options.jqXHR = jqXHR;
+            options.textStatus = textStatus;
+            options.errorThrown = errorThrown;
+            this._trigger('fail', null, options);
+            if (options.recalculateProgress) {
+                // Remove the failed (error or abort) file upload from
+                // the global progress calculation:
+                this._loaded -= options.loaded || options.uploadedBytes || 0;
+                this._total -= options.total || this._getTotal(options.files);
+            }
+        },
+
+        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
+            this._active -= 1;
+            options.textStatus = textStatus;
+            if (jqXHRorError && jqXHRorError.always) {
+                options.jqXHR = jqXHRorError;
+                options.result = jqXHRorResult;
+            } else {
+                options.jqXHR = jqXHRorResult;
+                options.errorThrown = jqXHRorError;
+            }
+            this._trigger('always', null, options);
+            if (this._active === 0) {
+                // The stop callback is triggered when all uploads have
+                // been completed, equivalent to the global ajaxStop event:
+                this._trigger('stop');
+                // Reset the global progress values:
+                this._loaded = this._total = 0;
+            }
+        },
+
+        _onSend: function (e, data) {
+            var that = this,
+                jqXHR,
+                slot,
+                pipe,
+                options = that._getAJAXSettings(data),
+                send = function (resolve, args) {
+                    that._sending += 1;
+                    jqXHR = jqXHR || (
+                        (resolve !== false &&
+                        that._trigger('send', e, options) !== false &&
+                        (that._chunkedUpload(options) || $.ajax(options))) ||
+                        that._getXHRPromise(false, options.context, args)
+                    ).done(function (result, textStatus, jqXHR) {
+                        that._onDone(result, textStatus, jqXHR, options);
+                    }).fail(function (jqXHR, textStatus, errorThrown) {
+                        that._onFail(jqXHR, textStatus, errorThrown, options);
+                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
+                        that._sending -= 1;
+                        that._onAlways(
+                            jqXHRorResult,
+                            textStatus,
+                            jqXHRorError,
+                            options
+                        );
+                        if (options.limitConcurrentUploads &&
+                                options.limitConcurrentUploads > that._sending) {
+                            // Start the next queued upload,
+                            // that has not been aborted:
+                            var nextSlot = that._slots.shift();
+                            while (nextSlot) {
+                                if (!nextSlot.isRejected()) {
+                                    nextSlot.resolve();
+                                    break;
+                                }
+                                nextSlot = that._slots.shift();
+                            }
+                        }
+                    });
+                    return jqXHR;
+                };
+            this._beforeSend(e, options);
+            if (this.options.sequentialUploads ||
+                    (this.options.limitConcurrentUploads &&
+                    this.options.limitConcurrentUploads <= this._sending)) {
+                if (this.options.limitConcurrentUploads > 1) {
+                    slot = $.Deferred();
+                    this._slots.push(slot);
+                    pipe = slot.pipe(send);
+                } else {
+                    pipe = (this._sequence = this._sequence.pipe(send, send));
+                }
+                // Return the piped Promise object, enhanced with an abort method,
+                // which is delegated to the jqXHR object of the current upload,
+                // and jqXHR callbacks mapped to the equivalent Promise methods:
+                pipe.abort = function () {
+                    var args = [undefined, 'abort', 'abort'];
+                    if (!jqXHR) {
+                        if (slot) {
+                            slot.rejectWith(args);
+                        }
+                        return send(false, args);
+                    }
+                    return jqXHR.abort();
+                };
+                return this._enhancePromise(pipe);
+            }
+            return send();
+        },
+
+        _onAdd: function (e, data) {
+            var that = this,
+                result = true,
+                options = $.extend({}, this.options, data),
+                limit = options.limitMultiFileUploads,
+                fileSet,
+                i;
+            if (!(options.singleFileUploads || limit) ||
+                    !this._isXHRUpload(options)) {
+                fileSet = [data.files];
+            } else if (!options.singleFileUploads && limit) {
+                fileSet = [];
+                for (i = 0; i < data.files.length; i += limit) {
+                    fileSet.push(data.files.slice(i, i + limit));
+                }
+            }
+            data.originalFiles = data.files;
+            $.each(fileSet || data.files, function (index, element) {
+                var files = fileSet ? element : [element],
+                    newData = $.extend({}, data, {files: files});
+                newData.submit = function () {
+                    newData.jqXHR = this.jqXHR =
+                        (that._trigger('submit', e, this) !== false) &&
+                        that._onSend(e, this);
+                    return this.jqXHR;
+                };
+                return (result = that._trigger('add', e, newData));
+            });
+            return result;
+        },
+
+        // File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
+        _normalizeFile: function (index, file) {
+            if (file.name === undefined && file.size === undefined) {
+                file.name = file.fileName;
+                file.size = file.fileSize;
+            }
+        },
+
+        _replaceFileInput: function (input) {
+            var inputClone = input.clone(true);
+            $('<form></form>').append(inputClone)[0].reset();
+            // Detaching allows to insert the fileInput on another form
+            // without loosing the file input value:
+            input.after(inputClone).detach();
+            // Avoid memory leaks with the detached file input:
+            $.cleanData(input.unbind('remove'));
+            // Replace the original file input element in the fileInput
+            // collection with the clone, which has been copied including
+            // event handlers:
+            this.options.fileInput = this.options.fileInput.map(function (i, el) {
+                if (el === input[0]) {
+                    return inputClone[0];
+                }
+                return el;
+            });
+            // If the widget has been initialized on the file input itself,
+            // override this.element with the file input clone:
+            if (input[0] === this.element[0]) {
+                this.element = inputClone;
+            }
+        },
+
+        _onChange: function (e) {
+            var that = e.data.fileupload,
+                data = {
+                    files: $.each($.makeArray(e.target.files), that._normalizeFile),
+                    fileInput: $(e.target),
+                    form: $(e.target.form)
+                };
+            if (!data.files.length) {
+                // If the files property is not available, the browser does not
+                // support the File API and we add a pseudo File object with
+                // the input value as name with path information removed:
+                data.files = [{name: e.target.value.replace(/^.*\\/, '')}];
+            }
+            if (that.options.replaceFileInput) {
+                that._replaceFileInput(data.fileInput);
+            }
+            if (that._trigger('change', e, data) === false ||
+                    that._onAdd(e, data) === false) {
+                return false;
+            }
+        },
+
+        _onPaste: function (e) {
+            var that = e.data.fileupload,
+                cbd = e.originalEvent.clipboardData,
+                items = (cbd && cbd.items) || [],
+                data = {files: []};
+            $.each(items, function (index, item) {
+                var file = item.getAsFile && item.getAsFile();
+                if (file) {
+                    data.files.push(file);
+                }
+            });
+            if (that._trigger('paste', e, data) === false ||
+                    that._onAdd(e, data) === false) {
+                return false;
+            }
+        },
+
+        _onDrop: function (e) {
+            var that = e.data.fileupload,
+                dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
+                data = {
+                    files: $.each(
+                        $.makeArray(dataTransfer && dataTransfer.files),
+                        that._normalizeFile
+                    )
+                };
+            if (that._trigger('drop', e, data) === false ||
+                    that._onAdd(e, data) === false) {
+                return false;
+            }
+            e.preventDefault();
+        },
+
+        _onDragOver: function (e) {
+            var that = e.data.fileupload,
+                dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
+            if (that._trigger('dragover', e) === false) {
+                return false;
+            }
+            if (dataTransfer) {
+                dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
+            }
+            e.preventDefault();
+        },
+
+        _initEventHandlers: function () {
+            var ns = this.options.namespace;
+            if (this._isXHRUpload(this.options)) {
+                this.options.dropZone
+                    .bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
+                    .bind('drop.' + ns, {fileupload: this}, this._onDrop)
+                    .bind('paste.' + ns, {fileupload: this}, this._onPaste);
+            }
+            this.options.fileInput
+                .bind('change.' + ns, {fileupload: this}, this._onChange);
+        },
+
+        _destroyEventHandlers: function () {
+            var ns = this.options.namespace;
+            this.options.dropZone
+                .unbind('dragover.' + ns, this._onDragOver)
+                .unbind('drop.' + ns, this._onDrop)
+                .unbind('paste.' + ns, this._onPaste);
+            this.options.fileInput
+                .unbind('change.' + ns, this._onChange);
+        },
+
+        _setOption: function (key, value) {
+            var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
+            if (refresh) {
+                this._destroyEventHandlers();
+            }
+            $.Widget.prototype._setOption.call(this, key, value);
+            if (refresh) {
+                this._initSpecialOptions();
+                this._initEventHandlers();
+            }
+        },
+
+        _initSpecialOptions: function () {
+            var options = this.options;
+            if (options.fileInput === undefined) {
+                options.fileInput = this.element.is('input:file') ?
+                        this.element : this.element.find('input:file');
+            } else if (!(options.fileInput instanceof $)) {
+                options.fileInput = $(options.fileInput);
+            }
+            if (!(options.dropZone instanceof $)) {
+                options.dropZone = $(options.dropZone);
+            }
+        },
+
+        _create: function () {
+            var options = this.options,
+                dataOpts = $.extend({}, this.element.data());
+            dataOpts[this.widgetName] = undefined;
+            $.extend(options, dataOpts);
+            options.namespace = options.namespace || this.widgetName;
+            this._initSpecialOptions();
+            this._slots = [];
+            this._sequence = this._getXHRPromise(true);
+            this._sending = this._active = this._loaded = this._total = 0;
+            this._initEventHandlers();
+        },
+
+        destroy: function () {
+            this._destroyEventHandlers();
+            $.Widget.prototype.destroy.call(this);
+        },
+
+        enable: function () {
+            $.Widget.prototype.enable.call(this);
+            this._initEventHandlers();
+        },
+
+        disable: function () {
+            this._destroyEventHandlers();
+            $.Widget.prototype.disable.call(this);
+        },
+
+        // This method is exposed to the widget API and allows adding files
+        // using the fileupload API. The data parameter accepts an object which
+        // must have a files property and can contain additional options:
+        // .fileupload('add', {files: filesList});
+        add: function (data) {
+            if (!data || this.options.disabled) {
+                return;
+            }
+            data.files = $.each($.makeArray(data.files), this._normalizeFile);
+            this._onAdd(null, data);
+        },
+
+        // This method is exposed to the widget API and allows sending files
+        // using the fileupload API. The data parameter accepts an object which
+        // must have a files property and can contain additional options:
+        // .fileupload('send', {files: filesList});
+        // The method returns a Promise object for the file upload call.
+        send: function (data) {
+            if (data && !this.options.disabled) {
+                data.files = $.each($.makeArray(data.files), this._normalizeFile);
+                if (data.files.length) {
+                    return this._onSend(null, data);
+                }
+            }
+            return this._getXHRPromise(false, data && data.context);
+        }
+
+    });
+
+}));
diff --git a/files/js/jquery.iframe-transport.js b/files/js/jquery.iframe-transport.js
new file mode 100644
index 0000000000000000000000000000000000000000..d85c0c112973b2f6a433fb4a375adcb1c08f9bf6
--- /dev/null
+++ b/files/js/jquery.iframe-transport.js
@@ -0,0 +1,165 @@
+/*
+ * jQuery Iframe Transport Plugin 1.3
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2011, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint unparam: true, nomen: true */
+/*global define, window, document */
+
+(function (factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        // Register as an anonymous AMD module:
+        define(['jquery'], factory);
+    } else {
+        // Browser globals:
+        factory(window.jQuery);
+    }
+}(function ($) {
+    'use strict';
+
+    // Helper variable to create unique names for the transport iframes:
+    var counter = 0;
+
+    // The iframe transport accepts three additional options:
+    // options.fileInput: a jQuery collection of file input fields
+    // options.paramName: the parameter name for the file form data,
+    //  overrides the name property of the file input field(s)
+    // options.formData: an array of objects with name and value properties,
+    //  equivalent to the return data of .serializeArray(), e.g.:
+    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
+    $.ajaxTransport('iframe', function (options) {
+        if (options.async && (options.type === 'POST' || options.type === 'GET')) {
+            var form,
+                iframe;
+            return {
+                send: function (_, completeCallback) {
+                    form = $('<form style="display:none;"></form>');
+                    // javascript:false as initial iframe src
+                    // prevents warning popups on HTTPS in IE6.
+                    // IE versions below IE8 cannot set the name property of
+                    // elements that have already been added to the DOM,
+                    // so we set the name along with the iframe HTML markup:
+                    iframe = $(
+                        '<iframe src="javascript:false;" name="iframe-transport-' +
+                            (counter += 1) + '"></iframe>'
+                    ).bind('load', function () {
+                        var fileInputClones;
+                        iframe
+                            .unbind('load')
+                            .bind('load', function () {
+                                var response;
+                                // Wrap in a try/catch block to catch exceptions thrown
+                                // when trying to access cross-domain iframe contents:
+                                try {
+                                    response = iframe.contents();
+                                    // Google Chrome and Firefox do not throw an
+                                    // exception when calling iframe.contents() on
+                                    // cross-domain requests, so we unify the response:
+                                    if (!response.length || !response[0].firstChild) {
+                                        throw new Error();
+                                    }
+                                } catch (e) {
+                                    response = undefined;
+                                }
+                                // The complete callback returns the
+                                // iframe content document as response object:
+                                completeCallback(
+                                    200,
+                                    'success',
+                                    {'iframe': response}
+                                );
+                                // Fix for IE endless progress bar activity bug
+                                // (happens on form submits to iframe targets):
+                                $('<iframe src="javascript:false;"></iframe>')
+                                    .appendTo(form);
+                                form.remove();
+                            });
+                        form
+                            .prop('target', iframe.prop('name'))
+                            .prop('action', options.url)
+                            .prop('method', options.type);
+                        if (options.formData) {
+                            $.each(options.formData, function (index, field) {
+                                $('<input type="hidden"/>')
+                                    .prop('name', field.name)
+                                    .val(field.value)
+                                    .appendTo(form);
+                            });
+                        }
+                        if (options.fileInput && options.fileInput.length &&
+                                options.type === 'POST') {
+                            fileInputClones = options.fileInput.clone();
+                            // Insert a clone for each file input field:
+                            options.fileInput.after(function (index) {
+                                return fileInputClones[index];
+                            });
+                            if (options.paramName) {
+                                options.fileInput.each(function () {
+                                    $(this).prop('name', options.paramName);
+                                });
+                            }
+                            // Appending the file input fields to the hidden form
+                            // removes them from their original location:
+                            form
+                                .append(options.fileInput)
+                                .prop('enctype', 'multipart/form-data')
+                                // enctype must be set as encoding for IE:
+                                .prop('encoding', 'multipart/form-data');
+                        }
+                        form.submit();
+                        // Insert the file input fields at their original location
+                        // by replacing the clones with the originals:
+                        if (fileInputClones && fileInputClones.length) {
+                            options.fileInput.each(function (index, input) {
+                                var clone = $(fileInputClones[index]);
+                                $(input).prop('name', clone.prop('name'));
+                                clone.replaceWith(input);
+                            });
+                        }
+                    });
+                    form.append(iframe).appendTo(document.body);
+                },
+                abort: function () {
+                    if (iframe) {
+                        // javascript:false as iframe src aborts the request
+                        // and prevents warning popups on HTTPS in IE6.
+                        // concat is used to avoid the "Script URL" JSLint error:
+                        iframe
+                            .unbind('load')
+                            .prop('src', 'javascript'.concat(':false;'));
+                    }
+                    if (form) {
+                        form.remove();
+                    }
+                }
+            };
+        }
+    });
+
+    // The iframe transport returns the iframe content document as response.
+    // The following adds converters from iframe to text, json, html, and script:
+    $.ajaxSetup({
+        converters: {
+            'iframe text': function (iframe) {
+                return $(iframe[0].body).text();
+            },
+            'iframe json': function (iframe) {
+                return $.parseJSON($(iframe[0].body).text());
+            },
+            'iframe html': function (iframe) {
+                return $(iframe[0].body).html();
+            },
+            'iframe script': function (iframe) {
+                return $.globalEval($(iframe[0].body).text());
+            }
+        }
+    });
+
+}));
diff --git a/lib/base.php b/lib/base.php
index 74693641f6e786e059cc97721810c9217e33f01c..fa4c9850a3b1c4e70973e17beee56f24439b2ce3 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -428,7 +428,7 @@ class OC{
 			$parent = OC::$APPSROOT . '/' . self::$REQUESTEDAPP;
 			if(!OC_Helper::issubdirectory($subdir, $parent)){
 				self::$REQUESTEDFILE = null;
-				//header('HTTP/1.0 404 Not Found');
+				header('HTTP/1.0 404 Not Found');
 				exit;
 			}
 		}
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php
index cc37bf22d5dae2e15257e893b8b0a348ebcfda80..912c8cd439a10b3a6b2b5f934c08ce875ba1a11a 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/connector/sabre/directory.php
@@ -50,7 +50,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 
 		$path = $this->path . '/' . $name;
 
-		if (!OC_Filesystem::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located');
+		if (!OC_Filesystem::file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
 
 		if (OC_Filesystem::is_dir($path)) {
 
diff --git a/lib/connector/sabre/principal.php b/lib/connector/sabre/principal.php
index 28a36438e8767d5c4d1fb4dd9fdcb5ec441a6b4c..d1456f7c64215a780c96f24d5d6ace63bcff47d3 100644
--- a/lib/connector/sabre/principal.php
+++ b/lib/connector/sabre/principal.php
@@ -46,7 +46,7 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend {
 	 * @return array
 	 */
 	public function getPrincipalByPath($path) {
-		list($prefix,$name) = Sabre_DAV_URLUtil::splitPath($path);
+		list($prefix,$name) = explode('/', $path);
 
 		if ($prefix == 'principals' && OC_User::userExists($name)) {
 			return array(
@@ -115,4 +115,6 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend {
 	public function setGroupMemberSet($principal, array $members) {
 		throw new Sabre_DAV_Exception('Setting members of the group is not supported yet');
 	}
+	function updatePrincipal($path, $mutations){return 0;}
+	function searchPrincipals($prefixPath, array $searchProperties){return 0;}
 }
diff --git a/lib/filecache.php b/lib/filecache.php
index 19286ff746b70672887f179ebe44fd347b095661..28a9eb247a6fa92dbed427d4e69007d702a3a40c 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -64,7 +64,7 @@ class OC_FileCache{
 		if(is_array($result)){
 			return $result;
 		}else{
-			OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+			OC_Log::write('files','get(): file not found in cache ('.$path.')',OC_Log::DEBUG);
 			return false;
 		}
 	}
@@ -257,7 +257,7 @@ class OC_FileCache{
 		if(is_array($result)){
 			return $result;
 		}else{
-			OC_Log::write('getFolderContent(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+			OC_Log::write('files','getFolderContent(): file not found in cache ('.$path.')',OC_Log::DEBUG);
 			return false;
 		}
 	}
@@ -300,7 +300,7 @@ class OC_FileCache{
 		if(is_array($result)){
 			return $result['id'];
 		}else{
-			OC_Log::write('getFileId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+			OC_Log::write('files','getFileId(): file not found in cache ('.$path.')',OC_Log::DEBUG);
 			return -1;
 		}
 	}
@@ -414,8 +414,12 @@ class OC_FileCache{
 			}
 			return $result;
 		}else{
-			OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
-			return false;
+			OC_Log::write('files','getChached(): file not found in cache ('.$path.')',OC_Log::DEBUG);
+			if(isset(self::$savedData[$path])){
+				return self::$savedData[$path];
+			}else{
+				return array();
+			}
 		}
 	}
 	
@@ -553,6 +557,7 @@ class OC_FileCache{
 			$view=new OC_FilesystemView(($root=='/')?'':$root);
 		}
 		if(!$view->is_readable($path)) return; //cant read, nothing we can do
+		clearstatcache();
 		$stat=$view->stat($path);
 		$mimetype=$view->getMimeType($path);
 		$writable=$view->is_writable($path);
diff --git a/lib/filesystem.php b/lib/filesystem.php
index dc678fba74c3d45a14c55b06e08e5250b6303306..1b91eabc7c17a553e1e05ff9374280ff84123b8f 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -196,9 +196,57 @@ class OC_Filesystem{
 			return false;
 		}
 		self::$defaultInstance=new OC_FilesystemView($root);
+
+		//load custom mount config
+		if(is_file(OC::$SERVERROOT.'/config/mount.php')){
+			$mountConfig=include(OC::$SERVERROOT.'/config/mount.php');
+			if(isset($mountConfig['global'])){
+				foreach($mountConfig['global'] as $mountPoint=>$options){
+					self::mount($options['class'],$options['options'],$mountPoint);
+				}
+			}
+
+			if(isset($mountConfig['group'])){
+				foreach($mountConfig['group'] as $group=>$mounts){
+					if(OC_Group::inGroup(OC_User::getUser(),$group)){
+						foreach($mounts as $mountPoint=>$options){
+							$mountPoint=self::setUserVars($mountPoint);
+							foreach($options as &$option){
+								$option=self::setUserVars($option);
+							}
+							self::mount($options['class'],$options['options'],$mountPoint);
+						}
+					}
+				}
+			}
+
+			if(isset($mountConfig['user'])){
+				foreach($mountConfig['user'] as $user=>$mounts){
+					if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())){
+						foreach($mounts as $mountPoint=>$options){
+							$mountPoint=self::setUserVars($mountPoint);
+							foreach($options as &$option){
+								$option=self::setUserVars($option);
+							}
+							self::mount($options['class'],$options['options'],$mountPoint);
+						}
+					}
+				}
+			}
+		}
+		
 		self::$loaded=true;
 	}
 
+	/**
+	 * fill in the correct values for $user, and $password placeholders
+	 * @param string intput
+	 * @return string
+	 */
+	private static function setUserVars($input){
+		return str_replace('$user',OC_User::getUser(),$input);
+	}
+
 	/**
 	 * get the default filesystem view
 	 * @return OC_FilesystemView
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index 95873bd87cfabd61f519611d7ade6716dadf8497..ac5a0a3bff50bc81d6039dd614033a4fae05b8bd 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -136,15 +136,16 @@ class OC_FilesystemView {
 		return $this->basicOperation('filesize',$path);
 	}
 	public function readfile($path){
+		@ob_end_clean();
 		$handle=$this->fopen($path,'r');
 		if ($handle) {
-			$chunkSize = 1024*1024;// 1 MB chunks
+			$chunkSize = 8*1024;// 1 MB chunks
 			while (!feof($handle)) {
 				echo fread($handle, $chunkSize);
-				@ob_flush();
 				flush();
 			}
-			return $this->filesize($path);
+			$size=$this->filesize($path);
+			return $size;
 		}
 		return false;
 	}
@@ -174,11 +175,23 @@ class OC_FilesystemView {
 	}
 	public function file_put_contents($path,$data){
 		if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier
+			$exists=$this->file_exists($path);
+			$run=true;
+			if(!$exists){
+				OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+			}
+			OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+			if(!$run){
+				return false;
+			}
 			$target=$this->fopen($path,'w');
 			if($target){
 				$count=OC_Helper::streamCopy($data,$target);
 				fclose($target);
 				fclose($data);
+				if(!$exists){
+					OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path));
+				}
 				OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path));
 				return $count>0;
 			}else{
diff --git a/lib/helper.php b/lib/helper.php
index 1d9862bf8b1086173a7764b653a0e223f4a8ae08..c5af76dbe525b5007ac663f87ed74fb55e68bbd1 100755
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -569,14 +569,22 @@ class OC_Helper {
 			return false;
 		}
 		if($realpath_sub && $realpath_sub != '' && $realpath_parent && $realpath_parent != ''){
-			if(substr($sub, 0, strlen($parent)) == $parent){
+			if(substr($realpath_sub, 0, strlen($realpath_parent)) == $realpath_parent){
 				return true;
 			}
 		}else{
-			if(substr($realpath_sub, 0, strlen($realpath_parent)) == $realpath_parent){
+			if(substr($sub, 0, strlen($parent)) == $parent){
 				return true;
 			}
 		}
+		/*
+		echo 'SUB: ' . $sub . "\n";
+		echo 'PAR: ' . $parent . "\n";
+		echo 'REALSUB: ' . $realpath_sub . "\n";
+		echo 'REALPAR: ' . $realpath_parent . "\n";
+		echo substr($realpath_sub, 0, strlen($realpath_parent));
+		exit;
+		*/
 		return false;
 	}
 }
diff --git a/lib/vobject.php b/lib/vobject.php
index e3479fc6d3687a3a9c8f09416e37b8c2d06d737b..ec80e1d605ae2d163c06b2a78fb1068351378db8 100644
--- a/lib/vobject.php
+++ b/lib/vobject.php
@@ -41,7 +41,7 @@ class OC_VObject{
 	 */
 	public static function parse($data){
 		try {
-			Sabre_VObject_Reader::$elementMap['LAST-MODIFIED'] = 'Sabre_VObject_Element_DateTime';
+			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);
@@ -150,12 +150,12 @@ class OC_VObject{
 	 * @param int $dateType
 	 * @return void
 	 */
-	public function setDateTime($name, $datetime, $dateType=Sabre_VObject_Element_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_Element_DateTime($name);
+			$datetime_element = new Sabre_VObject_Property_DateTime($name);
 			$datetime_element->setDateTime($datetime, $dateType);
 			$this->vobject->__set($name, $datetime_element);
 		}else{
diff --git a/settings/templates/help.php b/settings/templates/help.php
index df640d974693f4ba4a83869f93ae0eb91bda6d9c..f9eb8615972ea4d4c28bf8b20d7665945fd80900 100644
--- a/settings/templates/help.php
+++ b/settings/templates/help.php
@@ -6,6 +6,7 @@
 
 <div id="controls">
 	<a class="button newquestion" href="http://owncloud.org/support" target="_blank"><?php echo $l->t( 'Documentation' ); ?></a>
+	<a class="button newquestion" href="http://owncloud.org/support/big-files" target="_blank"><?php echo $l->t( 'Managing Big Files' ); ?></a>
 	<a class="button newquestion" href="http://apps.owncloud.com/knowledgebase/editquestion.php?action=new" target="_blank"><?php echo $l->t( 'Ask a question' ); ?></a>
 	<?php
 		$url=OC_Helper::linkTo( "settings", "help.php" ).'?page=';