diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 330574c1d42fcbb5b6acae2ada9e00c8bb802284..3c6da47d71a157b1677ba0049009d610dfac7c59 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -21,15 +21,17 @@
 *
 */
 
-require_once('apps/user_ldap/lib_ldap.php');
-require_once('apps/user_ldap/user_ldap.php');
-require_once('apps/user_ldap/group_ldap.php');
+OCP\App::registerAdmin('user_ldap', 'settings');
 
-OCP\App::registerAdmin('user_ldap','settings');
+$connector = new OCA\user_ldap\lib\Connection('user_ldap');
+$userBackend  = new OCA\user_ldap\USER_LDAP();
+$userBackend->setConnector($connector);
+$groupBackend = new OCA\user_ldap\GROUP_LDAP();
+$groupBackend->setConnector($connector);
 
 // register user backend
-OC_User::useBackend( 'LDAP' );
-OC_Group::useBackend( new OC_GROUP_LDAP() );
+OC_User::useBackend($userBackend);
+OC_Group::useBackend($groupBackend);
 
 // add settings page to navigation
 $entry = array(
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index d438c7d84dfa6b29e98ef87b54f93d7fb368a334..b9f4bdf199039592da85c8189fdf29de1a4dae45 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -21,24 +21,22 @@
  *
  */
 
-class OC_GROUP_LDAP extends OC_Group_Backend {
-// 	//group specific settings
-	protected $ldapGroupFilter;
-	protected $ldapGroupMemberAssocAttr;
-	protected $configured = false;
+namespace OCA\user_ldap;
+
+class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
+	protected $enabled = false;
 
 	protected $_group_user = array();
 	protected $_user_groups = array();
 	protected $_group_users = array();
 	protected $_groups = array();
 
-	public function __construct() {
-		$this->ldapGroupFilter          = OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)');
-		$this->ldapGroupMemberAssocAttr = OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember');
-
-		if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) {
-			$this->configured = true;
+	public function setConnector(lib\Connection &$connection) {
+		parent::setConnector($connection);
+		if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) {
+			$this->enabled = false;
 		}
+		$this->enabled = true;
 	}
 
 	/**
@@ -50,31 +48,31 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * Checks whether the user is member of a group or not.
 	 */
 	public function inGroup($uid, $gid) {
-		if(!$this->configured) {
+		if(!$this->enabled) {
 			return false;
 		}
 		if(isset($this->_group_user[$gid][$uid])) {
 			return $this->_group_user[$gid][$uid];
 		}
-		$dn_user = OC_LDAP::username2dn($uid);
-		$dn_group = OC_LDAP::groupname2dn($gid);
+		$dn_user = $this->username2dn($uid);
+		$dn_group = $this->groupname2dn($gid);
 		// just in case
 		if(!$dn_group || !$dn_user) {
 			return false;
 		}
 		//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
-		$members = OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr);
+		$members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr);
 		if(!$members) {
 			return false;
 		}
 
 		//extra work if we don't get back user DNs
 		//TODO: this can be done with one LDAP query
-		if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
+		if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
 			$dns = array();
 			foreach($members as $mid) {
-				$filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter'));
-				$ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+				$filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter);
+				$ldap_users = $this->fetchListOfUsers($filter, 'dn');
 				if(count($ldap_users) < 1) {
 					continue;
 				}
@@ -96,36 +94,37 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * if the user exists at all.
 	 */
 	public function getUserGroups($uid) {
-		if(!$this->configured) {
+		if(!$this->enabled) {
 			return array();
 		}
 		if(isset($this->_user_groups[$uid])) {
 			return $this->_user_groups[$uid];
 		}
-		$userDN = OC_LDAP::username2dn($uid);
+		$userDN = $this->username2dn($uid);
 		if(!$userDN) {
 			$this->_user_groups[$uid] = array();
 			return array();
 		}
 
 		//uniqueMember takes DN, memberuid the uid, so we need to distinguish
-		if((strtolower($this->ldapGroupMemberAssocAttr) == 'uniquemember')
-			|| (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) {
+		if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember')
+			|| (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')
+		) {
 			$uid = $userDN;
-		} else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
-			$result = OC_LDAP::readAttribute($userDN, 'uid');
+		} else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
+			$result = $this->readAttribute($userDN, 'uid');
 			$uid = $result[0];
 		} else {
 			// just in case
 			$uid = $userDN;
 		}
 
-		$filter = OC_LDAP::combineFilterWithAnd(array(
-			$this->ldapGroupFilter,
-			$this->ldapGroupMemberAssocAttr.'='.$uid
+		$filter = $this->combineFilterWithAnd(array(
+			$this->connection->ldapGroupFilter,
+			$this->connection->ldapGroupMemberAssocAttr.'='.$uid
 		));
-		$groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
-		$this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING);
+		$groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn'));
+		$this->_user_groups[$uid] = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
 
 		return $this->_user_groups[$uid];
 	}
@@ -135,44 +134,44 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * @returns array with user ids
 	 */
 	public function usersInGroup($gid) {
-		if(!$this->configured) {
+		if(!$this->enabled) {
 			return array();
 		}
 		if(isset($this->_group_users[$gid])) {
 			return $this->_group_users[$gid];
 		}
 
-		$groupDN = OC_LDAP::groupname2dn($gid);
+		$groupDN = $this->groupname2dn($gid);
 		if(!$groupDN) {
 			$this->_group_users[$gid] = array();
 			return array();
 		}
 
-		$members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr);
+		$members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr);
 		if(!$members) {
 			$this->_group_users[$gid] = array();
 			return array();
 		}
 
 		$result = array();
-		$isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid');
+		$isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid');
 		foreach($members as $member) {
 			if($isMemberUid) {
-				$filter = OCP\Util::mb_str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
-				$ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+				$filter = \OCP\Util::mb_str_replace('%uid', $member, $this->connection->ldapLoginFilter, 'UTF-8');
+				$ldap_users = $this->fetchListOfUsers($filter, 'dn');
 				if(count($ldap_users) < 1) {
 					continue;
 				}
-				$result[] = OC_LDAP::dn2username($ldap_users[0]);
+				$result[] = $this->dn2username($ldap_users[0]);
 				continue;
 			} else {
-				if($ocname = OC_LDAP::dn2username($member)){
+				if($ocname = $this->dn2username($member)) {
 					$result[] = $ocname;
 				}
 			}
 		}
 		if(!$isMemberUid) {
-			$result = array_intersect($result, OCP\User::getUsers());
+			$result = array_intersect($result, \OCP\User::getUsers());
 		}
 		$this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING);
 		return $this->_group_users[$gid];
@@ -185,12 +184,12 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	 * Returns a list with all groups
 	 */
 	public function getGroups() {
-		if(!$this->configured) {
+		if(!$this->enabled) {
 			return array();
 		}
 		if(empty($this->_groups)) {
-			$ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
-			$this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+			$ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn'));
+			$this->_groups = $this->ownCloudGroupNames($ldap_groups);
 		}
 		return $this->_groups;
 	}
@@ -203,4 +202,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	public function groupExists($gid){
 		return in_array($gid, $this->getGroups());
 	}
+
+	/**
+	* @brief Check if backend implements actions
+	* @param $actions bitwise-or'ed actions
+	* @returns boolean
+	*
+	* Returns the supported actions as int to be
+	* compared with OC_USER_BACKEND_CREATE_USER etc.
+	*/
+	public function implementsActions($actions) {
+		//always returns false, because possible actions are modifying actions. We do not write to LDAP, at least for now.
+		return false;
+	}
 }
\ No newline at end of file
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
new file mode 100644
index 0000000000000000000000000000000000000000..870f6330edd01d48de753cd5ecb62f8bec82d886
--- /dev/null
+++ b/apps/user_ldap/lib/access.php
@@ -0,0 +1,593 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+abstract class Access {
+	protected $connection;
+
+	public function setConnector(Connection &$connection) {
+		$this->connection = $connection;
+	}
+
+	private function checkConnection() {
+		return ($this->connection instanceof Connection);
+	}
+
+	/**
+	 * @brief reads a given attribute for an LDAP record identified by a DN
+	 * @param $dn the record in question
+	 * @param $attr the attribute that shall be retrieved
+	 * @returns the values in an array on success, false otherwise
+	 *
+	 * Reads an attribute from an LDAP entry
+	 */
+	public function readAttribute($dn, $attr) {
+		if(!$this->checkConnection()) {
+			\OCP\Util::writeLog('user_ldap', 'No LDAP Connector assigned, access impossible for readAttribute.', \OCP\Util::WARN);
+			return false;
+		}
+		$cr = $this->connection->getConnectionResource();
+		$rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr));
+		if(!is_resource($rr)) {
+			\OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
+			//in case an error occurs , e.g. object does not exist
+			return false;
+		}
+		$er = ldap_first_entry($cr, $rr);
+		//LDAP attributes are not case sensitive
+		$result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
+		$attr = mb_strtolower($attr, 'UTF-8');
+
+		if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
+			$values = array();
+			for($i=0;$i<$result[$attr]['count'];$i++) {
+				$values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
+			}
+			return $values;
+		}
+		return false;
+	}
+
+	/**
+	 * @brief checks wether the given attribute`s valua is probably a DN
+	 * @param $attr the attribute in question
+	 * @return if so true, otherwise false
+	 */
+	private function resemblesDN($attr) {
+		$resemblingAttributes = array(
+			'dn',
+			'uniquemember',
+			'member'
+		);
+		return in_array($attr, $resemblingAttributes);
+	}
+
+	/**
+	 * @brief sanitizes a DN received from the LDAP server
+	 * @param $dn the DN in question
+	 * @return the sanitized DN
+	 */
+	private function sanitizeDN($dn) {
+		//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');
+
+		return $dn;
+	}
+
+	/**
+	 * gives back the database table for the query
+	 */
+	private function getMapTable($isUser) {
+		if($isUser) {
+			return '*PREFIX*ldap_user_mapping';
+		} else {
+			return '*PREFIX*ldap_group_mapping';
+		}
+	}
+
+	/**
+	 * @brief returns the LDAP DN for the given internal ownCloud name of the group
+	 * @param $name the ownCloud name in question
+	 * @returns string with the LDAP DN on success, otherwise false
+	 *
+	 * returns the LDAP DN for the given internal ownCloud name of the group
+	 */
+	public function groupname2dn($name) {
+		return $this->ocname2dn($name, false);
+	}
+
+	/**
+	 * @brief returns the LDAP DN for the given internal ownCloud name of the user
+	 * @param $name the ownCloud name in question
+	 * @returns string with the LDAP DN on success, otherwise false
+	 *
+	 * returns the LDAP DN for the given internal ownCloud name of the user
+	 */
+	public function username2dn($name) {
+		$dn = $this->ocname2dn($name, true);
+		if($dn) {
+			return $dn;
+		} else {
+			//fallback: user is not mapped
+			$filter = $this->combineFilterWithAnd(array(
+				$this->connection->ldapUserFilter,
+				$this->connection->ldapUserDisplayName . '=' . $name,
+			));
+			$result = $this->searchUsers($filter, 'dn');
+			if(isset($result[0]['dn'])) {
+				$this->mapComponent($result[0], $name, true);
+				return $result[0];
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * @brief returns the LDAP DN for the given internal ownCloud name
+	 * @param $name the ownCloud name in question
+	 * @param $isUser is it a user? otherwise group
+	 * @returns string with the LDAP DN on success, otherwise false
+	 *
+	 * returns the LDAP DN for the given internal ownCloud name
+	 */
+	private function ocname2dn($name, $isUser) {
+		$table = $this->getMapTable($isUser);
+
+		$query = \OCP\DB::prepare('
+			SELECT ldap_dn
+			FROM '.$table.'
+			WHERE owncloud_name = ?
+		');
+
+		$record = $query->execute(array($name))->fetchOne();
+		return $record;
+	}
+
+	/**
+	 * @brief returns the internal ownCloud name for the given LDAP DN of the group
+	 * @param $dn the dn of the group object
+	 * @param $ldapname optional, the display name of the object
+	 * @returns string with with the name to use in ownCloud, false on DN outside of search DN
+	 *
+	 * returns the internal ownCloud name for the given LDAP DN of the group
+	 */
+	public function dn2groupname($dn, $ldapname = null) {
+		if(mb_strripos($dn, $this->connection->ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseGroups, 'UTF-8'))) {
+			return false;
+		}
+		return $this->dn2ocname($dn, $ldapname, false);
+	}
+
+	/**
+	 * @brief returns the internal ownCloud name for the given LDAP DN of the user
+	 * @param $dn the dn of the user object
+	 * @param $ldapname optional, the display name of the object
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
+	 */
+	public function dn2username($dn, $ldapname = null) {
+		if(mb_strripos($dn, $this->connection->ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseUsers, 'UTF-8'))) {
+			return false;
+		}
+		return $this->dn2ocname($dn, $ldapname, true);
+	}
+
+	/**
+	 * @brief returns an internal ownCloud name for the given LDAP DN
+	 * @param $dn the dn of the user object
+	 * @param $ldapname optional, the display name of the object
+	 * @param $isUser optional, wether it is a user object (otherwise group assumed)
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
+	 */
+	public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+		$dn = $this->sanitizeDN($dn);
+		$table = $this->getMapTable($isUser);
+		if($isUser) {
+			$nameAttribute = $this->connection->ldapUserDisplayName;
+		} else {
+			$nameAttribute = $this->connection->ldapGroupDisplayName;
+		}
+
+		$query = \OCP\DB::prepare('
+			SELECT owncloud_name
+			FROM '.$table.'
+			WHERE ldap_dn = ?
+		');
+
+		$component = $query->execute(array($dn))->fetchOne();
+		if($component) {
+			return $component;
+		}
+
+		if(is_null($ldapname)) {
+			$ldapname = $this->readAttribute($dn, $nameAttribute);
+			$ldapname = $ldapname[0];
+		}
+		$ldapname = $this->sanitizeUsername($ldapname);
+
+		//a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
+		if($this->mapComponent($dn, $ldapname, $isUser)) {
+			return $ldapname;
+		}
+
+		//doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
+		$oc_name = $this->alternateOwnCloudName($ldapname, $dn);
+		if($this->mapComponent($dn, $oc_name, $isUser)) {
+			return $oc_name;
+		}
+
+		//TODO: do not simple die away!
+		//and this of course should never been thrown :)
+		throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+	}
+
+	/**
+	 * @brief gives back the user names as they are used ownClod internally
+	 * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
+	 * @returns an array with the user names to use in ownCloud
+	 *
+	 * gives back the user names as they are used ownClod internally
+	 */
+	public function ownCloudUserNames($ldapUsers) {
+		return $this->ldap2ownCloudNames($ldapUsers, true);
+	}
+
+	/**
+	 * @brief gives back the group names as they are used ownClod internally
+	 * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
+	 * @returns an array with the group names to use in ownCloud
+	 *
+	 * gives back the group names as they are used ownClod internally
+	 */
+	public function ownCloudGroupNames($ldapGroups) {
+		return $this->ldap2ownCloudNames($ldapGroups, false);
+	}
+
+	private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+		if($isUsers) {
+			$knownObjects = $this->mappedUsers();
+			$nameAttribute = $this->connection->ldapUserDisplayName;
+		} else {
+			$knownObjects = $this->mappedGroups();
+			$nameAttribute = $this->connection->ldapGroupDisplayName;
+		}
+		$ownCloudNames = array();
+
+		foreach($ldapObjects as $ldapObject) {
+			$key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+			//everything is fine when we know the group
+			if($key !== false) {
+				$ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
+				continue;
+			}
+
+			//a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters.
+			$ocname = $this->sanitizeUsername($ldapObject[$nameAttribute]);
+			if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+				$ownCloudNames[] = $ocname;
+				continue;
+			}
+
+			//doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
+			$ocname = $this->alternateOwnCloudName($ocname, $ldapObject['dn']);
+			if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+				$ownCloudNames[] = $ocname;
+				continue;
+			}
+
+			//TODO: do not simple die away
+			//and this of course should never been thrown :)
+			throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+		}
+		return $ownCloudNames;
+	}
+
+	/**
+	 * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+	 * @param $name the display name of the object
+	 * @param $dn the dn of the object
+	 * @returns string with with the name to use in ownCloud
+	 *
+	 * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+	 */
+	private function alternateOwnCloudName($name, $dn) {
+		$ufn = ldap_dn2ufn($dn);
+		$name = $name . '@' . trim(\OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
+		$name = $this->sanitizeUsername($name);
+		return $name;
+	}
+
+	/**
+	 * @brief retrieves all known groups from the mappings table
+	 * @returns array with the results
+	 *
+	 * retrieves all known groups from the mappings table
+	 */
+	private function mappedGroups() {
+		return $this->mappedComponents(false);
+	}
+
+	/**
+	 * @brief retrieves all known users from the mappings table
+	 * @returns array with the results
+	 *
+	 * retrieves all known users from the mappings table
+	 */
+	private function mappedUsers() {
+		return $this->mappedComponents(true);
+	}
+
+	private function mappedComponents($isUsers) {
+		$table = $this->getMapTable($isUsers);
+
+		$query = \OCP\DB::prepare('
+			SELECT ldap_dn, owncloud_name
+			FROM '. $table
+		);
+
+		return $query->execute()->fetchAll();
+	}
+
+	/**
+	 * @brief inserts a new user or group into the mappings table
+	 * @param $dn the record in question
+	 * @param $ocname the name to use in ownCloud
+	 * @param $isUser is it a user or a group?
+	 * @returns true on success, false otherwise
+	 *
+	 * inserts a new user or group into the mappings table
+	 */
+	private function mapComponent($dn, $ocname, $isUser = true) {
+		$table = $this->getMapTable($isUser);
+		$dn = $this->sanitizeDN($dn);
+
+		$sqlAdjustment = '';
+		$dbtype = \OCP\Config::getSystemValue('dbtype');
+		if($dbtype == 'mysql') {
+			$sqlAdjustment = 'FROM dual';
+		}
+
+		$insert = \OCP\DB::prepare('
+			INSERT INTO '.$table.' (ldap_dn, owncloud_name)
+				SELECT ?,?
+				'.$sqlAdjustment.'
+				WHERE NOT EXISTS (
+					SELECT 1
+					FROM '.$table.'
+					WHERE ldap_dn = ?
+						OR owncloud_name = ? )
+		');
+
+		$res = $insert->execute(array($dn, $ocname, $dn, $ocname));
+
+		if(\OCP\DB::isError($res)) {
+			return false;
+		}
+
+		$insRows = $res->numRows();
+
+		if($insRows == 0) {
+			return false;
+		}
+
+		return true;
+	}
+
+	public function fetchListOfUsers($filter, $attr) {
+		return $this->fetchList($this->searchUsers($filter, $attr), (count($attr) > 1));
+	}
+
+	public function fetchListOfGroups($filter, $attr) {
+		return $this->fetchList($this->searchGroups($filter, $attr), (count($attr) > 1));
+	}
+
+	private function fetchList($list, $manyAttributes) {
+		if(is_array($list)) {
+			if($manyAttributes) {
+				return $list;
+			} else {
+				return array_unique($list, SORT_LOCALE_STRING);
+			}
+		}
+
+		//error cause actually, maybe throw an exception in future.
+		return array();
+	}
+
+	/**
+	 * @brief executes an LDAP search, optimized for Users
+	 * @param $filter the LDAP filter for the search
+	 * @param $attr optional, when a certain attribute shall be filtered out
+	 * @returns array with the search result
+	 *
+	 * Executes an LDAP search
+	 */
+	public function searchUsers($filter, $attr = null) {
+		return $this->search($filter, $this->connection->ldapBaseUsers, $attr);
+	}
+
+	/**
+	 * @brief executes an LDAP search, optimized for Groups
+	 * @param $filter the LDAP filter for the search
+	 * @param $attr optional, when a certain attribute shall be filtered out
+	 * @returns array with the search result
+	 *
+	 * Executes an LDAP search
+	 */
+	public function searchGroups($filter, $attr = null) {
+		return $this->search($filter, $this->connection->ldapBaseGroups, $attr);
+	}
+
+	/**
+	 * @brief executes an LDAP search
+	 * @param $filter the LDAP filter for the search
+	 * @param $base the LDAP subtree that shall be searched
+	 * @param $attr optional, when a certain attribute shall be filtered out
+	 * @returns array with the search result
+	 *
+	 * Executes an LDAP search
+	 */
+	private function search($filter, $base, $attr = null) {
+		if(!is_null($attr) && !is_array($attr)) {
+			$attr = array(mb_strtolower($attr, 'UTF-8'));
+		}
+
+		// See if we have a resource
+		$link_resource = $this->connection->getConnectionResource();
+		if(is_resource($link_resource)) {
+			$sr = ldap_search($link_resource, $base, $filter, $attr);
+			$findings = ldap_get_entries($link_resource, $sr );
+
+			// if we're here, probably no connection resource is returned.
+			// to make ownCloud behave nicely, we simply give back an empty array.
+			if(is_null($findings)) {
+				return array();
+			}
+		} else {
+			// Seems like we didn't find any resource.
+			// Return an empty array just like before.
+			\OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG);
+			return array();
+		}
+
+		if(!is_null($attr)) {
+			$selection = array();
+			$multiarray = false;
+			if(count($attr) > 1) {
+				$multiarray = true;
+				$i = 0;
+			}
+			foreach($findings as $item) {
+				if(!is_array($item)) {
+					continue;
+				}
+				$item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
+
+				if($multiarray) {
+					foreach($attr as $key) {
+						$key = mb_strtolower($key, 'UTF-8');
+						if(isset($item[$key])) {
+							if($key != 'dn') {
+								$selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0];
+							} else {
+								$selection[$i][$key] = $this->sanitizeDN($item[$key]);
+							}
+						}
+
+					}
+					$i++;
+				} else {
+					//tribute to case insensitivity
+					$key = mb_strtolower($attr[0], 'UTF-8');
+
+					if(isset($item[$key])) {
+						if($this->resemblesDN($key)) {
+							$selection[] = $this->sanitizeDN($item[$key]);
+						} else {
+							$selection[] = $item[$key];
+						}
+					}
+				}
+			}
+			return $selection;
+		}
+		return $findings;
+	}
+
+	public function sanitizeUsername($name) {
+		if($this->connection->ldapIgnoreNamingRules) {
+			return $name;
+		}
+
+		//REPLACEMENTS
+		$name = \OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
+
+		//every remaining unallowed characters will be removed
+		$name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
+
+		return $name;
+	}
+
+	/**
+	 * @brief combines the input filters with AND
+	 * @param $filters array, the filters to connect
+	 * @returns the combined filter
+	 *
+	 * Combines Filter arguments with AND
+	 */
+	public function combineFilterWithAnd($filters) {
+		return $this->combineFilter($filters, '&');
+	}
+
+	/**
+	 * @brief combines the input filters with AND
+	 * @param $filters array, the filters to connect
+	 * @returns the combined filter
+	 *
+	 * Combines Filter arguments with AND
+	 */
+	public function combineFilterWithOr($filters) {
+		return $this->combineFilter($filters, '|');
+	}
+
+	/**
+	 * @brief combines the input filters with given operator
+	 * @param $filters array, the filters to connect
+	 * @param $operator either & or |
+	 * @returns the combined filter
+	 *
+	 * Combines Filter arguments with AND
+	 */
+	private function combineFilter($filters, $operator) {
+		$combinedFilter = '('.$operator;
+		foreach($filters as $filter) {
+		    if($filter[0] != '(') {
+				$filter = '('.$filter.')';
+		    }
+		    $combinedFilter.=$filter;
+		}
+		$combinedFilter.=')';
+		return $combinedFilter;
+	}
+
+	public function areCredentialsValid($name, $password) {
+		$testConnection = clone $this->connection;
+		$credentials = array(
+			'ldapAgentName' => $name,
+			'ldapAgentPassword' => $password
+		);
+		if(!$testConnection->setConfiguration($credentials)) {
+			return false;
+		}
+		return $testConnection->bind();
+	}
+}
\ No newline at end of file
diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8ba9dad70ef857ec6d56d83fd395cc378ae7f6f
--- /dev/null
+++ b/apps/user_ldap/lib/connection.php
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+class Connection {
+	private $ldapConnectionRes = null;
+	private $configID;
+	private $configured = false;
+
+	//cached settings
+	protected $config = array(
+		'ldapHost' => null,
+		'ldapPort' => null,
+		'ldapBase' => null,
+		'ldapBaseUsers' => null,
+		'ldapBaseGroups' => null,
+		'ldapAgentName' => null,
+		'ldapAgentPassword' => null,
+		'ldapTLS' => null,
+		'ldapNoCase' => null,
+		'ldapIgnoreNamingRules' => null,
+		'ldapUserDisplayName' => null,
+		'ldapUserFilter' => null,
+		'ldapGroupFilter' => null,
+		'ldapGroupDisplayName' => null,
+		'ldapLoginFilter' => null,
+		'ldapQuotaAttribute' => null,
+		'ldapQuotaDefault' => null,
+		'ldapEmailAttribute' => null,
+	);
+
+	public function __construct($configID = 'user_ldap') {
+		$this->configID = $configID;
+	}
+
+	public function __destruct() {
+		@ldap_unbind($this->ldapConnectionRes);
+	}
+
+	public function __get($name) {
+		if(!$this->configured) {
+			$this->readConfiguration();
+		}
+
+		if(isset($this->config[$name])) {
+			return $this->config[$name];
+		}
+	}
+
+	/**
+	 * @brief initializes the LDAP backend
+	 * @param $force read the config settings no matter what
+	 *
+	 * initializes the LDAP backend
+	 */
+	public function init($force = false) {
+		$this->readConfiguration($force);
+		$this->establishConnection();
+	}
+
+	/**
+	 * Returns the LDAP handler
+	 */
+	public function getConnectionResource() {
+		if(!$this->ldapConnectionRes) {
+			$this->init();
+		}
+		if(is_null($this->ldapConnectionRes)) {
+			\OCP\Util::writeLog('user_ldap', 'Connection could not be established', \OCP\Util::ERROR);
+		}
+		return $this->ldapConnectionRes;
+	}
+
+	/**
+	 * Caches the general LDAP configuration.
+	 */
+	private function readConfiguration($force = false) {
+		\OCP\Util::writeLog('user_ldap','Checking conf state: isConfigured? '.print_r($this->configured, true).' isForce? '.print_r($force, true).' configID? '.print_r($this->configID, true), \OCP\Util::DEBUG);
+		if((!$this->configured || $force) && !is_null($this->configID)) {
+			\OCP\Util::writeLog('user_ldap','Reading the configuration', \OCP\Util::DEBUG);
+			$this->config['ldapHost']              = \OCP\Config::getAppValue($this->configID, 'ldap_host', '');
+			$this->config['ldapPort']              = \OCP\Config::getAppValue($this->configID, 'ldap_port', 389);
+			$this->config['ldapAgentName']         = \OCP\Config::getAppValue($this->configID, 'ldap_dn','');
+			$this->config['ldapAgentPassword']     = base64_decode(\OCP\Config::getAppValue($this->configID, 'ldap_agent_password',''));
+			$this->config['ldapBase']              = \OCP\Config::getAppValue($this->configID, 'ldap_base', '');
+			$this->config['ldapBaseUsers']         = \OCP\Config::getAppValue($this->configID, 'ldap_base_users',$this->config['ldapBase']);
+			$this->config['ldapBaseGroups']        = \OCP\Config::getAppValue($this->configID, 'ldap_base_groups', $this->config['ldapBase']);
+			$this->config['ldapTLS']               = \OCP\Config::getAppValue($this->configID, 'ldap_tls',0);
+			$this->config['ldapNoCase']            = \OCP\Config::getAppValue($this->configID, 'ldap_nocase', 0);
+			$this->config['ldapUserDisplayName']   = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_display_name', 'uid'), 'UTF-8');
+			$this->config['ldapUserFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person');
+			$this->config['ldapGroupFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)');
+			$this->config['ldapLoginFilter']       = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)');
+			$this->config['ldapGroupDisplayName']  = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', 'uid'), 'UTF-8');
+			$this->config['ldapQuotaAttribute']    = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', '');
+			$this->config['ldapQuotaDefault']      = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', '');
+			$this->config['ldapEmailAttribute']      = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', '');
+			$this->config['ldapGroupMemberAssocAttr']      = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember');
+			$this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
+
+			$this->configured = $this->validateConfiguration();
+		}
+	}
+
+	/**
+	 * @brief set LDAP configuration with values delivered by an array, not read from configuration
+	 * @param $config array that holds the config parameters in an associated array
+	 * @param &$setParameters optional; array where the set fields will be given to
+	 * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
+	 */
+	public function setConfiguration($config, &$setParameters = null) {
+		if(!is_array($config)) {
+			return false;
+		}
+
+		foreach($config as $parameter => $value) {
+		    if(isset($this->config[$parameter])) {
+				$this->config[$parameter] = $value;
+				if(is_array($setParameters)) {
+					$setParameters[] = $parameter;
+				}
+		    }
+		}
+
+		$this->configured = $this->validateConfiguration();
+
+		return $this->configured;
+	}
+
+	/**
+	 * @brief Validates the user specified configuration
+	 * @returns true if configuration seems OK, false otherwise
+	 */
+	private function validateConfiguration() {
+		//first step: "soft" checks: settings that are not really necessary, but advisable. If left empty, give an info message
+		if(empty($this->config['ldapBaseUsers'])) {
+			\OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO);
+			$this->config['ldapBaseUsers'] = $this->config['ldapBase'];
+		}
+		if(empty($this->config['ldapBaseGroups'])) {
+			\OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO);
+			$this->config['ldapBaseGroups'] = $this->config['ldapBase'];
+		}
+		if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) {
+			\OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO);
+		}
+
+		//second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning.
+		$configurationOK = true;
+		if(empty($this->config['ldapHost'])) {
+			\OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapPort'])) {
+			\OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword']))
+			|| (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) {
+			\OCP\Util::writeLog('user_ldap', 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		//TODO: check if ldapAgentName is in DN form
+		if(empty($this->config['ldapBase']) && (empty($this->config['ldapBaseUsers']) && empty($this->config['ldapBaseGroups']))) {
+			\OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapUserDisplayName'])) {
+			\OCP\Util::writeLog('user_ldap', 'No user display name attribute specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapGroupDisplayName'])) {
+			\OCP\Util::writeLog('user_ldap', 'No group display name attribute specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapLoginFilter'])) {
+			\OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) {
+			\OCP\Util::writeLog('user_ldap', 'Login filter does not contain %uid place holder, won`t connect.', \OCP\Util::WARN);
+			\OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG);
+			$configurationOK = false;
+		}
+
+		return $configurationOK;
+	}
+
+	/**
+	 * Connects and Binds to LDAP
+	 */
+	private function establishConnection() {
+		if(!$this->configured) {
+			\OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN);
+			return false;
+		}
+		if(!$this->ldapConnectionRes) {
+			$this->ldapConnectionRes = ldap_connect($this->config['ldapHost'], $this->config['ldapPort']);
+			if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+					if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
+						if($this->config['ldapTLS']) {
+							ldap_start_tls($this->ldapConnectionRes);
+						}
+					}
+			}
+
+			return $this->bind();
+		}
+	}
+
+	/**
+	 * Binds to LDAP
+	 */
+	public function bind() {
+		$ldapLogin = @ldap_bind($this->getConnectionResource(), $this->config['ldapAgentName'], $this->config['ldapAgentPassword']);
+		if(!$ldapLogin) {
+			\OCP\Util::writeLog('user_ldap', 'Bind failed: ' . ldap_errno($this->ldapConnectionRes) . ': ' . ldap_error($this->ldapConnectionRes), \OCP\Util::ERROR);
+			$this->ldapConnectionRes = null;
+			return false;
+		}
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
deleted file mode 100644
index 08b09304d780cd224e680010011582a05f131aaa..0000000000000000000000000000000000000000
--- a/apps/user_ldap/lib_ldap.php
+++ /dev/null
@@ -1,721 +0,0 @@
-<?php
-
-/**
- * ownCloud – LDAP lib
- *
- * @author Arthur Schiwon
- * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember');
-define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn');
-
-//needed to unbind, because we use OC_LDAP only statically
-class OC_LDAP_DESTRUCTOR {
-	public function __destruct() {
-		OC_LDAP::destruct();
-	}
-}
-
-class OC_LDAP {
-	static protected $ldapConnectionRes = false;
-	static protected $configured = false;
-
-	//cached settings
-	static protected $ldapHost;
-	static protected $ldapPort;
-	static protected $ldapBase;
-	static protected $ldapBaseUsers;
-	static protected $ldapBaseGroups;
-	static protected $ldapAgentName;
-	static protected $ldapAgentPassword;
-	static protected $ldapTLS;
-	static protected $ldapNoCase;
-	static protected $ldapIgnoreNamingRules;
-	// user and group settings, that are needed in both backends
-	static protected $ldapUserDisplayName;
-	static protected $ldapUserFilter;
-	static protected $ldapGroupDisplayName;
-	static protected $ldapLoginFilter;
-
-	static protected $__d;
-
-	/**
-	 * @brief initializes the LDAP backend
-	 * @param $force read the config settings no matter what
-	 *
-	 * initializes the LDAP backend
-	 */
-	static public function init($force = false) {
-		if(is_null(self::$__d)) {
-			self::$__d = new OC_LDAP_DESTRUCTOR();
-		}
-		self::readConfiguration($force);
-		self::establishConnection();
-	}
-
-	static public function destruct() {
-		@ldap_unbind(self::$ldapConnectionRes);
-	}
-
-	/**
-	 * @brief returns a read-only configuration value
-	 * @param $key the name of the configuration value
-	 * @returns the value on success, otherwise null
-	 *
-	 * returns a read-only configuration values
-	 *
-	 * we cannot work with getters, because it is a static class
-	 */
-	static public function conf($key) {
-		if(!self::$configured) {
-			self::init();
-		}
-
-		$availableProperties = array(
-			'ldapUserDisplayName',
-			'ldapGroupDisplayName',
-			'ldapLoginFilter'
-		);
-
-		if(in_array($key, $availableProperties)) {
-			return self::$$key;
-		}
-
-		return null;
-	}
-
-	/**
-	 * gives back the database table for the query
-	 */
-	static private function getMapTable($isUser) {
-		if($isUser) {
-			return '*PREFIX*ldap_user_mapping';
-		} else {
-			return '*PREFIX*ldap_group_mapping';
-		}
-	}
-
-	/**
-	 * @brief returns the LDAP DN for the given internal ownCloud name of the group
-	 * @param $name the ownCloud name in question
-	 * @returns string with the LDAP DN on success, otherwise false
-	 *
-	 * returns the LDAP DN for the given internal ownCloud name of the group
-	 */
-	static public function groupname2dn($name) {
-		return self::ocname2dn($name, false);
-	}
-
-	/**
-	 * @brief returns the LDAP DN for the given internal ownCloud name of the user
-	 * @param $name the ownCloud name in question
-	 * @returns string with the LDAP DN on success, otherwise false
-	 *
-	 * returns the LDAP DN for the given internal ownCloud name of the user
-	 */
-	static public function username2dn($name) {
-		$dn = self::ocname2dn($name, true);
-		if($dn) {
-			return $dn;
-		} else {
-			//fallback: user is not mapped
-			self::init();
-			$filter = self::combineFilterWithAnd(array(
-				self::$ldapUserFilter,
-				self::$ldapUserDisplayName . '=' . $name,
-			));
-			$result = self::searchUsers($filter, 'dn');
-			if(isset($result[0]['dn'])) {
-				self::mapUser($result[0], $name);
-				return $result[0];
-			}
-		}
-
-		return false;
-	}
-
-	static private function ocname2dn($name, $isUser) {
-		$table = self::getMapTable($isUser);
-
-		$query = OCP\DB::prepare('
-			SELECT ldap_dn
-			FROM '.$table.'
-			WHERE owncloud_name = ?
-		');
-
-		$record = $query->execute(array($name))->fetchOne();
-		return $record;
-	}
-
-	/**
-	 * @brief returns the internal ownCloud name for the given LDAP DN of the group
-	 * @param $dn the dn of the group object
-	 * @param $ldapname optional, the display name of the object
-	 * @returns string with with the name to use in ownCloud, false on DN outside of search DN
-	 *
-	 * returns the internal ownCloud name for the given LDAP DN of the group
-	 */
-	static public function dn2groupname($dn, $ldapname = null) {
-		if(mb_strripos($dn, self::$ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseGroups, 'UTF-8'))) {
-			return false;
-		}
-		return self::dn2ocname($dn, $ldapname, false);
-	}
-
-	/**
-	 * @brief returns the internal ownCloud name for the given LDAP DN of the user
-	 * @param $dn the dn of the user object
-	 * @param $ldapname optional, the display name of the object
-	 * @returns string with with the name to use in ownCloud
-	 *
-	 * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
-	 */
-	static public function dn2username($dn, $ldapname = null) {
-		if(mb_strripos($dn, self::$ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseUsers, 'UTF-8'))) {
-			return false;
-		}
-		return self::dn2ocname($dn, $ldapname, true);
-	}
-
-	static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
-		$dn = self::sanitizeDN($dn);
-		$table = self::getMapTable($isUser);
-		if($isUser) {
-			$nameAttribute = self::conf('ldapUserDisplayName');
-		} else {
-			$nameAttribute = self::conf('ldapGroupDisplayName');
-		}
-
-		$query = OCP\DB::prepare('
-			SELECT owncloud_name
-			FROM '.$table.'
-			WHERE ldap_dn = ?
-		');
-
-		$component = $query->execute(array($dn))->fetchOne();
-		if($component) {
-			return $component;
-		}
-
-		if(is_null($ldapname)) {
-			$ldapname = self::readAttribute($dn, $nameAttribute);
-			$ldapname = $ldapname[0];
-		}
-		$ldapname = self::sanitizeUsername($ldapname);
-
-		//a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
-		if(self::mapComponent($dn, $ldapname, $isUser)) {
-			return $ldapname;
-		}
-
-		//doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
-		$oc_name = self::alternateOwnCloudName($ldapname, $dn);
-		if(self::mapComponent($dn, $oc_name, $isUser)) {
-			return $oc_name;
-		}
-
-		//and this of course should never been thrown :)
-		throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
-	}
-
-	/**
-	 * @brief gives back the user names as they are used ownClod internally
-	 * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
-	 * @returns an array with the user names to use in ownCloud
-	 *
-	 * gives back the user names as they are used ownClod internally
-	 */
-	static public function ownCloudUserNames($ldapUsers) {
-		return self::ldap2ownCloudNames($ldapUsers, true);
-	}
-
-	/**
-	 * @brief gives back the group names as they are used ownClod internally
-	 * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
-	 * @returns an array with the group names to use in ownCloud
-	 *
-	 * gives back the group names as they are used ownClod internally
-	 */
-	static public function ownCloudGroupNames($ldapGroups) {
-		return self::ldap2ownCloudNames($ldapGroups, false);
-	}
-
-	static private function ldap2ownCloudNames($ldapObjects, $isUsers) {
-		if($isUsers) {
-			$knownObjects = self::mappedUsers();
-			$nameAttribute = self::conf('ldapUserDisplayName');
-		} else {
-			$knownObjects = self::mappedGroups();
-			$nameAttribute = self::conf('ldapGroupDisplayName');
-		}
-		$ownCloudNames = array();
-
-		foreach($ldapObjects as $ldapObject) {
-			$key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
-
-			//everything is fine when we know the group
-			if($key !== false) {
-				$ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
-				continue;
-			}
-
-			//a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters.
-			$ocname = self::sanitizeUsername($ldapObject[$nameAttribute]);
-			if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
-				$ownCloudNames[] = $ocname;
-				continue;
-			}
-
-			//doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
-			$ocname = self::alternateOwnCloudName($ocname, $ldapObject['dn']);
-			if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
-				$ownCloudNames[] = $ocname;
-				continue;
-			}
-
-			//and this of course should never been thrown :)
-			throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
-		}
-		return $ownCloudNames;
-	}
-
-	/**
-	 * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
-	 * @param $name the display name of the object
-	 * @param $dn the dn of the object
-	 * @returns string with with the name to use in ownCloud
-	 *
-	 * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
-	 */
-	static private function alternateOwnCloudName($name, $dn) {
-		$ufn = ldap_dn2ufn($dn);
-		$name = $name . '@' . trim(OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
-		$name = self::sanitizeUsername($name);
-		return $name;
-	}
-
-	/**
-	 * @brief retrieves all known groups from the mappings table
-	 * @returns array with the results
-	 *
-	 * retrieves all known groups from the mappings table
-	 */
-	static private function mappedGroups() {
-		return self::mappedComponents(false);
-	}
-
-	/**
-	 * @brief retrieves all known users from the mappings table
-	 * @returns array with the results
-	 *
-	 * retrieves all known users from the mappings table
-	 */
-	static private function mappedUsers() {
-		return self::mappedComponents(true);
-	}
-
-	static private function mappedComponents($isUsers) {
-		$table = self::getMapTable($isUsers);
-
-		$query = OCP\DB::prepare('
-			SELECT ldap_dn, owncloud_name
-			FROM '. $table
-		);
-
-		return $query->execute()->fetchAll();
-	}
-
-	/**
-	 * @brief inserts a new user or group into the mappings table
-	 * @param $dn the record in question
-	 * @param $ocname the name to use in ownCloud
-	 * @param $isUser is it a user or a group?
-	 * @returns true on success, false otherwise
-	 *
-	 * inserts a new user or group into the mappings table
-	 */
-	static private function mapComponent($dn, $ocname, $isUser = true) {
-		$table = self::getMapTable($isUser);
-		$dn = self::sanitizeDN($dn);
-
-		$sqlAdjustment = '';
-		$dbtype = OCP\Config::getSystemValue('dbtype');
-		if($dbtype == 'mysql') {
-			$sqlAdjustment = 'FROM dual';
-		}
-
-		$insert = OCP\DB::prepare('
-			INSERT INTO '.$table.' (ldap_dn, owncloud_name)
-				SELECT ?,?
-				'.$sqlAdjustment.'
-				WHERE NOT EXISTS (
-					SELECT 1
-					FROM '.$table.'
-					WHERE ldap_dn = ?
-						OR owncloud_name = ? )
-		');
-
-		$res = $insert->execute(array($dn, $ocname, $dn, $ocname));
-
-		if(OCP\DB::isError($res)) {
-			return false;
-		}
-
-		$insRows = $res->numRows();
-
-		if($insRows == 0) {
-			return false;
-		}
-
-		return true;
-	}
-
-	static public function fetchListOfUsers($filter, $attr) {
-		return self::fetchList(OC_LDAP::searchUsers($filter, $attr), (count($attr) > 1));
-	}
-
-	static public function fetchListOfGroups($filter, $attr) {
-		return self::fetchList(OC_LDAP::searchGroups($filter, $attr), (count($attr) > 1));
-	}
-
-	static private function fetchList($list, $manyAttributes) {
-		if(is_array($list)) {
-			if($manyAttributes) {
-				return $list;
-			} else {
-				return array_unique($list, SORT_LOCALE_STRING);
-			}
-		}
-
-		//error cause actually, maybe throw an exception in future.
-		return array();
-	}
-
-	/**
-	 * @brief reads a given attribute for an LDAP record identified by a DN
-	 * @param $dn the record in question
-	 * @param $attr the attribute that shall be retrieved
-	 * @returns the values in an array on success, false otherwise
-	 *
-	 * Reads an attribute from an LDAP entry
-	 */
-	static public function readAttribute($dn, $attr) {
-		$cr = self::getConnectionResource();
-		$rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
-		$er = ldap_first_entry($cr, $rr);
-		//LDAP attributes are not case sensitive
-		$result = OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
-		$attr = mb_strtolower($attr, 'UTF-8');
-
-		if(isset($result[$attr]) && $result[$attr]['count'] > 0){
-			$values = array();
-			for($i=0;$i<$result[$attr]['count'];$i++) {
-				$values[] = self::resemblesDN($attr) ? self::sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
-			}
-			return $values;
-		}
-		return false;
-	}
-
-	/**
-	 * @brief executes an LDAP search, optimized for Users
-	 * @param $filter the LDAP filter for the search
-	 * @param $attr optional, when a certain attribute shall be filtered out
-	 * @returns array with the search result
-	 *
-	 * Executes an LDAP search
-	 */
-	static public function searchUsers($filter, $attr = null) {
-		self::init();
-		return self::search($filter, self::$ldapBaseUsers, $attr);
-	}
-
-	/**
-	 * @brief executes an LDAP search, optimized for Groups
-	 * @param $filter the LDAP filter for the search
-	 * @param $attr optional, when a certain attribute shall be filtered out
-	 * @returns array with the search result
-	 *
-	 * Executes an LDAP search
-	 */
-	static public function searchGroups($filter, $attr = null) {
-		self::init();
-		return self::search($filter, self::$ldapBaseGroups, $attr);
-	}
-
-	/**
-	 * @brief executes an LDAP search
-	 * @param $filter the LDAP filter for the search
-	 * @param $base the LDAP subtree that shall be searched
-	 * @param $attr optional, when a certain attribute shall be filtered out
-	 * @returns array with the search result
-	 *
-	 * Executes an LDAP search
-	 */
-	static private function search($filter, $base, $attr = null) {
-		if(!is_null($attr) && !is_array($attr)) {
-			$attr = array(mb_strtolower($attr, 'UTF-8'));
-		}
-
-		// See if we have a resource
-		$link_resource = self::getConnectionResource();
-		if(is_resource($link_resource)) {
-			$sr = ldap_search($link_resource, $base, $filter, $attr);
-			$findings = ldap_get_entries($link_resource, $sr );
-
-			// if we're here, probably no connection resource is returned.
-			// to make ownCloud behave nicely, we simply give back an empty array.
-			if(is_null($findings)) {
-				return array();
-			}
-		} else {
-			// Seems like we didn't find any resource.
-			// Return an empty array just like before.
-			return array();
-		}
-
-		if(!is_null($attr)) {
-			$selection = array();
-			$multiarray = false;
-			if(count($attr) > 1) {
-				$multiarray = true;
-				$i = 0;
-			}
-			foreach($findings as $item) {
-				if(!is_array($item)) {
-					continue;
-				}
-				$item = OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
-
-				if($multiarray) {
-					foreach($attr as $key) {
-						$key = mb_strtolower($key, 'UTF-8');
-						if(isset($item[$key])) {
-							if($key != 'dn'){
-								$selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0];
-							} else {
-								$selection[$i][$key] = self::sanitizeDN($item[$key]);
-							}
-						}
-
-					}
-					$i++;
-				} else {
-					//tribute to case insensitivity
-					$key = mb_strtolower($attr[0], 'UTF-8');
-
-					if(isset($item[$key])) {
-						if(self::resemblesDN($key)) {
-							$selection[] = self::sanitizeDN($item[$key]);
-						} else {
-							$selection[] = $item[$key];
-						}
-					}
-				}
-
-			}
-			return $selection;
-		}
-
-		return $findings;
-	}
-
-	static private function resemblesDN($attr) {
-		$resemblingAttributes = array(
-			'dn',
-			'uniquemember',
-			'member'
-		);
-		return in_array($attr, $resemblingAttributes);
-	}
-
-	static private function sanitizeDN($dn) {
-		//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');
-
-		return $dn;
-	}
-
-	static private function sanitizeUsername($name) {
-		if(self::$ldapIgnoreNamingRules) {
-			return $name;
-		}
-
-		//REPLACEMENTS
-		$name = OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
-
-		//every remaining unallowed characters will be removed
-		$name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
-
-		return $name;
-	}
-
-	/**
-	 * @brief combines the input filters with AND
-	 * @param $filters array, the filters to connect
-	 * @returns the combined filter
-	 *
-	 * Combines Filter arguments with AND
-	 */
-	static public function combineFilterWithAnd($filters) {
-		return self::combineFilter($filters,'&');
-	}
-
-	/**
-	 * @brief combines the input filters with AND
-	 * @param $filters array, the filters to connect
-	 * @returns the combined filter
-	 *
-	 * Combines Filter arguments with AND
-	 */
-	static public function combineFilterWithOr($filters) {
-		return self::combineFilter($filters,'|');
-	}
-
-	/**
-	 * @brief combines the input filters with given operator
-	 * @param $filters array, the filters to connect
-	 * @param $operator either & or |
-	 * @returns the combined filter
-	 *
-	 * Combines Filter arguments with AND
-	 */
-	static private function combineFilter($filters, $operator) {
-		$combinedFilter = '('.$operator;
-		foreach($filters as $filter) {
-		    if($filter[0] != '(') {
-				$filter = '('.$filter.')';
-		    }
-		    $combinedFilter.=$filter;
-		}
-		$combinedFilter.=')';
-		return $combinedFilter;
-	}
-
-	/**
-	 * Returns the LDAP handler
-	 */
-	static private function getConnectionResource() {
-		if(!self::$ldapConnectionRes) {
-			self::init();
-		}
-		if(is_null(self::$ldapConnectionRes)) {
-			OCP\Util::writeLog('ldap', 'Connection could not be established', OCP\Util::INFO);
-		}
-		return self::$ldapConnectionRes;
-	}
-
-	/**
-	 * Caches the general LDAP configuration.
-	 */
-	static private function readConfiguration($force = false) {
-		if(!self::$configured || $force) {
-			self::$ldapHost              = OCP\Config::getAppValue('user_ldap', 'ldap_host', '');
-			self::$ldapPort              = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389);
-			self::$ldapAgentName         = OCP\Config::getAppValue('user_ldap', 'ldap_dn','');
-			self::$ldapAgentPassword     = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password',''));
-			self::$ldapBase              = OCP\Config::getAppValue('user_ldap', 'ldap_base', '');
-			self::$ldapBaseUsers         = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase);
-			self::$ldapBaseGroups        = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
-			self::$ldapTLS               = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0);
-			self::$ldapNoCase            = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0);
-			self::$ldapUserDisplayName   = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'), 'UTF-8');
-			self::$ldapUserFilter        = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
-			self::$ldapLoginFilter       = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)');
-			self::$ldapGroupDisplayName  = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
-			self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
-
-			if(empty(self::$ldapBaseUsers)) {
-				OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO);
-				self::$ldapBaseUsers = self::$ldapBase;
-			}
-			if(empty(self::$ldapBaseGroups)) {
-				OCP\Util::writeLog('ldap', 'Base for Groups is empty, using Base DN', OCP\Util::INFO);
-				self::$ldapBaseGroups = self::$ldapBase;
-			}
-
-			if(
-				   !empty(self::$ldapHost)
-				&& !empty(self::$ldapPort)
-				&& (
-					   (!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword))
-					|| ( empty(self::$ldapAgentName) &&  empty(self::$ldapAgentPassword))
-				)
-				&& !empty(self::$ldapBase)
-				&& !empty(self::$ldapUserDisplayName)
-			)
-			{
-				self::$configured = true;
-			}
-		}
-	}
-
-	/**
-	 * Connects and Binds to LDAP
-	 */
-	static private function establishConnection() {
-		if(!self::$configured) {
-			OCP\Util::writeLog('ldap', 'Configuration is invalid, cannot connect', OCP\Util::INFO);
-			return false;
-		}
-		if(!self::$ldapConnectionRes) {
-			self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort);
-			if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
-					if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
-						if(self::$ldapTLS) {
-							ldap_start_tls(self::$ldapConnectionRes);
-						}
-					}
-			}
-
-			$ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword );
-			if(!$ldapLogin) {
-				OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR);
-				self::$ldapConnectionRes = null;
-				return false;
-			}
-		}
-	}
-
-	static public function areCredentialsValid($name, $password) {
-		return @ldap_bind(self::getConnectionResource(), $name, $password);
-	}
-
-	/**
-	* taken from http://www.php.net/manual/en/function.array-search.php#97645
-	* TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
-	*/
-	static public function recursiveArraySearch($haystack, $needle, $index = null) {
-		$aIt = new RecursiveArrayIterator($haystack);
-		$it = new RecursiveIteratorIterator($aIt);
-
-		while($it->valid()) {
-			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
-				return $aIt->key();
-			}
-
-			$it->next();
-		}
-
-		return false;
-	}
-
- }
diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php
index 2be6b46fb23c05eff40b242240d09b9187d2fbce..106459580fa0e8e900f4c88c694724d441946576 100644
--- a/apps/user_ldap/tests/group_ldap.php
+++ b/apps/user_ldap/tests/group_ldap.php
@@ -26,8 +26,8 @@ class Test_Group_Ldap extends UnitTestCase {
 	}
 
 	function testSingleBackend(){
-		OC_Group::useBackend(new OC_GROUP_LDAP());
-		$group_ldap = new OC_GROUP_LDAP();
+		OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP());
+		$group_ldap = new OCA\user_ldap\GROUP_LDAP();
 
  		$this->assertIsA(OC_Group::getGroups(),gettype(array()));
 		$this->assertIsA($group_ldap->getGroups(),gettype(array()));
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index b51d9a55cc79466ee892fddf69d92eecf0aecc7e..a4a8921d08d77451f176d003b9d3c726a54f488c 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -23,13 +23,9 @@
  *
  */
 
