diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php
index b5eab90af48a88638af344651dd353d36c0efeda..654fb70ced584e9c114d53cf91ffe5a8fdd6bc91 100644
--- a/apps/user_ldap/ajax/wizard.php
+++ b/apps/user_ldap/ajax/wizard.php
@@ -60,7 +60,7 @@ $userManager = new \OCA\User_LDAP\User\Manager(
 	\OC::$server->getDatabaseConnection(),
 	\OC::$server->getUserManager());
 
-$access = new \OCA\User_LDAP\Access($con, $ldapWrapper, $userManager);
+$access = new \OCA\User_LDAP\Access($con, $ldapWrapper, $userManager, new \OCA\User_LDAP\Helper());
 
 $wizard = new \OCA\User_LDAP\Wizard($configuration, $ldapWrapper, $access);
 
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 18987614bdbcab5e8acb306034c59fbabf092408..10cc003a3f5a8d5ac6e70325b169b624f90d2311 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -44,7 +44,7 @@ if(count($configPrefixes) === 1) {
 		\OC::$server->getUserManager()
 	);
 	$connector = new OCA\User_LDAP\Connection($ldapWrapper, $configPrefixes[0]);
-	$ldapAccess = new OCA\User_LDAP\Access($connector, $ldapWrapper, $userManager);
+	$ldapAccess = new OCA\User_LDAP\Access($connector, $ldapWrapper, $userManager, $helper);
 
 	$ldapAccess->setUserMapper(new OCA\User_LDAP\Mapping\UserMapping($dbc));
 	$ldapAccess->setGroupMapper(new OCA\User_LDAP\Mapping\GroupMapping($dbc));
diff --git a/apps/user_ldap/appinfo/install.php b/apps/user_ldap/appinfo/install.php
index b3c92b0024ae62f4c05ca7427751d9b02b7667a1..c16a1f4a039caf4fa70a01b1fc88e6e086611827 100644
--- a/apps/user_ldap/appinfo/install.php
+++ b/apps/user_ldap/appinfo/install.php
@@ -4,6 +4,7 @@
  *
  * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  * @author Christopher Schäpers <kondou@ts.unde.re>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -24,3 +25,6 @@ $state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doSet');
 if($state === 'doSet') {
 	OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
 }
