diff --git a/apps/files_external/3rdparty/autoload.php b/apps/files_external/3rdparty/autoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..78e3de4ca0c7a61afd9d32250ec3cd89b853b19f
--- /dev/null
+++ b/apps/files_external/3rdparty/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer' . '/autoload_real.php';
+
+return ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3::getLoader();
diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b1315651c99a7441e2928c56988f52f0006f51d5
--- /dev/null
+++ b/apps/files_external/3rdparty/composer.json
@@ -0,0 +1,13 @@
+{
+	"name": "files_external/3rdparty",
+	"description": "3rdparty components for files_external",
+	"license": "MIT",
+	"config": {
+		"vendor-dir": "."
+	},
+	"require": {
+		"icewind/smb": "dev-master",
+		"icewind/streams": "0.2"
+	}
+}
+
diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock
new file mode 100644
index 0000000000000000000000000000000000000000..3da75b2a900daba7d683eaa266b00cb6c8efaaed
--- /dev/null
+++ b/apps/files_external/3rdparty/composer.lock
@@ -0,0 +1,101 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "This file is @generated automatically"
+    ],
+    "hash": "c854ee7f5bdcb3f2c8ee0a8cfe5e193a",
+    "packages": [
+        {
+            "name": "icewind/smb",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/icewind1991/SMB.git",
+                "reference": "ededbfbaa3d7124ce8d4b6c119cd225fa342916d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/icewind1991/SMB/zipball/ededbfbaa3d7124ce8d4b6c119cd225fa342916d",
+                "reference": "ededbfbaa3d7124ce8d4b6c119cd225fa342916d",
+                "shasum": ""
+            },
+            "require": {
+                "icewind/streams": "0.2.x",
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "satooshi/php-coveralls": "dev-master"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Icewind\\SMB\\": "src/",
+                    "Icewind\\SMB\\Test\\": "tests/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Robin Appelman",
+                    "email": "icewind@owncloud.com"
+                }
+            ],
+            "description": "php wrapper for smbclient and libsmbclient-php",
+            "time": "2015-02-10 16:37:37"
+        },
+        {
+            "name": "icewind/streams",
+            "version": "0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/icewind1991/Streams.git",
+                "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/icewind1991/Streams/zipball/5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a",
+                "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "satooshi/php-coveralls": "dev-master"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Icewind\\Streams\\Tests\\": "tests/",
+                    "Icewind\\Streams\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Robin Appelman",
+                    "email": "icewind@owncloud.com"
+                }
+            ],
+            "description": "A set of generic stream wrappers",
+            "time": "2014-07-30 23:46:15"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": {
+        "icewind/smb": 20
+    },
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}
diff --git a/apps/files_external/3rdparty/composer/ClassLoader.php b/apps/files_external/3rdparty/composer/ClassLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e1469e8307d9c644831f694ed8eccdd4afccc28
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/ClassLoader.php
@@ -0,0 +1,413 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0 class loader
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
+ *
+ *     $loader = new \Composer\Autoload\ClassLoader();
+ *
+ *     // register classes with namespaces
+ *     $loader->add('Symfony\Component', __DIR__.'/component');
+ *     $loader->add('Symfony',           __DIR__.'/framework');
+ *
+ *     // activate the autoloader
+ *     $loader->register();
+ *
+ *     // to enable searching the include path (eg. for PEAR packages)
+ *     $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class ClassLoader
+{
+    // PSR-4
+    private $prefixLengthsPsr4 = array();
+    private $prefixDirsPsr4 = array();
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    private $prefixesPsr0 = array();
+    private $fallbackDirsPsr0 = array();
+
+    private $useIncludePath = false;
+    private $classMap = array();
+
+    private $classMapAuthoritative = false;
+
+    public function getPrefixes()
+    {
+        if (!empty($this->prefixesPsr0)) {
+            return call_user_func_array('array_merge', $this->prefixesPsr0);
+        }
+
+        return array();
+    }
+
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
+    }
+
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirsPsr0;
+    }
+
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
+    }
+
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param array $classMap Class to filename map
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
+     *
+     * @param string       $prefix  The prefix
+     * @param array|string $paths   The PSR-0 root directories
+     * @param bool         $prepend Whether to prepend the directories
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr0
+                );
+            } else {
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-0 base directories
+     * @param bool         $prepend Whether to prepend the directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixDirsPsr4[$prefix]
+            );
+        } else {
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
+     *
+     * @param string       $prefix The prefix
+     * @param array|string $paths  The PSR-0 base directories
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string       $prefix The prefix/namespace, with trailing '\\'
+     * @param array|string $paths  The PSR-4 base directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function setPsr4($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Turns off searching the prefix and fallback directories for classes
+     * that have not been registered with the class map.
+     *
+     * @param bool $classMapAuthoritative
+     */
+    public function setClassMapAuthoritative($classMapAuthoritative)
+    {
+        $this->classMapAuthoritative = $classMapAuthoritative;
+    }
+
+    /**
+     * Should class lookup fail if not found in the current class map?
+     *
+     * @return bool
+     */
+    public function isClassMapAuthoritative()
+    {
+        return $this->classMapAuthoritative;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param bool $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return bool|null True if loaded, null otherwise
+     */
+    public function loadClass($class)
+    {
+        if ($file = $this->findFile($class)) {
+            includeFile($file);
+
+            return true;
+        }
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+        if ('\\' == $class[0]) {
+            $class = substr($class, 1);
+        }
+
+        // class map lookup
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+        if ($this->classMapAuthoritative) {
+            return false;
+        }
+
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if ($file === null && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if ($file === null) {
+            // Remember that this class does not exist.
+            return $this->classMap[$class] = false;
+        }
+
+        return $file;
+    }
+
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+        } else {
+            // PEAR-like class name
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+        }
+
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+            return $file;
+        }
+    }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+    include $file;
+}
diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bd6482f9ea0a8e3df6cecfe964b8182058e6632
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/autoload_classmap.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = $vendorDir;
+
+return array(
+);
diff --git a/apps/files_external/3rdparty/composer/autoload_namespaces.php b/apps/files_external/3rdparty/composer/autoload_namespaces.php
new file mode 100644
index 0000000000000000000000000000000000000000..71c9e91858d8e1304b3bac8426d9457257afa03c
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = $vendorDir;
+
+return array(
+);
diff --git a/apps/files_external/3rdparty/composer/autoload_psr4.php b/apps/files_external/3rdparty/composer/autoload_psr4.php
new file mode 100644
index 0000000000000000000000000000000000000000..7cfe0f1c46dc0fa3c935121d88467271f23dd054
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/autoload_psr4.php
@@ -0,0 +1,13 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = $vendorDir;
+
+return array(
+    'Icewind\\Streams\\Tests\\' => array($vendorDir . '/icewind/streams/tests'),
+    'Icewind\\Streams\\' => array($vendorDir . '/icewind/streams/src'),
+    'Icewind\\SMB\\Test\\' => array($vendorDir . '/icewind/smb/tests'),
+    'Icewind\\SMB\\' => array($vendorDir . '/icewind/smb/src'),
+);
diff --git a/apps/files_external/3rdparty/composer/autoload_real.php b/apps/files_external/3rdparty/composer/autoload_real.php
new file mode 100644
index 0000000000000000000000000000000000000000..3391b322be0ca74caf328d1569feb78cb4c8e675
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/autoload_real.php
@@ -0,0 +1,50 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3
+{
+    private static $loader;
+
+    public static function loadClassLoader($class)
+    {
+        if ('Composer\Autoload\ClassLoader' === $class) {
+            require __DIR__ . '/ClassLoader.php';
+        }
+    }
+
+    public static function getLoader()
+    {
+        if (null !== self::$loader) {
+            return self::$loader;
+        }
+
+        spl_autoload_register(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader'), true, true);
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        spl_autoload_unregister(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader'));
+
+        $map = require __DIR__ . '/autoload_namespaces.php';
+        foreach ($map as $namespace => $path) {
+            $loader->set($namespace, $path);
+        }
+
+        $map = require __DIR__ . '/autoload_psr4.php';
+        foreach ($map as $namespace => $path) {
+            $loader->setPsr4($namespace, $path);
+        }
+
+        $classMap = require __DIR__ . '/autoload_classmap.php';
+        if ($classMap) {
+            $loader->addClassMap($classMap);
+        }
+
+        $loader->register(true);
+
+        return $loader;
+    }
+}
+
+function composerRequire98fe9b281934250b3a93f69a5ce843b3($file)
+{
+    require $file;
+}
diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json
new file mode 100644
index 0000000000000000000000000000000000000000..03bad8abf36255f363c0fa24ea0f0d0c06dee3b4
--- /dev/null
+++ b/apps/files_external/3rdparty/composer/installed.json
@@ -0,0 +1,87 @@
+[
+    {
+        "name": "icewind/streams",
+        "version": "0.2",
+        "version_normalized": "0.2.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/icewind1991/Streams.git",
+            "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/icewind1991/Streams/zipball/5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a",
+            "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3"
+        },
+        "require-dev": {
+            "satooshi/php-coveralls": "dev-master"
+        },
+        "time": "2014-07-30 23:46:15",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Icewind\\Streams\\Tests\\": "tests/",
+                "Icewind\\Streams\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Robin Appelman",
+                "email": "icewind@owncloud.com"
+            }
+        ],
+        "description": "A set of generic stream wrappers"
+    },
+    {
+        "name": "icewind/smb",
+        "version": "dev-master",
+        "version_normalized": "9999999-dev",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/icewind1991/SMB.git",
+            "reference": "ededbfbaa3d7124ce8d4b6c119cd225fa342916d"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/icewind1991/SMB/zipball/ededbfbaa3d7124ce8d4b6c119cd225fa342916d",
+            "reference": "ededbfbaa3d7124ce8d4b6c119cd225fa342916d",
+            "shasum": ""
+        },
+        "require": {
+            "icewind/streams": "0.2.x",
+            "php": ">=5.3"
+        },
+        "require-dev": {
+            "satooshi/php-coveralls": "dev-master"
+        },
+        "time": "2015-02-10 16:37:37",
+        "type": "library",
+        "installation-source": "source",
+        "autoload": {
+            "psr-4": {
+                "Icewind\\SMB\\": "src/",
+                "Icewind\\SMB\\Test\\": "tests/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Robin Appelman",
+                "email": "icewind@owncloud.com"
+            }
+        ],
+        "description": "php wrapper for smbclient and libsmbclient-php"
+    }
+]
diff --git a/apps/files_external/3rdparty/icewind/smb/.gitignore b/apps/files_external/3rdparty/icewind/smb/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..3ce5adbbde5536c3d923b26fb03652d0fa05ba3a
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/.gitignore
@@ -0,0 +1,2 @@
+.idea
+vendor
diff --git a/apps/files_external/3rdparty/icewind/smb/.travis.yml b/apps/files_external/3rdparty/icewind/smb/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c1ac3727d086dc94dd53c767f63968b29fac7618
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/.travis.yml
@@ -0,0 +1,50 @@
+language: php
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+
+env:
+  global:
+    - CURRENT_DIR=`pwd`
+
+before_install:
+  - pass=$(perl -e 'print crypt("test", "password")')
+  - sudo useradd -m -p $pass test
+  - sudo apt-get update -qq
+  - sudo apt-get install samba smbclient libsmbclient-dev libsmbclient
+  - wget -O /tmp/libsmbclient-php.zip https://github.com/eduardok/libsmbclient-php/archive/master.zip
+  - unzip /tmp/libsmbclient-php.zip -d /tmp
+  - cd /tmp/libsmbclient-php-master
+  - phpize && ./configure && make && sudo make install
+  - echo 'extension="libsmbclient.so"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
+  - cd $CURRENT_DIR
+  - chmod go+w $HOME
+  - printf "%s\n%s\n" test test|sudo smbpasswd -s test
+  - sudo mkdir /home/test/test
+  - sudo chown test /home/test/test
+  - |
+    echo "[test]
+    comment = test
+    path = /home/test
+    guest ok = yes
+    writeable = yes
+    map archive = yes
+    map system = yes
+    map hidden = yes
+    create mask = 0777
+    inherit permissions = yes" | sudo tee -a /etc/samba/smb.conf
+  - sudo service smbd restart
+  - testparm -s
+
+install:
+  - composer install --dev --no-interaction
+
+script:
+  - mkdir -p build/logs
+  - cd tests
+  - phpunit --coverage-clover ../build/logs/clover.xml --configuration phpunit.xml
+
+after_script:
+ - cd $CURRENT_DIR
+ - php vendor/bin/coveralls -v
diff --git a/apps/files_external/3rdparty/icewind/smb/LICENSE.txt b/apps/files_external/3rdparty/icewind/smb/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..16e3a1004ec41d8619350d685378fd013371b705
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a0864717b098a12a73d496b7e9fbfbbd2788397d
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/README.md
@@ -0,0 +1,136 @@
+SMB
+===
+
+[![Coverage Status](https://img.shields.io/coveralls/icewind1991/SMB.svg)](https://coveralls.io/r/icewind1991/SMB?branch=master)
+[![Build Status](https://travis-ci.org/icewind1991/SMB.svg?branch=master)](https://travis-ci.org/icewind1991/SMB)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/icewind1991/SMB/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/SMB/?branch=master)
+
+PHP wrapper for `smbclient` and [`libsmbclient-php`](https://github.com/eduardok/libsmbclient-php)
+
+- Reuses a single `smbclient` instance for multiple requests
+- Doesn't leak the password to the process list
+- Simple 1-on-1 mapping of SMB commands
+- A stream-based api to remove the need for temporary files
+- Support for using libsmbclient directly trough [`libsmbclient-php`](https://github.com/eduardok/libsmbclient-php)
+
+Examples
+----
+
+### Upload a file ###
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$fileToUpload = __FILE__;
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+$share->put($fileToUpload, 'example.txt');
+```
+
+### Download a file ###
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$target = __DIR__ . '/target.txt';
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+$share->get('example.txt', $target);
+```
+
+### List shares on the remote server ###
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$server = new Server('localhost', 'test', 'test');
+$shares = $server->listShares();
+
+foreach ($shares as $share) {
+	echo $share->getName() . "\n";
+}
+```
+
+### List the content of a folder ###
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+$content = $share->dir('test');
+
+foreach ($content as $info) {
+	echo $name->getName() . "\n";
+	echo "\tsize :" . $info->getSize() . "\n";
+}
+```
+
+### Using read streams
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+
+$fh = $share->read('test.txt');
+echo fread($fh, 4086);
+fclose($fh);
+```
+
+### Using write streams
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+
+$fh = $share->write('test.txt');
+fwrite($fh, 'bar');
+fclose($fh);
+```
+
+### Using libsmbclient-php ###
+
+Install [libsmbclient-php](https://github.com/eduardok/libsmbclient-php)
+
+```php
+<?php
+use Icewind\SMB\Server;
+use Icewind\SMB\NativeServer;
+
+require('vendor/autoload.php');
+
+$fileToUpload = __FILE__;
+
+if (Server::NativeAvailable()) {
+    $server = new NativeServer('localhost', 'test', 'test');
+} else {
+    echo 'libsmbclient-php not available, falling back to wrapping smbclient';
+    $server = new Server('localhost', 'test', 'test');
+}
+$share = $server->getShare('test');
+$share->put($fileToUpload, 'example.txt');
+```
diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..92f4280d775d49f085e28da5ce6d6236f2577367
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/composer.json
@@ -0,0 +1,24 @@
+{
+	"name"             : "icewind/smb",
+	"description"      : "php wrapper for smbclient and libsmbclient-php",
+	"license"          : "MIT",
+	"authors"          : [
+		{
+			"name" : "Robin Appelman",
+			"email": "icewind@owncloud.com"
+		}
+	],
+	"require"          : {
+		"php": ">=5.3",
+		"icewind/streams": "0.2.x"
+	},
+	"require-dev": {
+		"satooshi/php-coveralls"  : "dev-master"
+	},
+	"autoload"         : {
+		"psr-4": {
+			"Icewind\\SMB\\": "src/",
+			"Icewind\\SMB\\Test\\": "tests/"
+		}
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Connection.php
new file mode 100644
index 0000000000000000000000000000000000000000..6191b11ac8e509f892e529edbf79e3ee4f9bab1a
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Connection.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\AuthenticationException;
+use Icewind\SMB\Exception\ConnectionException;
+use Icewind\SMB\Exception\InvalidHostException;
+
+class Connection extends RawConnection {
+	const DELIMITER = 'smb:';
+
+	/**
+	 * send input to smbclient
+	 *
+	 * @param string $input
+	 */
+	public function write($input) {
+		parent::write($input . PHP_EOL);
+	}
+
+	/**
+	 * get all unprocessed output from smbclient until the next prompt
+	 *
+	 * @throws ConnectionException
+	 * @return string
+	 */
+	public function read() {
+		if (!$this->isValid()) {
+			throw new ConnectionException();
+		}
+		$line = $this->readLine(); //first line is prompt
+		$this->checkConnectionError($line);
+
+		$output = array();
+		$line = $this->readLine();
+		$length = mb_strlen(self::DELIMITER);
+		while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter
+			$output[] .= $line;
+			$line = $this->readLine();
+		}
+		return $output;
+	}
+
+	/**
+	 * check if the first line holds a connection failure
+	 *
+	 * @param $line
+	 * @throws AuthenticationException
+	 * @throws InvalidHostException
+	 */
+	private function checkConnectionError($line) {
+		$line = rtrim($line, ')');
+		if (substr($line, -23) === ErrorCodes::LogonFailure) {
+			throw new AuthenticationException();
+		}
+		if (substr($line, -26) === ErrorCodes::BadHostName) {
+			throw new InvalidHostException();
+		}
+		if (substr($line, -22) === ErrorCodes::Unsuccessful) {
+			throw new InvalidHostException();
+		}
+		if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
+			throw new InvalidHostException();
+		}
+	}
+
+	public function close($terminate = true) {
+		if (is_resource($this->getInputStream())) {
+			$this->write('close' . PHP_EOL);
+		}
+		parent::close($terminate);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php b/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9f2507cba9345b4a94ba4938b489a1bdaddbafe
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+class ErrorCodes {
+	/**
+	 * connection errors
+	 */
+	const LogonFailure = 'NT_STATUS_LOGON_FAILURE';
+	const BadHostName = 'NT_STATUS_BAD_NETWORK_NAME';
+	const Unsuccessful = 'NT_STATUS_UNSUCCESSFUL';
+	const ConnectionRefused = 'NT_STATUS_CONNECTION_REFUSED';
+
+	const PathNotFound = 'NT_STATUS_OBJECT_PATH_NOT_FOUND';
+	const NoSuchFile = 'NT_STATUS_NO_SUCH_FILE';
+	const ObjectNotFound = 'NT_STATUS_OBJECT_NAME_NOT_FOUND';
+	const NameCollision = 'NT_STATUS_OBJECT_NAME_COLLISION';
+	const AccessDenied = 'NT_STATUS_ACCESS_DENIED';
+	const DirectoryNotEmpty = 'NT_STATUS_DIRECTORY_NOT_EMPTY';
+	const FileIsADirectory = 'NT_STATUS_FILE_IS_A_DIRECTORY';
+	const NotADirectory = 'NT_STATUS_NOT_A_DIRECTORY';
+	const SharingViolation = 'NT_STATUS_SHARING_VIOLATION';
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b7d22b35407614f3abccb01adb125e7e4b60036
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class AccessDeniedException extends ConnectException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php
new file mode 100644
index 0000000000000000000000000000000000000000..4636b9d17867ec3ceed987f4fbf6d750d3602666
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class AlreadyExistsException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddf5d7e34dc6a03bc5d26c228d4ae95a96a64b89
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class AuthenticationException extends ConnectException{}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php
new file mode 100644
index 0000000000000000000000000000000000000000..310d441bf5c097bb1d814d33a84bd2d98b0bc91e
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class ConnectException extends Exception {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php
new file mode 100644
index 0000000000000000000000000000000000000000..21033560fc058bd17c8971b9a115517958e3c718
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class ConnectionException extends ConnectException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionRefusedException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionRefusedException.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffebb4c8a515cac6a4a4765beef26558beda1e4d
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionRefusedException.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class ConnectionRefusedException extends ConnectException {
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..3307ad57a24843d233def454d728fbb12e684dcf
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class Exception extends \Exception {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php
new file mode 100644
index 0000000000000000000000000000000000000000..46460eb6936c8cc4100f2a81c97594673b0cb189
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class FileInUseException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php
new file mode 100644
index 0000000000000000000000000000000000000000..117d6a438ea0c78126fa92b2d669f4dd00d7134d
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class ForbiddenException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/HostDownException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/HostDownException.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ae762b6108d17fd003006c363133342946745f7
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/HostDownException.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class HostDownException extends ConnectException {
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b17f1a4de601af2093971d66b98ef5c0dbe9a34
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class InvalidHostException extends ConnectException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidRequestException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidRequestException.php
new file mode 100644
index 0000000000000000000000000000000000000000..0dccd8b909e454833b47d4376a5790ef7ddbe67c
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidRequestException.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class InvalidRequestException extends Exception {
+	/**
+	 * @var string
+	 */
+	protected $path;
+
+	/**
+	 * @param string $path
+	 * @param int $code
+	 */
+	public function __construct($path, $code = 0) {
+		parent::__construct('Invalid request for ' . $path, $code);
+		$this->path = $path;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getPath() {
+		return $this->path;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php
new file mode 100644
index 0000000000000000000000000000000000000000..63b79305ad42693db82577ad81a80e42025de78c
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class InvalidTypeException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NoRouteToHostException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoRouteToHostException.php
new file mode 100644
index 0000000000000000000000000000000000000000..03daf36d610a3f085a0685d3e48cbd98cfb2bdfc
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoRouteToHostException.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class NoRouteToHostException extends ConnectException {
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php
new file mode 100644
index 0000000000000000000000000000000000000000..789a76bcb9ee90dd665f6fd687577df289bd6c01
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class NotEmptyException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ce97cd535b912d73722950f5fb1430a830fcc8d
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class NotFoundException extends InvalidRequestException {}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/TimedOutException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/TimedOutException.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd57c9b8ccc18d31fe1f843ec1d35cb334510697
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/TimedOutException.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Exception;
+
+class TimedOutException extends ConnectException {
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/FileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/FileInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef9121a8f57ec71b719828262111fb7be2db94d2
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/FileInfo.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+class FileInfo implements IFileInfo {
+	/*
+	 * Mappings of the DOS mode bits, as returned by smbc_getxattr() when the
+	 * attribute name "system.dos_attr.mode" (or "system.dos_attr.*" or
+	 * "system.*") is specified.
+	 */
+	const MODE_READONLY = 0x01;
+	const MODE_HIDDEN = 0x02;
+	const MODE_SYSTEM = 0x04;
+	const MODE_VOLUME_ID = 0x08;
+	const MODE_DIRECTORY = 0x10;
+	const MODE_ARCHIVE = 0x20;
+	const MODE_NORMAL = 0x80;
+
+	/**
+	 * @var string
+	 */
+	protected $path;
+
+	/**
+	 * @var string
+	 */
+	protected $name;
+
+	/**
+	 * @var int
+	 */
+	protected $size;
+
+	/**
+	 * @var int
+	 */
+	protected $time;
+
+	/**
+	 * @var int
+	 */
+	protected $mode;
+
+	/**
+	 * @param string $path
+	 * @param string $name
+	 * @param int $size
+	 * @param int $time
+	 * @param int $mode
+	 */
+	public function __construct($path, $name, $size, $time, $mode) {
+		$this->path = $path;
+		$this->name = $name;
+		$this->size = $size;
+		$this->time = $time;
+		$this->mode = $mode;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getPath() {
+		return $this->path;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getName() {
+		return $this->name;
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getSize() {
+		return $this->size;
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getMTime() {
+		return $this->time;
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isDirectory() {
+		return (bool)($this->mode & self::MODE_DIRECTORY);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isReadOnly() {
+		return (bool)($this->mode & self::MODE_READONLY);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isHidden() {
+		return (bool)($this->mode & self::MODE_HIDDEN);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isSystem() {
+		return (bool)($this->mode & self::MODE_SYSTEM);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isArchived() {
+		return (bool)($this->mode & self::MODE_ARCHIVE);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/IFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/IFileInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..16ea8cfbd048051f6a0dfe7b0fbf6619ce627839
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/IFileInfo.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+interface IFileInfo {
+	/**
+	 * @return string
+	 */
+	public function getPath();
+
+	/**
+	 * @return string
+	 */
+	public function getName();
+
+	/**
+	 * @return int
+	 */
+	public function getSize();
+
+	/**
+	 * @return int
+	 */
+	public function getMTime();
+
+	/**
+	 * @return bool
+	 */
+	public function isDirectory();
+
+	/**
+	 * @return bool
+	 */
+	public function isReadOnly();
+
+	/**
+	 * @return bool
+	 */
+	public function isHidden();
+
+	/**
+	 * @return bool
+	 */
+	public function isSystem();
+
+	/**
+	 * @return bool
+	 */
+	public function isArchived();
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/IShare.php b/apps/files_external/3rdparty/icewind/smb/src/IShare.php
new file mode 100644
index 0000000000000000000000000000000000000000..4851e9de053ab6f7527def204723313825e38d50
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/IShare.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+interface IShare {
+	/**
+	 * Get the name of the share
+	 *
+	 * @return string
+	 */
+	public function getName();
+
+	/**
+	 * Download a remote file
+	 *
+	 * @param string $source remove file
+	 * @param string $target local file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function get($source, $target);
+
+	/**
+	 * Upload a local file
+	 *
+	 * @param string $source local file
+	 * @param string $target remove file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function put($source, $target);
+
+	/**
+	 * Open a readable stream top a remote file
+	 *
+	 * @param string $source
+	 * @return resource a read only stream with the contents of the remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function read($source);
+
+	/**
+	 * Open a writable stream to a remote file
+	 *
+	 * @param string $target
+	 * @return resource a write only stream to upload a remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function write($target);
+
+	/**
+	 * Rename a remote file
+	 *
+	 * @param string $from
+	 * @param string $to
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function rename($from, $to);
+
+	/**
+	 * Delete a file on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function del($path);
+
+	/**
+	 * List the content of a remote folder
+	 *
+	 * @param $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function dir($path);
+
+	/**
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function stat($path);
+
+	/**
+	 * Create a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function mkdir($path);
+
+	/**
+	 * Remove a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function rmdir($path);
+
+	/**
+	 * @param string $path
+	 * @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
+	 * @return mixed
+	 */
+	public function setMode($path, $mode);
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ef5cf0c5b9d8237dd3829bbd1fdcd8a972866ce
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+class NativeFileInfo implements IFileInfo {
+	const MODE_FILE = 0100000;
+
+	/**
+	 * @var string
+	 */
+	protected $path;
+
+	/**
+	 * @var string
+	 */
+	protected $name;
+
+	/**
+	 * @var \Icewind\SMB\NativeShare
+	 */
+	protected $share;
+
+	/**
+	 * @var array | null
+	 */
+	protected $statCache;
+
+	/**
+	 * @var int
+	 */
+	protected $modeCache;
+
+	/**
+	 * @param \Icewind\SMB\NativeShare $share
+	 * @param string $path
+	 * @param string $name
+	 * @param array $stat
+	 */
+	public function __construct($share, $path, $name, $stat = null) {
+		$this->share = $share;
+		$this->path = $path;
+		$this->name = $name;
+		$this->statCache = $stat;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getPath() {
+		return $this->path;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getName() {
+		return $this->name;
+	}
+
+	/**
+	 * @return array
+	 */
+	protected function stat() {
+		if (!$this->statCache) {
+			$this->statCache = $this->share->getStat($this->getPath());
+		}
+		return $this->statCache;
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getSize() {
+		$stat = $this->stat();
+		return $stat['size'];
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getMTime() {
+		$stat = $this->stat();
+		return $stat['mtime'];
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isDirectory() {
+		$stat = $this->stat();
+		return !($stat['mode'] & self::MODE_FILE);
+	}
+
+	/**
+	 * @return int
+	 */
+	protected function getMode() {
+		if (!$this->modeCache) {
+			$attribute = $this->share->getAttribute($this->path, 'system.dos_attr.mode');
+			// parse hex string
+			$this->modeCache = (int)hexdec(substr($attribute, 2));
+		}
+		return $this->modeCache;
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isReadOnly() {
+		$mode = $this->getMode();
+		return (bool)($mode & FileInfo::MODE_READONLY);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isHidden() {
+		$mode = $this->getMode();
+		return (bool)($mode & FileInfo::MODE_HIDDEN);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isSystem() {
+		$mode = $this->getMode();
+		return (bool)($mode & FileInfo::MODE_SYSTEM);
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function isArchived() {
+		$mode = $this->getMode();
+		return (bool)($mode & FileInfo::MODE_ARCHIVE);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeServer.php b/apps/files_external/3rdparty/icewind/smb/src/NativeServer.php
new file mode 100644
index 0000000000000000000000000000000000000000..4628e3ec10874d83406854fc977258188235056f
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeServer.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+class NativeServer extends Server {
+	/**
+	 * @var \Icewind\SMB\NativeState
+	 */
+	protected $state;
+
+	/**
+	 * @param string $host
+	 * @param string $user
+	 * @param string $password
+	 */
+	public function __construct($host, $user, $password) {
+		parent::__construct($host, $user, $password);
+		$this->state = new NativeState();
+	}
+
+	protected function connect() {
+		$user = $this->getUser();
+		$workgroup = null;
+		if (strpos($user, '/')) {
+			list($workgroup, $user) = explode($user, '/');
+		}
+		$this->state->init($workgroup, $user, $this->getPassword());
+	}
+
+	/**
+	 * @return \Icewind\SMB\IShare[]
+	 * @throws \Icewind\SMB\Exception\AuthenticationException
+	 * @throws \Icewind\SMB\Exception\InvalidHostException
+	 */
+	public function listShares() {
+		$this->connect();
+		$shares = array();
+		$dh = $this->state->opendir('smb://' . $this->getHost());
+		while ($share = $this->state->readdir($dh)) {
+			if ($share['type'] === 'file share') {
+				$shares[] = $this->getShare($share['name']);
+			}
+		}
+		$this->state->closedir($dh);
+		return $shares;
+	}
+
+	/**
+	 * @param string $name
+	 * @return \Icewind\SMB\IShare
+	 */
+	public function getShare($name) {
+		return new NativeShare($this, $name);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php
new file mode 100644
index 0000000000000000000000000000000000000000..c84e96116672579a766a8d72bf29b2511fdfc390
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php
@@ -0,0 +1,288 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+class NativeShare implements IShare {
+	/**
+	 * @var Server $server
+	 */
+	private $server;
+
+	/**
+	 * @var string $name
+	 */
+	private $name;
+
+	/**
+	 * @var \Icewind\SMB\NativeState $state
+	 */
+	private $state;
+
+	/**
+	 * @param Server $server
+	 * @param string $name
+	 */
+	public function __construct($server, $name) {
+		$this->server = $server;
+		$this->name = $name;
+		$this->state = new NativeState();
+	}
+
+	/**
+	 * @throws \Icewind\SMB\Exception\ConnectionException
+	 * @throws \Icewind\SMB\Exception\AuthenticationException
+	 * @throws \Icewind\SMB\Exception\InvalidHostException
+	 */
+	protected function connect() {
+		if ($this->state and $this->state instanceof NativeShare) {
+			return;
+		}
+
+		$user = $this->server->getUser();
+		if (strpos($user, '/')) {
+			list($workgroup, $user) = explode('/', $user);
+		} elseif (strpos($user, '\\')) {
+			list($workgroup, $user) = explode('\\', $user);
+		} else {
+			$workgroup = null;
+		}
+		$this->state->init($workgroup, $user, $this->server->getPassword());
+	}
+
+	/**
+	 * Get the name of the share
+	 *
+	 * @return string
+	 */
+	public function getName() {
+		return $this->name;
+	}
+
+	private function buildUrl($path) {
+		$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
+		if ($path) {
+			$path = trim($path, '/');
+			$url .= '/';
+			$url .= implode('/', array_map('rawurlencode', explode('/', $path)));
+		}
+		return $url;
+	}
+
+	/**
+	 * List the content of a remote folder
+	 *
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function dir($path) {
+		$this->connect();
+		$files = array();
+
+		$dh = $this->state->opendir($this->buildUrl($path));
+		while ($file = $this->state->readdir($dh)) {
+			$name = $file['name'];
+			if ($name !== '.' and $name !== '..') {
+				$files [] = new NativeFileInfo($this, $path . '/' . $name, $name);
+			}
+		}
+
+		$this->state->closedir($dh);
+		return $files;
+	}
+
+	/**
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 */
+	public function stat($path) {
+		return new NativeFileInfo($this, $path, basename($path), $this->getStat($path));
+	}
+
+	public function getStat($path) {
+		$this->connect();
+		return $this->state->stat($this->buildUrl($path));
+	}
+
+	/**
+	 * Create a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function mkdir($path) {
+		$this->connect();
+		return $this->state->mkdir($this->buildUrl($path));
+	}
+
+	/**
+	 * Remove a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function rmdir($path) {
+		$this->connect();
+		return $this->state->rmdir($this->buildUrl($path));
+	}
+
+	/**
+	 * Delete a file on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function del($path) {
+		return $this->state->unlink($this->buildUrl($path));
+	}
+
+	/**
+	 * Rename a remote file
+	 *
+	 * @param string $from
+	 * @param string $to
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function rename($from, $to) {
+		$this->connect();
+		return $this->state->rename($this->buildUrl($from), $this->buildUrl($to));
+	}
+
+	/**
+	 * Upload a local file
+	 *
+	 * @param string $source local file
+	 * @param string $target remove file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function put($source, $target) {
+		$this->connect();
+		$sourceHandle = fopen($source, 'rb');
+		$targetHandle = $this->state->create($this->buildUrl($target));
+
+		while ($data = fread($sourceHandle, 4096)) {
+			$this->state->write($targetHandle, $data);
+		}
+		$this->state->close($targetHandle);
+		return true;
+	}
+
+	/**
+	 * Download a remote file
+	 *
+	 * @param string $source remove file
+	 * @param string $target local file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function get($source, $target) {
+		$this->connect();
+		$sourceHandle = $this->state->open($this->buildUrl($source), 'r');
+		$targetHandle = fopen($target, 'wb');
+
+		while ($data = $this->state->read($sourceHandle, 4096)) {
+			fwrite($targetHandle, $data);
+		}
+		$this->state->close($sourceHandle);
+		return true;
+	}
+
+	/**
+	 * Open a readable stream top a remote file
+	 *
+	 * @param string $source
+	 * @return resource a read only stream with the contents of the remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function read($source) {
+		$this->connect();
+		$handle = $this->state->open($this->buildUrl($source), 'r');
+		return NativeStream::wrap($this->state, $handle, 'r');
+	}
+
+	/**
+	 * Open a readable stream top a remote file
+	 *
+	 * @param string $source
+	 * @return resource a read only stream with the contents of the remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function write($source) {
+		$this->connect();
+		$handle = $this->state->create($this->buildUrl($source));
+		return NativeStream::wrap($this->state, $handle, 'w');
+	}
+
+	/**
+	 * Get extended attributes for the path
+	 *
+	 * @param string $path
+	 * @param string $attribute attribute to get the info
+	 * @return string the attribute value
+	 */
+	public function getAttribute($path, $attribute) {
+		$this->connect();
+
+		$result = $this->state->getxattr($this->buildUrl($path), $attribute);
+		return $result;
+	}
+
+	/**
+	 * Get extended attributes for the path
+	 *
+	 * @param string $path
+	 * @param string $attribute attribute to get the info
+	 * @param mixed $value
+	 * @return string the attribute value
+	 */
+	public function setAttribute($path, $attribute, $value) {
+		$this->connect();
+
+		if ($attribute === 'system.dos_attr.mode' and is_int($value)) {
+			$value = '0x' . dechex($value);
+		}
+
+		return $this->state->setxattr($this->buildUrl($path), $attribute, $value);
+	}
+
+	/**
+	 * @param string $path
+	 * @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
+	 * @return mixed
+	 */
+	public function setMode($path, $mode) {
+		return $this->setAttribute($path, 'system.dos_attr.mode', $mode);
+	}
+
+	public function __destruct() {
+		unset($this->state);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeState.php b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3e344d9e01d15bfcf14e3e05074290d6b63d23e
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php
@@ -0,0 +1,308 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\AlreadyExistsException;
+use Icewind\SMB\Exception\ConnectionRefusedException;
+use Icewind\SMB\Exception\Exception;
+use Icewind\SMB\Exception\ForbiddenException;
+use Icewind\SMB\Exception\HostDownException;
+use Icewind\SMB\Exception\InvalidTypeException;
+use Icewind\SMB\Exception\NoRouteToHostException;
+use Icewind\SMB\Exception\NotEmptyException;
+use Icewind\SMB\Exception\NotFoundException;
+use Icewind\SMB\Exception\TimedOutException;
+
+/**
+ * Low level wrapper for libsmbclient-php for error handling
+ */
+class NativeState {
+	/**
+	 * @var resource
+	 */
+	protected $state;
+
+	protected $handlerSet = false;
+
+	protected $connected = false;
+
+	protected function handleError($path) {
+		$error = smbclient_state_errno($this->state);
+		switch ($error) {
+			// see error.h
+			case 0;
+				return;
+			case 1:
+			case 13:
+				throw new ForbiddenException($path, $error);
+			case 2:
+				throw new NotFoundException($path, $error);
+			case 17:
+				throw new AlreadyExistsException($path, $error);
+			case 20:
+				throw new InvalidTypeException($path, $error);
+			case 21:
+				throw new InvalidTypeException($path, $error);
+			case 39:
+				throw new NotEmptyException($path, $error);
+			case 110:
+				throw new TimedOutException($path, $error);
+			case 111:
+				throw new ConnectionRefusedException($path, $error);
+			case 112:
+				throw new HostDownException($path, $error);
+			case 113:
+				throw new NoRouteToHostException($path, $error);
+			default:
+				$message = 'Unknown error (' . $error . ')';
+				if ($path) {
+					$message .= ' for ' . $path;
+				}
+				throw new Exception($message, $error);
+		}
+	}
+
+	protected function testResult($result, $path) {
+		if ($result === false or $result === null) {
+			$this->handleError($path);
+		}
+	}
+
+	/**
+	 * @param string $workGroup
+	 * @param string $user
+	 * @param string $password
+	 * @return bool
+	 */
+	public function init($workGroup, $user, $password) {
+		if ($this->connected) {
+			return true;
+		}
+		$this->state = smbclient_state_new();
+		$result = @smbclient_state_init($this->state, $workGroup, $user, $password);
+
+		$this->testResult($result, '');
+		$this->connected = true;
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @return resource
+	 */
+	public function opendir($uri) {
+		$result = @smbclient_opendir($this->state, $uri);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param resource $dir
+	 * @return array
+	 */
+	public function readdir($dir) {
+		$result = @smbclient_readdir($this->state, $dir);
+
+		$this->testResult($result, $dir);
+		return $result;
+	}
+
+	/**
+	 * @param $dir
+	 * @return bool
+	 */
+	public function closedir($dir) {
+		$result = smbclient_closedir($this->state, $dir);
+
+		$this->testResult($result, $dir);
+		return $result;
+	}
+
+	/**
+	 * @param string $old
+	 * @param string $new
+	 * @return bool
+	 */
+	public function rename($old, $new) {
+		$result = @smbclient_rename($this->state, $old, $this->state, $new);
+
+		$this->testResult($result, $new);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @return bool
+	 */
+	public function unlink($uri) {
+		$result = @smbclient_unlink($this->state, $uri);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @param int $mask
+	 * @return bool
+	 */
+	public function mkdir($uri, $mask = 0777) {
+		$result = @smbclient_mkdir($this->state, $uri, $mask);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @return bool
+	 */
+	public function rmdir($uri) {
+		$result = @smbclient_rmdir($this->state, $uri);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @return array
+	 */
+	public function stat($uri) {
+		$result = @smbclient_stat($this->state, $uri);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param resource $file
+	 * @return array
+	 */
+	public function fstat($file) {
+		$result = @smbclient_fstat($this->state, $file);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @param string $mode
+	 * @param int $mask
+	 * @return resource
+	 */
+	public function open($uri, $mode, $mask = 0666) {
+		$result = @smbclient_open($this->state, $uri, $mode, $mask);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @param int $mask
+	 * @return resource
+	 */
+	public function create($uri, $mask = 0666) {
+		$result = @smbclient_creat($this->state, $uri, $mask);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param resource $file
+	 * @param int $bytes
+	 * @return string
+	 */
+	public function read($file, $bytes) {
+		$result = @smbclient_read($this->state, $file, $bytes);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	/**
+	 * @param resource $file
+	 * @param string $data
+	 * @param int $length
+	 * @return int
+	 */
+	public function write($file, $data, $length = null) {
+		$result = @smbclient_write($this->state, $file, $data, $length);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	/**
+	 * @param resource $file
+	 * @param int $offset
+	 * @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
+	 * @return int | bool new file offset as measured from the start of the file on success, false on failure.
+	 */
+	public function lseek($file, $offset, $whence = SEEK_SET) {
+		$result = @smbclient_lseek($this->state, $file, $offset, $whence);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	/**
+	 * @param resource $file
+	 * @param int $size
+	 * @return bool
+	 */
+	public function ftruncate($file, $size) {
+		$result = @smbclient_ftruncate($this->state, $file, $size);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	public function close($file) {
+		$result = @smbclient_close($this->state, $file);
+
+		$this->testResult($result, $file);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @param string $key
+	 * @return string
+	 */
+	public function getxattr($uri, $key) {
+		$result = @smbclient_getxattr($this->state, $uri, $key);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	/**
+	 * @param string $uri
+	 * @param string $key
+	 * @param string $value
+	 * @param int $flags
+	 * @return mixed
+	 */
+	public function setxattr($uri, $key, $value, $flags = 0) {
+		$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
+
+		$this->testResult($result, $uri);
+		return $result;
+	}
+
+	public function __destruct() {
+		if ($this->connected) {
+			smbclient_state_free($this->state);
+		}
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..07bd2f1e7978fee2816f25086df58a47e24bb6e9
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\InvalidRequestException;
+use Icewind\Streams\File;
+
+class NativeStream implements File {
+	/**
+	 * @var resource
+	 */
+	public $context;
+
+	/**
+	 * @var \Icewind\SMB\NativeState
+	 */
+	private $state;
+
+	/**
+	 * @var resource
+	 */
+	private $handle;
+
+	/**
+	 * @var bool
+	 */
+	private $eof = false;
+
+	/**
+	 * Wrap a stream from libsmbclient-php into a regular php stream
+	 *
+	 * @param \Icewind\SMB\NativeState $state
+	 * @param resource $smbStream
+	 * @param string $mode
+	 * @return resource
+	 */
+	public static function wrap($state, $smbStream, $mode) {
+		stream_wrapper_register('nativesmb', '\Icewind\SMB\NativeStream');
+		$context = stream_context_create(array(
+			'nativesmb' => array(
+				'state' => $state,
+				'handle' => $smbStream
+			)
+		));
+		$fh = fopen('nativesmb://', $mode, false, $context);
+		stream_wrapper_unregister('nativesmb');
+		return $fh;
+	}
+
+	public function stream_close() {
+		return $this->state->close($this->handle);
+	}
+
+	public function stream_eof() {
+		return $this->eof;
+	}
+
+	public function stream_flush() {
+	}
+
+
+	public function stream_open($path, $mode, $options, &$opened_path) {
+		$context = stream_context_get_options($this->context);
+		$this->state = $context['nativesmb']['state'];
+		$this->handle = $context['nativesmb']['handle'];
+		return true;
+	}
+
+	public function stream_read($count) {
+		$result = $this->state->read($this->handle, $count);
+		if (strlen($result) < $count) {
+			$this->eof = true;
+		}
+		return $result;
+	}
+
+	public function stream_seek($offset, $whence = SEEK_SET) {
+		$this->eof = false;
+		try {
+			return $this->state->lseek($this->handle, $offset, $whence) !== false;
+		} catch (InvalidRequestException $e) {
+			return false;
+		}
+	}
+
+	public function stream_stat() {
+		return $this->state->fstat($this->handle);
+	}
+
+	public function stream_tell() {
+		return $this->state->lseek($this->handle, 0, SEEK_CUR);
+	}
+
+	public function stream_write($data) {
+		return $this->state->write($this->handle, $data);
+	}
+
+	public function stream_truncate($size) {
+		return $this->state->ftruncate($this->handle, $size);
+	}
+
+	public function stream_set_option($option, $arg1, $arg2) {
+		return false;
+	}
+
+	public function stream_lock($operation) {
+		return false;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Parser.php b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
new file mode 100644
index 0000000000000000000000000000000000000000..645678d9855444209113ada96903ed49db606707
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\AccessDeniedException;
+use Icewind\SMB\Exception\AlreadyExistsException;
+use Icewind\SMB\Exception\Exception;
+use Icewind\SMB\Exception\FileInUseException;
+use Icewind\SMB\Exception\InvalidTypeException;
+use Icewind\SMB\Exception\NotEmptyException;
+use Icewind\SMB\Exception\NotFoundException;
+
+class Parser {
+	/**
+	 * @var string
+	 */
+	protected $timeZone;
+
+	/**
+	 * @param string $timeZone
+	 */
+	public function __construct($timeZone) {
+		$this->timeZone = $timeZone;
+	}
+
+	public function checkForError($output, $path) {
+		if (count($output) === 0) {
+			return true;
+		} else {
+			if (strpos($output[0], 'does not exist')) {
+				throw new NotFoundException($path);
+			}
+			$parts = explode(' ', $output[0]);
+			$error = false;
+			foreach ($parts as $part) {
+				if (substr($part, 0, 9) === 'NT_STATUS') {
+					$error = $part;
+				}
+			}
+			switch ($error) {
+				case ErrorCodes::PathNotFound:
+				case ErrorCodes::ObjectNotFound:
+				case ErrorCodes::NoSuchFile:
+					throw new NotFoundException($path);
+				case ErrorCodes::NameCollision:
+					throw new AlreadyExistsException($path);
+				case ErrorCodes::AccessDenied:
+					throw new AccessDeniedException($path);
+				case ErrorCodes::DirectoryNotEmpty:
+					throw new NotEmptyException($path);
+				case ErrorCodes::FileIsADirectory:
+				case ErrorCodes::NotADirectory:
+					throw new InvalidTypeException($path);
+				case ErrorCodes::SharingViolation:
+					throw new FileInUseException($path);
+				default:
+					$message = 'Unknown error (' . $error . ')';
+					if ($path) {
+						$message .= ' for ' . $path;
+					}
+					throw new Exception($message);
+			}
+		}
+	}
+
+	public function parseMode($mode) {
+		$result = 0;
+		$modeStrings = array(
+			'R' => FileInfo::MODE_READONLY,
+			'H' => FileInfo::MODE_HIDDEN,
+			'S' => FileInfo::MODE_SYSTEM,
+			'D' => FileInfo::MODE_DIRECTORY,
+			'A' => FileInfo::MODE_ARCHIVE,
+			'N' => FileInfo::MODE_NORMAL
+		);
+		foreach ($modeStrings as $char => $val) {
+			if (strpos($mode, $char) !== false) {
+				$result |= $val;
+			}
+		}
+		return $result;
+	}
+
+	public function parseStat($output) {
+		$mtime = 0;
+		$mode = 0;
+		$size = 0;
+		foreach ($output as $line) {
+			list($name, $value) = explode(':', $line, 2);
+			$value = trim($value);
+			if ($name === 'write_time') {
+				$mtime = strtotime($value);
+			} else if ($name === 'attributes') {
+				$mode = hexdec(substr($value, 1, -1));
+			} else if ($name === 'stream') {
+				list(, $size,) = explode(' ', $value);
+				$size = intval($size);
+			}
+		}
+		return array(
+			'mtime' => $mtime,
+			'mode' => $mode,
+			'size' => $size
+		);
+	}
+
+	public function parseDir($output, $basePath) {
+		//last line is used space
+		array_pop($output);
+		$regex = '/^\s*(.*?)\s\s\s\s+(?:([NDHARS]*)\s+)?([0-9]+)\s+(.*)$/';
+		//2 spaces, filename, optional type, size, date
+		$content = array();
+		foreach ($output as $line) {
+			if (preg_match($regex, $line, $matches)) {
+				list(, $name, $mode, $size, $time) = $matches;
+				if ($name !== '.' and $name !== '..') {
+					$mode = $this->parseMode($mode);
+					$time = strtotime($time . ' ' . $this->timeZone);
+					$content[] = new FileInfo($basePath . '/' . $name, $name, $size, $time, $mode);
+				}
+			}
+		}
+		return $content;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php
new file mode 100644
index 0000000000000000000000000000000000000000..926ce3714cfea902c39bc4444b17f279a6b5efb7
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\ConnectionException;
+
+class RawConnection {
+	/**
+	 * @var string
+	 */
+	private $command;
+
+	/**
+	 * @var string[]
+	 */
+	private $env;
+
+	/**
+	 * @var resource[] $pipes
+	 *
+	 * $pipes[0] holds STDIN for smbclient
+	 * $pipes[1] holds STDOUT for smbclient
+	 */
+	private $pipes;
+
+	/**
+	 * @var resource $process
+	 */
+	private $process;
+
+	public function __construct($command, $env = array()) {
+		$this->command = $command;
+		$this->env = $env;
+		$this->connect();
+	}
+
+	private function connect() {
+		$descriptorSpec = array(
+			0 => array('pipe', 'r'), // child reads from stdin
+			1 => array('pipe', 'w'), // child writes to stdout
+			2 => array('pipe', 'w'), // child writes to stderr
+			3 => array('pipe', 'r'), // child reads from fd#3
+			4 => array('pipe', 'r'), // child reads from fd#4
+			5 => array('pipe', 'w')  // child writes to fd#5
+		);
+		setlocale(LC_ALL, Server::LOCALE);
+		$env = array_merge($this->env, array(
+			'CLI_FORCE_INTERACTIVE' => 'y', // Needed or the prompt isn't displayed!!
+			'LC_ALL' => Server::LOCALE,
+			'LANG' => Server::LOCALE,
+			'COLUMNS' => 8192 // prevent smbclient from line-wrapping it's output
+		));
+		$this->process = proc_open($this->command, $descriptorSpec, $this->pipes, '/', $env);
+		if (!$this->isValid()) {
+			throw new ConnectionException();
+		}
+	}
+
+	/**
+	 * check if the connection is still active
+	 *
+	 * @return bool
+	 */
+	public function isValid() {
+		if (is_resource($this->process)) {
+			$status = proc_get_status($this->process);
+			return $status['running'];
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * send input to the process
+	 *
+	 * @param string $input
+	 */
+	public function write($input) {
+		fwrite($this->getInputStream(), $input);
+		fflush($this->getInputStream());
+	}
+
+	/**
+	 * read a line of output
+	 *
+	 * @return string
+	 */
+	public function readLine() {
+		return stream_get_line($this->getOutputStream(), 4086, "\n");
+	}
+
+	/**
+	 * get all output until the process closes
+	 *
+	 * @return array
+	 */
+	public function readAll() {
+		$output = array();
+		while ($line = $this->readLine()) {
+			$output[] = $line;
+		}
+		return $output;
+	}
+
+	public function getInputStream() {
+		return $this->pipes[0];
+	}
+
+	public function getOutputStream() {
+		return $this->pipes[1];
+	}
+
+	public function getErrorStream() {
+		return $this->pipes[2];
+	}
+
+	public function getAuthStream() {
+		return $this->pipes[3];
+	}
+
+	public function getFileInputStream() {
+		return $this->pipes[4];
+	}
+
+	public function getFileOutputStream() {
+		return $this->pipes[5];
+	}
+
+	public function writeAuthentication($user, $password) {
+		$auth = ($password === false)
+			? "username=$user"
+			: "username=$user\npassword=$password";
+
+		if (fwrite($this->getAuthStream(), $auth) === false) {
+			fclose($this->getAuthStream());
+			return false;
+		}
+		fclose($this->getAuthStream());
+		return true;
+	}
+
+	public function close($terminate = true) {
+		if (!is_resource($this->process)) {
+			return;
+		}
+		if ($terminate) {
+			proc_terminate($this->process);
+		}
+		proc_close($this->process);
+	}
+
+	public function reconnect() {
+		$this->close();
+		$this->connect();
+	}
+
+	public function __destruct() {
+		$this->close();
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Server.php b/apps/files_external/3rdparty/icewind/smb/src/Server.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7227d4baef342a3405416e17879de8114fbf1c1
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Server.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\AuthenticationException;
+use Icewind\SMB\Exception\InvalidHostException;
+
+class Server {
+	const CLIENT = 'smbclient';
+	const LOCALE = 'en_US.UTF-8';
+
+	/**
+	 * @var string $host
+	 */
+	protected $host;
+
+	/**
+	 * @var string $user
+	 */
+	protected $user;
+
+	/**
+	 * @var string $password
+	 */
+	protected $password;
+
+	/**
+	 * Check if the smbclient php extension is available
+	 *
+	 * @return bool
+	 */
+	public static function NativeAvailable() {
+		return function_exists('smbclient_state_new');
+	}
+
+	/**
+	 * @param string $host
+	 * @param string $user
+	 * @param string $password
+	 */
+	public function __construct($host, $user, $password) {
+		$this->host = $host;
+		$this->user = $user;
+		$this->password = $password;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getAuthString() {
+		return $this->user . '%' . $this->password;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getUser() {
+		return $this->user;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getPassword() {
+		return $this->password;
+	}
+
+	/**
+	 * return string
+	 */
+	public function getHost() {
+		return $this->host;
+	}
+
+	/**
+	 * @return \Icewind\SMB\IShare[]
+	 *
+	 * @throws \Icewind\SMB\Exception\AuthenticationException
+	 * @throws \Icewind\SMB\Exception\InvalidHostException
+	 */
+	public function listShares() {
+		$command = Server::CLIENT . ' --authentication-file=/proc/self/fd/3' .
+			' -gL ' . escapeshellarg($this->getHost());
+		$connection = new RawConnection($command);
+		$connection->writeAuthentication($this->getUser(), $this->getPassword());
+		$output = $connection->readAll();
+
+		$line = $output[0];
+
+		$line = rtrim($line, ')');
+		if (substr($line, -23) === ErrorCodes::LogonFailure) {
+			throw new AuthenticationException();
+		}
+		if (substr($line, -26) === ErrorCodes::BadHostName) {
+			throw new InvalidHostException();
+		}
+		if (substr($line, -22) === ErrorCodes::Unsuccessful) {
+			throw new InvalidHostException();
+		}
+		if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
+			throw new InvalidHostException();
+		}
+
+		$shareNames = array();
+		foreach ($output as $line) {
+			if (strpos($line, '|')) {
+				list($type, $name, $description) = explode('|', $line);
+				if (strtolower($type) === 'disk') {
+					$shareNames[$name] = $description;
+				}
+			}
+		}
+
+		$shares = array();
+		foreach ($shareNames as $name => $description) {
+			$shares[] = $this->getShare($name);
+		}
+		return $shares;
+	}
+
+	/**
+	 * @param string $name
+	 * @return \Icewind\SMB\IShare
+	 */
+	public function getShare($name) {
+		return new Share($this, $name);
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getTimeZone() {
+		$command = 'net time zone -S ' . escapeshellarg($this->getHost());
+		return exec($command);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Share.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c48b1702fa8b6bacc9bc712eb4cef05ba470237
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/src/Share.php
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB;
+
+use Icewind\SMB\Exception\AccessDeniedException;
+use Icewind\SMB\Exception\AlreadyExistsException;
+use Icewind\SMB\Exception\ConnectionException;
+use Icewind\SMB\Exception\Exception;
+use Icewind\SMB\Exception\FileInUseException;
+use Icewind\SMB\Exception\InvalidTypeException;
+use Icewind\SMB\Exception\NotEmptyException;
+use Icewind\SMB\Exception\NotFoundException;
+use Icewind\Streams\CallbackWrapper;
+
+class Share implements IShare {
+	/**
+	 * @var Server $server
+	 */
+	private $server;
+
+	/**
+	 * @var string $name
+	 */
+	private $name;
+
+	/**
+	 * @var Connection $connection
+	 */
+	public $connection;
+
+	/**
+	 * @var \Icewind\SMB\Parser
+	 */
+	protected $parser;
+
+	private $serverTimezone;
+
+	/**
+	 * @param Server $server
+	 * @param string $name
+	 */
+	public function __construct($server, $name) {
+		$this->server = $server;
+		$this->name = $name;
+		$this->parser = new Parser($this->server->getTimeZone());
+	}
+
+	/**
+	 * @throws \Icewind\SMB\Exception\ConnectionException
+	 * @throws \Icewind\SMB\Exception\AuthenticationException
+	 * @throws \Icewind\SMB\Exception\InvalidHostException
+	 */
+	protected function connect() {
+		if ($this->connection and $this->connection->isValid()) {
+			return;
+		}
+		$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s',
+			Server::CLIENT,
+			$this->server->getHost(),
+			$this->name
+		);
+		$this->connection = new Connection($command);
+		$this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
+		if (!$this->connection->isValid()) {
+			throw new ConnectionException();
+		}
+	}
+
+	protected function reconnect() {
+		$this->connection->reconnect();
+		$this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
+		if (!$this->connection->isValid()) {
+			throw new ConnectionException();
+		}
+	}
+
+	/**
+	 * Get the name of the share
+	 *
+	 * @return string
+	 */
+	public function getName() {
+		return $this->name;
+	}
+
+	protected function simpleCommand($command, $path) {
+		$path = $this->escapePath($path);
+		$cmd = $command . ' ' . $path;
+		$output = $this->execute($cmd);
+		return $this->parseOutput($output, $path);
+	}
+
+	/**
+	 * List the content of a remote folder
+	 *
+	 * @param $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function dir($path) {
+		$escapedPath = $this->escapePath($path);
+		$output = $this->execute('cd ' . $escapedPath);
+		//check output for errors
+		$this->parseOutput($output, $path);
+		$output = $this->execute('dir');
+		$this->execute('cd /');
+
+		return $this->parser->parseDir($output, $path);
+	}
+
+	/**
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 */
+	public function stat($path) {
+		$escapedPath = $this->escapePath($path);
+		$output = $this->execute('allinfo ' . $escapedPath);
+		if (count($output) < 3) {
+			$this->parseOutput($output, $path);
+		}
+		$stat = $this->parser->parseStat($output);
+		return new FileInfo($path, basename($path), $stat['size'], $stat['mtime'], $stat['mode']);
+	}
+
+	/**
+	 * Create a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function mkdir($path) {
+		return $this->simpleCommand('mkdir', $path);
+	}
+
+	/**
+	 * Remove a folder on the share
+	 *
+	 * @param string $path
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function rmdir($path) {
+		return $this->simpleCommand('rmdir', $path);
+	}
+
+	/**
+	 * Delete a file on the share
+	 *
+	 * @param string $path
+	 * @param bool $secondTry
+	 * @return bool
+	 * @throws InvalidTypeException
+	 * @throws NotFoundException
+	 * @throws \Exception
+	 */
+	public function del($path, $secondTry = false) {
+		//del return a file not found error when trying to delete a folder
+		//we catch it so we can check if $path doesn't exist or is of invalid type
+		try {
+			return $this->simpleCommand('del', $path);
+		} catch (NotFoundException $e) {
+			//no need to do anything with the result, we just check if this throws the not found error
+			try {
+				$this->simpleCommand('ls', $path);
+			} catch (NotFoundException $e2) {
+				throw $e;
+			} catch (\Exception $e2) {
+				throw new InvalidTypeException($path);
+			}
+			throw $e;
+		} catch (FileInUseException $e) {
+			if ($secondTry) {
+				throw $e;
+			}
+			$this->reconnect();
+			return $this->del($path, true);
+		}
+	}
+
+	/**
+	 * Rename a remote file
+	 *
+	 * @param string $from
+	 * @param string $to
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function rename($from, $to) {
+		$path1 = $this->escapePath($from);
+		$path2 = $this->escapePath($to);
+		$cmd = 'rename ' . $path1 . ' ' . $path2;
+		$output = $this->execute($cmd);
+		return $this->parseOutput($output, $to);
+	}
+
+	/**
+	 * Upload a local file
+	 *
+	 * @param string $source local file
+	 * @param string $target remove file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function put($source, $target) {
+		$path1 = $this->escapeLocalPath($source); //first path is local, needs different escaping
+		$path2 = $this->escapePath($target);
+		$output = $this->execute('put ' . $path1 . ' ' . $path2);
+		return $this->parseOutput($output, $target);
+	}
+
+	/**
+	 * Download a remote file
+	 *
+	 * @param string $source remove file
+	 * @param string $target local file
+	 * @return bool
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function get($source, $target) {
+		$path1 = $this->escapePath($source);
+		$path2 = $this->escapeLocalPath($target); //second path is local, needs different escaping
+		$output = $this->execute('get ' . $path1 . ' ' . $path2);
+		return $this->parseOutput($output, $source);
+	}
+
+	/**
+	 * Open a readable stream to a remote file
+	 *
+	 * @param string $source
+	 * @return resource a read only stream with the contents of the remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function read($source) {
+		$source = $this->escapePath($source);
+		// close the single quote, open a double quote where we put the single quote...
+		$source = str_replace('\'', '\'"\'"\'', $source);
+		// since returned stream is closed by the caller we need to create a new instance
+		// since we can't re-use the same file descriptor over multiple calls
+		$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s -c \'get %s /proc/self/fd/5\'',
+			Server::CLIENT,
+			$this->server->getHost(),
+			$this->name,
+			$source
+		);
+		$connection = new Connection($command);
+		$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
+		$fh = $connection->getFileOutputStream();
+		stream_context_set_option($fh, 'file', 'connection', $connection);
+		return $fh;
+	}
+
+	/**
+	 * Open a writable stream to a remote file
+	 *
+	 * @param string $target
+	 * @return resource a write only stream to upload a remote file
+	 *
+	 * @throws \Icewind\SMB\Exception\NotFoundException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function write($target) {
+		$target = $this->escapePath($target);
+		// close the single quote, open a double quote where we put the single quote...
+		$target = str_replace('\'', '\'"\'"\'', $target);
+		// since returned stream is closed by the caller we need to create a new instance
+		// since we can't re-use the same file descriptor over multiple calls
+		$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s -c \'put /proc/self/fd/4 %s\'',
+			Server::CLIENT,
+			$this->server->getHost(),
+			$this->name,
+			$target
+		);
+		$connection = new RawConnection($command);
+		$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
+		$fh = $connection->getFileInputStream();
+
+		// use a close callback to ensure the upload is finished before continuing
+		// this also serves as a way to keep the connection in scope
+		return CallbackWrapper::wrap($fh, null, null, function () use ($connection) {
+			$connection->close(false); // dont terminate, give the upload some time
+		});
+	}
+
+	/**
+	 * @param string $path
+	 * @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
+	 * @return mixed
+	 */
+	public function setMode($path, $mode) {
+		$modeString = '';
+		$modeMap = array(
+			FileInfo::MODE_READONLY => 'r',
+			FileInfo::MODE_HIDDEN => 'h',
+			FileInfo::MODE_ARCHIVE => 'a',
+			FileInfo::MODE_SYSTEM => 's'
+		);
+		foreach ($modeMap as $modeByte => $string) {
+			if ($mode & $modeByte) {
+				$modeString .= $string;
+			}
+		}
+		$path = $this->escapePath($path);
+
+		// first reset the mode to normal
+		$cmd = 'setmode ' . $path . ' -rsha';
+		$output = $this->execute($cmd);
+		$this->parseOutput($output, $path);
+
+		// then set the modes we want
+		$cmd = 'setmode ' . $path . ' ' . $modeString;
+		$output = $this->execute($cmd);
+		return $this->parseOutput($output, $path);
+	}
+
+	/**
+	 * @param string $command
+	 * @return array
+	 */
+	protected function execute($command) {
+		$this->connect();
+		$this->connection->write($command . PHP_EOL);
+		$output = $this->connection->read();
+		return $output;
+	}
+
+	/**
+	 * check output for errors
+	 *
+	 * @param string[] $lines
+	 * @param string $path
+	 *
+	 * @throws NotFoundException
+	 * @throws \Icewind\SMB\Exception\AlreadyExistsException
+	 * @throws \Icewind\SMB\Exception\AccessDeniedException
+	 * @throws \Icewind\SMB\Exception\NotEmptyException
+	 * @throws \Icewind\SMB\Exception\InvalidTypeException
+	 * @throws \Icewind\SMB\Exception\Exception
+	 * @return bool
+	 */
+	protected function parseOutput($lines, $path = '') {
+		$this->parser->checkForError($lines, $path);
+	}
+
+	/**
+	 * @param string $string
+	 * @return string
+	 */
+	protected function escape($string) {
+		return escapeshellarg($string);
+	}
+
+	/**
+	 * @param string $path
+	 * @return string
+	 */
+	protected function escapePath($path) {
+		$path = str_replace('/', '\\', $path);
+		$path = str_replace('"', '^"', $path);
+		return '"' . $path . '"';
+	}
+
+	/**
+	 * @param string $path
+	 * @return string
+	 */
+	protected function escapeLocalPath($path) {
+		$path = str_replace('"', '\"', $path);
+		return '"' . $path . '"';
+	}
+
+	public function __destruct() {
+		unset($this->connection);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/AbstractShare.php b/apps/files_external/3rdparty/icewind/smb/tests/AbstractShare.php
new file mode 100644
index 0000000000000000000000000000000000000000..117fff1ca196efb2e0944cb6fe5a0febde565e83
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/AbstractShare.php
@@ -0,0 +1,534 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+use Icewind\SMB\FileInfo;
+
+abstract class AbstractShare extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \Icewind\SMB\Server $server
+	 */
+	protected $server;
+
+	/**
+	 * @var \Icewind\SMB\IShare $share
+	 */
+	protected $share;
+
+	/**
+	 * @var string $root
+	 */
+	protected $root;
+
+	protected $config;
+
+	public function tearDown() {
+		try {
+			if ($this->share) {
+				$this->cleanDir($this->root);
+			}
+			unset($this->share);
+		} catch (\Exception $e) {
+			unset($this->share);
+			throw $e;
+		}
+	}
+
+	public function nameProvider() {
+		// / ? < > \ : * | " are illegal characters in path on windows
+		return array(
+			array('simple'),
+			array('with spaces_and-underscores'),
+			array("single'quote'"),
+			array('日本語'),
+			array('url %2F +encode'),
+			array('a somewhat longer filename than the other with more charaters as the all the other filenames'),
+			array('$as#d€££Ö€ßœĚęĘĞĜΣΥΦΩΫ')
+		);
+	}
+
+	public function fileDataProvider() {
+		return array(
+			array('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'),
+			array('Mixed language, 日本語 が わからか and Various _/* characters \\|” €')
+		);
+	}
+
+	public function nameAndDataProvider() {
+		$names = $this->nameProvider();
+		$data = $this->fileDataProvider();
+		$result = array();
+		foreach ($names as $name) {
+			foreach ($data as $text) {
+				$result[] = array($name[0], $text[0]);
+			}
+		}
+		return $result;
+	}
+
+	public function cleanDir($dir) {
+		$content = $this->share->dir($dir);
+		foreach ($content as $metadata) {
+			if ($metadata->isDirectory()) {
+				$this->cleanDir($metadata->getPath());
+			} else {
+				$this->share->del($metadata->getPath());
+			}
+		}
+		$this->share->rmdir($dir);
+	}
+
+	private function getTextFile($text = '') {
+		if (!$text) {
+			$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';
+		}
+		$file = tempnam('/tmp', 'smb_test_');
+		file_put_contents($file, $text);
+		return $file;
+	}
+
+	public function testListShares() {
+		$shares = $this->server->listShares();
+		foreach ($shares as $share) {
+			if ($share->getName() === $this->config->share) {
+				return;
+			}
+		}
+		$this->fail('Share "' . $this->config->share . '" not found');
+	}
+
+	public function testRootStartsEmpty() {
+		$this->assertEquals(array(), $this->share->dir($this->root));
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testMkdir($name) {
+		$this->share->mkdir($this->root . '/' . $name);
+		$dirs = $this->share->dir($this->root);
+		$this->assertCount(1, $dirs);
+		$this->assertEquals($name, $dirs[0]->getName());
+		$this->assertTrue($dirs[0]->isDirectory());
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testRenameDirectory($name) {
+		$this->share->mkdir($this->root . '/' . $name);
+		$this->share->rename($this->root . '/' . $name, $this->root . '/' . $name . '_rename');
+		$dirs = $this->share->dir($this->root);
+		$this->assertEquals(1, count($dirs));
+		$this->assertEquals($name . '_rename', $dirs[0]->getName());
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testRmdir($name) {
+		$this->share->mkdir($this->root . '/' . $name);
+		$this->share->rmdir($this->root . '/' . $name);
+		$this->assertCount(0, $this->share->dir($this->root));
+	}
+
+	/**
+	 * @dataProvider nameAndDataProvider
+	 */
+	public function testPut($name, $text) {
+		$tmpFile = $this->getTextFile($text);
+		$size = filesize($tmpFile);
+
+		$this->share->put($tmpFile, $this->root . '/' . $name);
+		unlink($tmpFile);
+
+		$files = $this->share->dir($this->root);
+		$this->assertCount(1, $files);
+		$this->assertEquals($name, $files[0]->getName());
+		$this->assertEquals($size, $files[0]->getSize());
+		$this->assertFalse($files[0]->isDirectory());
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testRenameFile($name) {
+		$tmpFile = $this->getTextFile();
+
+		$this->share->put($tmpFile, $this->root . '/' . $name);
+		unlink($tmpFile);
+
+		$this->share->rename($this->root . '/' . $name, $this->root . '/' . $name . '_renamed');
+
+		$files = $this->share->dir($this->root);
+		$this->assertEquals(1, count($files));
+		$this->assertEquals($name . '_renamed', $files[0]->getName());
+	}
+
+	/**
+	 * @dataProvider nameAndDataProvider
+	 */
+	public function testGet($name, $text) {
+		$tmpFile = $this->getTextFile($text);
+
+		$this->share->put($tmpFile, $this->root . '/' . $name);
+		unlink($tmpFile);
+
+		$targetFile = tempnam('/tmp', 'smb_test_');
+		$this->share->get($this->root . '/' . $name, $targetFile);
+
+		$this->assertEquals($text, file_get_contents($targetFile));
+		unlink($targetFile);
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testDel($name) {
+		$tmpFile = $this->getTextFile();
+
+		$this->share->put($tmpFile, $this->root . '/' . $name);
+		unlink($tmpFile);
+
+		$this->share->del($this->root . '/' . $name);
+		$this->assertCount(0, $this->share->dir($this->root));
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testCreateFolderInNonExistingFolder() {
+		$this->share->mkdir($this->root . '/foo/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testRemoveFolderInNonExistingFolder() {
+		$this->share->rmdir($this->root . '/foo/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testRemoveNonExistingFolder() {
+		$this->share->rmdir($this->root . '/foo');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\AlreadyExistsException
+	 */
+	public function testCreateExistingFolder() {
+		$this->share->mkdir($this->root . '/bar');
+		$this->share->mkdir($this->root . '/bar');
+		$this->share->rmdir($this->root . '/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function testCreateFileExistingFolder() {
+		$this->share->mkdir($this->root . '/bar');
+		$this->share->put($this->getTextFile(), $this->root . '/bar');
+		$this->share->rmdir($this->root . '/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testCreateFileInNonExistingFolder() {
+		$this->share->put($this->getTextFile(), $this->root . '/foo/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testTestRemoveNonExistingFile() {
+		$this->share->del($this->root . '/foo');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testDownloadNonExistingFile() {
+		$this->share->get($this->root . '/foo', '/dev/null');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function testDownloadFolder() {
+		$this->share->mkdir($this->root . '/foobar');
+		$this->share->get($this->root . '/foobar', '/dev/null');
+		$this->share->rmdir($this->root . '/foobar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function testDelFolder() {
+		$this->share->mkdir($this->root . '/foobar');
+		$this->share->del($this->root . '/foobar');
+		$this->share->rmdir($this->root . '/foobar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\InvalidTypeException
+	 */
+	public function testRmdirFile() {
+		$this->share->put($this->getTextFile(), $this->root . '/foobar');
+		$this->share->rmdir($this->root . '/foobar');
+		$this->share->del($this->root . '/foobar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotEmptyException
+	 */
+	public function testRmdirNotEmpty() {
+		$this->share->mkdir($this->root . '/foobar');
+		$this->share->put($this->getTextFile(), $this->root . '/foobar/asd');
+		$this->share->rmdir($this->root . '/foobar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testDirNonExisting() {
+		$this->share->dir('/foobar/asd');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testRmDirNonExisting() {
+		$this->share->rmdir('/foobar/asd');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testRenameNonExisting() {
+		$this->share->rename('/foobar/asd', '/foobar/bar');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testRenameTargetNonExisting() {
+		$txt = $this->getTextFile();
+		$this->share->put($txt, $this->root . '/foo.txt');
+		unlink($txt);
+		$this->share->rename($this->root . '/foo.txt', $this->root . '/bar/foo.txt');
+	}
+
+	public function testModifiedDate() {
+		$now = time();
+		$this->share->put($this->getTextFile(), $this->root . '/foo.txt');
+		$dir = $this->share->dir($this->root);
+		$mtime = $dir[0]->getMTime();
+		$this->assertTrue(abs($now - $mtime) <= 1, 'Modified time differs by ' . abs($now - $mtime) . ' seconds');
+		$this->share->del($this->root . '/foo.txt');
+	}
+
+	/**
+	 * @dataProvider nameAndDataProvider
+	 */
+	public function testReadStream($name, $text) {
+		$sourceFile = $this->getTextFile($text);
+		$this->share->put($sourceFile, $this->root . '/' . $name);
+		$fh = $this->share->read($this->root . '/' . $name);
+		$content = stream_get_contents($fh);
+		fclose($fh);
+		$this->share->del($this->root . '/' . $name);
+
+		$this->assertEquals(file_get_contents($sourceFile), $content);
+	}
+
+	/**
+	 * @dataProvider nameAndDataProvider
+	 */
+	public function testWriteStream($name, $text) {
+		$fh = $this->share->write($this->root . '/' . $name);
+		fwrite($fh, $text);
+		fclose($fh);
+
+		$tmpFile1 = tempnam('/tmp', 'smb_test_');
+		$this->share->get($this->root . '/' . $name, $tmpFile1);
+		$this->assertEquals($text, file_get_contents($tmpFile1));
+		$this->share->del($this->root . '/' . $name);
+		unlink($tmpFile1);
+	}
+
+	public function testDir() {
+		$txtFile = $this->getTextFile();
+
+		$this->share->mkdir($this->root . '/dir');
+		$this->share->put($txtFile, $this->root . '/file.txt');
+		unlink($txtFile);
+
+		$dir = $this->share->dir($this->root);
+		if ($dir[0]->getName() === 'dir') {
+			$dirEntry = $dir[0];
+		} else {
+			$dirEntry = $dir[1];
+		}
+		$this->assertTrue($dirEntry->isDirectory());
+		$this->assertFalse($dirEntry->isReadOnly());
+		$this->assertFalse($dirEntry->isReadOnly());
+
+		if ($dir[0]->getName() === 'file.txt') {
+			$fileEntry = $dir[0];
+		} else {
+			$fileEntry = $dir[1];
+		}
+		$this->assertFalse($fileEntry->isDirectory());
+		$this->assertFalse($fileEntry->isReadOnly());
+		$this->assertFalse($fileEntry->isReadOnly());
+	}
+
+	/**
+	 * @dataProvider nameProvider
+	 */
+	public function testStat($name) {
+		$txtFile = $this->getTextFile();
+		$size = filesize($txtFile);
+
+		$this->share->put($txtFile, $this->root . '/' . $name);
+		unlink($txtFile);
+
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertEquals($size, $info->getSize());
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\NotFoundException
+	 */
+	public function testStatNonExisting() {
+		$this->share->stat($this->root . '/fo.txt');
+	}
+
+	/**
+	 * note setting archive and system bit is not supported
+	 *
+	 * @dataProvider nameProvider
+	 */
+	public function testSetMode($name) {
+		$txtFile = $this->getTextFile();
+
+		$this->share->put($txtFile, $this->root . '/' . $name);
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_NORMAL);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertFalse($info->isReadOnly());
+		$this->assertFalse($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertFalse($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_READONLY);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertTrue($info->isReadOnly());
+		$this->assertFalse($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertFalse($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_ARCHIVE);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertFalse($info->isReadOnly());
+		$this->assertTrue($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertFalse($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertTrue($info->isReadOnly());
+		$this->assertTrue($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertFalse($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_HIDDEN);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertFalse($info->isReadOnly());
+		$this->assertFalse($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertTrue($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_SYSTEM);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertFalse($info->isReadOnly());
+		$this->assertFalse($info->isArchived());
+		$this->assertTrue($info->isSystem());
+		$this->assertFalse($info->isHidden());
+
+		$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_NORMAL);
+		$info = $this->share->stat($this->root . '/' . $name);
+		$this->assertFalse($info->isReadOnly());
+		$this->assertFalse($info->isArchived());
+		$this->assertFalse($info->isSystem());
+		$this->assertFalse($info->isHidden());
+	}
+
+	public function pathProvider() {
+		// / ? < > \ : * | " are illegal characters in path on windows
+		return array(
+			array('dir/sub/foo.txt'),
+			array('bar.txt'),
+			array("single'quote'/sub/foo.txt"),
+			array('日本語/url %2F +encode/asd.txt'),
+			array(
+				'a somewhat longer folder than the other with more charaters as the all the other filenames/' .
+				'followed by a somewhat long file name after that.txt'
+			)
+		);
+	}
+
+	/**
+	 * @dataProvider pathProvider
+	 */
+	public function testSubDirs($path) {
+		$dirs = explode('/', $path);
+		$name = array_pop($dirs);
+		$fullPath = '';
+		foreach ($dirs as $dir) {
+			$fullPath .= '/' . $dir;
+			$this->share->mkdir($this->root . $fullPath);
+		}
+		$txtFile = $this->getTextFile();
+		$size = filesize($txtFile);
+		$this->share->put($txtFile, $this->root . $fullPath . '/' . $name);
+		unlink($txtFile);
+		$info = $this->share->stat($this->root . $fullPath . '/' . $name);
+		$this->assertEquals($size, $info->getSize());
+		$this->assertFalse($info->isHidden());
+	}
+
+	public function testDelAfterStat() {
+		$name = 'foo.txt';
+		$txtFile = $this->getTextFile();
+
+		$this->share->put($txtFile, $this->root . '/' . $name);
+		unlink($txtFile);
+
+		$this->share->stat($this->root . '/' . $name);
+		$this->share->del($this->root . '/foo.txt');
+	}
+
+	/**
+	 * @param $name
+	 * @dataProvider nameProvider
+	 */
+	public function testDirPaths($name) {
+		$txtFile = $this->getTextFile();
+		$this->share->mkdir($this->root . '/' . $name);
+		$this->share->put($txtFile, $this->root . '/' . $name . '/' . $name);
+		unlink($txtFile);
+
+		$content = $this->share->dir($this->root . '/' . $name);
+		$this->assertCount(1, $content);
+		$this->assertEquals($name, $content[0]->getName());
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/tests/NativeShare.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8e10235c1274512cd38524bf17c242df1fd2285
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/NativeShare.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+use Icewind\SMB\NativeServer;
+
+class NativeShare extends AbstractShare {
+	public function setUp() {
+		if (!function_exists('smbclient_state_new')) {
+			$this->markTestSkipped('libsmbclient php extension not installed');
+		}
+		$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
+		$this->server = new NativeServer($this->config->host, $this->config->user, $this->config->password);
+		$this->share = $this->server->getShare($this->config->share);
+		if ($this->config->root) {
+			$this->root = '/' . $this->config->root . '/' . uniqid();
+		} else {
+			$this->root = '/' . uniqid();
+		}
+		$this->share->mkdir($this->root);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/NativeStream.php b/apps/files_external/3rdparty/icewind/smb/tests/NativeStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d7b62fedebaea0d50f8a07136a3f0c91943bcd1
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/NativeStream.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+use Icewind\SMB\NativeServer;
+
+class NativeStream extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \Icewind\SMB\Server $server
+	 */
+	protected $server;
+
+	/**
+	 * @var \Icewind\SMB\NativeShare $share
+	 */
+	protected $share;
+
+	/**
+	 * @var string $root
+	 */
+	protected $root;
+
+	protected $config;
+
+	public function setUp() {
+		if (!function_exists('smbclient_state_new')) {
+			$this->markTestSkipped('libsmbclient php extension not installed');
+		}
+		$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
+		$this->server = new NativeServer($this->config->host, $this->config->user, $this->config->password);
+		$this->share = $this->server->getShare($this->config->share);
+		if ($this->config->root) {
+			$this->root = '/' . $this->config->root . '/' . uniqid();
+		} else {
+			$this->root = '/' . uniqid();
+		}
+		$this->share->mkdir($this->root);
+	}
+
+	private function getTextFile() {
+		$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';
+		$file = tempnam('/tmp', 'smb_test_');
+		file_put_contents($file, $text);
+		return $file;
+	}
+
+	public function testSeekTell() {
+		$sourceFile = $this->getTextFile();
+		$this->share->put($sourceFile, $this->root . '/foobar');
+		$fh = $this->share->read($this->root . '/foobar');
+		$content = fread($fh, 3);
+		$this->assertEquals('Lor', $content);
+
+		fseek($fh, -2, SEEK_CUR);
+
+		$content = fread($fh, 3);
+		$this->assertEquals('ore', $content);
+
+		fseek($fh, 3, SEEK_SET);
+
+		$content = fread($fh, 3);
+		$this->assertEquals('em ', $content);
+
+		fseek($fh, -3, SEEK_END);
+
+		$content = fread($fh, 3);
+		$this->assertEquals('qua', $content);
+
+		fseek($fh, -3, SEEK_END);
+		$this->assertEquals(120, ftell($fh));
+	}
+
+	public function testStat() {
+		$sourceFile = $this->getTextFile();
+		$this->share->put($sourceFile, $this->root . '/foobar');
+		$fh = $this->share->read($this->root . '/foobar');
+		$stat = fstat($fh);
+		$this->assertEquals(filesize($sourceFile), $stat['size']);
+		unlink($sourceFile);
+	}
+
+	public function testTruncate() {
+		if (version_compare(phpversion(), '5.4.0', '<')) {
+			$this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
+		}
+		$fh = $this->share->write($this->root . '/foobar');
+		fwrite($fh, 'foobar');
+		ftruncate($fh, 3);
+		fclose($fh);
+
+		$fh = $this->share->read($this->root . '/foobar');
+		$this->assertEquals('foo', stream_get_contents($fh));
+	}
+
+	public function testEOF() {
+		if (version_compare(phpversion(), '5.4.0', '<')) {
+			$this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
+		}
+		$fh = $this->share->write($this->root . '/foobar');
+		fwrite($fh, 'foobar');
+		fclose($fh);
+
+		$fh = $this->share->read($this->root . '/foobar');
+		fread($fh, 3);
+		$this->assertFalse(feof($fh));
+		fread($fh, 5);
+		$this->assertTrue(feof($fh));
+	}
+
+	public function testLockUnsupported() {
+		$fh = $this->share->write($this->root . '/foobar');
+		$this->assertFalse(flock($fh, LOCK_SH));
+	}
+
+	public function testSetOptionUnsupported() {
+		$fh = $this->share->write($this->root . '/foobar');
+		$this->assertFalse(stream_set_blocking($fh, false));
+	}
+
+	public function tearDown() {
+		if ($this->share) {
+			$this->cleanDir($this->root);
+		}
+		unset($this->share);
+	}
+
+	public function cleanDir($dir) {
+		$content = $this->share->dir($dir);
+		foreach ($content as $metadata) {
+			if ($metadata->isDirectory()) {
+				$this->cleanDir($metadata->getPath());
+			} else {
+				$this->share->del($metadata->getPath());
+			}
+		}
+		$this->share->rmdir($dir);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/Parser.php b/apps/files_external/3rdparty/icewind/smb/tests/Parser.php
new file mode 100644
index 0000000000000000000000000000000000000000..0dd06d6af3311c5727fcb67aa4a7fac02963af17
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/Parser.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+
+use Icewind\SMB\FileInfo;
+
+class Parser extends \PHPUnit_Framework_TestCase {
+	public function modeProvider() {
+		return array(
+			array('D', FileInfo::MODE_DIRECTORY),
+			array('A', FileInfo::MODE_ARCHIVE),
+			array('S', FileInfo::MODE_SYSTEM),
+			array('H', FileInfo::MODE_HIDDEN),
+			array('R', FileInfo::MODE_READONLY),
+			array('N', FileInfo::MODE_NORMAL),
+			array('RA', FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE),
+			array('RAH', FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE | FileInfo::MODE_HIDDEN)
+		);
+	}
+
+	/**
+	 * @dataProvider modeProvider
+	 */
+	public function testParseMode($string, $mode) {
+		$parser = new \Icewind\SMB\Parser('UTC');
+		$this->assertEquals($mode, $parser->parseMode($string), 'Failed parsing ' . $string);
+	}
+
+	public function statProvider() {
+		return array(
+			array(
+				array(
+					'altname: test.txt',
+					'create_time:    Sat Oct 12 07:05:58 PM 2013 CEST',
+					'access_time:    Tue Oct 15 02:58:48 PM 2013 CEST',
+					'write_time:     Sat Oct 12 07:05:58 PM 2013 CEST',
+					'change_time:    Sat Oct 12 07:05:58 PM 2013 CEST',
+					'attributes:  (80)',
+					'stream: [::$DATA], 29634 bytes'
+				),
+				array(
+					'mtime' => strtotime('12 Oct 2013 19:05:58 CEST'),
+					'mode' => FileInfo::MODE_NORMAL,
+					'size' => 29634
+				))
+		);
+	}
+
+	/**
+	 * @dataProvider statProvider
+	 */
+	public function testStat($output, $stat) {
+		$parser = new \Icewind\SMB\Parser('UTC');
+		$this->assertEquals($stat, $parser->parseStat($output));
+	}
+
+	public function dirProvider() {
+		return array(
+			array(
+				array(
+					'  .                                   D        0  Tue Aug 26 19:11:56 2014',
+					'  ..                                 DR        0  Sun Oct 28 15:24:02 2012',
+					'  c.pdf                               N    29634  Sat Oct 12 19:05:58 2013',
+					'',
+					'                62536 blocks of size 8388608. 57113 blocks available'
+				),
+				array(
+					new FileInfo('/c.pdf', 'c.pdf', 29634, strtotime('12 Oct 2013 19:05:58 CEST'), FileInfo::MODE_NORMAL)
+				)
+			)
+		);
+	}
+
+	/**
+	 * @dataProvider dirProvider
+	 */
+	public function testDir($output, $dir) {
+		$parser = new \Icewind\SMB\Parser('CEST');
+		$this->assertEquals($dir, $parser->parseDir($output, ''));
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/Server.php b/apps/files_external/3rdparty/icewind/smb/tests/Server.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f62886654f45239df7c1e5635c75ac7609e2309
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/Server.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+class Server extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \Icewind\SMB\Server $server
+	 */
+	private $server;
+
+	private $config;
+
+	public function setUp() {
+		$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
+		$this->server = new \Icewind\SMB\Server($this->config->host, $this->config->user, $this->config->password);
+	}
+
+	public function testListShares() {
+		$shares = $this->server->listShares();
+		foreach ($shares as $share) {
+			if ($share->getName() === $this->config->share) {
+				return;
+			}
+		}
+		$this->fail('Share "' . $this->config->share . '" not found');
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\AuthenticationException
+	 */
+	public function testWrongUserName() {
+		$this->markTestSkipped('This fails for no reason on travis');
+		$server = new \Icewind\SMB\Server($this->config->host, uniqid(), uniqid());
+		$server->listShares();
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\AuthenticationException
+	 */
+	public function testWrongPassword() {
+		$server = new \Icewind\SMB\Server($this->config->host, $this->config->user, uniqid());
+		$server->listShares();
+	}
+
+	/**
+	 * @expectedException \Icewind\SMB\Exception\InvalidHostException
+	 */
+	public function testWrongHost() {
+		$server = new \Icewind\SMB\Server(uniqid(), $this->config->user, $this->config->password);
+		$server->listShares();
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/Share.php b/apps/files_external/3rdparty/icewind/smb/tests/Share.php
new file mode 100644
index 0000000000000000000000000000000000000000..a629914d748d107271c00ecf78e4791b46a0b955
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/Share.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\SMB\Test;
+
+use Icewind\SMB\Server as NormalServer;
+
+class Share extends AbstractShare {
+	public function setUp() {
+		$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
+		$this->server = new NormalServer($this->config->host, $this->config->user, $this->config->password);
+		$this->share = $this->server->getShare($this->config->share);
+		if ($this->config->root) {
+			$this->root = '/' . $this->config->root . '/' . uniqid();
+		} else {
+			$this->root = '/' . uniqid();
+		}
+		$this->share->mkdir($this->root);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/bootstrap.php b/apps/files_external/3rdparty/icewind/smb/tests/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc2e34b183e28dcd8855b602ea7d6e823606d92b
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/bootstrap.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+date_default_timezone_set('UTC');
+require_once __DIR__.'/../vendor/autoload.php';
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/config.json b/apps/files_external/3rdparty/icewind/smb/tests/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ecd7e3715d5edf29a4b17f89b842c7be32d640a
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/config.json
@@ -0,0 +1,7 @@
+{
+	"host": "localhost",
+	"user": "test",
+	"password": "test",
+	"share": "test",
+	"root": "test"
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/tests/phpunit.xml b/apps/files_external/3rdparty/icewind/smb/tests/phpunit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3ab244dd34f917d1ddf41ef03cbf7c6d9b1b7387
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/smb/tests/phpunit.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<phpunit bootstrap="bootstrap.php">
+	<testsuite name='SMB'>
+		<directory suffix='.php'>./</directory>
+	</testsuite>
+</phpunit>
diff --git a/apps/files_external/3rdparty/icewind/streams/.gitignore b/apps/files_external/3rdparty/icewind/streams/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f389129e2d9021981c41e0389a3bbb2455d8786
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/.gitignore
@@ -0,0 +1,3 @@
+.idea
+vendor
+composer.lock
diff --git a/apps/files_external/3rdparty/icewind/streams/.travis.yml b/apps/files_external/3rdparty/icewind/streams/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dfa52767dda15a7146f712c0795f4afb66419c53
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/.travis.yml
@@ -0,0 +1,26 @@
+language: php
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+  - hhvm
+
+matrix:
+    allow_failures:
+        - php: hhvm # due to facebook/hhvm#3321
+
+env:
+  global:
+    - CURRENT_DIR=`pwd`
+
+install:
+  - composer install --dev --no-interaction
+
+script:
+  - mkdir -p build/logs
+  - cd tests
+  - phpunit --coverage-clover ../build/logs/clover.xml --configuration phpunit.xml
+
+after_script:
+ - cd $CURRENT_DIR
+ - php vendor/bin/coveralls -v
diff --git a/apps/files_external/3rdparty/icewind/streams/README.md b/apps/files_external/3rdparty/icewind/streams/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..54f6d19a56080c6923b9d2f73e182bcb4204b218
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/README.md
@@ -0,0 +1,52 @@
+#Streams#
+
+[![Build Status](https://travis-ci.org/icewind1991/Streams.svg?branch=master)](https://travis-ci.org/icewind1991/Streams)
+[![Coverage Status](https://img.shields.io/coveralls/icewind1991/Streams.svg)](https://coveralls.io/r/icewind1991/Streams?branch=master)
+
+Generic stream wrappers for php.
+
+##CallBackWrapper##
+
+A `CallBackWrapper` can be used to register callbacks on read, write and closing of the stream,
+it wraps an existing stream and can thus be used for any stream in php
+
+The callbacks are passed in the stream context along with the source stream
+and can be any valid [php callable](http://php.net/manual/en/language.types.callable.php)
+
+###Example###
+```php
+<?php
+
+use \Icewind\Streams\CallBackWrapper;
+
+require('vendor/autoload.php');
+
+// get an existing stream to wrap
+$source = fopen('php://temp', 'r+');
+
+// register the callbacks
+$stream = CallbackWrapper::wrap($source,
+	// read callback
+	function ($count) {
+		echo "read " . $count . "bytes\n";
+	},
+	// write callback
+	function ($data) {
+		echo "wrote '" . $data . "'\n";
+	},
+	// close callback
+	function () {
+		echo "stream closed\n";
+	});
+
+fwrite($stream, 'some dummy data');
+
+rewind($stream);
+fread($stream, 5);
+
+fclose($stream);
+```
+
+Note: due to php's internal stream buffering the `$count` passed to the read callback
+will be equal to php's internal buffer size (8192 on default) an not the number of bytes
+requested by `fopen()`
diff --git a/apps/files_external/3rdparty/icewind/streams/composer.json b/apps/files_external/3rdparty/icewind/streams/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..86d3c834258d16a69c6169e83bdd65a031ecec96
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/composer.json
@@ -0,0 +1,23 @@
+{
+	"name"             : "icewind/streams",
+	"description"      : "A set of generic stream wrappers",
+	"license"          : "MIT",
+	"authors"          : [
+		{
+			"name" : "Robin Appelman",
+			"email": "icewind@owncloud.com"
+		}
+	],
+	"require"          : {
+		"php": ">=5.3"
+	},
+	"require-dev"      : {
+		"satooshi/php-coveralls": "dev-master"
+	},
+	"autoload"         : {
+		"psr-4": {
+			"Icewind\\Streams\\Tests\\": "tests/",
+			"Icewind\\Streams\\": "src/"
+		}
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd99aa6ebe8cefe0e5e371e9121cc4d21ee5a820
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Wrapper that provides callbacks for write, read and close
+ *
+ * The following options should be passed in the context when opening the stream
+ * [
+ *     'callback' => [
+ *        'source' => resource
+ *        'read'   => function($count){} (optional)
+ *        'write'  => function($data){} (optional)
+ *        'close'  => function(){} (optional)
+ *     ]
+ * ]
+ *
+ * All callbacks are called after the operation is executed on the source stream
+ */
+class CallbackWrapper extends Wrapper {
+	/**
+	 * @var callable
+	 */
+	protected $readCallback;
+
+	/**
+	 * @var callable
+	 */
+	protected $writeCallback;
+
+	/**
+	 * @var callable
+	 */
+	protected $closeCallback;
+
+	/**
+	 * Wraps a stream with the provided callbacks
+	 *
+	 * @param resource $source
+	 * @param callable $read (optional)
+	 * @param callable $write (optional)
+	 * @param callable $close (optional)
+	 * @return resource
+	 *
+	 * @throws \BadMethodCallException
+	 */
+	public static function wrap($source, $read = null, $write = null, $close = null) {
+		$context = stream_context_create(array(
+			'callback' => array(
+				'source' => $source,
+				'read' => $read,
+				'write' => $write,
+				'close' => $close
+			)
+		));
+		stream_wrapper_register('callback', '\Icewind\Streams\CallbackWrapper');
+		try {
+			$wrapped = fopen('callback://', 'r+', false, $context);
+		} catch (\BadMethodCallException $e) {
+			stream_wrapper_unregister('callback');
+			throw $e;
+		}
+		stream_wrapper_unregister('callback');
+		return $wrapped;
+	}
+
+	public function stream_open($path, $mode, $options, &$opened_path) {
+		$context = $this->loadContext('callback');
+
+		if (isset($context['read']) and is_callable($context['read'])) {
+			$this->readCallback = $context['read'];
+		}
+		if (isset($context['write']) and is_callable($context['write'])) {
+			$this->writeCallback = $context['write'];
+		}
+		if (isset($context['close']) and is_callable($context['close'])) {
+			$this->closeCallback = $context['close'];
+		}
+		return true;
+	}
+
+	public function stream_read($count) {
+		$result = parent::stream_read($count);
+		if ($this->readCallback) {
+			call_user_func($this->readCallback, $count);
+		}
+		return $result;
+	}
+
+	public function stream_write($data) {
+		$result = parent::stream_write($data);
+		if ($this->writeCallback) {
+			call_user_func($this->writeCallback, $data);
+		}
+		return $result;
+	}
+
+	public function stream_close() {
+		$result = parent::stream_close();
+		if ($this->closeCallback) {
+			call_user_func($this->closeCallback);
+		}
+		return $result;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/Directory.php b/apps/files_external/3rdparty/icewind/streams/src/Directory.php
new file mode 100644
index 0000000000000000000000000000000000000000..c80a878386b53d50a5094510fcf241a8b213952e
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/Directory.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Interface for stream wrappers that implements a directory
+ */
+interface Directory {
+	/**
+	 * @param string $path
+	 * @param array $options
+	 * @return bool
+	 */
+	public function dir_opendir($path, $options);
+
+	/**
+	 * @return string
+	 */
+	public function dir_readdir();
+
+	/**
+	 * @return bool
+	 */
+	public function dir_closedir();
+
+	/**
+	 * @return bool
+	 */
+	public function dir_rewinddir();
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/File.php b/apps/files_external/3rdparty/icewind/streams/src/File.php
new file mode 100644
index 0000000000000000000000000000000000000000..6202ef4a4b445c9bdfc413b20b23c741ee6a2f72
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/File.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Interface for stream wrappers that implements a file
+ */
+interface File {
+	/**
+	 * @param string $path
+	 * @param string $mode
+	 * @param int $options
+	 * @param string &$opened_path
+	 * @return bool
+	 */
+	public function stream_open($path, $mode, $options, &$opened_path);
+
+	/**
+	 * @param string $offset
+	 * @param int $whence
+	 * @return bool
+	 */
+	public function stream_seek($offset, $whence = SEEK_SET);
+
+	/**
+	 * @return int
+	 */
+	public function stream_tell();
+
+	/**
+	 * @param int $count
+	 * @return string
+	 */
+	public function stream_read($count);
+
+	/**
+	 * @param string $data
+	 * @return int
+	 */
+	public function stream_write($data);
+
+	/**
+	 * @param int $option
+	 * @param int $arg1
+	 * @param int $arg2
+	 * @return bool
+	 */
+	public function stream_set_option($option, $arg1, $arg2);
+
+	/**
+	 * @param int $size
+	 * @return bool
+	 */
+	public function stream_truncate($size);
+
+	/**
+	 * @return array
+	 */
+	public function stream_stat();
+
+	/**
+	 * @param int $operation
+	 * @return bool
+	 */
+	public function stream_lock($operation);
+
+	/**
+	 * @return bool
+	 */
+	public function stream_flush();
+
+	/**
+	 * @return bool
+	 */
+	public function stream_eof();
+
+	/**
+	 * @return bool
+	 */
+	public function stream_close();
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php
new file mode 100644
index 0000000000000000000000000000000000000000..c4eac5d4ed3e74f707b58c5c127d92da8af8c292
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Create a directory handle from an iterator or array
+ *
+ * The following options should be passed in the context when opening the stream
+ * [
+ *     'dir' => [
+ *        'array'    => string[]
+ *        'iterator' => \Iterator
+ *     ]
+ * ]
+ *
+ * Either 'array' or 'iterator' need to be set, if both are set, 'iterator' takes preference
+ */
+class IteratorDirectory implements Directory {
+	/**
+	 * @var resource
+	 */
+	public $context;
+
+	/**
+	 * @var \Iterator
+	 */
+	protected $iterator;
+
+	/**
+	 * Load the source from the stream context and return the context options
+	 *
+	 * @param string $name
+	 * @return array
+	 * @throws \Exception
+	 */
+	protected function loadContext($name) {
+		$context = stream_context_get_options($this->context);
+		if (isset($context[$name])) {
+			$context = $context[$name];
+		} else {
+			throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set');
+		}
+		if (isset($context['iterator']) and $context['iterator'] instanceof \Iterator) {
+			$this->iterator = $context['iterator'];
+		} else if (isset($context['array']) and is_array($context['array'])) {
+			$this->iterator = new \ArrayIterator($context['array']);
+		} else {
+			throw new \BadMethodCallException('Invalid context, iterator or array not set');
+		}
+		return $context;
+	}
+
+	/**
+	 * @param string $path
+	 * @param array $options
+	 * @return bool
+	 */
+	public function dir_opendir($path, $options) {
+		$this->loadContext('dir');
+		return true;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function dir_readdir() {
+		if ($this->iterator->valid()) {
+			$result = $this->iterator->current();
+			$this->iterator->next();
+			return $result;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function dir_closedir() {
+		return true;
+	}
+
+	/**
+	 * @return bool
+	 */
+	public function dir_rewinddir() {
+		$this->iterator->rewind();
+		return true;
+	}
+
+	/**
+	 * Creates a directory handle from the provided array or iterator
+	 *
+	 * @param \Iterator | array $source
+	 * @return resource
+	 *
+	 * @throws \BadMethodCallException
+	 */
+	public static function wrap($source) {
+		if ($source instanceof \Iterator) {
+			$context = stream_context_create(array(
+				'dir' => array(
+					'iterator' => $source)
+			));
+		} else if (is_array($source)) {
+			$context = stream_context_create(array(
+				'dir' => array(
+					'array' => $source)
+			));
+		} else {
+			throw new \BadMethodCallException('$source should be an Iterator or array');
+		}
+		stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+		$wrapped = opendir('iterator://', $context);
+		stream_wrapper_unregister('iterator');
+		return $wrapped;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..8cbaaa756d3728887e91f8c971651356a792e38b
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Stream wrapper that does nothing, used for tests
+ */
+class NullWrapper extends Wrapper {
+	/**
+	 * Wraps a stream with the provided callbacks
+	 *
+	 * @param resource $source
+	 * @return resource
+	 *
+	 * @throws \BadMethodCallException
+	 */
+	public static function wrap($source) {
+		$context = stream_context_create(array(
+			'null' => array(
+				'source' => $source)
+		));
+		stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+		try {
+			$wrapped = fopen('null://', 'r+', false, $context);
+		} catch (\BadMethodCallException $e) {
+			stream_wrapper_unregister('null');
+			throw $e;
+		}
+		stream_wrapper_unregister('null');
+		return $wrapped;
+	}
+
+	public function stream_open($path, $mode, $options, &$opened_path) {
+		$this->loadContext('null');
+		return true;
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e3a6e6cd88124e9bc66a9b6baf91c0eb1c9a5b4
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams;
+
+/**
+ * Base class for stream wrappers, wraps an existing stream
+ *
+ * This wrapper itself doesn't implement any functionality but is just a base class for other wrappers to extend
+ */
+abstract class Wrapper implements File {
+	/**
+	 * @var resource
+	 */
+	public $context;
+
+	/**
+	 * The wrapped stream
+	 *
+	 * @var resource
+	 */
+	protected $source;
+
+	/**
+	 * Load the source from the stream context and return the context options
+	 *
+	 * @param string $name
+	 * @return array
+	 * @throws \Exception
+	 */
+	protected function loadContext($name) {
+		$context = stream_context_get_options($this->context);
+		if (isset($context[$name])) {
+			$context = $context[$name];
+		} else {
+			throw new \BadMethodCallException('Invalid context, "callable" options not set');
+		}
+		if (isset($context['source']) and is_resource($context['source'])) {
+			$this->setSourceStream($context['source']);
+		} else {
+			throw new \BadMethodCallException('Invalid context, source not set');
+		}
+		return $context;
+	}
+
+	/**
+	 * @param resource $source
+	 */
+	protected function setSourceStream($source) {
+		$this->source = $source;
+	}
+
+	public function stream_seek($offset, $whence = SEEK_SET) {
+		$result = fseek($this->source, $offset, $whence);
+		return $result == 0 ? true : false;
+	}
+
+	public function stream_tell() {
+		return ftell($this->source);
+	}
+
+	public function stream_read($count) {
+		return fread($this->source, $count);
+	}
+
+	public function stream_write($data) {
+		return fwrite($this->source, $data);
+	}
+
+	public function stream_set_option($option, $arg1, $arg2) {
+		switch ($option) {
+			case STREAM_OPTION_BLOCKING:
+				stream_set_blocking($this->source, $arg1);
+				break;
+			case STREAM_OPTION_READ_TIMEOUT:
+				stream_set_timeout($this->source, $arg1, $arg2);
+				break;
+			case STREAM_OPTION_WRITE_BUFFER:
+				stream_set_write_buffer($this->source, $arg1);
+		}
+	}
+
+	public function stream_truncate($size) {
+		return ftruncate($this->source, $size);
+	}
+
+	public function stream_stat() {
+		return fstat($this->source);
+	}
+
+	public function stream_lock($mode) {
+		return flock($this->source, $mode);
+	}
+
+	public function stream_flush() {
+		return fflush($this->source);
+	}
+
+	public function stream_eof() {
+		return feof($this->source);
+	}
+
+	public function stream_close() {
+		return fclose($this->source);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..229b629dcd99a8d2bd958cc5ba5d8837f295f9de
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class CallbackWrapper extends Wrapper {
+
+	/**
+	 * @param resource $source
+	 * @param callable $read
+	 * @param callable $write
+	 * @param callable $close
+	 * @return resource
+	 */
+	protected function wrapSource($source, $read = null, $write = null, $close = null) {
+		return \Icewind\Streams\CallbackWrapper::wrap($source, $read, $write, $close);
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testWrapInvalidSource() {
+		$this->wrapSource('foo');
+	}
+
+	public function testReadCallback() {
+		$called = false;
+		$callBack = function () use (&$called) {
+			$called = true;
+		};
+
+		$source = fopen('php://temp', 'r+');
+		fwrite($source, 'foobar');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source, $callBack);
+		$this->assertEquals('foo', fread($wrapped, 3));
+		$this->assertTrue($called);
+	}
+
+	public function testWriteCallback() {
+		$lastData = '';
+		$callBack = function ($data) use (&$lastData) {
+			$lastData = $data;
+		};
+
+		$source = fopen('php://temp', 'r+');
+
+		$wrapped = $this->wrapSource($source, null, $callBack);
+		fwrite($wrapped, 'foobar');
+		$this->assertEquals('foobar', $lastData);
+	}
+
+	public function testCloseCallback() {
+		$called = false;
+		$callBack = function () use (&$called) {
+			$called = true;
+		};
+
+		$source = fopen('php://temp', 'r+');
+		fwrite($source, 'foobar');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source, null, null, $callBack);
+		fclose($wrapped);
+		$this->assertTrue($called);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d990468368def6b7dcb60fc59f0bb0261ec9dc9
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class IteratorDirectory extends \PHPUnit_Framework_TestCase {
+
+	/**
+	 * @param \Iterator | array $source
+	 * @return resource
+	 */
+	protected function wrapSource($source) {
+		return \Icewind\Streams\IteratorDirectory::wrap($source);
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testNoContext() {
+		$context = stream_context_create(array());
+		stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+		try {
+			opendir('iterator://', $context);
+			stream_wrapper_unregister('iterator');
+		} catch (\Exception $e) {
+			stream_wrapper_unregister('iterator');
+			throw $e;
+		}
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testInvalidSource() {
+		$context = stream_context_create(array(
+			'dir' => array(
+				'array' => 2
+			)
+		));
+		stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory');
+		try {
+			opendir('iterator://', $context);
+			stream_wrapper_unregister('iterator');
+		} catch (\Exception $e) {
+			stream_wrapper_unregister('iterator');
+			throw $e;
+		}
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testWrapInvalidSource() {
+		$this->wrapSource(2);
+	}
+
+	public function fileListProvider() {
+		$longList = array_fill(0, 500, 'foo');
+		return array(
+			array(
+				array(
+					'foo',
+					'bar',
+					'qwerty'
+				)
+			),
+			array(
+				array(
+					'with spaces',
+					'under_scores',
+					'日本語',
+					'character %$_',
+					'.',
+					'0',
+					'double "quotes"',
+					"single 'quotes'"
+				)
+			),
+			array(
+				array(
+					'single item'
+				)
+			),
+			array(
+				$longList
+			),
+			array(
+				array()
+			)
+		);
+	}
+
+	protected function basicTest($fileList, $dh) {
+		$result = array();
+
+		while (($file = readdir($dh)) !== false) {
+			$result[] = $file;
+		}
+
+		$this->assertEquals($fileList, $result);
+
+		rewinddir($dh);
+		if (count($fileList)) {
+			$this->assertEquals($fileList[0], readdir($dh));
+		} else {
+			$this->assertFalse(readdir($dh));
+		}
+	}
+
+	/**
+	 * @dataProvider fileListProvider
+	 */
+	public function testBasicIterator($fileList) {
+		$iterator = new \ArrayIterator($fileList);
+		$dh = $this->wrapSource($iterator);
+		$this->basicTest($fileList, $dh);
+	}
+
+	/**
+	 * @dataProvider fileListProvider
+	 */
+	public function testBasicArray($fileList) {
+		$dh = $this->wrapSource($fileList);
+		$this->basicTest($fileList, $dh);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba42b4dfea1ba573d4e48551b42e8a4a92ad4967
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+class NullWrapper extends Wrapper {
+
+	/**
+	 * @param resource $source
+	 * @return resource
+	 */
+	protected function wrapSource($source) {
+		return \Icewind\Streams\NullWrapper::wrap($source);
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testNoContext() {
+		stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+		$context = stream_context_create(array());
+		try {
+			fopen('null://', 'r+', false, $context);
+			stream_wrapper_unregister('null');
+		} catch (\Exception $e) {
+			stream_wrapper_unregister('null');
+			throw $e;
+		}
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testNoSource() {
+		stream_wrapper_register('null', '\Icewind\Streams\NullWrapper');
+		$context = stream_context_create(array(
+			'null' => array(
+				'source' => 'bar'
+			)
+		));
+		try {
+			fopen('null://', 'r+', false, $context);
+		} catch (\Exception $e) {
+			stream_wrapper_unregister('null');
+			throw $e;
+		}
+	}
+
+	/**
+	 * @expectedException \BadMethodCallException
+	 */
+	public function testWrapInvalidSource() {
+		$this->wrapSource('foo');
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..6bb644dd6116e703c74a08fb7a70a5a8cef08b4b
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+namespace Icewind\Streams\Tests;
+
+abstract class Wrapper extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @param resource $source
+	 * @return resource
+	 */
+	abstract protected function wrapSource($source);
+
+	public function testRead() {
+		$source = fopen('php://temp', 'r+');
+		fwrite($source, 'foobar');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source);
+		$this->assertEquals('foo', fread($wrapped, 3));
+		$this->assertEquals('bar', fread($wrapped, 3));
+		$this->assertEquals('', fread($wrapped, 3));
+	}
+
+	public function testWrite() {
+		$source = fopen('php://temp', 'r+');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source);
+
+		$this->assertEquals(6, fwrite($wrapped, 'foobar'));
+		rewind($source);
+		$this->assertEquals('foobar', stream_get_contents($source));
+	}
+
+	public function testClose() {
+		$source = fopen('php://temp', 'r+');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source);
+
+		fclose($wrapped);
+		$this->assertFalse(is_resource($source));
+	}
+
+	public function testSeekTell() {
+		$source = fopen('php://temp', 'r+');
+		fwrite($source, 'foobar');
+		rewind($source);
+
+		$wrapped = $this->wrapSource($source);
+
+		$this->assertEquals(0, ftell($wrapped));
+
+		fseek($wrapped, 2);
+		$this->assertEquals(2, ftell($source));
+		$this->assertEquals(2, ftell($wrapped));
+
+		fseek($wrapped, 2, SEEK_CUR);
+		$this->assertEquals(4, ftell($source));
+		$this->assertEquals(4, ftell($wrapped));
+
+		fseek($wrapped, -1, SEEK_END);
+		$this->assertEquals(5, ftell($source));
+		$this->assertEquals(5, ftell($wrapped));
+	}
+
+	public function testStat() {
+		$source = fopen(__FILE__, 'r+');
+		$wrapped = $this->wrapSource($source);
+		$this->assertEquals(stat(__FILE__), fstat($wrapped));
+	}
+
+	public function testTruncate() {
+		if (version_compare(phpversion(), '5.4.0', '<')) {
+			$this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
+		}
+		$source = fopen('php://temp', 'r+');
+		fwrite($source, 'foobar');
+		rewind($source);
+		$wrapped = $this->wrapSource($source);
+
+		ftruncate($wrapped, 2);
+		$this->assertEquals('fo', fread($wrapped, 10));
+	}
+
+	public function testLock() {
+		$source = tmpfile();
+		$wrapped = $this->wrapSource($source);
+		if (!flock($wrapped, LOCK_EX)) {
+			$this->fail('Unable to acquire lock');
+		}
+	}
+
+	public function testStreamOptions() {
+		$source = fopen('php://temp', 'r+');
+		$wrapped = $this->wrapSource($source);
+		stream_set_blocking($wrapped, 0);
+		stream_set_timeout($wrapped, 1, 0);
+		stream_set_write_buffer($wrapped, 0);
+	}
+}
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php b/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c17fd57febfa16bf0c1e73be9a5c43c538fd647
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Licensed under the MIT license:
+ * http://opensource.org/licenses/MIT
+ */
+
+date_default_timezone_set('UTC');
+require_once __DIR__ . '/../vendor/autoload.php';
diff --git a/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml b/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e3d96352c43687821fe97f44c282ea38b7bd22dc
--- /dev/null
+++ b/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<phpunit bootstrap="bootstrap.php">
+	<testsuite name='Stream'>
+		<directory suffix='.php'>./</directory>
+	</testsuite>
+</phpunit>
diff --git a/apps/files_external/3rdparty/smb4php/smb.php b/apps/files_external/3rdparty/smb4php/smb.php
deleted file mode 100644
index e325506fa147eeac74018de5875346ee1f69a46c..0000000000000000000000000000000000000000
--- a/apps/files_external/3rdparty/smb4php/smb.php
+++ /dev/null
@@ -1,516 +0,0 @@
-<?php
-###################################################################
-# smb.php
-# This class implements a SMB stream wrapper based on 'smbclient'
-#
-# Date: lun oct 22 10:35:35 CEST 2007
-#
-# Homepage: http://www.phpclasses.org/smb4php
-#
-# Copyright (c) 2007 Victor M. Varela <vmvarela@gmail.com>
-# Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
-# Copyright (c) 2014 Robin McCorkell <rmccorkell@karoshi.org.uk>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# On the official website http://www.phpclasses.org/smb4php the
-# license is listed as LGPL so we assume that this is
-# dual-licensed GPL/LGPL
-###################################################################
-
-define ('SMB4PHP_VERSION', '0.8');
-
-###################################################################
-# CONFIGURATION SECTION - Change for your needs
-###################################################################
-
-define ('SMB4PHP_SMBCLIENT', 'smbclient');
-define ('SMB4PHP_SMBOPTIONS', 'TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192');
-define ('SMB4PHP_AUTHMODE', 'arg'); # set to 'env' to use USER enviroment variable
-
-###################################################################
-# SMB - commands that does not need an instance
-###################################################################
-
-$GLOBALS['__smb_cache'] = array ('stat' => array (), 'dir' => array ());
-
-class smb {
-
-	private static $regexp = array (
-		'^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip',
-		'Anonymous login successful' => 'skip',
-		'^Domain=\[(.*)\] OS=\[(.*)\] Server=\[(.*)\]$' => 'skip',
-		'^\tSharename[ ]+Type[ ]+Comment$' => 'shares',
-		'^\t---------[ ]+----[ ]+-------$' => 'skip',
-		'^\tServer   [ ]+Comment$' => 'servers',
-		'^\t---------[ ]+-------$' => 'skip',
-		'^\tWorkgroup[ ]+Master$' => 'workg',
-		'^\t(.*)[ ]+(Disk|IPC)[ ]+IPC.*$' => 'skip',
-		'^\tIPC\\\$(.*)[ ]+IPC' => 'skip',
-		'^\t(.*)[ ]+(Disk)[ ]+(.*)$' => 'share',
-		'^\t(.*)[ ]+(Printer)[ ]+(.*)$' => 'skip',
-		'([0-9]+) blocks of size ([0-9]+)\. ([0-9]+) blocks available' => 'skip',
-		'Got a positive name query response from ' => 'skip',
-		'^(session setup failed): (.*)$' => 'error',
-		'^(.*): ERRSRV - ERRbadpw' => 'error',
-		'^Error returning browse list: (.*)$' => 'error',
-		'^tree connect failed: (.*)$' => 'error',
-		'^(Connection to .* failed)(.*)$' => 'error-connect',
-		'^NT_STATUS_(.*) ' => 'error',
-		'^NT_STATUS_(.*)\$' => 'error',
-		'ERRDOS - ERRbadpath \((.*).\)' => 'error',
-		'cd (.*): (.*)$' => 'error',
-		'^cd (.*): NT_STATUS_(.*)' => 'error',
-		'^\t(.*)$' => 'srvorwg',
-		'^([0-9]+)[ ]+([0-9]+)[ ]+(.*)$' => 'skip',
-		'^Job ([0-9]+) cancelled' => 'skip',
-		'^[ ]+(.*)[ ]+([0-9]+)[ ]+(Mon|Tue|Wed|Thu|Fri|Sat|Sun)[ ](Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+([0-9]+)[ ]+([0-9]{2}:[0-9]{2}:[0-9]{2})[ ]([0-9]{4})$' => 'files',
-		'^message start: ERRSRV - (ERRmsgoff)' => 'error'
-	);
-
-	function getRegexp() {
-		return self::$regexp;
-	}
-
-	function parse_url ($url) {
-		$pu = parse_url (trim($url));
-		foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i) {
-			if (! isset($pu[$i])) {
-				$pu[$i] = '';
-			}
-		}
-		if (count ($userdomain = explode (';', urldecode ($pu['user']))) > 1) {
-			@list ($pu['domain'], $pu['user']) = $userdomain;
-		}
-		$path = preg_replace (array ('/^\//', '/\/$/'), '', urldecode ($pu['path']));
-		list ($pu['share'], $pu['path']) = (preg_match ('/^([^\/]+)\/(.*)/', $path, $regs))
-			? array ($regs[1], preg_replace ('/\//', '\\', $regs[2]))
-			: array ($path, '');
-		$pu['type'] = $pu['path'] ? 'path' : ($pu['share'] ? 'share' : ($pu['host'] ? 'host' : '**error**'));
-		if (! ($pu['port'] = intval(@$pu['port']))) {
-			$pu['port'] = 139;
-		}
-
-		// decode user and password
-		$pu['user'] = urldecode($pu['user']);
-		$pu['pass'] = urldecode($pu['pass']);
-		return $pu;
-	}
-
-
-	function look ($purl) {
-		return smb::client ('-L ' . escapeshellarg ($purl['host']), $purl);
-	}
-
-
-	function execute ($command, $purl, $regexp = NULL) {
-		return smb::client ('-d 0 '
-				. escapeshellarg ('//' . $purl['host'] . '/' . $purl['share'])
-				. ' -c ' . escapeshellarg ($command), $purl, $regexp
-		);
-	}
-
-	function client ($params, $purl, $regexp = NULL) {
-
-		if ($regexp === NULL) $regexp = smb::$regexp;
-
-		if (SMB4PHP_AUTHMODE == 'env') {
-			putenv("USER={$purl['user']}%{$purl['pass']}");
-			$auth = '';
-		} else {
-			$auth = ($purl['user'] <> '' ? (' -U ' . escapeshellarg ($purl['user'] . '%' . $purl['pass'])) : '');
-		}
-		if ($purl['domain'] <> '') {
-			$auth .= ' -W ' . escapeshellarg ($purl['domain']);
-		}
-		$port = ($purl['port'] <> 139 ? ' -p ' . escapeshellarg ($purl['port']) : '');
-		$options = '-O ' . escapeshellarg(SMB4PHP_SMBOPTIONS);
-
-		// this put env is necessary to read the output of smbclient correctly
-		$old_locale = getenv('LC_ALL');
-		putenv('LC_ALL=en_US.UTF-8');
-		$output = popen ('TZ=UTC '.SMB4PHP_SMBCLIENT." -N {$auth} {$options} {$port} {$options} {$params} 2>/dev/null", 'r');
-		$gotInfo = false;
-		$info = array ();
-		$info['info']= array ();
-		$mode = '';
-		while ($line = fgets ($output, 4096)) {
-			list ($tag, $regs, $i) = array ('skip', array (), array ());
-			reset ($regexp);
-			foreach ($regexp as $r => $t) if (preg_match ('/'.$r.'/', $line, $regs)) {
-				$tag = $t;
-				break;
-			}
-			switch ($tag) {
-				case 'skip':    continue;
-				case 'shares':  $mode = 'shares';     break;
-				case 'servers': $mode = 'servers';    break;
-				case 'workg':   $mode = 'workgroups'; break;
-				case 'share':
-					list($name, $type) = array (
-						trim(substr($line, 1, 15)),
-						trim(strtolower(substr($line, 17, 10)))
-					);
-					$i = ($type <> 'disk' && preg_match('/^(.*) Disk/', $line, $regs))
-						? array(trim($regs[1]), 'disk')
-						: array($name, 'disk');
-					break;
-				case 'srvorwg':
-					list ($name, $master) = array (
-						strtolower(trim(substr($line,1,21))),
-						strtolower(trim(substr($line, 22)))
-					);
-					$i = ($mode == 'servers') ? array ($name, "server") : array ($name, "workgroup", $master);
-					break;
-				case 'files':
-					list ($attr, $name) = preg_match ("/^(.*)[ ]+([D|A|H|N|S|R]+)$/", trim ($regs[1]), $regs2)
-						? array (trim ($regs2[2]), trim ($regs2[1]))
-						: array ('', trim ($regs[1]));
-					list ($his, $im) = array (
-						explode(':', $regs[6]), 1 + strpos("JanFebMarAprMayJunJulAugSepOctNovDec", $regs[4]) / 3);
-					$i = ($name <> '.' && $name <> '..')
-						? array (
-							$name,
-							(strpos($attr,'D') === FALSE) ? 'file' : 'folder',
-							'attr' => $attr,
-							'size' => intval($regs[2]),
-							'time' => mktime ($his[0], $his[1], $his[2], $im, $regs[5], $regs[7])
-						)
-						: array();
-					break;
-				case 'error':
-					if(substr($regs[0],0,22)=='NT_STATUS_NO_SUCH_FILE'){
-						return false;
-					}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_NAME_COLLISION'){
-						return false;
-					}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_PATH_NOT_FOUND'){
-						return false;
-					}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_NAME_NOT_FOUND'){
-						return false;
-					}elseif(substr($regs[0],0,29)=='NT_STATUS_FILE_IS_A_DIRECTORY'){
-						return false;
-					}
-					trigger_error($regs[0].' params('.$params.')', E_USER_ERROR);
-				case 'error-connect':
-					// connection error can happen after obtaining share list if
-					// NetBIOS is disabled/blocked on the target server,
-					// in which case we keep the info and continue
-					if (!$gotInfo) {
-						return false;
-					}
-			}
-			if ($i) switch ($i[1]) {
-				case 'file':
-				case 'folder':    $info['info'][$i[0]] = $i;
-				case 'disk':
-				case 'server':
-				case 'workgroup': $info[$i[1]][] = $i[0];
-				$gotInfo = true;
-			}
-		}
-		pclose($output);
-
-
-		// restore previous locale
-		if ($old_locale===false) {
-			putenv('LC_ALL');
-		} else {
-			putenv('LC_ALL='.$old_locale);
-		}
-
-		return $info;
-	}
-
-
-	# stats
-
-	function url_stat ($url, $flags = STREAM_URL_STAT_LINK) {
-		if ($s = smb::getstatcache($url)) {
-			return $s;
-		}
-		list ($stat, $pu) = array (false, smb::parse_url ($url));
-		switch ($pu['type']) {
-			case 'host':
-				if ($o = smb::look ($pu))
-					$stat = stat ("/tmp");
-				else
-					trigger_error ("url_stat(): list failed for host '{$pu['host']}'", E_USER_WARNING);
-				break;
-			case 'share':
-				if (smb::execute("ls", $pu))
-					$stat = stat ("/tmp");
-				else
-					trigger_error ("url_stat(): disk resource '{$pu['share']}' not found in '{$pu['host']}'", E_USER_WARNING);
-				break;
-			case 'path':
-				if ($o = smb::execute ('dir "'.$pu['path'].'"', $pu)) {
-					$p = explode('\\', $pu['path']);
-					$name = $p[count($p)-1];
-					if (isset ($o['info'][$name])) {
-						$stat = smb::addstatcache ($url, $o['info'][$name]);
-					} else {
-						trigger_error ("url_stat(): path '{$pu['path']}' not found", E_USER_WARNING);
-					}
-				} else {
-					return false;
-// 					trigger_error ("url_stat(): dir failed for path '{$pu['path']}'", E_USER_WARNING);
-				}
-				break;
-			default: trigger_error ('error in URL', E_USER_ERROR);
-		}
-		return $stat;
-	}
-
-	function addstatcache ($url, $info) {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		$is_file = (strpos ($info['attr'],'D') === FALSE);
-		$s = ($is_file) ? stat ('/etc/passwd') : stat ('/tmp');
-		$s[7] = $s['size'] = $info['size'];
-		$s[8] = $s[9] = $s[10] = $s['atime'] = $s['mtime'] = $s['ctime'] = $info['time'];
-		return $__smb_cache['stat'][$url] = $s;
-	}
-
-	function getstatcache ($url) {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		return isset ($__smb_cache['stat'][$url]) ? $__smb_cache['stat'][$url] : FALSE;
-	}
-
-	function clearstatcache ($url='') {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		if ($url == '') $__smb_cache['stat'] = array (); else unset ($__smb_cache['stat'][$url]);
-	}
-
-
-	# commands
-
-	function unlink ($url) {
-		$pu = smb::parse_url($url);
-		if ($pu['type'] <> 'path') trigger_error('unlink(): error in URL', E_USER_ERROR);
-		smb::clearstatcache ($url);
-		smb_stream_wrapper::cleardircache (dirname($url));
-		return smb::execute ('del "'.$pu['path'].'"', $pu);
-	}
-
-	function rename ($url_from, $url_to) {
-		$replace = false;
-		list ($from, $to) = array (smb::parse_url($url_from), smb::parse_url($url_to));
-		if ($from['host'] <> $to['host'] ||
-			$from['share'] <> $to['share'] ||
-			$from['user'] <> $to['user'] ||
-			$from['pass'] <> $to['pass'] ||
-			$from['domain'] <> $to['domain']) {
-			trigger_error('rename(): FROM & TO must be in same server-share-user-pass-domain', E_USER_ERROR);
-		}
-		if ($from['type'] <> 'path' || $to['type'] <> 'path') {
-			trigger_error('rename(): error in URL', E_USER_ERROR);
-		}
-		smb::clearstatcache ($url_from);
-		$cmd = '';
-		// check if target file exists
-		if (smb::url_stat($url_to)) {
-			// delete target file first
-			$cmd = 'del "' . $to['path'] . '"; ';
-			$replace = true;
-		}
-		$cmd .= 'rename "' . $from['path'] . '" "' . $to['path'] . '"';
-		$result = smb::execute($cmd, $to);
-		if ($replace) {
-			// clear again, else the cache will return the info
-			// from the old file
-			smb::clearstatcache ($url_to);
-		}
-		return $result !== false;
-	}
-
-	function mkdir ($url, $mode, $options) {
-		$pu = smb::parse_url($url);
-		if ($pu['type'] <> 'path') trigger_error('mkdir(): error in URL', E_USER_ERROR);
-		return smb::execute ('mkdir "'.$pu['path'].'"', $pu)!==false;
-	}
-
-	function rmdir ($url) {
-		$pu = smb::parse_url($url);
-		if ($pu['type'] <> 'path') trigger_error('rmdir(): error in URL', E_USER_ERROR);
-		smb::clearstatcache ($url);
-		smb_stream_wrapper::cleardircache (dirname($url));
-		return smb::execute ('rmdir "'.$pu['path'].'"', $pu)!==false;
-	}
-
-}
-
-###################################################################
-# SMB_STREAM_WRAPPER - class to be registered for smb:// URLs
-###################################################################
-
-class smb_stream_wrapper extends smb {
-
-	# variables
-
-	private $stream, $url, $parsed_url = array (), $mode, $tmpfile;
-	private $need_flush = FALSE;
-	private $dir = array (), $dir_index = -1;
-
-
-	# directories
-
-	function dir_opendir ($url, $options) {
-		if ($d = $this->getdircache ($url)) {
-			$this->dir = $d;
-			$this->dir_index = 0;
-			return TRUE;
-		}
-		$pu = smb::parse_url ($url);
-		switch ($pu['type']) {
-			case 'host':
-				if ($o = smb::look ($pu)) {
-					$this->dir = $o['disk'];
-					$this->dir_index = 0;
-				} else {
-					trigger_error ("dir_opendir(): list failed for host '{$pu['host']}'", E_USER_WARNING);
-					return false;
-				}
-				break;
-			case 'share':
-			case 'path':
-				if (is_array($o = smb::execute ('dir "'.$pu['path'].'\*"', $pu))) {
-					$this->dir = array_keys($o['info']);
-					$this->dir_index = 0;
-					$this->adddircache ($url, $this->dir);
-					if(substr($url,-1,1)=='/'){
-						$url=substr($url,0,-1);
-					}
-					foreach ($o['info'] as $name => $info) {
-						smb::addstatcache($url . '/' . $name, $info);
-					}
-				} else {
-					trigger_error ("dir_opendir(): dir failed for path '".$pu['path']."'", E_USER_WARNING);
-					return false;
-				}
-				break;
-			default:
-				trigger_error ('dir_opendir(): error in URL', E_USER_ERROR);
-				return false;
-		}
-		return TRUE;
-	}
-
-	function dir_readdir () {
-		return ($this->dir_index < count($this->dir)) ? $this->dir[$this->dir_index++] : FALSE;
-	}
-
-	function dir_rewinddir () { $this->dir_index = 0; }
-
-	function dir_closedir () { $this->dir = array(); $this->dir_index = -1; return TRUE; }
-
-
-	# cache
-
-	function adddircache ($url, $content) {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		return $__smb_cache['dir'][$url] = $content;
-	}
-
-	function getdircache ($url) {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		return isset ($__smb_cache['dir'][$url]) ? $__smb_cache['dir'][$url] : FALSE;
-	}
-
-	function cleardircache ($url='') {
-		$url = str_replace('//', '/', $url);
-		$url = rtrim($url, '/');
-		global $__smb_cache;
-		if ($url == ''){
-			$__smb_cache['dir'] = array ();
-		}else{
-			unset ($__smb_cache['dir'][$url]);
-		}
-	}
-
-
-	# streams
-
-	function stream_open ($url, $mode, $options, $opened_path) {
-		$this->url = $url;
-		$this->mode = $mode;
-		$this->parsed_url = $pu = smb::parse_url($url);
-		if ($pu['type'] <> 'path') trigger_error('stream_open(): error in URL', E_USER_ERROR);
-		switch ($mode) {
-			case 'r':
-			case 'r+':
-			case 'rb':
-			case 'a':
-			case 'a+':  $this->tmpfile = tempnam('/tmp', 'smb.down.');
-				$result = smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu);
-				if($result === false){
-					return $result;
-				}
-				break;
-			case 'w':
-			case 'w+':
-			case 'wb':
-			case 'x':
-			case 'x+':  $this->cleardircache();
-				$this->tmpfile = tempnam('/tmp', 'smb.up.');
-				$this->need_flush=true;
-		}
-		$this->stream = fopen ($this->tmpfile, $mode);
-		return TRUE;
-	}
-
-	function stream_close () { return fclose($this->stream); }
-
-	function stream_read ($count) { return fread($this->stream, $count); }
-
-	function stream_write ($data) { $this->need_flush = TRUE; return fwrite($this->stream, $data); }
-
-	function stream_eof () { return feof($this->stream); }
-
-	function stream_tell () { return ftell($this->stream); }
-
-	// PATCH: the wrapper must return true when fseek succeeded by returning 0.
-	function stream_seek ($offset, $whence=null) { return fseek($this->stream, $offset, $whence) === 0; }
-
-	function stream_flush () {
-		if ($this->mode <> 'r' && $this->need_flush) {
-			smb::clearstatcache ($this->url);
-			smb::execute ('put "'.$this->tmpfile.'" "'.$this->parsed_url['path'].'"', $this->parsed_url);
-			$this->need_flush = FALSE;
-		}
-	}
-
-	function stream_stat () { return smb::url_stat ($this->url); }
-
-	function __destruct () {
-		if ($this->tmpfile <> '') {
-			if ($this->need_flush) $this->stream_flush ();
-			unlink ($this->tmpfile);
-
-		}
-	}
-
-}
-
-###################################################################
-# Register 'smb' protocol !
-###################################################################
-
-stream_wrapper_register('smb', 'smb_stream_wrapper')
-	or die ('Failed to register protocol');
diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php
index 70f6b0159a6f75721ac106ab28ce327ba2ad5159..e74ce3594c19640f515bb9c2f251224556be18f6 100644
--- a/apps/files_external/appinfo/app.php
+++ b/apps/files_external/appinfo/app.php
@@ -22,6 +22,8 @@ OC::$CLASSPATH['OC\Files\Storage\SFTP_Key'] = 'files_external/lib/sftp_key.php';
 OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php';
 OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php';
 
+require_once __DIR__ . '/../3rdparty/autoload.php';
+
 OCP\App::registerAdmin('files_external', 'settings');
 if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == 'yes') {
 	OCP\App::registerPersonal('files_external', 'personal');
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index 3f0b0f45bfb0eef63858d7895f2440f262d99a05..c554eaf19ee7485fbd37a680a67372826b0a7d53 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -8,139 +8,273 @@
 
 namespace OC\Files\Storage;
 
-require_once __DIR__ . '/../3rdparty/smb4php/smb.php';
+use Icewind\SMB\Exception\Exception;
+use Icewind\SMB\Exception\NotFoundException;
+use Icewind\SMB\NativeServer;
+use Icewind\SMB\Server;
+use Icewind\Streams\CallbackWrapper;
+use Icewind\Streams\IteratorDirectory;
+use OC\Files\Filesystem;
 
-class SMB extends \OC\Files\Storage\StreamWrapper{
-	private $password;
-	private $user;
-	private $host;
-	private $root;
-	private $share;
+class SMB extends Common {
+	/**
+	 * @var \Icewind\SMB\Server
+	 */
+	protected $server;
+
+	/**
+	 * @var \Icewind\SMB\Share
+	 */
+	protected $share;
+
+	/**
+	 * @var \Icewind\SMB\FileInfo[]
+	 */
+	protected $statCache = array();
 
 	public function __construct($params) {
 		if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) {
-			$this->host=$params['host'];
-			$this->user=$params['user'];
-			$this->password=$params['password'];
-			$this->share=$params['share'];
-			$this->root=isset($params['root'])?$params['root']:'/';
-			if ( ! $this->root || $this->root[0]!='/') {
-				$this->root='/'.$this->root;
-			}
-			if (substr($this->root, -1, 1)!='/') {
-				$this->root.='/';
+			if (Server::NativeAvailable()) {
+				$this->server = new NativeServer($params['host'], $params['user'], $params['password']);
+			} else {
+				$this->server = new Server($params['host'], $params['user'], $params['password']);
 			}
-			if ( ! $this->share || $this->share[0]!='/') {
-				$this->share='/'.$this->share;
+			$this->share = $this->server->getShare(trim($params['share'], '/'));
+
+			$this->root = isset($params['root']) ? $params['root'] : '/';
+			if (!$this->root || $this->root[0] != '/') {
+				$this->root = '/' . $this->root;
 			}
-			if (substr($this->share, -1, 1)=='/') {
-				$this->share = substr($this->share, 0, -1);
+			if (substr($this->root, -1, 1) != '/') {
+				$this->root .= '/';
 			}
 		} else {
 			throw new \Exception('Invalid configuration');
 		}
 	}
 
-	public function getId(){
-		return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root;
+	/**
+	 * @return string
+	 */
+	public function getId() {
+		return 'smb::' . $this->server->getUser() . '@' . $this->server->getHost() . '/' . $this->share->getName() . '/' . $this->root;
 	}
 
-	public function constructUrl($path) {
-		if (substr($path, -1)=='/') {
-			$path = substr($path, 0, -1);
-		}
-		if (substr($path, 0, 1)=='/') {
-			$path = substr($path, 1);
+	/**
+	 * @param string $path
+	 * @return string
+	 */
+	protected function buildPath($path) {
+		return Filesystem::normalizePath($this->root . '/' . $path);
+	}
+
+	/**
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo
+	 */
+	protected function getFileInfo($path) {
+		$path = $this->buildPath($path);
+		if (!isset($this->statCache[$path])) {
+			$this->statCache[$path] = $this->share->stat($path);
 		}
-		// remove trailing dots which some versions of samba don't seem to like
-		$path = rtrim($path, '.');
-		$path = urlencode($path);
-		$user = urlencode($this->user);
-		$pass = urlencode($this->password);
-		return 'smb://'.$user.':'.$pass.'@'.$this->host.$this->share.$this->root.$path;
+		return $this->statCache[$path];
 	}
 
-	public function stat($path) {
-		if ( ! $path and $this->root=='/') {//mtime doesn't work for shares
-			$stat=stat($this->constructUrl($path));
-			if (empty($stat)) {
-				return false;
-			}
-			$mtime=$this->shareMTime();
-			$stat['mtime']=$mtime;
-			return $stat;
-		} else {
-			$stat = stat($this->constructUrl($path));
+	/**
+	 * @param string $path
+	 * @return \Icewind\SMB\IFileInfo[]
+	 */
+	protected function getFolderContents($path) {
+		$path = $this->buildPath($path);
+		$files = $this->share->dir($path);
+		foreach ($files as $file) {
+			$this->statCache[$path . '/' . $file->getName()] = $file;
+		}
+		return $files;
+	}
 
-			// smb4php can return an empty array if the connection could not be established
-			if (empty($stat)) {
-				return false;
-			}
+	/**
+	 * @param \Icewind\SMB\IFileInfo $info
+	 * @return array
+	 */
+	protected function formatInfo($info) {
+		return array(
+			'size' => $info->getSize(),
+			'mtime' => $info->getMTime()
+		);
+	}
 
-			return $stat;
-		}
+	/**
+	 * @param string $path
+	 * @return array
+	 */
+	public function stat($path) {
+		return $this->formatInfo($this->getFileInfo($path));
 	}
 
 	/**
-	 * Unlinks file or directory
 	 * @param string $path
+	 * @return bool
 	 */
 	public function unlink($path) {
-		if ($this->is_dir($path)) {
-			$this->rmdir($path);
-		}
-		else {
-			$url = $this->constructUrl($path);
-			unlink($url);
-			clearstatcache(false, $url);
+		try {
+			if ($this->is_dir($path)) {
+				return $this->rmdir($path);
+			} else {
+				$path = $this->buildPath($path);
+				unset($this->statCache[$path]);
+				$this->share->del($path);
+				return true;
+			}
+		} catch (NotFoundException $e) {
+			return false;
 		}
-		// smb4php still returns false even on success so
-		// check here whether file was really deleted
-		return !file_exists($path);
 	}
 
 	/**
 	 * check if a file or folder has been updated since $time
+	 *
 	 * @param string $path
 	 * @param int $time
 	 * @return bool
 	 */
-	public function hasUpdated($path,$time) {
-		if(!$path and $this->root=='/') {
+	public function hasUpdated($path, $time) {
+		if (!$path and $this->root == '/') {
 			// mtime doesn't work for shares, but giving the nature of the backend,
 			// doing a full update is still just fast enough
 			return true;
 		} else {
-			$actualTime=$this->filemtime($path);
-			return $actualTime>$time;
+			$actualTime = $this->filemtime($path);
+			return $actualTime > $time;
 		}
 	}
 
 	/**
-	 * get the best guess for the modification time of the share
+	 * @param string $path
+	 * @param string $mode
+	 * @return resource
 	 */
-	private function shareMTime() {
-		$dh=$this->opendir('');
-		$lastCtime=0;
-		if(is_resource($dh)) {
-			while (($file = readdir($dh)) !== false) {
-				if ($file!='.' and $file!='..') {
-					$ctime=$this->filemtime($file);
-					if ($ctime>$lastCtime) {
-						$lastCtime=$ctime;
+	public function fopen($path, $mode) {
+		$fullPath = $this->buildPath($path);
+		try {
+			switch ($mode) {
+				case 'r':
+				case 'rb':
+					if (!$this->file_exists($path)) {
+						return false;
+					}
+					return $this->share->read($fullPath);
+				case 'w':
+				case 'wb':
+					return $this->share->write($fullPath);
+				case 'a':
+				case 'ab':
+				case 'r+':
+				case 'w+':
+				case 'wb+':
+				case 'a+':
+				case 'x':
+				case 'x+':
+				case 'c':
+				case 'c+':
+					//emulate these
+					if (strrpos($path, '.') !== false) {
+						$ext = substr($path, strrpos($path, '.'));
+					} else {
+						$ext = '';
 					}
+					if ($this->file_exists($path)) {
+						if (!$this->isUpdatable($path)) {
+							return false;
+						}
+						$tmpFile = $this->getCachedFile($path);
+					} else {
+						if (!$this->isCreatable(dirname($path))) {
+							return false;
+						}
+						$tmpFile = \OCP\Files::tmpFile($ext);
+					}
+					$source = fopen($tmpFile, $mode);
+					$share = $this->share;
+					return CallBackWrapper::wrap($source, null, null, function () use ($tmpFile, $fullPath, $share) {
+						$share->put($tmpFile, $fullPath);
+						unlink($tmpFile);
+					});
+			}
+			return false;
+		} catch (NotFoundException $e) {
+			return false;
+		}
+	}
+
+	public function rmdir($path) {
+		try {
+			$this->statCache = array();
+			$content = $this->share->dir($this->buildPath($path));
+			foreach ($content as $file) {
+				if ($file->isDirectory()) {
+					$this->rmdir($path . '/' . $file->getName());
+				} else {
+					$this->share->del($file->getPath());
 				}
 			}
+			$this->share->rmdir($this->buildPath($path));
+			return true;
+		} catch (NotFoundException $e) {
+			return false;
+		}
+	}
+
+	public function touch($path, $time = null) {
+		if (!$this->file_exists($path)) {
+			$fh = $this->share->write($this->buildPath($path));
+			fclose($fh);
+			return true;
+		}
+		return false;
+	}
+
+	public function opendir($path) {
+		$files = $this->getFolderContents($path);
+		$names = array_map(function ($info) {
+			/** @var \Icewind\SMB\IFileInfo $info */
+			return $info->getName();
+		}, $files);
+		return IteratorDirectory::wrap($names);
+	}
+
+	public function filetype($path) {
+		try {
+			return $this->getFileInfo($path)->isDirectory() ? 'dir' : 'file';
+		} catch (NotFoundException $e) {
+			return false;
+		}
+	}
+
+	public function mkdir($path) {
+		$path = $this->buildPath($path);
+		try {
+			$this->share->mkdir($path);
+			return true;
+		} catch (Exception $e) {
+			return false;
+		}
+	}
+
+	public function file_exists($path) {
+		try {
+			$this->getFileInfo($path);
+			return true;
+		} catch (NotFoundException $e) {
+			return false;
 		}
-		return $lastCtime;
 	}
 
 	/**
 	 * check if smbclient is installed
 	 */
 	public static function checkDependencies() {
-		$smbClientExists = (bool) \OC_Helper::findBinaryPath('smbclient');
+		$smbClientExists = (bool)\OC_Helper::findBinaryPath('smbclient');
 		return $smbClientExists ? true : array('smbclient');
 	}
-
 }
diff --git a/apps/files_external/lib/smb_oc.php b/apps/files_external/lib/smb_oc.php
index a7c93d97fd170e96cf674faa80af83e502e32748..245d1ed79b3e5835963f039e3be2b897da7e386c 100644
--- a/apps/files_external/lib/smb_oc.php
+++ b/apps/files_external/lib/smb_oc.php
@@ -8,9 +8,12 @@
 
 namespace OC\Files\Storage;
 
-require_once __DIR__ . '/../3rdparty/smb4php/smb.php';
 
-class SMB_OC extends \OC\Files\Storage\SMB {
+use Icewind\SMB\Exception\AccessDeniedException;
+use Icewind\SMB\Exception\Exception;
+use Icewind\SMB\Server;
+
+class SMB_OC extends SMB {
 	private $username_as_share;
 
 	/**
@@ -19,18 +22,18 @@ class SMB_OC extends \OC\Files\Storage\SMB {
 	 */
 	public function __construct($params) {
 		if (isset($params['host']) && \OC::$server->getSession()->exists('smb-credentials')) {
-			$host=$params['host'];
+			$host = $params['host'];
 			$this->username_as_share = ($params['username_as_share'] === 'true');
 
 			$params_auth = json_decode(\OC::$server->getCrypto()->decrypt(\OC::$server->getSession()->get('smb-credentials')), true);
 			$user = \OC::$server->getSession()->get('loginname');
 			$password = $params_auth['password'];
 
-			$root=isset($params['root'])?$params['root']:'/';
+			$root = isset($params['root']) ? $params['root'] : '/';
 			$share = '';
 
 			if ($this->username_as_share) {
-				$share = '/'.$user;
+				$share = '/' . $user;
 			} elseif (isset($params['share'])) {
 				$share = $params['share'];
 			} else {
@@ -84,33 +87,15 @@ class SMB_OC extends \OC\Files\Storage\SMB {
 			}
 			return false;
 		} else {
-			$smb = new \smb();
-			$pu = $smb->parse_url($this->constructUrl(''));
-
-			// Attempt to connect anonymously
-			$pu['user'] = '';
-			$pu['pass'] = '';
-
-			// Share cannot be checked if dynamic
-			if ($this->username_as_share) {
-				if ($smb->look($pu)) {
-					return true;
-				} else {
-					return false;
-				}
-			}
-			if (!$pu['share']) {
-				return false;
-			}
-
-			// The following error messages are expected due to anonymous login
-			$regexp = array(
-				'(NT_STATUS_ACCESS_DENIED)' => 'skip'
-			) + $smb->getRegexp();
+			$server = new Server($this->server->getHost(), '', '');
 
-			if ($smb->client("-d 0 " . escapeshellarg('//' . $pu['host'] . '/' . $pu['share']) . " -c exit", $pu, $regexp)) {
+			try {
+				$server->listShares();
 				return true;
-			} else {
+			} catch (AccessDeniedException $e) {
+				// expected due to anonymous login
+				return true;
+			} catch (Exception $e) {
 				return false;
 			}
 		}
diff --git a/apps/files_external/tests/backends/smb.php b/apps/files_external/tests/backends/smb.php
index 4b2f4425ebcef11c2291184b86b271062ea815e1..4b1150c6a258d5c39bcea4aac57c6840513a9b64 100644
--- a/apps/files_external/tests/backends/smb.php
+++ b/apps/files_external/tests/backends/smb.php
@@ -10,8 +10,6 @@ namespace Test\Files\Storage;
 
 class SMB extends Storage {
 
-	private $config;
-
 	protected function setUp() {
 		parent::setUp();
 
@@ -20,6 +18,9 @@ class SMB extends Storage {
 		if (!is_array($config) or !$config['run']) {
 			$this->markTestSkipped('Samba backend not configured');
 		}
+		if (substr($config['root'], -1, 1) != '/') {
+			$config['root'] .= '/';
+		}
 		$config['root'] .= $id; //make sure we have an new empty folder to work in
 		$this->instance = new \OC\Files\Storage\SMB($config);
 		$this->instance->mkdir('/');
@@ -27,7 +28,7 @@ class SMB extends Storage {
 
 	protected function tearDown() {
 		if ($this->instance) {
-			\OCP\Files::rmdirr($this->instance->constructUrl(''));
+			$this->instance->rmdir('');
 		}
 
 		parent::tearDown();
diff --git a/apps/files_external/tests/backends/webdav.php b/apps/files_external/tests/backends/webdav.php
index c390612810d0bafbe1bad9125b0588622c0215c1..c454c8e4a9dabd76df31158b5a6d94dadc2e693b 100644
--- a/apps/files_external/tests/backends/webdav.php
+++ b/apps/files_external/tests/backends/webdav.php
@@ -10,8 +10,6 @@ namespace Test\Files\Storage;
 
 class DAV extends Storage {
 
-	private $config;
-
 	protected function setUp() {
 		parent::setUp();
 
diff --git a/apps/files_external/tests/smbfunctions.php b/apps/files_external/tests/smbfunctions.php
deleted file mode 100644
index cf9f7cb20fe2fba28698885bc62902946112773d..0000000000000000000000000000000000000000
--- a/apps/files_external/tests/smbfunctions.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-/**
- * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-namespace Test\Files\Storage;
-
-class SMBFunctions extends \Test\TestCase {
-
-	protected function setUp() {
-		parent::setUp();
-
-		// dummy config
-		$this->config = array(
-			'run'=>false,
-			'user'=>'test',
-			'password'=>'testpassword',
-			'host'=>'smbhost',
-			'share'=>'/sharename',
-			'root'=>'/rootdir/',
-		);
-
-		$this->instance = new \OC\Files\Storage\SMB($this->config);
-	}
-
-	public function testGetId() {
-		$this->assertEquals('smb::test@smbhost//sharename//rootdir/', $this->instance->getId());
-	}
-
-	public function testConstructUrl() {
-		$this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc", $this->instance->constructUrl('/abc'));
-		$this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc", $this->instance->constructUrl('/abc/'));
-		$this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc%2F", $this->instance->constructUrl('/abc/.'));
-		$this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc%2Fdef", $this->instance->constructUrl('/abc/def'));
-	}
-}