diff --git a/apps/files_external/appinfo/database.xml b/apps/files_external/appinfo/database.xml
new file mode 100644
index 0000000000000000000000000000000000000000..27918bf981976e7b9f6810af3d580493ead8f87e
--- /dev/null
+++ b/apps/files_external/appinfo/database.xml
@@ -0,0 +1,222 @@
+<database>
+	<name>*dbname*</name>
+	<create>true</create>
+	<overwrite>false</overwrite>
+	<charset>utf8</charset>
+	<table>
+		<name>*dbprefix*external_mounts</name>
+		<declaration>
+			<field>
+				<name>mount_id</name>
+				<type>integer</type>
+				<default>0</default>
+				<notnull>true</notnull>
+				<autoincrement>1</autoincrement>
+				<length>6</length>
+			</field>
+			<field>
+				<name>mount_point</name>
+				<type>text</type>
+				<length>128</length>
+				<notnull>true</notnull>
+			</field>
+			<field>
+				<name>storage_backend</name>
+				<type>text</type>
+				<length>64</length>
+				<notnull>true</notnull>
+			</field>
+			<field>
+				<name>auth_backend</name>
+				<type>text</type>
+				<length>64</length>
+				<notnull>true</notnull>
+			</field>
+			<field>
+				<name>priority</name>
+				<type>integer</type>
+				<default>100</default>
+				<length>4</length>
+				<notnull>true</notnull>
+			</field>
+			<!-- admin = 1, personal = 2-->
+			<field>
+				<name>type</name>
+				<type>integer</type>
+				<length>4</length>
+				<notnull>true</notnull>
+			</field>
+		</declaration>
+	</table>
+	<table>
+		<name>*dbprefix*external_applicable</name>
+		<declaration>
+			<field>
+				<name>applicable_id</name>
+				<type>integer</type>
+				<default>0</default>
+				<notnull>true</notnull>
+				<autoincrement>1</autoincrement>
+				<length>6</length>
+			</field>
+			<field>
+				<!--foreign key: external_mounts.mount_id-->
+				<name>mount_id</name>
+				<type>integer</type>
+				<notnull>true</notnull>
+				<length>6</length>
+			</field>
+			<field>
+				<!-- possible mount types: global = 1, group = 2, user = 3 -->
+				<name>type</name>
+				<type>integer</type>
+				<length>4</length>
+				<notnull>true</notnull>
+			</field>
+			<field>
+				<!-- user_id, group_id or null for global mounts -->
+				<name>value</name>
+				<type>text</type>
+				<length>64</length>
+			</field>
+			<index>
+				<name>mount_id_app_index</name>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+			<index>
+				<name>applicable_value_index</name>
+				<field>
+					<name>type</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>value</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+			<index>
+				<name>applicable_value_mount_index</name>
+				<unique>true</unique>
+				<field>
+					<name>type</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>value</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+		</declaration>
+	</table>
+	<table>
+		<name>*dbprefix*external_config</name>
+		<declaration>
+			<field>
+				<name>config_id</name>
+				<type>integer</type>
+				<default>0</default>
+				<notnull>true</notnull>
+				<autoincrement>1</autoincrement>
+				<length>6</length>
+			</field>
+			<field>
+				<!--foreign key: external_mounts.mount_id-->
+				<name>mount_id</name>
+				<type>integer</type>
+				<notnull>true</notnull>
+				<length>6</length>
+			</field>
+			<field>
+				<name>key</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+			</field>
+			<field>
+				<name>value</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>4096</length>
+			</field>
+
+			<index>
+				<name>config_mount_id</name>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+			<index>
+				<name>config_mount_key</name>
+				<unique>true</unique>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>key</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+		</declaration>
+	</table>
+	<table>
+		<name>*dbprefix*external_options</name>
+		<declaration>
+			<field>
+				<name>option_id</name>
+				<type>integer</type>
+				<default>0</default>
+				<notnull>true</notnull>
+				<autoincrement>1</autoincrement>
+				<length>6</length>
+			</field>
+			<field>
+				<!--foreign key: external_mounts.mount_id-->
+				<name>mount_id</name>
+				<type>integer</type>
+				<notnull>true</notnull>
+				<length>6</length>
+			</field>
+			<field>
+				<name>key</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+			</field>
+			<field>
+				<name>value</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>256</length>
+			</field>
+
+			<index>
+				<name>option_mount_id</name>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+			<index>
+				<name>option_mount_key</name>
+				<unique>true</unique>
+				<field>
+					<name>mount_id</name>
+					<sorting>ascending</sorting>
+				</field>
+				<field>
+					<name>key</name>
+					<sorting>ascending</sorting>
+				</field>
+			</index>
+		</declaration>
+	</table>
+</database>
diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml
index bb494a2eaba9268dd73432999dc473bf93e6226b..f6d583d0a5adafd0ef2b17501a1401330f8c6c75 100644
--- a/apps/files_external/appinfo/info.xml
+++ b/apps/files_external/appinfo/info.xml
@@ -14,7 +14,7 @@
 		<admin>admin-external-storage</admin>
 	</documentation>
 	<rememberlogin>false</rememberlogin>
-	<version>0.4.0</version>
+	<version>0.5.0</version>
 	<types>
 		<filesystem/>
 	</types>
diff --git a/apps/files_external/appinfo/update.php b/apps/files_external/appinfo/update.php
new file mode 100644
index 0000000000000000000000000000000000000000..2eedfe9b88fb0185eb69dca89e4d567e3b0f237b
--- /dev/null
+++ b/apps/files_external/appinfo/update.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+$installedVersion = \OC::$server->getConfig()->getAppValue('files_external', 'installed_version');
+
+$app = new \OCA\Files_external\Appinfo\Application();
+
+// Migration to db config
+if (version_compare($installedVersion, '0.5.0', '<')) {
+	$migrator = $app->getContainer()->query('OCA\Files_external\Migration\StorageMigrator');
+	$migrator->migrateGlobal();
+}
diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php
index f9640d53377649341ca7aa6a60aec58c614c7fc0..4e37e6a4004e072a65c1c1d26491df68efafea8d 100644
--- a/apps/files_external/lib/config/configadapter.php
+++ b/apps/files_external/lib/config/configadapter.php
@@ -23,6 +23,7 @@
 
 namespace OCA\Files_External\Config;
 
+use OCA\Files_external\Migration\StorageMigrator;
 use OCP\Files\Storage;
 use OC\Files\Mount\MountPoint;
 use OCP\Files\Storage\IStorageFactory;