+
+$helper = new \OCA\User_LDAP\Helper();
+$helper->setLDAPProvider();
diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php
new file mode 100644
index 0000000000000000000000000000000000000000..f816a7ec9c6351b81a770ad0f2b37c6bca1bd96c
--- /dev/null
+++ b/apps/user_ldap/appinfo/update.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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/>
+ *
+ */
+$helper = new \OCA\User_LDAP\Helper();
+$helper->setLDAPProvider();
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index dabf243eda16105d2300ea846b8e8ecc53357700..299ad581644f8bba794f2a9efee98d5947982861 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -20,6 +20,7 @@
  * @author Ralph Krimmel <rkrimme1@gwdg.de>
  * @author Renaud Fortier <Renaud.Fortier@fsaa.ulaval.ca>
  * @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -77,13 +78,19 @@ class Access extends LDAPUtility implements IUserTools {
 	* @var AbstractMapping $userMapper
 	*/
 	protected $groupMapper;
+	
+	/**
+	 * @var \OCA\User_LDAP\Helper
+	 */
+	private $helper;
 
 	public function __construct(Connection $connection, ILDAPWrapper $ldap,
-		Manager $userManager) {
+		Manager $userManager, Helper $helper) {
 		parent::__construct($ldap);
 		$this->connection = $connection;
 		$this->userManager = $userManager;
 		$this->userManager->setLdapAccess($this);
+		$this->helper = $helper;
 	}
 
 	/**
@@ -173,7 +180,7 @@ class Access extends LDAPUtility implements IUserTools {
 		// (cf. #12306), 500 is default for paging and should work everywhere.
 		$maxResults = $pagingSize > 20 ? $pagingSize : 500;
 		$this->initPagedSearch($filter, array($dn), array($attr), $maxResults, 0);
-		$dn = $this->DNasBaseParameter($dn);
+		$dn = $this->helper->DNasBaseParameter($dn);
 		$rr = @$this->ldap->read($cr, $dn, $filter, array($attr));
 		if(!$this->ldap->isResource($rr)) {
 			if(!empty($attr)) {
@@ -201,7 +208,7 @@ class Access extends LDAPUtility implements IUserTools {
 			$values = array();
 			for($i=0;$i<$result[$attr]['count'];$i++) {
 				if($this->resemblesDN($attr)) {
-					$values[] = $this->sanitizeDN($result[$attr][$i]);
+					$values[] = $this->helper->sanitizeDN($result[$attr][$i]);
 				} elseif(strtolower($attr) === 'objectguid' || strtolower($attr) === 'guid') {
 					$values[] = $this->convertObjectGUID2Str($result[$attr][$i]);
 				} else {
@@ -242,49 +249,6 @@ class Access extends LDAPUtility implements IUserTools {
 		return (is_array($r) && count($r) > 1);
 	}
 
-	/**
-	 * sanitizes a DN received from the LDAP server
-	 * @param array $dn the DN in question
-	 * @return array the sanitized DN
-	 */
-	private function sanitizeDN($dn) {
-		//treating multiple base DNs
-		if(is_array($dn)) {
-			$result = array();
-			foreach($dn as $singleDN) {
-				$result[] = $this->sanitizeDN($singleDN);
-			}
-			return $result;
-		}
-
-		//OID sometimes gives back DNs with whitespace after the comma
-		// a la "uid=foo, cn=bar, dn=..." We need to tackle this!
-		$dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
-
-		//make comparisons and everything work
-		$dn = mb_strtolower($dn, 'UTF-8');
-
-		//escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
-		//to use the DN in search filters, \ needs to be escaped to \5c additionally
-		//to use them in bases, we convert them back to simple backslashes in readAttribute()
-		$replacements = array(
-			'\,' => '\5c2C',
-			'\=' => '\5c3D',
-			'\+' => '\5c2B',
-			'\<' => '\5c3C',
-			'\>' => '\5c3E',
-			'\;' => '\5c3B',
-			'\"' => '\5c22',
-			'\#' => '\5c23',
-			'('  => '\28',
-			')'  => '\29',
-			'*'  => '\2A',
-		);
-		$dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
-
-		return $dn;
-	}
-
 	/**
 	 * returns a DN-string that is cleaned from not domain parts, e.g.
 	 * cn=foo,cn=bar,dc=foobar,dc=server,dc=org
@@ -1071,10 +1035,10 @@ class Access extends LDAPUtility implements IUserTools {
 						}
 						if($key !== 'dn') {
 							$selection[$i][$key] = $this->resemblesDN($key) ?
-								$this->sanitizeDN($item[$key])
+								$this->helper->sanitizeDN($item[$key])
 								: $item[$key];
 						} else {
-							$selection[$i][$key] = [$this->sanitizeDN($item[$key])];
+							$selection[$i][$key] = [$this->helper->sanitizeDN($item[$key])];
 						}
 					}
 
@@ -1298,7 +1262,7 @@ class Access extends LDAPUtility implements IUserTools {
 	 * @return bool
 	 */
 	public function areCredentialsValid($name, $password) {
-		$name = $this->DNasBaseParameter($name);
+		$name = $this->helper->DNasBaseParameter($name);
 		$testConnection = clone $this->connection;
 		$credentials = array(
 			'ldapAgentName' => $name,
@@ -1569,15 +1533,6 @@ class Access extends LDAPUtility implements IUserTools {
 		return sprintf('S-%d-%s-%s', $revision, $iav, implode('-', $subIDs));
 	}
 
-	/**
-	 * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
-	 * @param string $dn the DN
-	 * @return string
-	 */
-	private function DNasBaseParameter($dn) {
-		return str_ireplace('\\5c', '\\', $dn);
-	}
-
 	/**
 	 * checks if the given DN is part of the given base DN(s)
 	 * @param string $dn the DN
@@ -1586,7 +1541,7 @@ class Access extends LDAPUtility implements IUserTools {
 	 */
 	public function isDNPartOfBase($dn, $bases) {
 		$belongsToBase = false;
-		$bases = $this->sanitizeDN($bases);
+		$bases = $this->helper->sanitizeDN($bases);
 
 		foreach($bases as $base) {
 			$belongsToBase = true;
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index 7bd5e97e4f4ca052455398f48afd1e4364399e30..7fb26526195e7c918b4092181163c72c09f792f0 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -11,6 +11,7 @@
  * @author Morris Jobke <hey@morrisjobke.de>
  * @author Robin Appelman <robin@icewind.nl>
  * @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -52,6 +53,8 @@ class Connection extends LDAPUtility {
 	private $configID;
 	private $configured = false;
 	private $hasPagedResultSupport = true;
+	//whether connection should be kept on __destruct
+	private $dontDestruct = false;
 
 	/**
 	 * @var bool runtime flag that indicates whether supported primary groups are available
@@ -93,7 +96,7 @@ class Connection extends LDAPUtility {
 	}
 
 	public function __destruct() {
-		if($this->ldap->isResource($this->ldapConnectionRes)) {
+		if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
 			@$this->ldap->unbind($this->ldapConnectionRes);
 		};
 	}
@@ -105,6 +108,7 @@ class Connection extends LDAPUtility {
 		$this->configuration = new Configuration($this->configPrefix,
 												 !is_null($this->configID));
 		$this->ldapConnectionRes = null;
+		$this->dontDestruct = true;
 	}
 
 	/**
diff --git a/apps/user_ldap/lib/Helper.php b/apps/user_ldap/lib/Helper.php
index ccc1d2c0b44e0c31c725582049db82cb10230709..90807a3c526bbc3cb3df2637bdc0481629894e52 100644
--- a/apps/user_ldap/lib/Helper.php
+++ b/apps/user_ldap/lib/Helper.php
@@ -10,6 +10,7 @@
  * @author Morris Jobke <hey@morrisjobke.de>
  * @author Thomas Müller <thomas.mueller@tmit.eu>
  * @author Vincent Petry <pvince81@owncloud.com>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -183,6 +184,70 @@ class Helper {
 
 		return $domain;
 	}
+	
+	/**
+	 *
+	 * Set the LDAPProvider in the config
+	 *
+	 */
+	public function setLDAPProvider() {
+		$current = \OC::$server->getConfig()->getSystemValue('ldapProviderFactory', null);
+		if(is_null($current)) {
+			\OC::$server->getConfig()->setSystemValue('ldapProviderFactory', '\\OCA\\User_LDAP\\LDAPProviderFactory');
+		}
+	}
+	
+	/**
+	 * sanitizes a DN received from the LDAP server
+	 * @param array $dn the DN in question
+	 * @return array the sanitized DN
+	 */
+	public function sanitizeDN($dn) {
+		//treating multiple base DNs
+		if(is_array($dn)) {
+			$result = array();
+			foreach($dn as $singleDN) {
+				$result[] = $this->sanitizeDN($singleDN);
+			}
+			return $result;
+		}
+
+		//OID sometimes gives back DNs with whitespace after the comma
+		// a la "uid=foo, cn=bar, dn=..." We need to tackle this!
+		$dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
+
+		//make comparisons and everything work
+		$dn = mb_strtolower($dn, 'UTF-8');
+
+		//escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
+		//to use the DN in search filters, \ needs to be escaped to \5c additionally
+		//to use them in bases, we convert them back to simple backslashes in readAttribute()
+		$replacements = array(
+			'\,' => '\5c2C',
+			'\=' => '\5c3D',
+			'\+' => '\5c2B',
+			'\<' => '\5c3C',
+			'\>' => '\5c3E',
+			'\;' => '\5c3B',
+			'\"' => '\5c22',
+			'\#' => '\5c23',
+			'('  => '\28',
+			')'  => '\29',
+			'*'  => '\2A',
+		);
+		$dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
+
+		return $dn;
+	}
+	
+	/**
+	 * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
+	 * @param string $dn the DN
+	 * @return string
+	 */
+	public function DNasBaseParameter($dn) {
+		return str_ireplace('\\5c', '\\', $dn);
+	}
 
 	/**
 	 * listens to a hook thrown by server2server sharing and replaces the given
diff --git a/apps/user_ldap/lib/IUserLDAP.php b/apps/user_ldap/lib/IUserLDAP.php
new file mode 100644
index 0000000000000000000000000000000000000000..c04e2ddffe7776de1f334ad30b54277c6e14d2e6
--- /dev/null
+++ b/apps/user_ldap/lib/IUserLDAP.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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\User_LDAP;
+
+interface IUserLDAP {
+
+	//Functions used by LDAPProvider
+	
+	/**
+	 * Return access for LDAP interaction.
+	 * @param string $uid
+	 * @return Access instance of Access for LDAP interaction
+	 */
+	public function getLDAPAccess($uid);
+	
+	/**
+	 * Return a new LDAP connection for the specified user.
+	 * @param string $uid
+	 * @return resource of the LDAP connection
+	 */
+	public function getNewLDAPConnection($uid);
+
+	/**
+	 * Return the username for the given LDAP DN, if available.
+	 * @param string $dn
+	 * @return string|false with the name to use in ownCloud
+	 */
+	public function dn2UserName($dn);
+}
diff --git a/apps/user_ldap/lib/Jobs/UpdateGroups.php b/apps/user_ldap/lib/Jobs/UpdateGroups.php
index 91d40d5874215332f478721d1c92f795c99c1687..047b95a6d9b78eecc521e417fe1bf71644bf8507 100644
--- a/apps/user_ldap/lib/Jobs/UpdateGroups.php
+++ b/apps/user_ldap/lib/Jobs/UpdateGroups.php
@@ -188,7 +188,7 @@ class UpdateGroups extends \OC\BackgroundJob\TimedJob {
 				$dbc,
 				\OC::$server->getUserManager());
 			$connector = new Connection($ldapWrapper, $configPrefixes[0]);
-			$ldapAccess = new Access($connector, $ldapWrapper, $userManager);
+			$ldapAccess = new Access($connector, $ldapWrapper, $userManager, $helper);
 			$groupMapper = new GroupMapping($dbc);
 			$userMapper  = new UserMapping($dbc);
 			$ldapAccess->setGroupMapper($groupMapper);
diff --git a/apps/user_ldap/lib/LDAPProvider.php b/apps/user_ldap/lib/LDAPProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d6b56005964a93a1c95dc9d8ad53dc857d199d7
--- /dev/null
+++ b/apps/user_ldap/lib/LDAPProvider.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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\User_LDAP;
+
+use OCP\IUserBackend;
+use OCP\LDAP\ILDAPProvider;
+use OCP\LDAP\IDeletionFlagSupport;
+use OCP\IServerContainer;
+use OCA\User_LDAP\User\DeletedUsersIndex;
+use OCA\User_LDAP\Mapping\UserMapping;
+
+/**
+ * LDAP provider for pulic access to the LDAP backend.
+ */
+class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
+
+	private $backend;
+	private $logger;
+	private $helper;
+	private $deletedUsersIndex;
+	
+	/**
+	 * Create new LDAPProvider
+	 * @param \OCP\IServerContainer $serverContainer
+	 * @throws \Exception if user_ldap app was not enabled
+	 */
+	public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
+		$this->logger = $serverContainer->getLogger();
+		$this->helper = $helper;
+		$this->deletedUsersIndex = $deletedUsersIndex;
+		foreach ($serverContainer->getUserManager()->getBackends() as $backend){
+			$this->logger->debug('instance '.get_class($backend).' backend.', ['app' => 'user_ldap']);
+			if ($backend instanceof IUserLDAP) {
+				$this->backend = $backend;
+				return;
+			}
+        }
+		throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled');
+	}
+	
+	/**
+	 * Translate an ownCloud user id to LDAP DN
+	 * @param string $uid ownCloud user id
+	 * @return string with the LDAP DN
+	 * @throws \Exception if translation was unsuccessful
+	 */
+	public function getUserDN($uid) {
+		if(!$this->backend->userExists($uid)){
+			throw new \Exception('User id not found in LDAP');
+		}
+		$result = $this->backend->getLDAPAccess($uid)->username2dn($uid);
+		if(!$result){
+			throw new \Exception('Translation to LDAP DN unsuccessful');
+		}
+		return $result;
+	}
+	
+	/**
+	 * Translate a LDAP DN to an ownCloud user name. If there is no mapping between 
+	 * the DN and the user name, a new one will be created.
+	 * @param string $dn LDAP DN
+	 * @return string with the ownCloud user name
+	 * @throws \Exception if translation was unsuccessful
+	 */
+	public function getUserName($dn) {
+		$result = $this->backend->dn2UserName($dn);
+		if(!$result){
+			throw new \Exception('Translation to ownCloud user name unsuccessful');
+		}
+		return $result;
+	}
+	
+	/**
+	 * Convert a stored DN so it can be used as base parameter for LDAP queries.
+	 * @param string $dn the DN in question
+	 * @return string
+	 */
+	public function DNasBaseParameter($dn) {
+		return $this->helper->DNasBaseParameter($dn);
+	}
+	
+	/**
+	 * Sanitize a DN received from the LDAP server.
+	 * @param array $dn the DN in question
+	 * @return array the sanitized DN
+	 */
+	public function sanitizeDN($dn) {
+		return $this->helper->sanitizeDN($dn);
+	}
+	
+	/**
+	 * Return a new LDAP connection resource for the specified user. 
+	 * The connection must be closed manually.
+	 * @param string $uid ownCloud user id
+	 * @return resource of the LDAP connection
+	 * @throws \Exception if user id was not found in LDAP
+	 */
+	public function getLDAPConnection($uid) {
+		if(!$this->backend->userExists($uid)){
+			throw new \Exception('User id not found in LDAP');
+		}
+		return $this->backend->getNewLDAPConnection($uid);
+	}
+	
+	/**
+	 * Get the LDAP base for users.
+	 * @param string $uid ownCloud user id
+	 * @return string the base for users
+	 * @throws \Exception if user id was not found in LDAP
+	 */
+	public function getLDAPBaseUsers($uid) {
+		if(!$this->backend->userExists($uid)){
+			throw new \Exception('User id not found in LDAP');
+		}	
+		return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users'];
+	}
+	
+	/**
+	 * Get the LDAP base for groups.
+	 * @param string $uid ownCloud user id
+	 * @return string the base for groups
+	 * @throws \Exception if user id was not found in LDAP
+	 */
+	public function getLDAPBaseGroups($uid) {
+		if(!$this->backend->userExists($uid)){
+			throw new \Exception('User id not found in LDAP');
+		}
+		return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups'];
+	}
+	
+	/**
+	 * Clear the cache if a cache is used, otherwise do nothing.
+	 * @param string $uid ownCloud user id
+	 * @throws \Exception if user id was not found in LDAP
+	 */
+	public function clearCache($uid) {
+		if(!$this->backend->userExists($uid)){
+			throw new \Exception('User id not found in LDAP');
+		}
+		$this->backend->getLDAPAccess($uid)->getConnection()->clearCache();
+	}
+	
+	/**
+	 * Check whether a LDAP DN exists
+	 * @param string $dn LDAP DN
+	 * @return bool whether the DN exists
+	 */
+	public function dnExists($dn) {
+		$result = $this->backend->dn2UserName($dn);
+		return !$result ? false : true;
+	}
+	
+	/**
+	 * Flag record for deletion.
+	 * @param string $uid ownCloud user id
+	 */
+	public function flagRecord($uid) {
+		$this->deletedUsersIndex->markUser($uid);
+	}
+	
+	/**
+	 * Unflag record for deletion.
+	 * @param string $uid ownCloud user id
+	 */
+	public function unflagRecord($uid) {
+		//do nothing
+	}
+}
diff --git a/apps/user_ldap/lib/LDAPProviderFactory.php b/apps/user_ldap/lib/LDAPProviderFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..6525d14d3fd8b04e9a292d2b54dd42355394062e
--- /dev/null
+++ b/apps/user_ldap/lib/LDAPProviderFactory.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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\User_LDAP;
+
+use OCP\LDAP\ILDAPProviderFactory;
+use OCP\IServerContainer;
+use OCA\User_LDAP\User\DeletedUsersIndex;
+use OCA\User_LDAP\Mapping\UserMapping;
+
+class LDAPProviderFactory implements ILDAPProviderFactory {
+	/**
+	 * Server container
+	 *
+	 * @var IServerContainer
+	 */
+	private $serverContainer;
+	
+	/**
+	 * Constructor for the LDAP provider factory
+	 *
+	 * @param IServerContainer $serverContainer server container
+	 */
+	public function __construct(IServerContainer $serverContainer) {
+		$this->serverContainer = $serverContainer;
+	}
+	
+	/**
+	 * creates and returns an instance of the ILDAPProvider
+	 *
+	 * @return OCP\LDAP\ILDAPProvider
+	 */
+	public function getLDAPProvider() {
+		$dbConnection = $this->serverContainer->getDatabaseConnection();
+		$userMapping = new UserMapping($dbConnection);
+		return new LDAPProvider($this->serverContainer, new Helper(), 
+					new DeletedUsersIndex($this->serverContainer->getConfig(), 
+					$dbConnection, $userMapping));
+	}
+}
diff --git a/apps/user_ldap/lib/Proxy.php b/apps/user_ldap/lib/Proxy.php
index 07cc1ea0e8c701b06a6bcfbc324b44fd345c7054..db1c761656f3a04f3fe64541d16635a6201de569 100644
--- a/apps/user_ldap/lib/Proxy.php
+++ b/apps/user_ldap/lib/Proxy.php
@@ -77,7 +77,7 @@ abstract class Proxy {
 		$userManager =
 			new Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, $coreUserManager);
 		$connector = new Connection($this->ldap, $configPrefix);
-		$access = new Access($connector, $this->ldap, $userManager);
+		$access = new Access($connector, $this->ldap, $userManager, new Helper());
 		$access->setUserMapper($userMap);
 		$access->setGroupMapper($groupMap);
 		self::$accesses[$configPrefix] = $access;
diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php
index a2a65bb8406af7aa5b8349df292ce19580db9267..712cc9601dd56afdc90fcc755989ad1d4fc8ef9e 100644
--- a/apps/user_ldap/lib/User_LDAP.php
+++ b/apps/user_ldap/lib/User_LDAP.php
@@ -15,6 +15,7 @@
  * @author Robin McCorkell <robin@mccorkell.me.uk>
  * @author Thomas Müller <thomas.mueller@tmit.eu>
  * @author Tom Needham <tom@owncloud.com>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -39,7 +40,7 @@ use OCA\User_LDAP\User\OfflineUser;
 use OCA\User_LDAP\User\User;
 use OCP\IConfig;
 
-class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface {
+class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
 	/** @var string[] $homesToKill */
 	protected $homesToKill = array();
 
@@ -90,6 +91,16 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
 			return false;
 		}
 	}
+	
+	/**
+	 * returns the username for the given LDAP DN, if available
+	 *
+	 * @param string $dn
+	 * @return string|false with the name to use in ownCloud
+	 */
+	public function dn2UserName($dn) {
+		return $this->access->dn2username($dn);
+	}
 
 	/**
 	 * returns an LDAP record based on a given login name
@@ -462,5 +473,25 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
 	public function getBackendName(){
 		return 'LDAP';
 	}
-
+	
+	/**
+	 * Return access for LDAP interaction.
+	 * @param string $uid
+	 * @return Access instance of Access for LDAP interaction
+	 */
+	public function getLDAPAccess($uid) {
+		return $this->access;
+	}
+	
+	/**
+	 * Return LDAP connection resource from a cloned connection.
+	 * The cloned connection needs to be closed manually.
+	 * of the current access.
+	 * @param string $uid
+	 * @return resource of the LDAP connection
+	 */
+	public function getNewLDAPConnection($uid) {
+		$connection = clone $this->access->getConnection();
+		return $connection->getConnectionResource();
+	}
 }
diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php
index c86d4f29ec417061d5de62f07b288c8801d8f107..8537d22a43bf83087468fc2f679a7541fef21eeb 100644
--- a/apps/user_ldap/lib/User_Proxy.php
+++ b/apps/user_ldap/lib/User_Proxy.php
@@ -9,6 +9,7 @@
  * @author Morris Jobke <hey@morrisjobke.de>
  * @author Robin McCorkell <robin@mccorkell.me.uk>
  * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -31,7 +32,7 @@ namespace OCA\User_LDAP;
 use OCA\User_LDAP\User\User;
 use OCP\IConfig;
 
-class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface {
+class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
 	private $backends = array();
 	private $refBackend = null;
 
@@ -193,6 +194,17 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface
 		$id = 'LOGINNAME,' . $loginName;
 		return $this->handleRequest($id, 'loginName2UserName', array($loginName));
 	}
+	
+	/**
+	 * returns the username for the given LDAP DN, if available
+	 *
+	 * @param string $dn
+	 * @return string|false with the name to use in ownCloud
+	 */
+	public function dn2UserName($dn) {
+		$id = 'DN,' . $dn;
+		return $this->handleRequest($id, 'dn2UserName', array($dn));
+	}
 
 	/**
 	 * get the user's home directory
@@ -273,4 +285,22 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface
 		return $users;
 	}
 
+	/**
+	 * Return access for LDAP interaction.
+	 * @param string $uid
+	 * @return Access instance of Access for LDAP interaction
+	 */
+	public function getLDAPAccess($uid) {
+		return $this->handleRequest($uid, 'getLDAPAccess', array($uid));
+	}
+	
+	/**
+	 * Return a new LDAP connection for the specified user.
+	 * The connection needs to be closed manually.
+	 * @param string $uid
+	 * @return resource of the LDAP connection
+	 */
+	public function getNewLDAPConnection($uid) {
+		return $this->handleRequest($uid, 'getNewLDAPConnection', array($uid));
+	}
 }
diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php
index f96813ba711b7fc72c4e7322fa5e373a0022fdf1..2fddafa214b13bec3b47bcd1ffeb75abd4652cc0 100644
--- a/apps/user_ldap/tests/AccessTest.php
+++ b/apps/user_ldap/tests/AccessTest.php
@@ -60,21 +60,22 @@ class AccessTest extends \Test\TestCase {
 				$this->getMock('\OCP\Image'),
 				$this->getMock('\OCP\IDBConnection'),
 				$this->getMock('\OCP\IUserManager')));
+		$helper = new \OCA\User_LDAP\Helper();
 
-		return array($lw, $connector, $um);
+		return array($lw, $connector, $um, $helper);
 	}
 
 	public function testEscapeFilterPartValidChars() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$input = 'okay';
 		$this->assertTrue($input === $access->escapeFilterPart($input));
 	}
 
 	public function testEscapeFilterPartEscapeWildcard() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$input = '*';
 		$expected = '\\\\*';
@@ -82,8 +83,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testEscapeFilterPartEscapeWildcard2() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$input = 'foo*bar';
 		$expected = 'foo\\\\*bar';
@@ -92,8 +93,8 @@ class AccessTest extends \Test\TestCase {
 
 	/** @dataProvider convertSID2StrSuccessData */
 	public function testConvertSID2StrSuccess(array $sidArray, $sidExpected) {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$sidBinary = implode('', $sidArray);
 		$this->assertSame($sidExpected, $access->convertSID2Str($sidBinary));
@@ -127,8 +128,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testConvertSID2StrInputError() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$sidIllegal = 'foobar';
 		$sidExpected = '';
@@ -137,8 +138,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testGetDomainDNFromDNSuccess() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$inputDN = 'uid=zaphod,cn=foobar,dc=my,dc=server,dc=com';
 		$domainDN = 'dc=my,dc=server,dc=com';
@@ -152,8 +153,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testGetDomainDNFromDNError() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$inputDN = 'foobar';
 		$expected = '';
@@ -187,8 +188,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testStringResemblesDN() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$cases = $this->getResemblesDNInputData();
 
@@ -208,9 +209,9 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testStringResemblesDNLDAPmod() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
 		$lw = new \OCA\User_LDAP\LDAP();
-		$access = new Access($con, $lw, $um);
+		$access = new Access($con, $lw, $um, $helper);
 
 		if(!function_exists('ldap_explode_dn')) {
 			$this->markTestSkipped('LDAP Module not available');
@@ -224,8 +225,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testCacheUserHome() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 
 		$con->expects($this->once())
 			->method('writeToCache');
@@ -234,8 +235,8 @@ class AccessTest extends \Test\TestCase {
 	}
 
 	public function testBatchApplyUserAttributes() {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
-		$access = new Access($con, $lw, $um);
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+		$access = new Access($con, $lw, $um, $helper);
 		$mapperMock = $this->getMockBuilder('\OCA\User_LDAP\Mapping\UserMapping')
 			->disableOriginalConstructor()
 			->getMock();
@@ -294,7 +295,7 @@ class AccessTest extends \Test\TestCase {
 	 * @dataProvider dNAttributeProvider
 	 */
 	public function testSanitizeDN($attribute) {
-		list($lw, $con, $um) = $this->getConnectorAndLdapMock();
+		list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
 
 
 		$dnFromServer = 'cn=Mixed Cases,ou=Are Sufficient To,ou=Test,dc=example,dc=org';
@@ -309,7 +310,7 @@ class AccessTest extends \Test\TestCase {
 				$attribute => array('count' => 1, $dnFromServer)
 			)));
 
-		$access = new Access($con, $lw, $um);
+		$access = new Access($con, $lw, $um, $helper);
 		$values = $access->readAttribute('uid=whoever,dc=example,dc=org', $attribute);
 		$this->assertSame($values[0], strtolower($dnFromServer));
 	}
diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php
index 71120bdb838d7fc6e8f57af40376b564cb4f9f23..83ec2dedf22bc4789cd6991426bad3fbcfa8172b 100644
--- a/apps/user_ldap/tests/Group_LDAPTest.php
+++ b/apps/user_ldap/tests/Group_LDAPTest.php
@@ -55,9 +55,10 @@ class Group_LDAPTest extends \Test\TestCase {
 		$um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager')
 			->disableOriginalConstructor()
 			->getMock();
+		$helper = new \OCA\User_LDAP\Helper();
 		$access = $this->getMock('\OCA\User_LDAP\Access',
 								 $accMethods,
-								 array($connector, $lw, $um));
+								 array($connector, $lw, $um, $helper));
 
 		$access->expects($this->any())
 			->method('getConnection')
diff --git a/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php b/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
index 4ec36617c14ae7dda8dcad51857cd9f4688f9545..bd56494eac028ac7543f22ab7892ec8904b4296d 100644
--- a/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
+++ b/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
@@ -26,6 +26,7 @@ namespace OCA\User_LDAP\Tests\Integration;
 use OCA\User_LDAP\Access;
 use OCA\User_LDAP\Connection;
 use OCA\User_LDAP\LDAP;
+use OCA\User_LDAP\Helper;
 use OCA\User_LDAP\User\Manager;
 
 abstract class AbstractIntegrationTest {
@@ -40,6 +41,9 @@ abstract class AbstractIntegrationTest {
 
 	/** @var Manager */
 	protected $userManager;
+	
+	/** @var Helper */
+	protected $helper;
 
 	/** @var  string */
 	protected $base;
@@ -65,6 +69,7 @@ abstract class AbstractIntegrationTest {
 		$this->initLDAPWrapper();
 		$this->initConnection();
 		$this->initUserManager();
+		$this->initHelper();
 		$this->initAccess();
 
 	}
@@ -103,12 +108,19 @@ abstract class AbstractIntegrationTest {
 	protected function initUserManager() {
 		$this->userManager = new FakeManager();
 	}
+	
+	/**
+	 * initializes the test Helper
+	 */
+	protected function initHelper() {
+		$this->helper = new Helper();
+	}
 
 	/**
 	 * initializes the Access test instance
 	 */
 	protected function initAccess() {
-		$this->access = new Access($this->connection, $this->ldap, $this->userManager);
+		$this->access = new Access($this->connection, $this->ldap, $this->userManager, $this->helper);
 	}
 
 	/**
diff --git a/apps/user_ldap/tests/Jobs/CleanUpTest.php b/apps/user_ldap/tests/Jobs/CleanUpTest.php
index 45e7998da0186675b422e6700714c58c812b1eb3..4785a227d26ee19bab58f84d924739fd0ba9f4e9 100644
--- a/apps/user_ldap/tests/Jobs/CleanUpTest.php
+++ b/apps/user_ldap/tests/Jobs/CleanUpTest.php
@@ -37,7 +37,7 @@ class CleanUpTest extends \Test\TestCase {
 				->getMock();
 		$mocks['ocConfig']    = $this->getMock('\OCP\IConfig');
 		$mocks['db']          = $this->getMock('\OCP\IDBConnection');
-		$mocks['helper']      = $this->getMock('\OCA\User_LDAP\Helper');
+		$mocks['helper']      = new \OCA\User_LDAP\Helper();
 
 		return $mocks;
 	}
diff --git a/apps/user_ldap/tests/LDAPProviderTest.php b/apps/user_ldap/tests/LDAPProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..071cc09fa63a663867f16efce9e2f70b4f179468
--- /dev/null
+++ b/apps/user_ldap/tests/LDAPProviderTest.php
@@ -0,0 +1,337 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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\User_LDAP\Tests;
+
+use OCP\IServerContainer;
+use OCA\User_LDAP\IUserLDAP;
+
+/**
+ * Class LDAPProviderTest
+ *
+ * @group DB
+ *
+ * @package OCA\User_LDAP\Tests
+ */
+class LDAPProviderTest extends \Test\TestCase {
+
+	protected function setUp() {
+		parent::setUp();
+	}
+	
+	private function getServerMock(IUserLDAP $backend) {
+		$server = $this->getMockBuilder('OC\Server')
+			 ->setMethods(['getUserManager', 'getBackends'])
+			 ->setConstructorArgs(['', new \OC\Config(\OC::$configDir)])
+			 ->getMock();
+		$server->expects($this->at(1))
+            ->method('getBackends')
+            ->willReturn([$backend]);
+		$server->expects($this->any())
+            ->method($this->anything())
+            ->willReturnSelf();
+			
+		return $server;
+	}
+	
+	private function getLDAPProvider(IServerContainer $serverContainer) {
+		$factory = new \OCA\User_LDAP\LDAPProviderFactory($serverContainer);
+		return $factory->getLDAPProvider();
+	}
+	
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage User id not found in LDAP
+	 */
+	public function testGetUserDNUserIDNotFound() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())->method('userExists')->willReturn(false);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->getUserDN('nonexisting_user');
+	}
+	
+	public function testGetUserDN() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists', 'getLDAPAccess', 'username2dn'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->at(0))
+            ->method('userExists')
+            ->willReturn(true);
+		$backend->expects($this->at(2))
+            ->method('username2dn')
+            ->willReturn('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org');
+		$backend->expects($this->any())
+            ->method($this->anything())
+            ->willReturnSelf();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org', 
+			$ldapProvider->getUserDN('existing_user'));
+	}
+
+	public function testGetUserName() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['dn2UserName'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())
+            ->method('dn2UserName')
+            ->willReturn('existing_user');
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals('existing_user', 
+			$ldapProvider->getUserName('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+	}
+	
+	public function testDNasBaseParameter() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods([])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		
+		$server = $this->getServerMock($backend);
+		
+		$helper = new \OCA\User_LDAP\Helper();
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals(
+			$helper->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'), 
+			$ldapProvider->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+	}
+
+	public function testSanitizeDN() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods([])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		
+		$server = $this->getServerMock($backend);
+		
+		$helper = new \OCA\User_LDAP\Helper();
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals(
+			$helper->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'), 
+			$ldapProvider->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+	}
+	
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage User id not found in LDAP
+	 */
+	public function testGetLDAPConnectionUserIDNotFound() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())->method('userExists')->willReturn(false);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->getLDAPConnection('nonexisting_user');
+	}
+	
+	public function testGetLDAPConnection() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists', 'getNewLDAPConnection'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())
+            ->method('userExists')
+            ->willReturn(true);
+		$backend->expects($this->any())
+            ->method('getNewLDAPConnection')
+            ->willReturn(true);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertTrue($ldapProvider->getLDAPConnection('existing_user'));
+	}
+	
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage User id not found in LDAP
+	 */
+	public function testGetLDAPBaseUsersUserIDNotFound() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())->method('userExists')->willReturn(false);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->getLDAPBaseUsers('nonexisting_user');
+	}
+	
+	public function testGetLDAPBaseUsers() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->at(0))
+            ->method('userExists')
+            ->willReturn(true);
+		$backend->expects($this->at(3))
+            ->method('getConfiguration')
+            ->willReturn(array('ldap_base_users'=>'ou=users,dc=example,dc=org'));
+		$backend->expects($this->any())
+            ->method($this->anything())
+            ->willReturnSelf();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals('ou=users,dc=example,dc=org', $ldapProvider->getLDAPBaseUsers('existing_user'));
+	}
+	
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage User id not found in LDAP
+	 */
+	public function testGetLDAPBaseGroupsUserIDNotFound() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())->method('userExists')->willReturn(false);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->getLDAPBaseGroups('nonexisting_user');
+	}
+	
+	public function testGetLDAPBaseGroups() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->at(0))
+            ->method('userExists')
+            ->willReturn(true);
+		$backend->expects($this->at(3))
+            ->method('getConfiguration')
+            ->willReturn(array('ldap_base_groups'=>'ou=groups,dc=example,dc=org'));
+		$backend->expects($this->any())
+            ->method($this->anything())
+            ->willReturnSelf();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertEquals('ou=groups,dc=example,dc=org', $ldapProvider->getLDAPBaseGroups('existing_user'));
+	}
+	
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage User id not found in LDAP
+	 */
+	public function testClearCacheUserIDNotFound() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())->method('userExists')->willReturn(false);
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->clearCache('nonexisting_user');
+	}
+	
+	public function testClearCache() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'clearCache'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->at(0))
+            ->method('userExists')
+            ->willReturn(true);
+		$backend->expects($this->at(3))
+            ->method('clearCache')
+            ->willReturn(true);
+		$backend->expects($this->any())
+            ->method($this->anything())
+            ->willReturnSelf();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->clearCache('existing_user');
+		$this->assertTrue(TRUE);
+	}
+	
+	public function testDnExists() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods(['dn2UserName'])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		$backend->expects($this->any())
+            ->method('dn2UserName')
+            ->willReturn('existing_user');
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$this->assertTrue($ldapProvider->dnExists('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+	}
+	
+	public function testFlagRecord() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods([])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->flagRecord('existing_user');
+		$this->assertTrue(TRUE);
+	}
+	
+	public function testUnflagRecord() {
+		$backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+			 ->setMethods([])
+			 ->disableOriginalConstructor()
+			 ->getMock();
+		
+		$server = $this->getServerMock($backend);
+			
+		$ldapProvider = $this->getLDAPProvider($server);
+		$ldapProvider->unflagRecord('existing_user');
+		$this->assertTrue(TRUE);
+	}
+}
diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php
index cf1514009d877870f210f9f4b96c56b385a550ce..d9e43dee0477f6d47f847c23b5f687c6d9239242 100644
--- a/apps/user_ldap/tests/User/UserTest.php
+++ b/apps/user_ldap/tests/User/UserTest.php
@@ -71,8 +71,9 @@ class UserTest extends \Test\TestCase {
 			$umMethods, array($cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr));
 		$connector = $this->getMock('\OCA\User_LDAP\Connection',
 			$conMethods, array($lw, null, null));