-class OC_USER_LDAP extends OC_User_Backend {
+namespace OCA\user_ldap;
 
-	// cached settings
-	protected $ldapUserFilter;
-	protected $ldapQuotaAttribute;
-	protected $ldapQuotaDefault;
-	protected $ldapEmailAttribute;
+class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 
 	// will be retrieved from LDAP server
 	protected $ldap_dc = false;
@@ -37,39 +33,32 @@ class OC_USER_LDAP extends OC_User_Backend {
 	// cache getUsers()
 	protected $_users = null;
 
-	public function __construct() {
-		$this->ldapUserFilter      = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)');
-		$this->ldapQuotaAttribute  = OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', '');
-		$this->ldapQuotaDefault    = OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', '');
-		$this->ldapEmailAttribute  = OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', '');
-	}
-
 	private function updateQuota($dn) {
 		$quota = null;
-		if(!empty($this->ldapQuotaDefault)) {
-			$quota = $this->ldapQuotaDefault;
+		if(!empty($this->connection->ldapQuotaDefault)) {
+			$quota = $this->connection->ldapQuotaDefault;
 		}
-		if(!empty($this->ldapQuotaAttribute)) {
-			$aQuota = OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute);
+		if(!empty($this->connection->ldapQuotaAttribute)) {
+			$aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute);
 
 			if($aQuota && (count($aQuota) > 0)) {
 				$quota = $aQuota[0];
 			}
 		}
 		if(!is_null($quota)) {
-			OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'files', 'quota', OCP\Util::computerFileSize($quota));
+			\OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota));
 		}
 	}
 
 	private function updateEmail($dn) {
 		$email = null;
-		if(!empty($this->ldapEmailAttribute)) {
-			$aEmail = OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute);
+		if(!empty($this->connection->ldapEmailAttribute)) {
+			$aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute);
 			if($aEmail && (count($aEmail) > 0)) {
 				$email = $aEmail[0];
 			}
-			if(!is_null($email)){
-				OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'settings', 'email', $email);
+			if(!is_null($email)) {
+				\OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email);
 			}
 		}
 	}