@@ -44,17 +45,22 @@ class ConfigAdapter implements IMountProvider {
 
 	/** @var UserGlobalStoragesService */
 	private $userGlobalStoragesService;
+	/** @var StorageMigrator  */
+	private $migrator;
 
 	/**
 	 * @param UserStoragesService $userStoragesService
 	 * @param UserGlobalStoragesService $userGlobalStoragesService
+	 * @param StorageMigrator $migrator
 	 */
 	public function __construct(
 		UserStoragesService $userStoragesService,
-		UserGlobalStoragesService $userGlobalStoragesService
+		UserGlobalStoragesService $userGlobalStoragesService,
+		StorageMigrator $migrator
 	) {
 		$this->userStoragesService = $userStoragesService;
 		$this->userGlobalStoragesService = $userGlobalStoragesService;
+		$this->migrator = $migrator;
 	}
 
 	/**
@@ -108,6 +114,8 @@ class ConfigAdapter implements IMountProvider {
 	 * @return \OCP\Files\Mount\IMountPoint[]
 	 */
 	public function getMountsForUser(IUser $user, IStorageFactory $loader) {
+		$this->migrator->migrateUser();
+
 		$mounts = [];
 
 		$this->userStoragesService->setUser($user);
@@ -124,7 +132,7 @@ class ConfigAdapter implements IMountProvider {
 
 			$mount = new MountPoint(
 				$impl,
-				'/'.$user->getUID().'/files' . $storage->getMountPoint(),
+				'/' . $user->getUID() . '/files' . $storage->getMountPoint(),
 				null,
 				$loader,
 				$storage->getMountOptions()
@@ -145,7 +153,7 @@ class ConfigAdapter implements IMountProvider {
 				$this->userStoragesService,
 				$storage->getId(),
 				$impl,
-				'/'.$user->getUID().'/files' . $storage->getMountPoint(),
+				'/' . $user->getUID() . '/files' . $storage->getMountPoint(),
 				null,
 				$loader,
 				$storage->getMountOptions()
diff --git a/apps/files_external/migration/storagemigrator.php b/apps/files_external/migration/storagemigrator.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8e323121ea7c51a0feab529e96a5599d61db71f
--- /dev/null
+++ b/apps/files_external/migration/storagemigrator.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_external\Migration;
+
+use OCA\Files_External\Service\BackendService;
+use OCA\Files_External\Service\DBConfigService;
+use OCA\Files_external\Service\GlobalLegacyStoragesService;
+use OCA\Files_external\Service\GlobalStoragesService;
+use OCA\Files_external\Service\LegacyStoragesService;
+use OCA\Files_external\Service\StoragesService;
+use OCA\Files_external\Service\UserLegacyStoragesService;
+use OCA\Files_external\Service\UserStoragesService;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\ILogger;
+use OCP\IUserSession;
+
+/**
+ * Migrate mount config from mount.json to the database
+ */
+class StorageMigrator {
+	/**
+	 * @var BackendService
+	 */
+	private $backendService;
+
+	/**
+	 * @var DBConfigService
+	 */
+	private $dbConfig;
+
+	/**
+	 * @var IUserSession
+	 */
+	private $userSession;
+
+	/**
+	 * @var IConfig
+	 */
+	private $config;
+
+	/**
+	 * @var IDBConnection
+	 */
+	private $connection;
+
+	/**
+	 * @var ILogger
+	 */
+	private $logger;
+
+	/**
+	 * StorageMigrator constructor.
+	 *
+	 * @param BackendService $backendService
+	 * @param DBConfigService $dbConfig
+	 * @param IUserSession $userSession
+	 * @param IConfig $config
+	 * @param IDBConnection $connection
+	 * @param ILogger $logger
+	 */
+	public function __construct(
+		BackendService $backendService,
+		DBConfigService $dbConfig,
+		IUserSession $userSession,
+		IConfig $config,
+		IDBConnection $connection,
+		ILogger $logger
+	) {
+		$this->backendService = $backendService;
+		$this->dbConfig = $dbConfig;
+		$this->userSession = $userSession;
+		$this->config = $config;
+		$this->connection = $connection;
+		$this->logger = $logger;
+	}
+
+	private function migrate(LegacyStoragesService $legacyService, StoragesService $storageService) {
+		$existingStorage = $legacyService->getAllStorages();
+
+		$this->connection->beginTransaction();
+		try {
+			foreach ($existingStorage as $storage) {
+				$storageService->addStorage($storage);
+			}
+			$this->connection->commit();
+		} catch (\Exception $e) {
+			$this->logger->logException($e);
+			$this->connection->rollBack();
+		}
+	}
+
+	/**
+	 * Migrate admin configured storages
+	 */
+	public function migrateGlobal() {
+		$legacyService = new GlobalLegacyStoragesService($this->backendService);
+		$storageService = new GlobalStoragesService($this->backendService, $this->dbConfig);
+
+		$this->migrate($legacyService, $storageService);
+	}
+
+	/**
+	 * Migrate personal storages configured by the current user
+	 */
+	public function migrateUser() {
+		$userId = $this->userSession->getUser()->getUID();
+		$userVersion = $this->config->getUserValue($userId, 'files_external', 'config_version', '0.0.0');
+		if (version_compare($userVersion, '0.5.0', '<')) {
+			$this->config->setUserValue($userId, 'files_external', 'config_version', '0.5.0');
+			$legacyService = new UserLegacyStoragesService($this->backendService, $this->userSession);
+			$storageService = new UserStoragesService($this->backendService, $this->dbConfig, $this->userSession);
+
+			$this->migrate($legacyService, $storageService);
+		}
+	}
+}
diff --git a/apps/files_external/service/dbconfigservice.php b/apps/files_external/service/dbconfigservice.php
new file mode 100644
index 0000000000000000000000000000000000000000..76f7052c4ed8e21869bdd7c54841edfa3ed7c955
--- /dev/null
+++ b/apps/files_external/service/dbconfigservice.php
@@ -0,0 +1,376 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_External\Service;
+
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+
+/**
+ * Stores the mount config in the database
+ */
+class DBConfigService {
+	const MOUNT_TYPE_ADMIN = 1;
+	const MOUNT_TYPE_PERSONAl = 2;
+
+	const APPLICABLE_TYPE_GLOBAL = 1;
+	const APPLICABLE_TYPE_GROUP = 2;
+	const APPLICABLE_TYPE_USER = 3;
+
+	/**
+	 * @var IDBConnection
+	 */
+	private $connection;
+
+	/**
+	 * DBConfigService constructor.
+	 *
+	 * @param IDBConnection $connection
+	 */
+	public function __construct(IDBConnection $connection) {
+		$this->connection = $connection;
+	}
+
+	/**
+	 * @param int $mountId
+	 * @return array
+	 */
+	public function getMountById($mountId) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
+			->from('external_mounts', 'm')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+		$mounts = $this->getMountsFromQuery($query);
+		if (count($mounts) > 0) {
+			return $mounts[0];
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * Get admin defined mounts
+	 *
+	 * @return array
+	 */
+	public function getAdminMounts() {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
+			->from('external_mounts')
+			->where($builder->expr()->eq('type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+		return $this->getMountsFromQuery($query);
+	}
+
+	protected function getForQuery(IQueryBuilder $builder, $type, $value) {
+		$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
+			->from('external_mounts', 'm')
+			->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id')
+			->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, \PDO::PARAM_INT)));
+
+		if (is_null($value)) {
+			$query = $query->andWhere($builder->expr()->isNull('a.value'));
+		} else {
+			$query = $query->andWhere($builder->expr()->eq('a.value', $builder->createNamedParameter($value)));
+		}
+
+		return $query;
+	}
+
+	/**
+	 * Get mounts by applicable
+	 *
+	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
+	 * @param string|null $value user_id, group_id or null for global mounts
+	 * @return array
+	 */
+	public function getMountsFor($type, $value) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $this->getForQuery($builder, $type, $value);
+
+		return $this->getMountsFromQuery($query);
+	}
+
+	/**
+	 * Get admin defined mounts by applicable
+	 *
+	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
+	 * @param string|null $value user_id, group_id or null for global mounts
+	 * @return array
+	 */
+	public function getAdminMountsFor($type, $value) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $this->getForQuery($builder, $type, $value);
+		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+
+		return $this->getMountsFromQuery($query);
+	}
+
+	/**
+	 * Get admin defined mounts for multiple applicable
+	 *
+	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
+	 * @param string[] $values user_ids or group_ids
+	 * @return array
+	 */
+	public function getAdminMountsForMultiple($type, array $values) {
+		$builder = $this->connection->getQueryBuilder();
+		$params = array_map(function ($value) use ($builder) {
+			return $builder->createNamedParameter($value, \PDO::PARAM_STR);
+		}, $values);
+
+		$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
+			->from('external_mounts', 'm')
+			->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id')
+			->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, \PDO::PARAM_INT)))
+			->andWhere($builder->expr()->in('a.value', $params));
+		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+
+		return $this->getMountsFromQuery($query);
+	}
+
+	/**
+	 * Get user defined mounts by applicable
+	 *
+	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
+	 * @param string|null $value user_id, group_id or null for global mounts
+	 * @return array
+	 */
+	public function getUserMountsFor($type, $value) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $this->getForQuery($builder, $type, $value);
+		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_PERSONAl, \PDO::PARAM_INT)));
+
+		return $this->getMountsFromQuery($query);
+	}
+
+	/**
+	 * Add a mount to the database
+	 *
+	 * @param string $mountPoint
+	 * @param string $storageBackend
+	 * @param string $authBackend
+	 * @param int $priority
+	 * @param int $type self::MOUNT_TYPE_ADMIN or self::MOUNT_TYPE_PERSONAL
+	 * @return int the id of the new mount
+	 */
+	public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+		if (!$priority) {
+			$priority = 100;
+		}
+		$builder = $this->connection->getQueryBuilder();
+		$query = $builder->insert('external_mounts')
+			->values([
+				'mount_point' => $builder->createNamedParameter($mountPoint, \PDO::PARAM_STR),
+				'storage_backend' => $builder->createNamedParameter($storageBackend, \PDO::PARAM_STR),
+				'auth_backend' => $builder->createNamedParameter($authBackend, \PDO::PARAM_STR),
+				'priority' => $builder->createNamedParameter($priority, \PDO::PARAM_INT),
+				'type' => $builder->createNamedParameter($type, \PDO::PARAM_INT)
+			]);
+		$query->execute();
+		return (int)$this->connection->lastInsertId('external_mounts');
+	}
+
+	/**
+	 * Remove a mount from the database
+	 *
+	 * @param int $mountId
+	 */
+	public function removeMount($mountId) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $builder->delete('external_mounts')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+		$query->execute();
+
+		$query = $builder->delete('external_applicable')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+		$query->execute();
+
+		$query = $builder->delete('external_config')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+		$query->execute();
+
+		$query = $builder->delete('external_options')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+		$query->execute();
+	}
+
+	/**
+	 * @param int $mountId
+	 * @param string $key
+	 * @param string $value
+	 */
+	public function setConfig($mountId, $key, $value) {
+		$count = $this->connection->insertIfNotExist('*PREFIX*external_config', [
+			'mount_id' => $mountId,
+			'key' => $key,
+			'value' => $value
+		], ['mount_id', 'key']);
+		if ($count === 0) {
+			$builder = $this->connection->getQueryBuilder();
+			$query = $builder->update('external_config')
+				->set('value', $builder->createNamedParameter($value, \PDO::PARAM_STR))
+				->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+				->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, \PDO::PARAM_STR)));
+			$query->execute();
+		}
+	}
+
+	/**
+	 * @param int $mountId
+	 * @param string $key
+	 * @param string $value
+	 */
+	public function setOption($mountId, $key, $value) {
+		$count = $this->connection->insertIfNotExist('*PREFIX*external_options', [
+			'mount_id' => $mountId,
+			'key' => $key,
+			'value' => json_encode($value)
+		], ['mount_id', 'key']);
+		if ($count === 0) {
+			$builder = $this->connection->getQueryBuilder();
+			$query = $builder->update('external_options')
+				->set('value', $builder->createNamedParameter(json_encode($value), \PDO::PARAM_STR))
+				->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+				->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, \PDO::PARAM_STR)));
+			$query->execute();
+		}
+	}
+
+	public function addApplicable($mountId, $type, $value) {
+		$this->connection->insertIfNotExist('*PREFIX*external_applicable', [
+			'mount_id' => $mountId,
+			'type' => $type,
+			'value' => $value
+		], ['mount_id', 'type', 'value']);
+	}
+
+	public function removeApplicable($mountId, $type, $value) {
+		$builder = $this->connection->getQueryBuilder();
+		$query = $builder->delete('external_applicable')
+			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+			->andWhere($builder->expr()->eq('type', $builder->createNamedParameter($type, \PDO::PARAM_INT)))
+			->andWhere($builder->expr()->eq('value', $builder->createNamedParameter($value, \PDO::PARAM_STR)));
+		$query->execute();
+	}
+
+	private function getMountsFromQuery(IQueryBuilder $query) {
+		$result = $query->execute();
+		$mounts = $result->fetchAll();
+
+		$mountIds = array_map(function ($mount) {
+			return $mount['mount_id'];
+		}, $mounts);
+
+		$applicable = $this->getApplicableForMounts($mountIds);
+		$config = $this->getConfigForMounts($mountIds);
+		$options = $this->getOptionsForMounts($mountIds);
+
+		return array_map(function ($mount, $applicable, $config, $options) {
+			$mount['type'] = (int)$mount['type'];
+			$mount['priority'] = (int)$mount['priority'];
+			$mount['applicable'] = $applicable;
+			$mount['config'] = $config;
+			$mount['options'] = $options;
+			return $mount;
+		}, $mounts, $applicable, $config, $options);
+	}
+
+	/**
+	 * Get mount options from a table grouped by mount id
+	 *
+	 * @param string $table
+	 * @param string[] $fields
+	 * @param int[] $mountIds
+	 * @return array [$mountId => [['field1' => $value1, ...], ...], ...]
+	 */
+	private function selectForMounts($table, array $fields, array $mountIds) {
+		if (count($mountIds) === 0) {
+			return [];
+		}
+		$builder = $this->connection->getQueryBuilder();
+		$fields[] = 'mount_id';
+		$placeHolders = array_map(function ($id) use ($builder) {
+			return $builder->createPositionalParameter($id, \PDO::PARAM_INT);
+		}, $mountIds);
+		$query = $builder->select($fields)
+			->from($table)
+			->where($builder->expr()->in('mount_id', $placeHolders));
+		$rows = $query->execute()->fetchAll();
+
+		$result = [];
+		foreach ($mountIds as $mountId) {
+			$result[$mountId] = [];
+		}
+		foreach ($rows as $row) {
+			if (isset($row['type'])) {
+				$row['type'] = (int)$row['type'];
+			}
+			$result[$row['mount_id']][] = $row;
+		}
+		return $result;
+	}
+
+	/**
+	 * @param int[] $mountIds
+	 * @return array [$id => [['type' => $type, 'value' => $value], ...], ...]
+	 */
+	public function getApplicableForMounts($mountIds) {
+		return $this->selectForMounts('external_applicable', ['type', 'value'], $mountIds);
+	}
+
+	/**
+	 * @param int[] $mountIds
+	 * @return array [$id => ['key1' => $value1, ...], ...]
+	 */
+	public function getConfigForMounts($mountIds) {
+		$mountConfigs = $this->selectForMounts('external_config', ['key', 'value'], $mountIds);
+		return array_map([$this, 'createKeyValueMap'], $mountConfigs);
+	}
+
+	/**
+	 * @param int[] $mountIds
+	 * @return array [$id => ['key1' => $value1, ...], ...]
+	 */
+	public function getOptionsForMounts($mountIds) {
+		$mountOptions = $this->selectForMounts('external_options', ['key', 'value'], $mountIds);
+		$optionsMap = array_map([$this, 'createKeyValueMap'], $mountOptions);
+		return array_map(function (array $options) {
+			return array_map(function ($option) {
+				return json_decode($option);
+			}, $options);
+		}, $optionsMap);
+	}
+
+	/**
+	 * @param array $keyValuePairs [['key'=>$key, 'value=>$value], ...]
+	 * @return array ['key1' => $value1, ...]
+	 */
+	private function createKeyValueMap(array $keyValuePairs) {
+		$keys = array_map(function ($pair) {
+			return $pair['key'];
+		}, $keyValuePairs);
+		$values = array_map(function ($pair) {
+			return $pair['value'];
+		}, $keyValuePairs);
+
+		return array_combine($keys, $values);
+	}
+}
diff --git a/apps/files_external/service/globallegacystoragesservice.php b/apps/files_external/service/globallegacystoragesservice.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc6a8862cddf5380b9addb09476cb89e700a1546
--- /dev/null
+++ b/apps/files_external/service/globallegacystoragesservice.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_external\Service;
+
+/**
+ * Read admin defined mounts from the legacy mount.json
+ */
+class GlobalLegacyStoragesService extends LegacyStoragesService {
+	/**
+	 * @param BackendService $backendService
+	 */
+	public function __construct(BackendService $backendService) {
+		$this->backendService = $backendService;
+	}
+
+	/**
+	 * Read legacy config data
+	 *
+	 * @return array list of mount configs
+	 */
+	protected function readLegacyConfig() {
+		// read global config
+		return \OC_Mount_Config::readData();
+	}
+}
diff --git a/apps/files_external/service/globalstoragesservice.php b/apps/files_external/service/globalstoragesservice.php
index ec9b8e782fa85c6561bb8de9d1bd88b9f3696459..2d25288e7bcd2a882ee77295b5f4715ebde647ba 100644
--- a/apps/files_external/service/globalstoragesservice.php
+++ b/apps/files_external/service/globalstoragesservice.php
@@ -33,68 +33,6 @@ use \OCA\Files_external\NotFoundException;
  * Service class to manage global external storages
  */
 class GlobalStoragesService extends StoragesService {
-
-	/**
-	 * Write the storages to the configuration.
-	 *
-	 * @param array $storages map of storage id to storage config
-	 */
-	public function writeConfig($storages) {
-		// let the horror begin
-		$mountPoints = [];
-		foreach ($storages as $storageConfig) {
-			$mountPoint = $storageConfig->getMountPoint();
-			$oldBackendOptions = $storageConfig->getBackendOptions();
-			$storageConfig->setBackendOptions(
-				\OC_Mount_Config::encryptPasswords(
-					$oldBackendOptions
-				)
-			);
-
-			// system mount
-			$rootMountPoint = '/$user/files/' . ltrim($mountPoint, '/');
-
-			$applicableUsers = $storageConfig->getApplicableUsers();
-			$applicableGroups = $storageConfig->getApplicableGroups();
-			foreach ($applicableUsers as $applicable) {
-				$this->addMountPoint(
-					$mountPoints,
-					\OC_Mount_Config::MOUNT_TYPE_USER,
-					$applicable,
-					$rootMountPoint,
-					$storageConfig
-				);
-			}
-
-			foreach ($applicableGroups as $applicable) {
-				$this->addMountPoint(
-					$mountPoints,
-					\OC_Mount_Config::MOUNT_TYPE_GROUP,
-					$applicable,
-					$rootMountPoint,
-					$storageConfig
-				);
-			}
-
-			// if neither "applicableGroups" or "applicableUsers" were set, use "all" user
-			if (empty($applicableUsers) && empty($applicableGroups)) {
-				$this->addMountPoint(
-					$mountPoints,
-					\OC_Mount_Config::MOUNT_TYPE_USER,
-					'all',
-					$rootMountPoint,
-					$storageConfig
-				);
-			}
-
-			// restore old backend options where the password was not encrypted,
-			// because we don't want to change the state of the original object
-			$storageConfig->setBackendOptions($oldBackendOptions);
-		}
-
-		$this->writeLegacyConfig($mountPoints);
-	}
-
 	/**
 	 * Triggers $signal for all applicable users of the given
 	 * storage
diff --git a/apps/files_external/service/legacystoragesservice.php b/apps/files_external/service/legacystoragesservice.php
new file mode 100644
index 0000000000000000000000000000000000000000..19cec733c13ccff1af5f9f1dc97cc471db35e803
--- /dev/null
+++ b/apps/files_external/service/legacystoragesservice.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_external\Service;
+
+use \OCA\Files_external\Lib\StorageConfig;
+
+/**
+ * Read mount config from legacy mount.json
+ */
+abstract class LegacyStoragesService {
+	/** @var BackendService */
+	protected $backendService;
+
+	/**
+	 * Read legacy config data
+	 *
+	 * @return array list of mount configs
+	 */
+	abstract protected function readLegacyConfig();
+
+	/**
+	 * Copy legacy storage options into the given storage config object.
+	 *
+	 * @param StorageConfig $storageConfig storage config to populate
+	 * @param string $mountType mount type
+	 * @param string $applicable applicable user or group
+	 * @param array $storageOptions legacy storage options
+	 *
+	 * @return StorageConfig populated storage config
+	 */
+	protected function populateStorageConfigWithLegacyOptions(
+		&$storageConfig,
+		$mountType,
+		$applicable,
+		$storageOptions
+	) {
+		$backend = $this->backendService->getBackend($storageOptions['backend']);
+		if (!$backend) {
+			throw new \UnexpectedValueException('Invalid backend ' . $storageOptions['backend']);
+		}
+		$storageConfig->setBackend($backend);
+		if (isset($storageOptions['authMechanism']) && $storageOptions['authMechanism'] !== 'builtin::builtin') {
+			$authMechanism = $this->backendService->getAuthMechanism($storageOptions['authMechanism']);
+		} else {
+			$authMechanism = $backend->getLegacyAuthMechanism($storageOptions);
+			$storageOptions['authMechanism'] = 'null'; // to make error handling easier
+		}
+		if (!$authMechanism) {
+			throw new \UnexpectedValueException('Invalid authentication mechanism ' . $storageOptions['authMechanism']);
+		}
+		$storageConfig->setAuthMechanism($authMechanism);
+		$storageConfig->setBackendOptions($storageOptions['options']);
+		if (isset($storageOptions['mountOptions'])) {
+			$storageConfig->setMountOptions($storageOptions['mountOptions']);
+		}
+		if (!isset($storageOptions['priority'])) {
+			$storageOptions['priority'] = $backend->getPriority();
+		}
+		$storageConfig->setPriority($storageOptions['priority']);
+		if ($mountType === \OC_Mount_Config::MOUNT_TYPE_USER) {
+			$applicableUsers = $storageConfig->getApplicableUsers();
+			if ($applicable !== 'all') {
+				$applicableUsers[] = $applicable;
+				$storageConfig->setApplicableUsers($applicableUsers);
+			}
+		} else if ($mountType === \OC_Mount_Config::MOUNT_TYPE_GROUP) {
+			$applicableGroups = $storageConfig->getApplicableGroups();
+			$applicableGroups[] = $applicable;
+			$storageConfig->setApplicableGroups($applicableGroups);
+		}
+		return $storageConfig;
+	}
+
+	/**
+	 * Read the external storages config
+	 *
+	 * @return StorageConfig[] map of storage id to storage config
+	 */
+	public function getAllStorages() {
+		$mountPoints = $this->readLegacyConfig();
+		/**
+		 * Here is the how the horribly messy mount point array looks like
+		 * from the mount.json file:
+		 *
+		 * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath]
+		 *
+		 * - $mountType is either "user" or "group"
+		 * - $applicable is the name of a user or group (or the current user for personal mounts)
+		 * - $mountPath is the mount point path (where the storage must be mounted)
+		 * - $storageOptions is a map of storage options:
+		 *     - "priority": storage priority
+		 *     - "backend": backend identifier
+		 *     - "class": LEGACY backend class name
+		 *     - "options": backend-specific options
+		 *     - "authMechanism": authentication mechanism identifier
+		 *     - "mountOptions": mount-specific options (ex: disable previews, scanner, etc)
+		 */
+		// group by storage id
+		/** @var StorageConfig[] $storages */
+		$storages = [];
+		// for storages without id (legacy), group by config hash for
+		// later processing
+		$storagesWithConfigHash = [];
+		foreach ($mountPoints as $mountType => $applicables) {
+			foreach ($applicables as $applicable => $mountPaths) {
+				foreach ($mountPaths as $rootMountPath => $storageOptions) {
+					$currentStorage = null;
+					/**
+					 * Flag whether the config that was read already has an id.
+					 * If not, it will use a config hash instead and generate
+					 * a proper id later
+					 *
+					 * @var boolean
+					 */
+					$hasId = false;
+					// the root mount point is in the format "/$user/files/the/mount/point"
+					// we remove the "/$user/files" prefix
+					$parts = explode('/', ltrim($rootMountPath, '/'), 3);
+					if (count($parts) < 3) {
+						// something went wrong, skip
+						\OCP\Util::writeLog(
+							'files_external',
+							'Could not parse mount point "' . $rootMountPath . '"',
+							\OCP\Util::ERROR
+						);
+						continue;
+					}
+					$relativeMountPath = rtrim($parts[2], '/');
+					// note: we cannot do this after the loop because the decrypted config
+					// options might be needed for the config hash
+					$storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']);
+					if (!isset($storageOptions['backend'])) {
+						$storageOptions['backend'] = $storageOptions['class']; // legacy compat
+					}
+					if (!isset($storageOptions['authMechanism'])) {
+						$storageOptions['authMechanism'] = null; // ensure config hash works
+					}
+					if (isset($storageOptions['id'])) {
+						$configId = (int)$storageOptions['id'];
+						if (isset($storages[$configId])) {
+							$currentStorage = $storages[$configId];
+						}
+						$hasId = true;
+					} else {
+						// missing id in legacy config, need to generate
+						// but at this point we don't know the max-id, so use
+						// first group it by config hash
+						$storageOptions['mountpoint'] = $rootMountPath;
+						$configId = \OC_Mount_Config::makeConfigHash($storageOptions);
+						if (isset($storagesWithConfigHash[$configId])) {
+							$currentStorage = $storagesWithConfigHash[$configId];
+						}
+					}
+					if (is_null($currentStorage)) {
+						// create new
+						$currentStorage = new StorageConfig($configId);
+						$currentStorage->setMountPoint($relativeMountPath);
+					}
+					try {
+						$this->populateStorageConfigWithLegacyOptions(
+							$currentStorage,
+							$mountType,
+							$applicable,
+							$storageOptions
+						);
+						if ($hasId) {
+							$storages[$configId] = $currentStorage;
+						} else {
+							$storagesWithConfigHash[$configId] = $currentStorage;
+						}
+					} catch (\UnexpectedValueException $e) {
+						// dont die if a storage backend doesn't exist
+						\OCP\Util::writeLog(
+							'files_external',
+							'Could not load storage: "' . $e->getMessage() . '"',
+							\OCP\Util::ERROR
+						);
+					}
+				}
+			}
+		}
+
+		// convert parameter values
+		foreach ($storages as $storage) {
+			$storage->getBackend()->validateStorageDefinition($storage);
+			$storage->getAuthMechanism()->validateStorageDefinition($storage);
+		}
+		return $storages;
+	}
+}
diff --git a/apps/files_external/service/storagesservice.php b/apps/files_external/service/storagesservice.php
index c847930ba2d247435c3cfed0807676e9f9a5002f..9be6498435c39be78501b79eeaf49017272caba8 100644
--- a/apps/files_external/service/storagesservice.php
+++ b/apps/files_external/service/storagesservice.php
@@ -42,88 +42,60 @@ abstract class StoragesService {
 	protected $backendService;
 
 	/**
-	 * @param BackendService $backendService
+	 * @var DBConfigService
 	 */
-	public function __construct(BackendService $backendService) {
-		$this->backendService = $backendService;
-	}
+	protected $dbConfig;
 
 	/**
-	 * Read legacy config data
-	 *
-	 * @return array list of mount configs
+	 * @param BackendService $backendService
+	 * @param DBConfigService $dbConfigService
 	 */
-	protected function readLegacyConfig() {
-		// read global config
-		return \OC_Mount_Config::readData();
+	public function __construct(BackendService $backendService, DBConfigService $dbConfigService) {
+		$this->backendService = $backendService;
+		$this->dbConfig = $dbConfigService;
 	}
 
-	/**
-	 * Write legacy config data
-	 *
-	 * @param array $mountPoints
-	 */
-	protected function writeLegacyConfig(array $mountPoints) {
-		// write global config
-		\OC_Mount_Config::writeData(null, $mountPoints);
+	protected function readDBConfig() {
+		return $this->dbConfig->getAdminMounts();
 	}
 
-	/**
-	 * Copy legacy storage options into the given storage config object.
-	 *
-	 * @param StorageConfig $storageConfig storage config to populate
-	 * @param string $mountType mount type
-	 * @param string $applicable applicable user or group
-	 * @param array $storageOptions legacy storage options
-	 *
-	 * @return StorageConfig populated storage config
-	 */
-	protected function populateStorageConfigWithLegacyOptions(
-		&$storageConfig,
-		$mountType,
-		$applicable,
-		$storageOptions
-	) {
-		$backend = $this->backendService->getBackend($storageOptions['backend']);
-		if (!$backend) {
-			throw new \UnexpectedValueException('Invalid backend '.$storageOptions['backend']);
-		}
-		$storageConfig->setBackend($backend);
-
-		if (isset($storageOptions['authMechanism']) && $storageOptions['authMechanism'] !== 'builtin::builtin') {
-			$authMechanism = $this->backendService->getAuthMechanism($storageOptions['authMechanism']);
-		} else {
-			$authMechanism = $backend->getLegacyAuthMechanism($storageOptions);
-			$storageOptions['authMechanism'] = 'null'; // to make error handling easier
-		}
-		if (!$authMechanism) {
-			throw new \UnexpectedValueException('Invalid authentication mechanism '.$storageOptions['authMechanism']);
-		}
-		$storageConfig->setAuthMechanism($authMechanism);
-
-		$storageConfig->setBackendOptions($storageOptions['options']);
-		if (isset($storageOptions['mountOptions'])) {
-			$storageConfig->setMountOptions($storageOptions['mountOptions']);
-		}
-		if (!isset($storageOptions['priority'])) {
-			$storageOptions['priority'] = $backend->getPriority();
-		}
-		$storageConfig->setPriority($storageOptions['priority']);
+	protected function getStorageConfigFromDBMount(array $mount) {
+		$applicableUsers = array_filter($mount['applicable'], function ($applicable) {
+			return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_USER;
+		});
+		$applicableUsers = array_map(function ($applicable) {
+			return $applicable['value'];
+		}, $applicableUsers);
+
+		$applicableGroups = array_filter($mount['applicable'], function ($applicable) {
+			return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_GROUP;
+		});
+		$applicableGroups = array_map(function ($applicable) {
+			return $applicable['value'];
+		}, $applicableGroups);
 
-		if ($mountType === \OC_Mount_Config::MOUNT_TYPE_USER) {
-			$applicableUsers = $storageConfig->getApplicableUsers();
-			if ($applicable !== 'all') {
-				$applicableUsers[] = $applicable;
-				$storageConfig->setApplicableUsers($applicableUsers);
-			}
-		} else if ($mountType === \OC_Mount_Config::MOUNT_TYPE_GROUP) {
-			$applicableGroups = $storageConfig->getApplicableGroups();
-			$applicableGroups[] = $applicable;
-			$storageConfig->setApplicableGroups($applicableGroups);
+		try {
+			$config = $this->createStorage(
+				$mount['mount_point'],
+				$mount['storage_backend'],
+				$mount['auth_backend'],
+				$mount['config'],
+				$mount['options'],
+				array_values($applicableUsers),
+				array_values($applicableGroups),
+				$mount['priority']
+			);
+			$config->setId((int)$mount['mount_id']);
+			return $config;
+		} catch (\UnexpectedValueException $e) {
+			// dont die if a storage backend doesn't exist
+			\OCP\Util::writeLog(
+				'files_external',
+				'Could not load storage: "' . $e->getMessage() . '"',
+				\OCP\Util::ERROR
+			);
+			return null;
 		}
-
-
-		return $storageConfig;
 	}
 
 	/**
@@ -132,198 +104,19 @@ abstract class StoragesService {
 	 * @return array map of storage id to storage config
 	 */
 	protected function readConfig() {
-		$mountPoints = $this->readLegacyConfig();
-
-		/**
-		 * Here is the how the horribly messy mount point array looks like
-		 * from the mount.json file:
-		 *
-		 * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath]
-		 *
-		 * - $mountType is either "user" or "group"
-		 * - $applicable is the name of a user or group (or the current user for personal mounts)
-		 * - $mountPath is the mount point path (where the storage must be mounted)
-		 * - $storageOptions is a map of storage options:
-		 *     - "priority": storage priority
-		 *     - "backend": backend identifier
-		 *     - "class": LEGACY backend class name
-		 *     - "options": backend-specific options
-		 *     - "authMechanism": authentication mechanism identifier
-		 *     - "mountOptions": mount-specific options (ex: disable previews, scanner, etc)
-		 */
-
-		// group by storage id
-		$storages = [];
-
-		// for storages without id (legacy), group by config hash for
-		// later processing
-		$storagesWithConfigHash = [];
-
-		foreach ($mountPoints as $mountType => $applicables) {
-			foreach ($applicables as $applicable => $mountPaths) {
-				foreach ($mountPaths as $rootMountPath => $storageOptions) {
-					$currentStorage = null;
-
-					/**
-					 * Flag whether the config that was read already has an id.
-					 * If not, it will use a config hash instead and generate
-					 * a proper id later
-					 *
-					 * @var boolean
-					 */
-					$hasId = false;
-
-					// the root mount point is in the format "/$user/files/the/mount/point"
-					// we remove the "/$user/files" prefix
-					$parts = explode('/', ltrim($rootMountPath, '/'), 3);
-					if (count($parts) < 3) {
-						// something went wrong, skip
-						\OCP\Util::writeLog(
-							'files_external',
-							'Could not parse mount point "' . $rootMountPath . '"',
-							\OCP\Util::ERROR
-						);
-						continue;
-					}
-
-					$relativeMountPath = rtrim($parts[2], '/');
-
-					// note: we cannot do this after the loop because the decrypted config
-					// options might be needed for the config hash
-					$storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']);
-
-					if (!isset($storageOptions['backend'])) {
-						$storageOptions['backend'] = $storageOptions['class']; // legacy compat
-					}
-					if (!isset($storageOptions['authMechanism'])) {
-						$storageOptions['authMechanism'] = null; // ensure config hash works
-					}
-
-					if (isset($storageOptions['id'])) {
-						$configId = (int)$storageOptions['id'];
-						if (isset($storages[$configId])) {
-							$currentStorage = $storages[$configId];
-						}
-						$hasId = true;
-					} else {
-						// missing id in legacy config, need to generate
-						// but at this point we don't know the max-id, so use
-						// first group it by config hash
-						$storageOptions['mountpoint'] = $rootMountPath;
-						$configId = \OC_Mount_Config::makeConfigHash($storageOptions);
-						if (isset($storagesWithConfigHash[$configId])) {
-							$currentStorage = $storagesWithConfigHash[$configId];
-						}
-					}
-
-					if (is_null($currentStorage)) {
-						// create new
-						$currentStorage = new StorageConfig($configId);
-						$currentStorage->setMountPoint($relativeMountPath);
-					}
-
-					try {
-						$this->populateStorageConfigWithLegacyOptions(
-								$currentStorage,
-								$mountType,
-								$applicable,
-								$storageOptions
-						);
-
-						if ($hasId) {
-							$storages[$configId] = $currentStorage;
-						} else {
-							$storagesWithConfigHash[$configId] = $currentStorage;
-						}
-					} catch (\UnexpectedValueException $e) {
-						// dont die if a storage backend doesn't exist
-						\OCP\Util::writeLog(
-								'files_external',
-								'Could not load storage: "' . $e->getMessage() . '"',
-								\OCP\Util::ERROR
-						);
-					}
-				}
-			}
-		}
-
-		// process storages with config hash, they must get a real id
-		if (!empty($storagesWithConfigHash)) {
-			$this->setRealStorageIds($storages, $storagesWithConfigHash);
-		}
+		$mounts = $this->readDBConfig();
+		$configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
+		$configs = array_filter($configs, function ($config) {
+			return $config instanceof StorageConfig;
+		});
 
-		// convert parameter values
-		foreach ($storages as $storage) {
-			$storage->getBackend()->validateStorageDefinition($storage);
-			$storage->getAuthMechanism()->validateStorageDefinition($storage);
-		}
+		$keys = array_map(function (StorageConfig $config) {
+			return $config->getId();
+		}, $configs);
 
-		return $storages;
+		return array_combine($keys, $configs);
 	}
 
-	/**
-	 * Replace config hash ID with real IDs, for migrating legacy storages
-	 *
-	 * @param StorageConfig[] $storages Storages with real IDs
-	 * @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
-	 */
-	protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
-		$nextId = $this->generateNextId($storages);
-		foreach ($storagesWithConfigHash as $storage) {
-			$storage->setId($nextId);
-			$storages[$nextId] = $storage;
-			$nextId++;
-		}
-
-		// re-save the config with the generated ids
-		$this->writeConfig($storages);
-	}
-
-	/**
-	 * Add mount point into the messy mount point structure
-	 *
-	 * @param array $mountPoints messy array of mount points
-	 * @param string $mountType mount type
-	 * @param string $applicable single applicable user or group
-	 * @param string $rootMountPoint root mount point to use
-	 * @param array $storageConfig storage config to set to the mount point
-	 */
-	protected function addMountPoint(&$mountPoints, $mountType, $applicable, $rootMountPoint, $storageConfig) {
-		if (!isset($mountPoints[$mountType])) {
-			$mountPoints[$mountType] = [];
-		}
-
-		if (!isset($mountPoints[$mountType][$applicable])) {
-			$mountPoints[$mountType][$applicable] = [];
-		}
-
-		$options = [
-			'id' => $storageConfig->getId(),
-			'backend' => $storageConfig->getBackend()->getIdentifier(),
-			//'class' => $storageConfig->getBackend()->getClass(),
-			'authMechanism' => $storageConfig->getAuthMechanism()->getIdentifier(),
-			'options' => $storageConfig->getBackendOptions(),
-		];
-
-		if (!is_null($storageConfig->getPriority())) {
-			$options['priority'] = $storageConfig->getPriority();
-		}
-
-		$mountOptions = $storageConfig->getMountOptions();
-		if (!empty($mountOptions)) {
-			$options['mountOptions'] = $mountOptions;
-		}
-
-		$mountPoints[$mountType][$applicable][$rootMountPoint] = $options;
-	}
-
-	/**
-	 * Write the storages to the configuration.
-	 *
-	 * @param array $storages map of storage id to storage config
-	 */
-	abstract protected function writeConfig($storages);
-
 	/**
 	 * Get a storage with status
 	 *
@@ -333,19 +126,19 @@ abstract class StoragesService {
 	 * @throws NotFoundException if the storage with the given id was not found
 	 */
 	public function getStorage($id) {
-		$allStorages = $this->readConfig();
+		$mount = $this->dbConfig->getMountById($id);
 
-		if (!isset($allStorages[$id])) {
+		if (!is_array($mount)) {
 			throw new NotFoundException('Storage with id "' . $id . '" not found');
 		}
 
-		return $allStorages[$id];
+		return $this->getStorageConfigFromDBMount($mount);
 	}
 
 	/**
 	 * Gets all storages, valid or not
 	 *
-	 * @return array array of storage configs
+	 * @return StorageConfig[] array of storage configs
 	 */
 	public function getAllStorages() {
 		return $this->readConfig();
@@ -354,7 +147,7 @@ abstract class StoragesService {
 	/**
 	 * Gets all valid storages
 	 *
-	 * @return array
+	 * @return StorageConfig[]
 	 */
 	public function getStorages() {
 		return array_filter($this->getAllStorages(), [$this, 'validateStorage']);
@@ -392,24 +185,50 @@ abstract class StoragesService {
 	 */
 	abstract public function getVisibilityType();
 
+	protected function getType() {
+		return DBConfigService::MOUNT_TYPE_ADMIN;
+	}
+
 	/**
 	 * Add new storage to the configuration
 	 *
-	 * @param array $newStorage storage attributes
+	 * @param StorageConfig $newStorage storage attributes
 	 *
 	 * @return StorageConfig storage config, with added id
 	 */
 	public function addStorage(StorageConfig $newStorage) {
 		$allStorages = $this->readConfig();
 
-		$configId = $this->generateNextId($allStorages);
+		$configId = $this->dbConfig->addMount(
+			$newStorage->getMountPoint(),
+			$newStorage->getBackend()->getIdentifier(),
+			$newStorage->getAuthMechanism()->getIdentifier(),
+			$newStorage->getPriority(),
+			$this->getType()
+		);
+
 		$newStorage->setId($configId);
 
+		foreach ($newStorage->getApplicableUsers() as $user) {
+			$this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_USER, $user);
+		}
+		foreach ($newStorage->getApplicableGroups() as $group) {
+			$this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
+		}
+		foreach ($newStorage->getBackendOptions() as $key => $value) {
+			$this->dbConfig->setConfig($configId, $key, $value);
+		}
+		foreach ($newStorage->getMountOptions() as $key => $value) {
+			$this->dbConfig->setOption($configId, $key, $value);
+		}
+
+		if (count($newStorage->getApplicableUsers()) === 0 && count($newStorage->getApplicableGroups()) === 0) {
+			$this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+		}
+
 		// add new storage
 		$allStorages[$configId] = $newStorage;
 
-		$this->writeConfig($allStorages);
-
 		$this->triggerHooks($newStorage, Filesystem::signal_create_mount);
 
 		$newStorage->setStatus(StorageNotAvailableException::STATUS_SUCCESS);
@@ -442,11 +261,11 @@ abstract class StoragesService {
 	) {
 		$backend = $this->backendService->getBackend($backendIdentifier);
 		if (!$backend) {
-			throw new \InvalidArgumentException('Unable to get backend for '.$backendIdentifier);
+			throw new \InvalidArgumentException('Unable to get backend for ' . $backendIdentifier);
 		}
 		$authMechanism = $this->backendService->getAuthMechanism($authMechanismIdentifier);
 		if (!$authMechanism) {
-			throw new \InvalidArgumentException('Unable to get authentication mechanism for '.$authMechanismIdentifier);
+			throw new \InvalidArgumentException('Unable to get authentication mechanism for ' . $authMechanismIdentifier);
 		}
 		$newStorage = new StorageConfig();
 		$newStorage->setMountPoint($mountPoint);
@@ -519,21 +338,56 @@ abstract class StoragesService {
 	 * @throws NotFoundException if the given storage does not exist in the config
 	 */
 	public function updateStorage(StorageConfig $updatedStorage) {
-		$allStorages = $this->readConfig();
-
 		$id = $updatedStorage->getId();
-		if (!isset($allStorages[$id])) {
-			throw new NotFoundException('Storage with id "' . $id . '" not found');
+
+		$existingMount = $this->dbConfig->getMountById($id);
+
+		if (!is_array($existingMount)) {
+			throw new NotFoundException('Storage with id "' . $id . '" not found while updating storage');
+		}
+
+		$oldStorage = $this->getStorageConfigFromDBMount($existingMount);
+
+		$removedUsers = array_diff($oldStorage->getApplicableUsers(), $updatedStorage->getApplicableUsers());
+		$removedGroups = array_diff($oldStorage->getApplicableGroups(), $updatedStorage->getApplicableGroups());
+		$addedUsers = array_diff($updatedStorage->getApplicableUsers(), $oldStorage->getApplicableUsers());
+		$addedGroups = array_diff($updatedStorage->getApplicableGroups(), $oldStorage->getApplicableGroups());
+
+		$oldUserCount = count($oldStorage->getApplicableUsers());
+		$oldGroupCount = count($oldStorage->getApplicableGroups());
+		$newUserCount = count($oldStorage->getApplicableUsers());
+		$newGroupCount = count($oldStorage->getApplicableGroups());
+		$wasGlobal = ($oldUserCount + $oldGroupCount) === 0;
+		$isGlobal = ($newUserCount + $newGroupCount) === 0;
+
+		foreach ($removedUsers as $user) {
+			$this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, $user);
+		}
+		foreach ($removedGroups as $group) {
+			$this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
+		}
+		foreach ($addedUsers as $user) {
+			$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, $user);
+		}
+		foreach ($addedGroups as $group) {
+			$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
 		}
-		$oldStorage = $allStorages[$id];
 
-		// ensure objectstore is persistent
-		if ($objectstore = $oldStorage->getBackendOption('objectstore')) {
-			$updatedStorage->setBackendOption('objectstore', $objectstore);
+		if ($wasGlobal && !$isGlobal) {
+			$this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+		} else if (!$wasGlobal && $isGlobal) {
+			$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
 		}
 
-		$allStorages[$id] = $updatedStorage;
-		$this->writeConfig($allStorages);
+		$changedConfig = array_diff_assoc($updatedStorage->getBackendOptions(), $oldStorage->getBackendOptions());
+		$changedOptions = array_diff_assoc($updatedStorage->getMountOptions(), $oldStorage->getMountOptions());
+
+		foreach ($changedConfig as $key => $value) {
+			$this->dbConfig->setConfig($id, $key, $value);
+		}
+		foreach ($changedOptions as $key => $value) {
+			$this->dbConfig->setOption($id, $key, $value);
+		}
 
 		$this->triggerChangeHooks($oldStorage, $updatedStorage);
 
@@ -548,17 +402,15 @@ abstract class StoragesService {
 	 * @throws NotFoundException if no storage was found with the given id
 	 */
 	public function removeStorage($id) {
-		$allStorages = $this->readConfig();
+		$existingMount = $this->dbConfig->getMountById($id);
 
-		if (!isset($allStorages[$id])) {
+		if (!is_array($existingMount)) {
 			throw new NotFoundException('Storage with id "' . $id . '" not found');
 		}
 
-		$deletedStorage = $allStorages[$id];
-		unset($allStorages[$id]);
-
-		$this->writeConfig($allStorages);
+		$this->dbConfig->removeMount($id);
 
+		$deletedStorage = $this->getStorageConfigFromDBMount($existingMount);
 		$this->triggerHooks($deletedStorage, Filesystem::signal_delete_mount);
 
 		// delete oc_storages entries and oc_filecache
@@ -577,24 +429,6 @@ abstract class StoragesService {
 		}
 	}
 
-	/**
-	 * Generates a configuration id to use for a new configuration entry.
-	 *
-	 * @param array $allStorages array of all storage configs
-	 *
-	 * @return int id
-	 */
-	protected function generateNextId($allStorages) {
-		if (empty($allStorages)) {
-			return 1;
-		}
-		// note: this will mess up with with concurrency,
-		// but so did the mount.json. This horribly hack
-		// will disappear once we move to DB tables to
-		// store the config
-		return (max(array_keys($allStorages)) + 1);
-	}
-
 	/**
 	 * Returns the rusty storage id from oc_storages from the given storage config.
 	 *
diff --git a/apps/files_external/service/userglobalstoragesservice.php b/apps/files_external/service/userglobalstoragesservice.php
index afe77e1e0591c38890ce7869fc6dcd44d396d8b4..cb49f0f6726f992ce8d8cd0ed4e2e1c68fe5cd82 100644
--- a/apps/files_external/service/userglobalstoragesservice.php
+++ b/apps/files_external/service/userglobalstoragesservice.php
@@ -41,15 +41,17 @@ class UserGlobalStoragesService extends GlobalStoragesService {
 
 	/**
 	 * @param BackendService $backendService
+	 * @param DBConfigService $dbConfig
 	 * @param IUserSession $userSession
 	 * @param IGroupManager $groupManager
 	 */
 	public function __construct(
 		BackendService $backendService,
+		DBConfigService $dbConfig,
 		IUserSession $userSession,
 		IGroupManager $groupManager
 	) {
-		parent::__construct($backendService);
+		parent::__construct($backendService, $dbConfig);
 		$this->userSession = $userSession;
 		$this->groupManager = $groupManager;
 	}
@@ -67,46 +69,27 @@ class UserGlobalStoragesService extends GlobalStoragesService {
 		}
 	}
 
-	/**
-	 * Read legacy config data
-	 *
-	 * @return array list of mount configs
-	 */
-	protected function readLegacyConfig() {
-		// read global config
-		$data = parent::readLegacyConfig();
-		$userId = $this->getUser()->getUID();
-
-		// don't use array_filter() with ARRAY_FILTER_USE_KEY, it's PHP 5.6+
-		if (isset($data[\OC_Mount_Config::MOUNT_TYPE_USER])) {
-			$newData = [];
-			foreach ($data[\OC_Mount_Config::MOUNT_TYPE_USER] as $key => $value) {
-				if (strtolower($key) === strtolower($userId) || $key === 'all') {
-					$newData[$key] = $value;
-				}
-			}
-			$data[\OC_Mount_Config::MOUNT_TYPE_USER] = $newData;
+	protected function readDBConfig() {
+		$userMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
+		$globalMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+		$groups = $this->groupManager->getUserGroupIds($this->getUser());
+		if (is_array($groups) && count($groups) !== 0) {
+			$groupMounts = $this->dbConfig->getAdminMountsForMultiple(DBConfigService::APPLICABLE_TYPE_GROUP, $groups);
+		} else {
+			$groupMounts = [];
 		}
+		return array_merge($userMounts, $groupMounts, $globalMounts);
+	}
 
-		if (isset($data[\OC_Mount_Config::MOUNT_TYPE_GROUP])) {
-			$newData = [];
-			foreach ($data[\OC_Mount_Config::MOUNT_TYPE_GROUP] as $key => $value) {
-				if ($this->groupManager->isInGroup($userId, $key)) {
-					$newData[$key] = $value;
-				}
-			}
-			$data[\OC_Mount_Config::MOUNT_TYPE_GROUP] = $newData;
-		}
+	public function addStorage(StorageConfig $newStorage) {
+		throw new \DomainException('UserGlobalStoragesService writing disallowed');
+	}
 
-		return $data;
+	public function updateStorage(StorageConfig $updatedStorage) {
+		throw new \DomainException('UserGlobalStoragesService writing disallowed');
 	}
 
-	/**
-	 * Write legacy config data
-	 *
-	 * @param array $mountPoints
-	 */
-	protected function writeLegacyConfig(array $mountPoints) {
+	public function removeStorage($id) {
 		throw new \DomainException('UserGlobalStoragesService writing disallowed');
 	}
 
@@ -126,7 +109,7 @@ class UserGlobalStoragesService extends GlobalStoragesService {
 
 		$result = [];
 		foreach ($storagesByMountpoint as $storageList) {
-			$storage = array_reduce($storageList, function($carry, $item) {
+			$storage = array_reduce($storageList, function ($carry, $item) {
 				if (isset($carry)) {
 					$carryPriorityType = $this->getPriorityType($carry);
 					$itemPriorityType = $this->getPriorityType($item);
diff --git a/apps/files_external/service/userlegacystoragesservice.php b/apps/files_external/service/userlegacystoragesservice.php
new file mode 100644
index 0000000000000000000000000000000000000000..13f34225d60242c732cbf6a73eabe068585b000a
--- /dev/null
+++ b/apps/files_external/service/userlegacystoragesservice.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_external\Service;
+
+use OCP\IUserSession;
+
+/**
+ * Read user defined mounts from the legacy mount.json
+ */
+class UserLegacyStoragesService extends LegacyStoragesService {
+	/**
+	 * @var IUserSession
+	 */
+	private $userSession;
+
+	/**
+	 * @param BackendService $backendService
+	 * @param IUserSession $userSession
+	 */
+	public function __construct(BackendService $backendService, IUserSession $userSession) {
+		$this->backendService = $backendService;
+		$this->userSession = $userSession;
+	}
+
+	/**
+	 * Read legacy config data
+	 *
+	 * @return array list of storage configs
+	 */
+	protected function readLegacyConfig() {
+		// read user config
+		$user = $this->userSession->getUser()->getUID();
+		return \OC_Mount_Config::readData($user);
+	}
+}
diff --git a/apps/files_external/service/userstoragesservice.php b/apps/files_external/service/userstoragesservice.php
index a8cdf60ad9cb0daf3db4bd3b64eda743bde839d9..5cf04578caf222cd50970870dfa6c40ef263dac1 100644
--- a/apps/files_external/service/userstoragesservice.php
+++ b/apps/files_external/service/userstoragesservice.php
@@ -35,107 +35,26 @@ use \OCA\Files_External\Service\UserTrait;
  * (aka personal storages)
  */
 class UserStoragesService extends StoragesService {
-
 	use UserTrait;
 
 	/**
 	 * Create a user storages service
 	 *
 	 * @param BackendService $backendService
+	 * @param DBConfigService $dbConfig
 	 * @param IUserSession $userSession user session
 	 */
 	public function __construct(
 		BackendService $backendService,
+		DBConfigService $dbConfig,
 		IUserSession $userSession
 	) {
 		$this->userSession = $userSession;
-		parent::__construct($backendService);
-	}
-
-	/**
-	 * Read legacy config data
-	 *
-	 * @return array list of storage configs
-	 */
-	protected function readLegacyConfig() {
-		// read user config
-		$user = $this->getUser()->getUID();
-		return \OC_Mount_Config::readData($user);
-	}
-
-	/**
-	 * Write legacy config data
-	 *
-	 * @param array $mountPoints
-	 */
-	protected function writeLegacyConfig(array $mountPoints) {
-		// write user config
-		$user = $this->getUser()->getUID();
-		\OC_Mount_Config::writeData($user, $mountPoints);
-	}
-
-	/**
-	 * Read the external storages config
-	 *
-	 * @return array map of storage id to storage config
-	 */
-	protected function readConfig() {
-		$user = $this->getUser()->getUID();
-		// TODO: in the future don't rely on the global config reading code
-		$storages = parent::readConfig();
-
-		$filteredStorages = [];
-		foreach ($storages as $configId => $storage) {
-			// filter out all bogus storages that aren't for the current user
-			if (!in_array($user, $storage->getApplicableUsers())) {
-				continue;
-			}
-
-			// clear applicable users, should not be used
-			$storage->setApplicableUsers([]);
-
-			// strip out unneeded applicableUser fields
-			$filteredStorages[$configId] = $storage;
-		}
-
-		return $filteredStorages;
+		parent::__construct($backendService, $dbConfig);
 	}
 
-	/**
-	 * Write the storages to the user's configuration.
-	 *
-	 * @param array $storages map of storage id to storage config
-	 */
-	public function writeConfig($storages) {
-		$user = $this->getUser()->getUID();
-
-		// let the horror begin
-		$mountPoints = [];
-		foreach ($storages as $storageConfig) {
-			$mountPoint = $storageConfig->getMountPoint();
-			$oldBackendOptions = $storageConfig->getBackendOptions();
-			$storageConfig->setBackendOptions(
-				\OC_Mount_Config::encryptPasswords(
-					$oldBackendOptions
-				)
-			);
-
-			$rootMountPoint = '/' . $user . '/files/' . ltrim($mountPoint, '/');
-
-			$this->addMountPoint(
-				$mountPoints,
-				\OC_Mount_Config::MOUNT_TYPE_USER,
-				$user,
-				$rootMountPoint,
-				$storageConfig
-			);
-
-			// restore old backend options where the password was not encrypted,
-			// because we don't want to change the state of the original object
-			$storageConfig->setBackendOptions($oldBackendOptions);
-		}
-
-		$this->writeLegacyConfig($mountPoints);
+	protected function readDBConfig() {
+		return $this->dbConfig->getUserMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
 	}
 
 	/**
@@ -173,6 +92,23 @@ class UserStoragesService extends StoragesService {
 		}
 	}
 
+	protected function getType() {
+		return DBConfigService::MOUNT_TYPE_PERSONAl;
+	}
+
+	/**
+	 * Add new storage to the configuration
+	 *
+	 * @param StorageConfig $newStorage storage attributes
+	 *
+	 * @return StorageConfig storage config, with added id
+	 */
+	public function addStorage(StorageConfig $newStorage) {
+		$config = parent::addStorage($newStorage);
+		$this->dbConfig->addApplicable($config->getId(), DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
+		return $config;
+	}
+
 	/**
 	 * Get the visibility type for this controller, used in validation
 	 *
diff --git a/apps/files_external/tests/service/dbconfigservicetest.php b/apps/files_external/tests/service/dbconfigservicetest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5b4ff1585dfdac70b83d45af3276e5080caccd2
--- /dev/null
+++ b/apps/files_external/tests/service/dbconfigservicetest.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_External\Tests\Service;
+
+
+use OCA\Files_External\Service\DBConfigService;
+use OCP\IDBConnection;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class DBConfigServiceTest extends TestCase {
+	/**
+	 * @var DBConfigService
+	 */
+	private $dbConfig;
+
+	/**
+	 * @var IDBConnection
+	 */
+	private $connection;
+
+	private $mounts = [];
+
+	public function setUp() {
+		parent::setUp();
+		$this->connection = \OC::$server->getDatabaseConnection();
+		$this->dbConfig = new DBConfigService($this->connection);
+	}
+
+	public function tearDown() {
+		foreach ($this->mounts as $mount) {
+			$this->dbConfig->removeMount($mount);
+		}
+		$this->mounts = [];
+	}
+
+	private function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+		$id = $this->dbConfig->addMount($mountPoint, $storageBackend, $authBackend, $priority, $type);
+		$this->mounts[] = $id;
+		return $id;
+	}
+
+	public function testAddSimpleMount() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals('/test', $mount['mount_point']);
+		$this->assertEquals('foo', $mount['storage_backend']);
+		$this->assertEquals('bar', $mount['auth_backend']);
+		$this->assertEquals(100, $mount['priority']);
+		$this->assertEquals(DBConfigService::MOUNT_TYPE_ADMIN, $mount['type']);
+		$this->assertEquals([], $mount['applicable']);
+		$this->assertEquals([], $mount['config']);
+		$this->assertEquals([], $mount['options']);
+	}
+
+	public function testAddApplicable() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals([
+			['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]
+		], $mount['applicable']);
+
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, 'bar');
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals([
+			['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id],
+			['type' => DBConfigService::APPLICABLE_TYPE_GROUP, 'value' => 'bar', 'mount_id' => $id],
+			['type' => DBConfigService::APPLICABLE_TYPE_GLOBAL, 'value' => null, 'mount_id' => $id]
+		], $mount['applicable']);
+	}
+
+	public function testAddApplicableDouble() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals([
+			['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]
+		], $mount['applicable']);
+	}
+
+	public function testDeleteMount() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+		$this->dbConfig->removeMount($id);
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(null, $mount);
+	}
+
+	public function testRemoveApplicable() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals([], $mount['applicable']);
+	}
+
+	public function testSetConfig() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->setConfig($id, 'foo', 'bar');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'bar'], $mount['config']);
+
+		$this->dbConfig->setConfig($id, 'foo2', 'bar2');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'bar', 'foo2' => 'bar2'], $mount['config']);
+	}
+
+	public function testSetConfigOverwrite() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->setConfig($id, 'foo', 'bar');
+		$this->dbConfig->setConfig($id, 'asd', '1');
+		$this->dbConfig->setConfig($id, 'foo', 'qwerty');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'qwerty', 'asd' => '1'], $mount['config']);
+	}
+
+	public function testSetOption() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->setOption($id, 'foo', 'bar');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'bar'], $mount['options']);
+
+		$this->dbConfig->setOption($id, 'foo2', 'bar2');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'bar', 'foo2' => 'bar2'], $mount['options']);
+	}
+
+	public function testSetOptionOverwrite() {
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->setOption($id, 'foo', 'bar');
+		$this->dbConfig->setOption($id, 'asd', '1');
+		$this->dbConfig->setOption($id, 'foo', 'qwerty');
+
+		$mount = $this->dbConfig->getMountById($id);
+		$this->assertEquals(['foo' => 'qwerty', 'asd' => '1'], $mount['options']);
+	}
+
+	public function testGetMountsFor() {
+		$mounts = $this->dbConfig->getMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->assertEquals([], $mounts);
+
+		$id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mounts = $this->dbConfig->getMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->assertCount(1, $mounts);
+		$this->assertEquals($id, $mounts[0]['mount_id']);
+		$this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]], $mounts[0]['applicable']);
+	}
+
+	public function testGetAdminMounts() {
+		$id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+		$mounts = $this->dbConfig->getAdminMounts();
+		$this->assertCount(1, $mounts);
+		$this->assertEquals($id1, $mounts[0]['mount_id']);
+	}
+
+	public function testGetAdminMountsFor() {
+		$id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$id3 = $this->addMount('/test3', 'foo3', 'bar3', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+		$this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->dbConfig->addApplicable($id3, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->assertCount(1, $mounts);
+		$this->assertEquals($id1, $mounts[0]['mount_id']);
+		$this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id1]], $mounts[0]['applicable']);
+	}
+
+	public function testGetUserMountsFor() {
+		$id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+		$this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+		$id3 = $this->addMount('/test3', 'foo3', 'bar3', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+		$this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->dbConfig->addApplicable($id3, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+		$mounts = $this->dbConfig->getUserMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+		$this->assertCount(1, $mounts);
+		$this->assertEquals($id3, $mounts[0]['mount_id']);
+		$this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id3]], $mounts[0]['applicable']);
+	}
+
+	public function testGetAdminMountsForGlobal() {
+		$id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+		$this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+
+		$mounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+		$this->assertCount(1, $mounts);
+		$this->assertEquals($id1, $mounts[0]['mount_id']);
+		$this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_GLOBAL, 'value' => null, 'mount_id' => $id1]], $mounts[0]['applicable']);
+	}
+}
diff --git a/apps/files_external/tests/service/globalstoragesservicetest.php b/apps/files_external/tests/service/globalstoragesservicetest.php
index c129365913fcf33cced2e4bbe3465223d23289d9..7c77616563cd17de76a61c8c15e5c543702442c2 100644
--- a/apps/files_external/tests/service/globalstoragesservicetest.php
+++ b/apps/files_external/tests/service/globalstoragesservicetest.php
@@ -23,14 +23,18 @@ namespace OCA\Files_external\Tests\Service;
 
 use \OC\Files\Filesystem;
 
+use OCA\Files_External\Service\DBConfigService;
 use \OCA\Files_external\Service\GlobalStoragesService;
 use \OCA\Files_external\NotFoundException;
 use \OCA\Files_external\Lib\StorageConfig;
 
+/**
+ * @group DB
+ */
 class GlobalStoragesServiceTest extends StoragesServiceTest {
 	public function setUp() {
 		parent::setUp();
-		$this->service = new GlobalStoragesService($this->backendService);
+		$this->service = new GlobalStoragesService($this->backendService, $this->dbConfig);
 	}
 
 	public function tearDown() {
@@ -39,7 +43,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 	}
 
 	protected function makeTestStorageData() {
-		return $this->makeStorageConfig([ 
+		return $this->makeStorageConfig([
 			'mountPoint' => 'mountpoint',
 			'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
 			'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
@@ -133,10 +137,9 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 		$storage = $this->makeStorageConfig($storageParams);
 		$newStorage = $this->service->addStorage($storage);
 
-		$this->assertEquals(1, $newStorage->getId());
-
+		$baseId = $newStorage->getId();
 
-		$newStorage = $this->service->getStorage(1);
+		$newStorage = $this->service->getStorage($baseId);
 
 		$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
 		$this->assertEquals($storage->getBackend(), $newStorage->getBackend());
@@ -145,12 +148,10 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 		$this->assertEquals($storage->getApplicableUsers(), $newStorage->getApplicableUsers());
 		$this->assertEquals($storage->getApplicableGroups(), $newStorage->getApplicableGroups());
 		$this->assertEquals($storage->getPriority(), $newStorage->getPriority());
-		$this->assertEquals(1, $newStorage->getId());
 		$this->assertEquals(0, $newStorage->getStatus());
 
-		// next one gets id 2
 		$nextStorage = $this->service->addStorage($storage);
-		$this->assertEquals(2, $nextStorage->getId());
+		$this->assertEquals($baseId + 1, $nextStorage->getId());
 	}
 
 	/**
@@ -173,19 +174,18 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 		]);
 
 		$newStorage = $this->service->addStorage($storage);
-		$this->assertEquals(1, $newStorage->getId());
+		$id = $newStorage->getId();
 
-		$updatedStorage->setId(1);
+		$updatedStorage->setId($id);
 
 		$this->service->updateStorage($updatedStorage);
-		$newStorage = $this->service->getStorage(1);
+		$newStorage = $this->service->getStorage($id);
 
 		$this->assertEquals($updatedStorage->getMountPoint(), $newStorage->getMountPoint());
 		$this->assertEquals($updatedStorage->getBackendOptions()['password'], $newStorage->getBackendOptions()['password']);
 		$this->assertEquals($updatedStorage->getApplicableUsers(), $newStorage->getApplicableUsers());
 		$this->assertEquals($updatedStorage->getApplicableGroups(), $newStorage->getApplicableGroups());
 		$this->assertEquals($updatedStorage->getPriority(), $newStorage->getPriority());
-		$this->assertEquals(1, $newStorage->getId());
 		$this->assertEquals(0, $newStorage->getStatus());
 	}
 
@@ -442,7 +442,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 		$sourceApplicableGroups,
 		$updatedApplicableUsers,
 		$updatedApplicableGroups,
-	   	$expectedCalls) {
+		$expectedCalls) {
 
 		$storage = $this->makeTestStorageData();
 		$storage->setApplicableUsers($sourceApplicableUsers);
@@ -601,7 +601,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 	public function testHooksDeleteStorage(
 		$sourceApplicableUsers,
 		$sourceApplicableGroups,
-	   	$expectedCalls) {
+		$expectedCalls) {
 
 		$storage = $this->makeTestStorageData();
 		$storage->setApplicableUsers($sourceApplicableUsers);
@@ -626,321 +626,4 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
 		}
 	}
 
-	/**
-	 * Make sure it uses the correct format when reading/writing
-	 * the legacy config
-	 */
-	public function testLegacyConfigConversionApplicableAll() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$storage = $this->makeTestStorageData();
-		$storage = $this->service->addStorage($storage);
-
-		$json = json_decode(file_get_contents($configFile), true);
-
-		$this->assertCount(1, $json);
-
-		$this->assertEquals([\OC_Mount_Config::MOUNT_TYPE_USER], array_keys($json));
-		$this->assertEquals(['all'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
-
-		$mountPointData = $json[\OC_Mount_config::MOUNT_TYPE_USER]['all'];
-		$this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
-		$mountPointOptions = current($mountPointData);
-		$this->assertEquals(1, $mountPointOptions['id']);
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
-		$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
-		$this->assertEquals(15, $mountPointOptions['priority']);
-		$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
-		$backendOptions = $mountPointOptions['options'];
-		$this->assertEquals('value1', $backendOptions['option1']);
-		$this->assertEquals('value2', $backendOptions['option2']);
-		$this->assertEquals('', $backendOptions['password']);
-		$this->assertNotEmpty($backendOptions['password_encrypted']);
-	}
-
-	/**
-	 * Make sure it uses the correct format when reading/writing
-	 * the legacy config
-	 */
-	public function testLegacyConfigConversionApplicableUserAndGroup() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$storage = $this->makeTestStorageData();
-		$storage->setApplicableUsers(['user1', 'user2']);
-		$storage->setApplicableGroups(['group1', 'group2']);
-
-		$storage = $this->service->addStorage($storage);
-
-		$json = json_decode(file_get_contents($configFile), true);
-
-		$this->assertCount(2, $json);
-
-		$this->assertTrue(isset($json[\OC_Mount_Config::MOUNT_TYPE_USER]));
-		$this->assertTrue(isset($json[\OC_Mount_Config::MOUNT_TYPE_GROUP]));
-		$this->assertEquals(['user1', 'user2'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
-		$this->assertEquals(['group1', 'group2'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_GROUP]));
-
-		// check that all options are the same for both users and both groups
-		foreach ($json[\OC_Mount_Config::MOUNT_TYPE_USER] as $mountPointData) {
-			$this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
-			$mountPointOptions = current($mountPointData);
-
-			$this->assertEquals(1, $mountPointOptions['id']);
-			$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
-			$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
-			$this->assertEquals(15, $mountPointOptions['priority']);
-			$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
-			$backendOptions = $mountPointOptions['options'];
-			$this->assertEquals('value1', $backendOptions['option1']);
-			$this->assertEquals('value2', $backendOptions['option2']);
-			$this->assertEquals('', $backendOptions['password']);
-			$this->assertNotEmpty($backendOptions['password_encrypted']);
-		}
-
-		foreach ($json[\OC_Mount_Config::MOUNT_TYPE_GROUP] as $mountPointData) {
-			$this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
-			$mountPointOptions = current($mountPointData);
-
-			$this->assertEquals(1, $mountPointOptions['id']);
-			$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
-			$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
-			$this->assertEquals(15, $mountPointOptions['priority']);
-			$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
-			$backendOptions = $mountPointOptions['options'];
-			$this->assertEquals('value1', $backendOptions['option1']);
-			$this->assertEquals('value2', $backendOptions['option2']);
-			$this->assertEquals('', $backendOptions['password']);
-			$this->assertNotEmpty($backendOptions['password_encrypted']);
-		}
-	}
-
-	/**
-	 * Test reading in a legacy config and generating config ids.
-	 */
-	public function testReadLegacyConfigAndGenerateConfigId() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$legacyBackendOptions = [
-			'user' => 'someuser',
-			'password' => 'somepassword',
-		];
-		$legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
-
-		$legacyConfig = [
-			'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
-			'authMechanism' => 'identifier:\Auth\Mechanism',
-			'options' => $legacyBackendOptions,
-			'mountOptions' => ['preview' => false],
-		];
-		// different mount options
-		$legacyConfig2 = [
-			'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
-			'authMechanism' => 'identifier:\Auth\Mechanism',
-			'options' => $legacyBackendOptions,
-			'mountOptions' => ['preview' => true],
-		];
-
-		$legacyBackendOptions2 = $legacyBackendOptions;
-		$legacyBackendOptions2 = ['user' => 'someuser2', 'password' => 'somepassword2'];
-		$legacyBackendOptions2 = \OC_Mount_Config::encryptPasswords($legacyBackendOptions2);
-
-		// different config
-		$legacyConfig3 = [
-			'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
-			'authMechanism' => 'identifier:\Auth\Mechanism',
-			'options' => $legacyBackendOptions2,
-			'mountOptions' => ['preview' => true],
-		];
-
-		$json = [
-			'user' => [
-				'user1' => [
-					'/$user/files/somemount' => $legacyConfig,
-				],
-				// same config
-				'user2' => [
-					'/$user/files/somemount' => $legacyConfig,
-				],
-				// different mountOptions
-				'user3' => [
-					'/$user/files/somemount' => $legacyConfig2,
-				],
-				// different mount point
-				'user4' => [
-					'/$user/files/anothermount' => $legacyConfig,
-				],
-				// different storage config
-				'user5' => [
-					'/$user/files/somemount' => $legacyConfig3,
-				],
-			],
-			'group' => [
-				'group1' => [
-					// will get grouped with user configs
-					'/$user/files/somemount' => $legacyConfig,
-				],
-			],
-		];
-
-		file_put_contents($configFile, json_encode($json));
-
-		$this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB')
-			->expects($this->exactly(4))
-			->method('validateStorageDefinition');
-		$this->backendService->getAuthMechanism('identifier:\Auth\Mechanism')
-			->expects($this->exactly(4))
-			->method('validateStorageDefinition');
-
-		$allStorages = $this->service->getAllStorages();
-
-		$this->assertCount(4, $allStorages);
-
-		$storage1 = $allStorages[1];
-		$storage2 = $allStorages[2];
-		$storage3 = $allStorages[3];
-		$storage4 = $allStorages[4];
-
-		$this->assertEquals('/somemount', $storage1->getMountPoint());
-		$this->assertEquals('someuser', $storage1->getBackendOptions()['user']);
-		$this->assertEquals('somepassword', $storage1->getBackendOptions()['password']);
-		$this->assertEquals(['user1', 'user2'], $storage1->getApplicableUsers());
-		$this->assertEquals(['group1'], $storage1->getApplicableGroups());
-		$this->assertEquals(['preview' => false], $storage1->getMountOptions());
-
-		$this->assertEquals('/somemount', $storage2->getMountPoint());
-		$this->assertEquals('someuser', $storage2->getBackendOptions()['user']);
-		$this->assertEquals('somepassword', $storage2->getBackendOptions()['password']);
-		$this->assertEquals(['user3'], $storage2->getApplicableUsers());
-		$this->assertEquals([], $storage2->getApplicableGroups());
-		$this->assertEquals(['preview' => true], $storage2->getMountOptions());
-
-		$this->assertEquals('/anothermount', $storage3->getMountPoint());
-		$this->assertEquals('someuser', $storage3->getBackendOptions()['user']);
-		$this->assertEquals('somepassword', $storage3->getBackendOptions()['password']);
-		$this->assertEquals(['user4'], $storage3->getApplicableUsers());
-		$this->assertEquals([], $storage3->getApplicableGroups());
-		$this->assertEquals(['preview' => false], $storage3->getMountOptions());
-
-		$this->assertEquals('/somemount', $storage4->getMountPoint());
-		$this->assertEquals('someuser2', $storage4->getBackendOptions()['user']);
-		$this->assertEquals('somepassword2', $storage4->getBackendOptions()['password']);
-		$this->assertEquals(['user5'], $storage4->getApplicableUsers());
-		$this->assertEquals([], $storage4->getApplicableGroups());
-		$this->assertEquals(['preview' => true], $storage4->getMountOptions());
-	}
-
-	public function testReadLegacyConfigNoAuthMechanism() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$json = [
-			'user' => [
-				'user1' => [
-					'/$user/files/somemount' => [
-						'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
-						'authMechanism' => 'identifier:\Auth\Mechanism',
-						'options' => [],
-						'mountOptions' => [],
-					],
-					'/$user/files/othermount' => [
-						'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
-						// no authMechanism
-						'options' => [],
-						'mountOptions' => [],
-					],
-				]
-			]
-		];
-
-		file_put_contents($configFile, json_encode($json));
-
-		$allStorages = $this->service->getAllStorages();
-
-		$this->assertCount(2, $allStorages);
-
-		$storage1 = $allStorages[1];
-		$storage2 = $allStorages[2];
-
-		$this->assertEquals('/somemount', $storage1->getMountPoint());
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
-		$this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
-
-		$this->assertEquals('/othermount', $storage2->getMountPoint());
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
-		$this->assertEquals('identifier:\Other\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
-	}
-
-	public function testReadLegacyConfigClass() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$json = [
-			'user' => [
-				'user1' => [
-					'/$user/files/somemount' => [
-						'class' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
-						'authMechanism' => 'identifier:\Auth\Mechanism',
-						'options' => [],
-						'mountOptions' => [],
-					],
-					'/$user/files/othermount' => [
-						'class' => 'identifier:sftp_alias',
-						'authMechanism' => 'identifier:\Auth\Mechanism',
-						'options' => [],
-						'mountOptions' => [],
-					],
-				]
-			]
-		];
-
-		file_put_contents($configFile, json_encode($json));
-
-		$allStorages = $this->service->getAllStorages();
-
-		$this->assertCount(2, $allStorages);
-
-		$storage1 = $allStorages[1];
-		$storage2 = $allStorages[2];
-
-		$this->assertEquals('/somemount', $storage1->getMountPoint());
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
-		$this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
-
-		$this->assertEquals('/othermount', $storage2->getMountPoint());
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
-		$this->assertEquals('identifier:\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
-	}
-
-	public function testReadEmptyMountPoint() {
-		$configFile = $this->dataDir . '/mount.json';
-
-		$json = [
-			'user' => [
-				'user1' => [
-					'/$user/files/' => [
-						'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
-						'authMechanism' => 'identifier:\Auth\Mechanism',
-						'options' => [],
-						'mountOptions' => [],
-					],
-				]
-			]
-		];
-
-		file_put_contents($configFile, json_encode($json));
-
-		$allStorages = $this->service->getAllStorages();
-
-		$this->assertCount(1, $allStorages);
-
-		$storage1 = $allStorages[1];
-
-		$this->assertEquals('/', $storage1->getMountPoint());
-	}
-
-
 }
diff --git a/apps/files_external/tests/service/storagesservicetest.php b/apps/files_external/tests/service/storagesservicetest.php
index 7487ba459afdd0785f09666b57af8e05aae67940..7847bd45d4aaea5276cf895563d0eb8214cd5ad2 100644
--- a/apps/files_external/tests/service/storagesservicetest.php
+++ b/apps/files_external/tests/service/storagesservicetest.php
@@ -25,8 +25,29 @@ use \OC\Files\Filesystem;
 
 use \OCA\Files_external\NotFoundException;
 use \OCA\Files_external\Lib\StorageConfig;
-use \OCA\Files_External\Lib\BackendService;
+use OCA\Files_External\Service\BackendService;
+use OCA\Files_External\Service\DBConfigService;
+use OCA\Files_external\Service\StoragesService;
 
+class CleaningDBConfig extends DBConfigService {
+	private $mountIds = [];
+
+	public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+		$id = parent::addMount($mountPoint, $storageBackend, $authBackend, $priority, $type); // TODO: Change the autogenerated stub
+		$this->mountIds[] = $id;
+		return $id;
+	}
+
+	public function clean() {
+		foreach ($this->mountIds as $id) {
+			$this->removeMount($id);
+		}
+	}
+}
+
+/**
+ * @group DB
+ */
 abstract class StoragesServiceTest extends \Test\TestCase {
 
 	/**
@@ -44,6 +65,9 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 	 */
 	protected $dataDir;
 
+	/** @var  CleaningDBConfig */
+	protected $dbConfig;
+
 	/**
 	 * Hook calls
 	 *
@@ -52,6 +76,8 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 	protected static $hookCalls;
 
 	public function setUp() {
+		parent::setUp();
+		$this->dbConfig = new CleaningDBConfig(\OC::$server->getDatabaseConnection());
 		self::$hookCalls = array();
 		$config = \OC::$server->getConfig();
 		$this->dataDir = $config->getSystemValue(
@@ -63,8 +89,8 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		// prepare BackendService mock
 		$this->backendService =
 			$this->getMockBuilder('\OCA\Files_External\Service\BackendService')
-			->disableOriginalConstructor()
-			->getMock();
+				->disableOriginalConstructor()
+				->getMock();
 
 		$authMechanisms = [
 			'identifier:\Auth\Mechanism' => $this->getAuthMechMock('null', '\Auth\Mechanism'),
@@ -72,14 +98,14 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 			'identifier:\OCA\Files_External\Lib\Auth\NullMechanism' => $this->getAuthMechMock(),
 		];
 		$this->backendService->method('getAuthMechanism')
-			->will($this->returnCallback(function($class) use ($authMechanisms) {
+			->will($this->returnCallback(function ($class) use ($authMechanisms) {
 				if (isset($authMechanisms[$class])) {
 					return $authMechanisms[$class];
 				}
 				return null;
 			}));
 		$this->backendService->method('getAuthMechanismsByScheme')
-			->will($this->returnCallback(function($schemes) use ($authMechanisms) {
+			->will($this->returnCallback(function ($schemes) use ($authMechanisms) {
 				return array_filter($authMechanisms, function ($authMech) use ($schemes) {
 					return in_array($authMech->getScheme(), $schemes, true);
 				});
@@ -96,7 +122,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		$backends['identifier:\OCA\Files_External\Lib\Backend\SFTP']->method('getLegacyAuthMechanism')
 			->willReturn($authMechanisms['identifier:\Other\Auth\Mechanism']);
 		$this->backendService->method('getBackend')
-			->will($this->returnCallback(function($backendClass) use ($backends) {
+			->will($this->returnCallback(function ($backendClass) use ($backends) {
 				if (isset($backends[$backendClass])) {
 					return $backends[$backendClass];
 				}
@@ -116,7 +142,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 
 		$containerMock = $this->getMock('\OCP\AppFramework\IAppContainer');
 		$containerMock->method('query')
-			->will($this->returnCallback(function($name) {
+			->will($this->returnCallback(function ($name) {
 				if ($name === 'OCA\Files_External\Service\BackendService') {
 					return $this->backendService;
 				}
@@ -132,6 +158,9 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 	public function tearDown() {
 		\OC_Mount_Config::$skipTest = false;
 		self::$hookCalls = array();
+		if ($this->dbConfig) {
+			$this->dbConfig->clean();
+		}
 	}
 
 	protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') {
@@ -141,7 +170,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		$backend->method('getStorageClass')
 			->willReturn($storageClass);
 		$backend->method('getIdentifier')
-			->willReturn('identifier:'.$class);
+			->willReturn('identifier:' . $class);
 		return $backend;
 	}
 
@@ -152,7 +181,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		$authMech->method('getScheme')
 			->willReturn($scheme);
 		$authMech->method('getIdentifier')
-			->willReturn('identifier:'.$class);
+			->willReturn('identifier:' . $class);
 
 		return $authMech;
 	}
@@ -258,7 +287,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		$storage->setBackendOptions($backendOptions);
 
 		$newStorage = $this->service->addStorage($storage);
-		$this->assertEquals(1, $newStorage->getId());
+		$id = $newStorage->getId();
 
 		// manually trigger storage entry because normally it happens on first
 		// access, which isn't possible within this test
@@ -267,7 +296,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 		// get numeric id for later check
 		$numericId = $storageCache->getNumericId();
 
-		$newStorage = $this->service->removeStorage(1);
+		$this->service->removeStorage($id);
 
 		$caught = false;
 		try {
@@ -317,7 +346,7 @@ abstract class StoragesServiceTest extends \Test\TestCase {
 			$priority
 		);
 
-		$this->assertEquals('/'.$mountPoint, $storage->getMountPoint());
+		$this->assertEquals('/' . $mountPoint, $storage->getMountPoint());
 		$this->assertEquals($backend, $storage->getBackend());
 		$this->assertEquals($authMechanism, $storage->getAuthMechanism());
 		$this->assertEquals($backendOptions, $storage->getBackendOptions());
diff --git a/apps/files_external/tests/service/userglobalstoragesservicetest.php b/apps/files_external/tests/service/userglobalstoragesservicetest.php
index e88764d0f78277a6466085509d575278b2354657..b8379288d436e9fea38fff5c4d06ab23250f84a9 100644
--- a/apps/files_external/tests/service/userglobalstoragesservicetest.php
+++ b/apps/files_external/tests/service/userglobalstoragesservicetest.php
@@ -21,17 +21,33 @@
  */
 namespace OCA\Files_External\Tests\Service;
 
+use OCA\Files_external\Service\StoragesService;
 use \OCA\Files_External\Service\UserGlobalStoragesService;
 use \OCP\IGroupManager;
 
 use \OCA\Files_External\Lib\StorageConfig;
+use OCP\IUser;
+use Test\Traits\UserTrait;
 
+/**
+ * @group DB
+ */
 class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
+	use UserTrait;
 
+	/** @var \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject groupManager */
 	protected $groupManager;
 
+	/**
+	 * @var StoragesService
+	 */
 	protected $globalStoragesService;
 
+	/**
+	 * @var UserGlobalStoragesService
+	 */
+	protected $service;
+
 	protected $user;
 
 	const USER_ID = 'test_user';
@@ -44,6 +60,7 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
 		$this->globalStoragesService = $this->service;
 
 		$this->user = new \OC\User\User(self::USER_ID, null);
+		/** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
 		$userSession = $this->getMock('\OCP\IUserSession');
 		$userSession
 			->expects($this->any())
@@ -52,19 +69,28 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
 
 		$this->groupManager = $this->getMock('\OCP\IGroupManager');
 		$this->groupManager->method('isInGroup')
-			->will($this->returnCallback(function($userId, $groupId) {
+			->will($this->returnCallback(function ($userId, $groupId) {
 				if ($userId === self::USER_ID) {
 					switch ($groupId) {
-					case self::GROUP_ID:
-					case self::GROUP_ID2:
-						return true;
+						case self::GROUP_ID:
+						case self::GROUP_ID2:
+							return true;
 					}
 				}
 				return false;
 			}));
+		$this->groupManager->method('getUserGroupIds')
+			->will($this->returnCallback(function (IUser $user) {
+				if ($user->getUID() === self::USER_ID) {
+					return [self::GROUP_ID, self::GROUP_ID2];
+				} else {
+					return [];
+				}
+			}));
 
 		$this->service = new UserGlobalStoragesService(
 			$this->backendService,
+			$this->dbConfig,
 			$userSession,
 			$this->groupManager
 		);
@@ -154,6 +180,13 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
 		$this->service->updateStorage($retrievedStorage);
 	}
 
+	/**
+	 * @expectedException \DomainException
+	 */
+	public function testNonExistingStorage() {
+		parent::testNonExistingStorage();
+	}
+
 	/**
 	 * @expectedException \DomainException
 	 * @dataProvider deleteStorageDataProvider
@@ -169,9 +202,16 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
 		$storage->setBackendOptions($backendOptions);
 
 		$newStorage = $this->globalStoragesService->addStorage($storage);
-		$this->assertEquals(1, $newStorage->getId());
+		$id = $newStorage->getId();
 
-		$this->service->removeStorage(1);
+		$this->service->removeStorage($id);
+	}
+
+	/**
+	 * @expectedException \DomainException
+	 */
+	public function testDeleteUnexistingStorage() {
+		parent::testDeleteUnexistingStorage();
 	}
 
 	public function getUniqueStoragesProvider() {
diff --git a/apps/files_external/tests/service/userstoragesservicetest.php b/apps/files_external/tests/service/userstoragesservicetest.php
index 78f9231c3d15ddad3a387890c8100308f1063c03..5e984c52bfd192c36a0017647e8724a1449534a8 100644
--- a/apps/files_external/tests/service/userstoragesservicetest.php
+++ b/apps/files_external/tests/service/userstoragesservicetest.php
@@ -26,36 +26,33 @@ use \OC\Files\Filesystem;
 use \OCA\Files_external\Service\UserStoragesService;
 use \OCA\Files_external\NotFoundException;
 use \OCA\Files_external\Lib\StorageConfig;
+use Test\Traits\UserTrait;
 
+/**
+ * @group DB
+ */
 class UserStoragesServiceTest extends StoragesServiceTest {
+	use UserTrait;
+
+	private $user;
+
+	private $userId;
 
 	public function setUp() {
 		parent::setUp();
 
-		$userManager = \OC::$server->getUserManager();
-
 		$this->userId = $this->getUniqueID('user_');
-		$this->user = $userManager->createUser(
-			$this->userId,
-			$this->userId
-		);
+		$this->createUser($this->userId, $this->userId);
+		$this->user = \OC::$server->getUserManager()->get($this->userId);
 
+		/** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
 		$userSession = $this->getMock('\OCP\IUserSession');
 		$userSession
 			->expects($this->any())
 			->method('getUser')
 			->will($this->returnValue($this->user));
 
-		$this->service = new UserStoragesService($this->backendService, $userSession);
-
-		// create home folder
-		mkdir($this->dataDir . '/' . $this->userId . '/');
-	}
-
-	public function tearDown() {
-		@unlink($this->dataDir . '/' . $this->userId . '/mount.json');
-		$this->user->delete();
-		parent::tearDown();
+		$this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession);
 	}
 
 	private function makeTestStorageData() {
@@ -79,15 +76,14 @@ class UserStoragesServiceTest extends StoragesServiceTest {
 
 		$newStorage = $this->service->addStorage($storage);
 
-		$this->assertEquals(1, $newStorage->getId());
+		$id = $newStorage->getId();
 
-		$newStorage = $this->service->getStorage(1);
+		$newStorage = $this->service->getStorage($id);
 
 		$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
 		$this->assertEquals($storage->getBackend(), $newStorage->getBackend());
 		$this->assertEquals($storage->getAuthMechanism(), $newStorage->getAuthMechanism());
 		$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
-		$this->assertEquals(1, $newStorage->getId());
 		$this->assertEquals(0, $newStorage->getStatus());
 
 		// hook called once for user
@@ -99,9 +95,8 @@ class UserStoragesServiceTest extends StoragesServiceTest {
 			$this->userId
 		);
 
-		// next one gets id 2
 		$nextStorage = $this->service->addStorage($storage);
-		$this->assertEquals(2, $nextStorage->getId());
+		$this->assertEquals($id + 1, $nextStorage->getId());
 	}
 
 	public function testUpdateStorage() {
@@ -117,7 +112,6 @@ class UserStoragesServiceTest extends StoragesServiceTest {
 		]);
 
 		$newStorage = $this->service->addStorage($storage);
-		$this->assertEquals(1, $newStorage->getId());
 
 		$backendOptions = $newStorage->getBackendOptions();
 		$backendOptions['password'] = 'anotherPassword';
@@ -131,7 +125,6 @@ class UserStoragesServiceTest extends StoragesServiceTest {
 		// these attributes are unused for user storages
 		$this->assertEmpty($newStorage->getApplicableUsers());
 		$this->assertEmpty($newStorage->getApplicableGroups());
-		$this->assertEquals(1, $newStorage->getId());
 		$this->assertEquals(0, $newStorage->getStatus());
 
 		// no hook calls
@@ -181,89 +174,4 @@ class UserStoragesServiceTest extends StoragesServiceTest {
 			$this->userId
 		);
 	}
-
-	/**
-	 * Make sure it uses the correct format when reading/writing
-	 * the legacy config
-	 */
-	public function testLegacyConfigConversion() {
-		$configFile = $this->dataDir . '/' . $this->userId . '/mount.json';
-
-		$storage = $this->makeTestStorageData();
-		$storage = $this->service->addStorage($storage);
-
-		$json = json_decode(file_get_contents($configFile), true);
-
-		$this->assertCount(1, $json);
-
-		$this->assertEquals([\OC_Mount_Config::MOUNT_TYPE_USER], array_keys($json));
-		$this->assertEquals([$this->userId], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
-
-		$mountPointData = $json[\OC_Mount_config::MOUNT_TYPE_USER][$this->userId];
-		$this->assertEquals(['/' . $this->userId . '/files/mountpoint'], array_keys($mountPointData));
-
-		$mountPointOptions = current($mountPointData);
-		$this->assertEquals(1, $mountPointOptions['id']);
-		$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
-		$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
-		$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
-		$backendOptions = $mountPointOptions['options'];
-		$this->assertEquals('value1', $backendOptions['option1']);
-		$this->assertEquals('value2', $backendOptions['option2']);
-		$this->assertEquals('', $backendOptions['password']);
-		$this->assertNotEmpty($backendOptions['password_encrypted']);
-	}
-
-	/**
-	 * Test reading in a legacy config and generating config ids.
-	 */
-	public function testReadLegacyConfigAndGenerateConfigId() {
-		$configFile = $this->dataDir . '/' . $this->userId . '/mount.json';
-
-		$legacyBackendOptions = [
-			'user' => 'someuser',
-			'password' => 'somepassword',
-		];
-		$legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
-
-		$legacyConfig = [
-			'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
-			'authMechanism' => 'identifier:\Auth\Mechanism',
-			'options' => $legacyBackendOptions,
-			'mountOptions' => ['preview' => false],
-		];
-		// different mount options
-		$legacyConfig2 = [
-			'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
-			'authMechanism' => 'identifier:\Auth\Mechanism',
-			'options' => $legacyBackendOptions,
-			'mountOptions' => ['preview' => true],
-		];
-
-		$json = ['user' => []];
-		$json['user'][$this->userId] = [
-			'/$user/files/somemount' => $legacyConfig,
-			'/$user/files/anothermount' => $legacyConfig2,
-		];
-
-		file_put_contents($configFile, json_encode($json));
-
-		$allStorages = $this->service->getAllStorages();
-
-		$this->assertCount(2, $allStorages);
-
-		$storage1 = $allStorages[1];
-		$storage2 = $allStorages[2];
-
-		$this->assertEquals('/somemount', $storage1->getMountPoint());
-		$this->assertEquals('someuser', $storage1->getBackendOptions()['user']);
-		$this->assertEquals('somepassword', $storage1->getBackendOptions()['password']);
-		$this->assertEquals(['preview' => false], $storage1->getMountOptions());
-
-		$this->assertEquals('/anothermount', $storage2->getMountPoint());
-		$this->assertEquals('someuser', $storage2->getBackendOptions()['user']);
-		$this->assertEquals('somepassword', $storage2->getBackendOptions()['password']);
-		$this->assertEquals(['preview' => true], $storage2->getMountOptions());
-	}
 }