+		$helper = new \OCA\User_LDAP\Helper();
 		$access = $this->getMock('\OCA\User_LDAP\Access',
-			$accMethods, array($connector, $lw, $um));
+			$accMethods, array($connector, $lw, $um, $helper));
 
 		return array($access, $connector);
 	}
diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php
index ae86e3cf3a21dc8c1e99ba8b3ef7a7cddafb6970..47e789142e51bf5b145a16f5d1511f711660d0b9 100644
--- a/apps/user_ldap/tests/User_LDAPTest.php
+++ b/apps/user_ldap/tests/User_LDAPTest.php
@@ -93,9 +93,11 @@ class User_LDAPTest extends \Test\TestCase {
 			->method('getDeletedUser')
 			->will($this->returnValue($offlineUser));
 
+		$helper = new \OCA\User_LDAP\Helper();
+		
 		$access = $this->getMock('\OCA\User_LDAP\Access',
 								 $accMethods,
-								 array($connector, $lw, $um));
+								 array($connector, $lw, $um, $helper));
 
 		$um->setLdapAccess($access);
 
diff --git a/apps/user_ldap/tests/WizardTest.php b/apps/user_ldap/tests/WizardTest.php
index cc110c6ee0def42617aa35aaa09ed9e4008a2ad4..e82cbcfc82a521acb3775c3638d05bf41db7f0ca 100644
--- a/apps/user_ldap/tests/WizardTest.php
+++ b/apps/user_ldap/tests/WizardTest.php
@@ -69,8 +69,9 @@ class WizardTest extends \Test\TestCase {
 		$um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager')
 					->disableOriginalConstructor()
 					->getMock();
+		$helper = new \OCA\User_LDAP\Helper();
 		$access = $this->getMock('\OCA\User_LDAP\Access',
-			$accMethods, array($connector, $lw, $um));
+			$accMethods, array($connector, $lw, $um, $helper));
 
 		return array(new Wizard($conf, $lw, $access), $conf, $lw, $access);
 	}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index de2970d9bfadf1a72a1eade69edefe5a258ed694..d7352613f274ac6c5350ccf161de8083aa68f5ab 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -21,6 +21,7 @@
  * @author Thomas Müller <thomas.mueller@tmit.eu>
  * @author Thomas Tanghus <thomas@tanghus.net>
  * @author Vincent Petry <pvince81@owncloud.com>