@@ -84,15 +73,15 @@ class OC_USER_LDAP extends OC_User_Backend {
 	 */
 	public function checkPassword($uid, $password){
 		//find out dn of the user name
-		$filter = OCP\Util::mb_str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
-		$ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+		$filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8');
+		$ldap_users = $this->fetchListOfUsers($filter, 'dn');
 		if(count($ldap_users) < 1) {
 			return false;
 		}
 		$dn = $ldap_users[0];
 
 		//are the credentials OK?
-		if(!OC_LDAP::areCredentialsValid($dn, $password)) {
+		if(!$this->areCredentialsValid($dn, $password)) {
 			return false;
 		}
 
@@ -101,7 +90,7 @@ class OC_USER_LDAP extends OC_User_Backend {
 		$this->updateEmail($dn);
 
 		//give back the display name
-		return OC_LDAP::dn2username($dn);
+		return $this->dn2username($dn);
 	}
 
 	/**
@@ -112,8 +101,8 @@ class OC_USER_LDAP extends OC_User_Backend {
 	 */
 	public function getUsers(){
 		if(is_null($this->_users)) {
-			$ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn'));
-			$this->_users = OC_LDAP::ownCloudUserNames($ldap_users);
+			$ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn'));
+			$this->_users = $this->ownCloudUserNames($ldap_users);
 		}
 		return $this->_users;
 	}
@@ -125,13 +114,13 @@ class OC_USER_LDAP extends OC_User_Backend {
 	 */
 	public function userExists($uid){
 		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
-		$dn = OC_LDAP::username2dn($uid);
+		$dn = $this->username2dn($uid);
 		if(!$dn) {
 			return false;
 		}
 
 		//if user really still exists, we will be able to read his cn
-		$cn = OC_LDAP::readAttribute($dn, 'cn');
+		$cn = $this->readAttribute($dn, 'cn');
 		if(!$cn || empty($cn)) {
 			return false;
 		}
@@ -139,4 +128,27 @@ class OC_USER_LDAP extends OC_User_Backend {
 		return true;
 	}
 
+	/**
+	* @brief delete a user
+	* @param $uid The username of the user to delete
+	* @returns true/false
+	*
+	* Deletes a user
+	*/
+	public function deleteUser($uid) {
+		return false;
+	}
+
+	/**
+	* @brief Check if backend implements actions
+	* @param $actions bitwise-or'ed actions
+	* @returns boolean
+	*
+	* Returns the supported actions as int to be
+	* compared with OC_USER_BACKEND_CREATE_USER etc.
+	*/
+	public function implementsActions($actions) {
+		return (bool)(OC_USER_BACKEND_CHECK_PASSWORD & $actions);
+	}
+
 }
\ No newline at end of file
diff --git a/apps/user_openid/appinfo/app.php b/apps/user_openid/appinfo/app.php
index a5fb6a0f45ea403366c578c2127ad6d99fc57033..fe57b189fac3a97205274ba06222f15f345b230a 100644
--- a/apps/user_openid/appinfo/app.php
+++ b/apps/user_openid/appinfo/app.php
@@ -19,7 +19,7 @@ OCP\Util::addHeader('link',array('rel'=>'openid.delegate', 'href'=>OCP\Util::lin
 
 OCP\App::registerPersonal('user_openid','settings');
 
-require_once 'openid/user_openid.php';
+require_once 'apps/user_openid/user_openid.php';
 
 //active the openid backend
 OC_User::useBackend('openid');
diff --git a/lib/base.php b/lib/base.php
index fcca1e77d265a58dc0a1f5f053a1b7e6442041a0..5041f43648e159e6439a36227ef441f0407dea23 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -83,6 +83,9 @@ class OC{
 		elseif(strpos($className,'OCP\\')===0){
 			require_once 'public/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
 		}
+		elseif(strpos($className,'OCA\\')===0){
+			require_once 'apps/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
+		}
 		elseif(strpos($className,'Sabre_')===0) {
 			require_once str_replace('_','/',$className) . '.php';
 		}
diff --git a/lib/group.php b/lib/group.php
index ceee5fa4edb787f0a0217ca8e69591b5078265b6..12e5f5ebb30ff82cccc343b456fec5232d6425cf 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -43,7 +43,7 @@ class OC_Group {
 	 * @returns true/false
 	 */
 	public static function useBackend( $backend ){
-		if($backend instanceof OC_Group_Backend){
+		if($backend instanceof OC_Group_Interface){
 			self::$_usedBackends[]=$backend;
 		}
 	}
@@ -168,7 +168,7 @@ class OC_Group {
 
 		if($run){
 			$succes=false;
-			
+
 			//add the user to the all backends that have the group
 			foreach(self::$_usedBackends as $backend){
 				if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP))
@@ -245,7 +245,7 @@ class OC_Group {
 		asort($groups);
 		return $groups;
 	}
-	
+
 	/**
 	 * check if a group exists
 	 * @param string $gid
@@ -259,7 +259,7 @@ class OC_Group {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * @brief get a list of all users in a group
 	 * @returns array with user ids
diff --git a/lib/group/backend.php b/lib/group/backend.php
index 24778afd1e56c3859684f7fb635abf5d22b964c7..ebc078f152a85d850e3597862b3289c6bc7ad240 100644
--- a/lib/group/backend.php
+++ b/lib/group/backend.php
@@ -37,7 +37,7 @@ define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP',  0x00001000);
 /**
  * Abstract base class for user management
  */
-abstract class OC_Group_Backend {
+abstract class OC_Group_Backend implements OC_Group_Interface {
 	protected $possibleActions = array(
 		OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup',
 		OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup',
diff --git a/lib/group/interface.php b/lib/group/interface.php
new file mode 100644
index 0000000000000000000000000000000000000000..7cca6061e10370bc7e774fc6d2e37132c833fb50
--- /dev/null
+++ b/lib/group/interface.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * ownCloud - group interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_Group_Interface {
+	/**
+	* @brief Check if backend implements actions
+	* @param $actions bitwise-or'ed actions
+	* @returns boolean
+	*
+	* Returns the supported actions as int to be
+	* compared with OC_GROUP_BACKEND_CREATE_GROUP etc.
+	*/
+	public function implementsActions($actions);
+
+	/**
+	 * @brief is user in group?
+	 * @param $uid uid of the user
+	 * @param $gid gid of the group
+	 * @returns true/false
+	 *
+	 * Checks whether the user is member of a group or not.
+	 */
+	public function inGroup($uid, $gid);
+
+	/**
+	 * @brief Get all groups a user belongs to
+	 * @param $uid Name of the user
+	 * @returns array with group names
+	 *
+	 * This function fetches all groups a user belongs to. It does not check
+	 * if the user exists at all.
+	 */
+	public function getUserGroups($uid);
+
+	/**
+	 * @brief get a list of all groups
+	 * @returns array with group names
+	 *
+	 * Returns a list with all groups
+	 */
+	public function getGroups();
+
+	/**
+	 * check if a group exists
+	 * @param string $gid
+	 * @return bool
+	 */
+	public function groupExists($gid);
+
+	/**
+	 * @brief get a list of all users in a group
+	 * @returns array with user ids
+	 */
+	public function usersInGroup($gid);
+
+}
\ No newline at end of file
diff --git a/lib/helper.php b/lib/helper.php
index f328c14ac7712a40d6bb0668cb795b2f2b4cc196..666bc6badfc9a718f43b5b9dcaf186a6baf24347 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -360,7 +360,7 @@ class OC_Helper {
 		}else{
 			$mimeType='application/octet-stream';
 		}
-		
+
 		if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){
 			$info = @strtolower(finfo_file($finfo,$path));
 			if($info){
@@ -679,4 +679,30 @@ class OC_Helper {
 		}
 		return $subject;
 	}
+
+	/**
+	* @brief performs a search in a nested array
+	* @param haystack the array to be searched
+	* @param needle the search string
+	* @param $index optional, only search this key name
+	* @return the key of the matching field, otherwise false
+	*
+	* performs a search in a nested array
+	*
+	* taken from http://www.php.net/manual/en/function.array-search.php#97645
+	*/
+	public static function recursiveArraySearch($haystack, $needle, $index = null) {
+		$aIt = new RecursiveArrayIterator($haystack);
+		$it = new RecursiveIteratorIterator($aIt);
+
+		while($it->valid()) {
+			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
+				return $aIt->key();
+			}
+
+			$it->next();
+		}
+
+		return false;
+	}
 }
diff --git a/lib/ocs.php b/lib/ocs.php
index 18f01518bdb430c0d646483e925ff5fbb55af82b..570f5ac3e59a4c801922e44a2fc9a846f0e5ee09 100644
--- a/lib/ocs.php
+++ b/lib/ocs.php
@@ -176,6 +176,10 @@ class OC_OCS {
 			->requirements(array('format'=>'xml|json'));
 
 		// CLOUD
+		// systemWebApps 
+		}elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-4]=='cloud') and ($ex[$paracount-3] == 'system') and ($ex[$paracount-2] == 'webapps')){
+			OC_OCS::systemwebapps($format);
+
 		// quotaget 
 		$router->create('quota_get',
 				  '/cloud/user/{user}.{format}')
@@ -199,6 +203,16 @@ class OC_OCS {
 					})
 			->requirements(array('format'=>'xml|json'));
 
+		// keygetpublic 
+		}elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){
+			$user=$ex[$paracount-3];
+			OC_OCS::publicKeyGet($format,$user);
+
+		// keygetprivate 
+		}elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){
+			$user=$ex[$paracount-3];
+			OC_OCS::privateKeyGet($format,$user);
+
 
 // add more calls here
 // please document all the call in the draft spec
@@ -580,6 +594,29 @@ class OC_OCS {
 
         // CLOUD API #############################################
 
+        /**
+        * get a list of installed web apps
+        * @param string $format
+        * @return string xml/json
+        */
+        private static function systemWebApps($format) {
+                $login=OC_OCS::checkpassword();
+		$apps=OC_App::getEnabledApps();
+		$values=array();
+		foreach($apps as $app) {
+			$info=OC_App::getAppInfo($app);
+			if(isset($info['standalone'])) {
+				$newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
+				$values[]=$newvalue;
+			}
+
+		}
+		$txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0);
+		echo($txt);
+
+        }
+
+
         /**
         * get the quota of a user
         * @param string $format
@@ -608,10 +645,10 @@ class OC_OCS {
 				$xml['used']=$used;
 				$xml['relative']=$relative;
 
-				$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0);
+				$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
 				echo($txt);
 			}else{
-			echo self::generateXml('', 'fail', 300, 'User does not exist');
+				echo self::generateXml('', 'fail', 300, 'User does not exist');
 			}
 		}else{
 			echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
@@ -631,16 +668,56 @@ class OC_OCS {
 
 			// todo
 			// not yet implemented
-			// edit logic here
+			// add logic here
 			error_log('OCS call: user:'.$user.' quota:'.$quota);
 
                         $xml=array();
-                        $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0);
+                        $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
                         echo($txt);
                 }else{
                         echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
                 }
         }
 
+        /**
+        * get the public key of a user
+        * @param string $format
+        * @param string $user
+        * @return string xml/json
+        */
+        private static function publicKeyGet($format,$user) {
+                $login=OC_OCS::checkpassword();
+
+		if(OC_User::userExists($user)){
+			// calculate the disc space
+			$txt='this is the public key of '.$user;
+			echo($txt);
+		}else{
+			echo self::generateXml('', 'fail', 300, 'User does not exist');
+		}
+	}
+
+        /**
+        * get the private key of a user
+        * @param string $format
+        * @param string $user
+        * @return string xml/json
+        */
+        private static function privateKeyGet($format,$user) {
+                $login=OC_OCS::checkpassword();
+                if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
+
+                        if(OC_User::userExists($user)){
+                                // calculate the disc space
+                                $txt='this is the private key of '.$user;
+                                echo($txt);
+                        }else{
+                                echo self::generateXml('', 'fail', 300, 'User does not exist');
+                        }
+                }else{
+                        echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+                }
+        }
+
 
 }
diff --git a/lib/public/groupinterface.php b/lib/public/groupinterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9783302811805920a760a4c7dd45e27fd99c3414
--- /dev/null
+++ b/lib/public/groupinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Group Class.
+ *
+ */
+
+namespace OCP;
+
+interface GroupInterface extends \OC_Group_Interface {}
\ No newline at end of file
diff --git a/lib/public/userinterface.php b/lib/public/userinterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..b73a8f8d8b07474d2a33ec196ac33d1ccf3ba6cd
--- /dev/null
+++ b/lib/public/userinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * User Class.
+ *
+ */
+
+namespace OCP;
+
+interface UserInterface extends \OC_User_Interface {}
\ No newline at end of file
diff --git a/lib/public/util.php b/lib/public/util.php
index 43f9e3cee5d67b2ced06d4bcafcc66797d0c2e4f..75ca29f7129d70817209b73ca318ae937cce62f2 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -320,4 +320,15 @@ class Util {
 	public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) {
 		return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count));
 	}
+
+	/**
+	* @brief performs a search in a nested array
+	* @param haystack the array to be searched
+	* @param needle the search string
+	* @param $index optional, only search this key name
+	* @return the key of the matching field, otherwise false
+	*/
+	public static function recursiveArraySearch($haystack, $needle, $index = null) {
+		return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index));
+	}
 }