+ * @author Roger Szabo <roger.szabo@web.de>
  *
  * @license AGPL-3.0
  *
@@ -583,6 +584,16 @@ class Server extends ServerContainer implements IServerContainer {
 				$this->getLogger()
 			);
 		});
+		$this->registerService('LDAPProvider', function(Server $c) {
+			$config = $c->getConfig();
+			$factoryClass = $config->getSystemValue('ldapProviderFactory', null);
+			if(is_null($factoryClass)) {
+				throw new \Exception('ldapProviderFactory not set');
+			}
+			/** @var \OCP\LDAP\ILDAPProviderFactory $factory */
+			$factory = new $factoryClass($this);
+			return $factory->getLDAPProvider();
+		});
 		$this->registerService('LockingProvider', function (Server $c) {
 			$ini = $c->getIniWrapper();
 			$config = $c->getConfig();
@@ -1398,4 +1409,12 @@ class Server extends ServerContainer implements IServerContainer {
 		return $this->query('ShareManager');
 	}
 
+	/**
+	 * Returns the LDAP Provider
+	 *
+	 * @return \OCP\LDAP\ILDAPProvider
+	 */
+	public function getLDAPProvider() {
+		return $this->query('LDAPProvider');
+	}
 }
diff --git a/lib/public/LDAP/IDeletionFlagSupport.php b/lib/public/LDAP/IDeletionFlagSupport.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca272d7aa795c0f2f354eff975781a8efa4490c0
--- /dev/null
+++ b/lib/public/LDAP/IDeletionFlagSupport.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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 OCP\LDAP;
+
+/**
+ * Interface IDeletionFlagSupport
+ *
+ * @package OCP\LDAP
+ * @since 9.2.0
+ */
+interface IDeletionFlagSupport {
+	/**
+	 * Flag record for deletion.
+	 * @param string $uid ownCloud user id
+	 * @since 9.2.0
+	 */
+	public function flagRecord($uid);
+	
+	/**
+	 * Unflag record for deletion.
+	 * @param string $uid ownCloud user id
+	 * @since 9.2.0
+	 */
+	public function unflagRecord($uid);
+}
diff --git a/lib/public/LDAP/ILDAPProvider.php b/lib/public/LDAP/ILDAPProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..44f7d88c94637446bbe6882979f3ab667fe9290b
--- /dev/null
+++ b/lib/public/LDAP/ILDAPProvider.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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 OCP\LDAP;
+
+/**
+ * Interface ILDAPProvider
+ *
+ * @package OCP\LDAP
+ * @since 9.2.0
+ */
+interface ILDAPProvider {
+	/**
+	 * Translate an ownCloud username to LDAP DN.
+	 * @param string $uid ownCloud user id
+	 * @return string
+	 * @since 9.2.0
+	 */
+	public function getUserDN($uid);
+	
+	/**
+	 * Translate a LDAP DN to an ownCloud user name.
+	 * @param string $dn LDAP DN
+	 * @return string with the ownCloud user name
+	 * @throws \Exception if translation was unsuccessful
+	 * @since 9.2.0
+	 */
+	public function getUserName($dn);
+	
+	/**
+	 * Convert a stored DN so it can be used as base parameter for LDAP queries.
+	 * @param string $dn the DN
+	 * @return string
+	 * @since 9.2.0
+	 */
+	public function DNasBaseParameter($dn);
+	
+	/**
+	 * Sanitize a DN received from the LDAP server.
+	 * @param array $dn the DN in question
+	 * @return array the sanitized DN
+	 * @since 9.2.0
+	 */
+	public function sanitizeDN($dn);
+	
+	/**
+	 * Return a new LDAP connection resource for the specified user. 
+	 * @param string $uid ownCloud user id
+	 * @return resource of the LDAP connection
+	 * @since 9.2.0
+	 */
+	public function getLDAPConnection($uid);
+	
+	/**
+	 * Get the LDAP base for users.
+	 * @param string $uid ownCloud user id
+	 * @return string the base for users
+	 * @throws \Exception if user id was not found in LDAP
+	 * @since 9.2.0
+	 */
+	public function getLDAPBaseUsers($uid);
+	
+	/**
+	 * Get the LDAP base for groups.
+	 * @param string $uid ownCloud user id
+	 * @return string the base for groups
+	 * @throws \Exception if user id was not found in LDAP
+	 * @since 9.2.0
+	 */
+	public function getLDAPBaseGroups($uid);
+	
+	/**
+	 * Check whether a LDAP DN exists
+	 * @param string $dn LDAP DN
+	 * @return bool whether the DN exists
+	 * @since 9.2.0
+	 */
+	public function dnExists($dn);
+	
+	/**
+	 * Clear the cache if a cache is used, otherwise do nothing.
+	 * @param string $uid ownCloud user id
+	 * @since 9.2.0
+	 */
+	public function clearCache($uid);
+}
diff --git a/lib/public/LDAP/ILDAPProviderFactory.php b/lib/public/LDAP/ILDAPProviderFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e1242e33db14933a474528f5437f6f2c679772f
--- /dev/null
+++ b/lib/public/LDAP/ILDAPProviderFactory.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @author Roger Szabo <roger.szabo@web.de>
+ *
+ * @copyright Copyright (c) 2016, 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 OCP\LDAP;
+
+use OCP\IServerContainer;
+
+/**
+ * Interface ILDAPProviderFactory
+ *
+ * This class is responsible for instantiating and returning an ILDAPProvider
+ * instance.
+ *
+ * @package OCP\LDAP
+ * @since 9.2.0
+ */
+interface ILDAPProviderFactory {
+
+	/**
+	 * Constructor for the LDAP provider factory
+	 *
+	 * @param IServerContainer $serverContainer server container
+	 * @since 9.2.0
+	 */
+	public function __construct(IServerContainer $serverContainer);
+	
+	/**
+	 * creates and returns an instance of the ILDAPProvider
+	 *
+	 * @return ILDAPProvider
+	 * @since 9.2.0
+	 */
+	public function getLDAPProvider();
+}