diff --git a/lib/user.php b/lib/user.php
index 549319b3a77b3962c6266a2a4e85ed50f995135d..e3c9c23effa1d566972e8deeaf4e41e1a7199b68 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -21,7 +21,7 @@
  */
 
 /**
- * This class provides wrapper methods for user management. Multiple backends are 
+ * This class provides wrapper methods for user management. Multiple backends are
  * supported. User management operations are delegated to the configured backend for
  * execution.
  *
@@ -83,7 +83,7 @@ class OC_User {
 	 * Set the User Authentication Module
 	 */
 	public static function useBackend( $backend = 'database' ){
-		if($backend instanceof OC_User_Backend){
+		if($backend instanceof OC_User_Interface){
 			self::$_usedBackends[get_class($backend)]=$backend;
 		}else{
 			// You'll never know what happens
diff --git a/lib/user/backend.php b/lib/user/backend.php
index be068a63ce093caa39afd2fd25c4d568cce6f3c9..daa942d261cfee852eddb24b1f7e6f661e7f4ec7 100644
--- a/lib/user/backend.php
+++ b/lib/user/backend.php
@@ -42,7 +42,7 @@ define('OC_USER_BACKEND_CHECK_PASSWORD',    0x000100);
  *
  * Subclass this for your own backends, and see OC_User_Example for descriptions
  */
-abstract class OC_User_Backend {
+abstract class OC_User_Backend implements OC_User_Interface {
 
 	protected $possibleActions = array(
 		OC_USER_BACKEND_CREATE_USER => 'createUser',
diff --git a/lib/user/interface.php b/lib/user/interface.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc3685dc20dcf23cf868b6f2b8190e3efc656cd3
--- /dev/null
+++ b/lib/user/interface.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * ownCloud - user interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_User_Interface {
+
+	/**
+	* @brief Check if backend implements actions
+	* @param $actions bitwise-or'ed actions
+	* @returns boolean
+	*
+	* Returns the supported actions as int to be
+	* compared with OC_USER_BACKEND_CREATE_USER etc.
+	*/
+	public function implementsActions($actions);
+
+	/**
+	* @brief delete a user
+	* @param $uid The username of the user to delete
+	* @returns true/false
+	*
+	* Deletes a user
+	*/
+	public function deleteUser($uid);
+
+	/**
+	* @brief Get a list of all users
+	* @returns array with all uids
+	*
+	* Get a list of all users.
+	*/
+	public function getUsers();
+
+	/**
+	* @brief check if a user exists
+	* @param string $uid the username
+	* @return boolean
+	*/
+	public function userExists($uid);
+
+}
\ No newline at end of file
diff --git a/webapps.php b/webapps.php
deleted file mode 100644
index 82e677a51c790dd4b6036cfa9f2c9d7f6893a719..0000000000000000000000000000000000000000
--- a/webapps.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-/**
-* ownCloud status page. usefull if you want to check from the outside if an owncloud installation exists
-*
-* @author Frank Karlitschek
-* @copyright 2012 Frank Karlitschek frank@owncloud.org
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-$RUNTIME_NOAPPS = TRUE; //no apps, yet
-
-require_once('lib/base.php');
-
-
-//valid user account 
-if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
-if(isset($_SERVER['PHP_AUTH_PW']))   $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
-
-if(!OC_User::login($authuser,$authpw)){
-	header('WWW-Authenticate: Basic realm="your valid user account"');
-	header('HTTP/1.0 401 Unauthorized');
-	exit;
-}else{
-
-	$apps=OC_App::getEnabledApps();
-	$values=array();
-	foreach($apps as $app) {
-		$info=OC_App::getAppInfo($app);
-		if(isset($info['standalone'])) {
-			$newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
-			$values[]=$newvalue;
-		}
-
-	}
-
-	echo(json_encode($values));
-	exit;
-
-
-}