diff --git a/.htaccess b/.htaccess
index b181f8b8452aeea506c695a0be3d74e05ea682f6..86a2de6b946aeea280c0df7d060828baba17bf18 100644
--- a/.htaccess
+++ b/.htaccess
@@ -5,6 +5,8 @@ php_value post_max_size 512M
 php_value memory_limit 512M
 SetEnv htaccessWorking true
 </IfModule>
+<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
+</IfModule>
 Options -Indexes
diff --git a/apps/contacts/ajax/addcard.php b/apps/contacts/ajax/addcard.php
index 9d782246a0acec2fbcb657e94493be959a136827..54c455e515f8688747b6df1677f5120b9ab14069 100644
--- a/apps/contacts/ajax/addcard.php
+++ b/apps/contacts/ajax/addcard.php
@@ -61,5 +61,6 @@ foreach( $add as $propname){
 	$vcard->addProperty($propname, $value, $prop_parameters);
 }
 $id = OC_Contacts_VCard::add($aid,$vcard->serialize());
+OC_Log::write('contacts','ajax/addcard.php - adding id: '.$id,OC_Log::DEBUG);
 
 OC_Contacts_App::renderDetails($id, $vcard);
diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php
index b34cf41424994725e8ce6c7b74eb7561b756bda2..54ad3e4c1030aa41271bb9057172537e5501ac65 100644
--- a/apps/contacts/ajax/contacts.php
+++ b/apps/contacts/ajax/contacts.php
@@ -6,14 +6,14 @@
  * See the COPYING-README file.
  */
 
-function contacts_namesort($a,$b){
-	return strcasecmp($a['fullname'],$b['fullname']);
-}
-
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('contacts');
 
+$ids = OC_Contacts_Addressbook::activeIds(OC_User::getUser());
+$contacts = OC_Contacts_VCard::all($ids);
+//OC_Log::write('contacts','contacts.php: '.count($contacts).' contacts.',OC_Log::DEBUG);
+/*
 $addressbooks = OC_Contacts_Addressbook::active(OC_User::getUser());
 $contacts = array();
 foreach( $addressbooks as $addressbook ){
@@ -26,6 +26,7 @@ foreach( $addressbooks as $addressbook ){
 	}
 }
 usort($contacts,'contacts_namesort');
+*/
 $tmpl = new OC_TEMPLATE("contacts", "part.contacts");
 $tmpl->assign('contacts', $contacts);
 $page = $tmpl->fetchPage();
diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css
index b6709c5a7912cef45e73cb90c689cd2f4ac12e1f..c890be8582403c2f8ae242d51e81d3b75d174520 100644
--- a/apps/contacts/css/styles.css
+++ b/apps/contacts/css/styles.css
@@ -1,4 +1,5 @@
-#contacts li { padding-left:25px;background:url('../img/person.svg') no-repeat; }
+#contacts { padding-left:2px; padding-top: 5px; background: #fff; }
+#leftcontent a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; }
 #chooseaddressbook {margin-right: 170px; float: right;}
 #contacts_details_name { font-weight:bold;font-size:1.1em;margin-left:25%;}
 #contacts_details_photo { margin:.5em 0em .5em 25%; }
diff --git a/apps/contacts/index.php b/apps/contacts/index.php
index a6af54c8789e757716eb73dc10c1cf4a796aba04..5ab6f293ab4527b413f9e2f7d57eece91c95fa2a 100644
--- a/apps/contacts/index.php
+++ b/apps/contacts/index.php
@@ -32,6 +32,9 @@ OC_Util::checkLoggedIn();
 OC_Util::checkAppEnabled('contacts');
 
 // Get active address books. This creates a default one if none exists.
+$ids = OC_Contacts_Addressbook::activeIds(OC_User::getUser());
+$contacts = OC_Contacts_VCard::all($ids);
+
 $addressbooks = OC_Contacts_Addressbook::active(OC_User::getUser());
 
 // Load the files we need
@@ -39,7 +42,7 @@ OC_App::setActiveNavigationEntry( 'contacts_index' );
 
 // Load a specific user?
 $id = isset( $_GET['id'] ) ? $_GET['id'] : null;
-
+/*
 // sort addressbooks  (use contactsort)
 usort($addressbooks,'contacts_namesort');
 
@@ -55,8 +58,10 @@ foreach( $addressbooks as $addressbook ){
 }
 
 usort($contacts,'contacts_namesort');
-
+*/
 $details = array();
+
+// FIXME: This cannot work..?
 if( !is_null($id)/* || count($contacts)*/){
 	if(is_null($id)) $id = $contacts[0]['id'];
 	$vcard = OC_Contacts_App::getContactVCard($id);
diff --git a/apps/contacts/js/LICENSE.jquery.inview b/apps/contacts/js/LICENSE.jquery.inview
new file mode 100644
index 0000000000000000000000000000000000000000..1ed340edbe5e6b970514688ebf26a170a122daf3
--- /dev/null
+++ b/apps/contacts/js/LICENSE.jquery.inview
@@ -0,0 +1,41 @@
+Attribution-Non-Commercial-Share Alike 2.0 UK: England & Wales
+
+http://creativecommons.org/licenses/by-nc-sa/2.0/uk/
+
+You are free:
+
+    * to copy, distribute, display, and perform the work
+    * to make derivative works
+
+
+Under the following conditions:
+
+    * Attribution — You must give the original author credit.
+      Attribute this work:
+      Information
+      What does "Attribute this work" mean?
+      The page you came from contained embedded licensing metadata, 
+      including how the creator wishes to be attributed for re-use. 
+      You can use the HTML here to cite the work. Doing so will 
+      also include metadata on your page so that others can find the 
+      original work as well.
+
+    * Non-Commercial — You may not use this work for commercial 
+      purposes.
+    * Share Alike — If you alter, transform, or build upon this 
+      work, you may distribute the resulting work only under a 
+      licence identical to this one.
+
+With the understanding that:
+
+    * Waiver — Any of the above conditions can be waived if you get 
+      permission from the copyright holder.
+    * Other Rights — In no way are any of the following rights 
+      affected by the license:
+          o Your fair dealing or fair use rights;
+          o The author's moral rights;
+          o Rights other persons may have either in the work itself 
+            or in how the work is used, such as publicity or privacy rights.
+    * Notice — For any reuse or distribution, you must make clear to 
+      others the licence terms of this work.
+
diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js
index 3190efae3cc3f2c90b0f972f5c1996e12b43c775..35639ef6cc79f460ecc6171e4561beadb4d6ee65 100644
--- a/apps/contacts/js/interface.js
+++ b/apps/contacts/js/interface.js
@@ -113,9 +113,9 @@ Contacts={
 			lazyupdate:function(){
 				//alert('lazyupdate');
 				$('#contacts li').live('inview', function(){
-					if (!$(this).attr('style')) {
+					if (!$(this).find('a').attr('style')) {
 						//alert($(this).data('id') + ' has background: ' + $(this).attr('style'));
-						$(this).css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat');
+						$(this).find('a').css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat');
 					}/* else {
 						alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url'));
 					}*/
@@ -301,9 +301,9 @@ $(document).ready(function(){
 				// bottom part of element is visible
 			} else {
 				// whole part of element is visible
-				if (!$(this).attr('style')) {
+				if (!$(this).find('a').attr('style')) {
 					//alert($(this).data('id') + ' has background: ' + $(this).attr('style'));
-					$(this).css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat');
+					$(this).find('a').css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat');
 				}/* else {
 					alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url'));
 				}*/
diff --git a/apps/contacts/js/jquery.inview.txt b/apps/contacts/js/jquery.inview.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c53dbd1d97c0d0a95d0685936ad961c20cbda173
--- /dev/null
+++ b/apps/contacts/js/jquery.inview.txt
@@ -0,0 +1,15 @@
+jQuery.inview is licensed Attribution-Non-Commercial-Share Alike 2.0 but the
+conditions has been waived by the author in the following tweet:
+
+https://twitter.com/#!/ChristopherBlum/status/148382899887013888 
+
+Saying:
+
+Thomas Tanghus @tanghus 18 Dec. 2011
+
+@ChristopherBlum Hi. Is it OK if I use https://github.com/protonet/jquery.inview in ownCloud? Preferably under an AGPL license ;-) owncloud.org
+
+
+Christopher Blum Christopher Blum @ChristopherBlum 18 Dec. 2011
+
+@tanghus Feel free to! :)
diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php
index 6f2f34225de755d7ba75dd224b65c659b3060ef8..78792f5f9482329f6f22117ee4f49cde1ab9ecce 100644
--- a/apps/contacts/lib/addressbook.php
+++ b/apps/contacts/lib/addressbook.php
@@ -140,6 +140,25 @@ class OC_Contacts_Addressbook{
 		return true;
 	}
 
+	public static function cleanArray($array, $remove_null_number = true){
+		$new_array = array();
+
+		$null_exceptions = array();
+
+		foreach ($array as $key => $value){
+			$value = trim($value);
+
+			if($remove_null_number){
+				$null_exceptions[] = '0';
+			}
+
+			if(!in_array($value, $null_exceptions) && $value != "")	{
+				$new_array[] = $value;
+			}
+		}
+		return $new_array;
+	}
+
 	/**
 	 * @brief Get active addressbooks for a user.
 	 * @param integer $uid User id. If null current user will be used.
@@ -170,8 +189,21 @@ class OC_Contacts_Addressbook{
 	public static function active($uid){
 		$active = self::activeIds($uid);
 		$addressbooks = array();
-		/** FIXME: Is there a way to prepare a statement 'WHERE id IN ([range])'?
-		*/
+		$ids_sql = join(',', array_fill(0, count($active), '?'));
+		$prep = 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id IN ('.$ids_sql.') ORDER BY displayname';
+		try {
+			$stmt = OC_DB::prepare( $prep );
+			$result = $stmt->execute($active);
+		} catch(Exception $e) {
+			OC_Log::write('contacts','OC_Contacts_Addressbook:active:, exception: '.$e->getMessage(),OC_Log::DEBUG);
+			OC_Log::write('contacts','OC_Contacts_Addressbook:active, ids: '.join(',', $active),OC_Log::DEBUG);
+			OC_Log::write('contacts','OC_Contacts_Addressbook::active, SQL:'.$prep,OC_Log::DEBUG);
+		}
+
+		while( $row = $result->fetchRow()){
+			$addressbooks[] = $row;
+		}
+		/*
 		foreach( $active as $aid ){
 			$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ? ORDER BY displayname' );
 			$result = $stmt->execute(array($aid,));
@@ -179,7 +211,7 @@ class OC_Contacts_Addressbook{
 			while( $row = $result->fetchRow()){
 				$addressbooks[] = $row;
 			}
-		}
+		}*/
 
 		return $addressbooks;
 	}
@@ -208,6 +240,7 @@ class OC_Contacts_Addressbook{
 				unset($openaddressbooks[array_search($id, $openaddressbooks)]);
 			}
 		}
+		$openaddressbooks = self::cleanArray($openaddressbooks, false);
 		sort($openaddressbooks, SORT_NUMERIC);
 		// FIXME: I alway end up with a ';' prepending when imploding the array..?
 		OC_Preferences::setValue(OC_User::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks));
@@ -221,7 +254,7 @@ class OC_Contacts_Addressbook{
 	 * @return boolean
 	 */
 	public static function isActive($id){
-		OC_Log::write('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OC_Log::DEBUG);
+		//OC_Log::write('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OC_Log::DEBUG);
 		return in_array($id, self::activeIds());
 	}
 
diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php
index 7285761fd58706ded153162076d2b8d254c1945f..beb291b481e0d3661adb4ebb85434f6380f1d761 100644
--- a/apps/contacts/lib/vcard.php
+++ b/apps/contacts/lib/vcard.php
@@ -47,9 +47,21 @@ class OC_Contacts_VCard{
 	 * ['carddata']
 	 */
 	public static function all($id){
-		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' );
-		$result = $stmt->execute(array($id));
-
+		if(is_array($id)) {
+			$id_sql = join(',', array_fill(0, count($id), '?'));
+			$prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname';
+			try {
+				$stmt = OC_DB::prepare( $prep );
+				$result = $stmt->execute($id);
+			} catch(Exception $e) {
+				OC_Log::write('contacts','OC_Contacts_VCard:all:, exception: '.$e->getMessage(),OC_Log::DEBUG);
+				OC_Log::write('contacts','OC_Contacts_VCard:all, ids: '.join(',', $id),OC_Log::DEBUG);
+				OC_Log::write('contacts','SQL:'.$prep,OC_Log::DEBUG);
+			}
+		} else {
+			$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' );
+			$result = $stmt->execute(array($id));
+		}
 		$cards = array();
 		while( $row = $result->fetchRow()){
 			$cards[] = $row;
diff --git a/core/js/setup.js b/core/js/setup.js
index b765d41ba351a7bac15c4aeee25bd78a2d8fa9fd..94097785e422cae42f16cdd98ca7c8abb1b34d28 100644
--- a/core/js/setup.js
+++ b/core/js/setup.js
@@ -7,7 +7,9 @@ $(document).ready(function() {
 		$('#dbhost').hide();
 		$('#dbhostlabel').hide();
 	}
-
+	$('#adminlogin').change(function(){
+		$('#adminlogin').val($.trim($('#adminlogin').val()));
+	});
 	$('#sqlite').click(function() {
 		$('#use_other_db').slideUp(250);
 		$('#dbhost').hide(250);
diff --git a/lib/filesystem.php b/lib/filesystem.php
index 1205a6aa51b23a536afa9f343e91657a401f14b1..627f494c9379b8651250759956c1ee3c69d45338 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -199,11 +199,26 @@ class OC_Filesystem{
 	*/
 	static public function getLocalFile($path){
 		$parent=substr($path,0,strrpos($path,'/'));
-		if(self::is_readable($parent) and $storage=self::getStorage($path)){
+		if(self::isValidPath($parent) and $storage=self::getStorage($path)){
 			return $storage->getLocalFile(self::getInternalPath($path));
 		}
 	}
 	
+	/**
+	 * check if the requested path is valid
+	 * @param string path
+	 * @return bool
+	 */
+	static public function isValidPath($path){
+		if(substr($path,0,1)!=='/'){
+			$path='/'.$path;
+		}
+		if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
+			return false;
+		}
+		return true;
+	}
+	
 	static public function mkdir($path){
 		return self::basicOperation('mkdir',$path,array('create','write'));
 	}
@@ -238,24 +253,10 @@ class OC_Filesystem{
 		return self::basicOperation('readfile',$path,array('read'));
 	}
 	static public function is_readable($path){
-		if(substr($path,0,1)!=='/'){
-			$path='/'.$path;
-		}
-		if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
-			return false;
-		}
-		$storage=self::getStorage($path);
-		return $storage->is_readable(self::getInternalPath($path));
+		return self::basicOperation('is_readable',$path);
 	}
 	static public function is_writeable($path){
-		if(substr($path,0,1)!=='/'){
-			$path='/'.$path;
-		}
-		if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
-			return false;
-		}
-		$storage=self::getStorage($path);
-		return $storage->is_writeable(self::getInternalPath($path));
+		return self::basicOperation('is_writeable',$path);
 	}
 	static public function file_exists($path){
 		if($path=='/'){
@@ -358,7 +359,7 @@ class OC_Filesystem{
 		return self::basicOperation('fopen',$path,$hooks,$mode);
 	}
 	static public function toTmpFile($path){
-		if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::is_readable($path) and $storage=self::getStorage($path)){
+		if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::isValidPath($path) and $storage=self::getStorage($path)){
 			OC_Hook::emit( 'OC_Filesystem', 'read', array( 'path' => $path));
 			return $storage->toTmpFile(self::getInternalPath($path));
 		}
@@ -447,7 +448,7 @@ class OC_Filesystem{
 	 * @return mixed
 	 */
 	private static function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
-		if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::is_readable($path) and $storage=self::getStorage($path)){
+		if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::isValidPath($path) and $storage=self::getStorage($path)){
 			$interalPath=self::getInternalPath($path);
 			$run=true;
 			foreach($hooks as $hook){
diff --git a/lib/image.php b/lib/image.php
new file mode 100644
index 0000000000000000000000000000000000000000..e09486be0817e9b22105876f8d9ebe80d146b20a
--- /dev/null
+++ b/lib/image.php
@@ -0,0 +1,474 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2011 Thomas Tanghus <thomas@tanghus.net>
+*
+* 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/>.
+*
+*/
+
+/** From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php
+ * Don't know if it can come in handy?
+if ( ! function_exists( 'exif_imagetype' ) ) {
+    function exif_imagetype ( $filename ) {
+        if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) {
+            return $type;
+        }
+    return false;
+    }
+}
+*/
+
+function ellipsis($str, $maxlen) {
+	if (strlen($str) > $maxlen) {
+		$characters = floor($maxlen / 2);
+		return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters);
+	}
+	return $str;
+}
+
+/**
+ * Class for image manipulation
+ * Ideas: imagerotate, chunk_split(base64_encode())
+ *
+ */
+class OC_Image {
+	static private $resource = false; // tmp resource.
+	static private $destroy = false; // if the resource is created withing the object.
+	static private $imagetype = IMAGETYPE_PNG; // Default to png if file type isn't evident.
+	static private $filepath = null;
+	/**
+	* @brief Constructor.
+	* @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
+	*					If a resource is passed it is the job of the caller to destroy it using imagedestroy($var)
+	* @returns bool False on error
+	*/
+	function __construct($imageref = null) {
+		//OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG);
+		if(!extension_loaded('gd') || !function_exists('gd_info')) {
+		//if(!function_exists('imagecreatefromjpeg')) {
+			OC_Log::write('core','OC_Image::__construct, GD module not installed', OC_Log::ERROR);
+			return false;
+		}
+		if(!is_null($imageref)) {
+			self::load($imageref);
+		}
+	}
+
+	/**
+	* @brief Destructor.
+	*/
+	function __destruct() {
+		if(is_resource(self::$resource) && self::$destroy) {
+			imagedestroy(self::$resource); // Why does this issue a warning.
+		}
+	}
+
+	/**
+	* @brief Determine whether the object contains an image resource.
+	* @returns bool
+	*/
+	public function valid() { // apparently you can't name a method 'empty'...
+		$ret = is_resource(self::$resource);
+		return $ret;
+	}
+
+	/**
+	* @brief Returns the MIME type of the image or an empty string if no image is loaded.
+	* @returns int
+	*/
+	public function mimeType() {
+		return is_resource(self::$resource) ? image_type_to_mime_type(self::$imagetype) : '';
+	}
+
+	/**
+	* @brief Returns the width of the image or -1 if no image is loaded.
+	* @returns int
+	*/
+	public function width() {
+		return is_resource(self::$resource) ? imagesx(self::$resource) : -1;
+	}
+
+	/**
+	* @brief Returns the height of the image or -1 if no image is loaded.
+	* @returns int
+	*/
+	public function height() {
+		return is_resource(self::$resource) ? imagesy(self::$resource) : -1;
+	}
+
+	/**
+	* @brief Outputs the image.
+	* @returns bool
+	*/
+	public function show() {
+		return $this->_output();
+	}
+
+	/**
+	* @brief Saves the image.
+	* @returns bool
+	*/
+
+	public function save($filepath=null) {
+		if($filepath === null && $this->filepath === null) {
+			OC_Log::write('core','OC_Image::save. save() called with no path.', OC_Log::ERROR);
+			return false;
+		} elseif($filepath === null && $this->filepath !== null) {
+			$filepath = $this->filepath;
+		}
+		return $this->_output($filepath, true);
+	}
+
+	/**
+	* @brief Outputs/saves the image.
+	*/
+	private function _output($filepath=null, $really=false) {
+		header('Content-Type: '.self::mimeType());
+		if($really === false) {
+			$filepath = null; // Just being cautious ;-)
+		} else {
+			if(!is_writable(dirname($filepath))) {
+				OC_Log::write('core','OC_Image::save. Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
+				return false;
+			} elseif(is_writable(dirname($filepath)) && !is_writable($filepath)) {
+				OC_Log::write('core','OC_Image::save. File \''.$filepath.'\' is not writable.', OC_Log::ERROR);
+				return false;
+			}
+		}
+		$retval = false;
+		switch(self::$imagetype) {
+			case IMAGETYPE_GIF:
+				$retval = imagegif(self::$resource, $filepath);
+				break;
+			case IMAGETYPE_JPEG:
+				$retval = imagejpeg(self::$resource, $filepath);
+				break;
+			case IMAGETYPE_PNG:
+				$retval = imagepng(self::$resource, $filepath);
+				break;
+			case IMAGETYPE_XBM:
+				$retval = imagexbm(self::$resource, $filepath);
+				break;
+			case IMAGETYPE_WBMP:
+			case IMAGETYPE_BMP:
+				$retval = imagewbmp(self::$resource, $filepath);
+				break;
+			default:
+				$retval = imagepng(self::$resource, $filepath);
+		}
+		return $retval;
+	}
+
+	/**
+	* @brief Prints the image when called as $image().
+	*/
+	public function __invoke() {
+		return self::show();
+	}
+
+	/**
+	* @returns Returns the image resource in any.
+	*/
+	public function resource() {
+		return self::$resource;
+	}
+
+	/**
+	* @returns Returns a base64 encoded string suitable for embedding in a VCard.
+	*/
+	function __toString() {
+		ob_start();
+		$res = imagepng(self::$resource);
+		if (!$res) {
+			OC_Log::write('core','OC_Image::_string. Error writing image',OC_Log::ERROR);
+		}
+		return chunk_split(base64_encode(ob_get_clean()));
+	}
+
+	/**
+	* @brief Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function.
+	* @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
+	*					If a resource is passed it is the job of the caller to destroy it using imagedestroy($var)
+	* @returns An image resource or false on error
+	*/
+	public function load($imageref) {
+		if(self::loadFromFile($imageref) !== false) {
+			return self::$resource;
+		} elseif(self::loadFromBase64($imageref) !== false) {
+			return self::$resource;
+		} elseif(self::loadFromData($imageref) !== false) {
+			return self::$resource;
+		} elseif(self::loadFromResource($imageref) !== false) {
+			return self::$resource;
+		} else {
+			OC_Log::write('core','OC_Image::load, couldn\'t load anything. Giving up!', OC_Log::DEBUG);
+			return false;
+		}
+	}
+
+	/**
+	* @brief Loads an image from a local file.
+	* @param $imageref The path to a local file.
+	* @returns An image resource or false on error
+	*/
+	public function loadFromFile($imagepath=false) {
+		if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) {
+			// Debug output disabled because this method is tried before loadFromBase64?
+			OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load: '.ellipsis($imagepath, 50), OC_Log::DEBUG);
+			return false;
+		}
+		$itype = exif_imagetype($imagepath);
+		switch($itype) {
+			case IMAGETYPE_GIF:
+				if (imagetypes() & IMG_GIF) {
+					self::$resource = imagecreatefromgif($imagepath);
+				} else {
+					OC_Log::write('core','OC_Image::loadFromFile, GIF images not supported: '.$imagepath, OC_Log::DEBUG);
+				}
+				break;
+			case IMAGETYPE_JPEG:
+				if (imagetypes() & IMG_JPG) {
+					self::$resource = imagecreatefromjpeg($imagepath);
+				} else {
+					OC_Log::write('core','OC_Image::loadFromFile, JPG images not supported: '.$imagepath, OC_Log::DEBUG);
+				}
+				break;
+			case IMAGETYPE_PNG:
+				if (imagetypes() & IMG_PNG) {
+					self::$resource = imagecreatefrompng($imagepath);
+				} else {
+					OC_Log::write('core','OC_Image::loadFromFile, PNG images not supported: '.$imagepath, OC_Log::DEBUG);
+				}
+				break;
+			case IMAGETYPE_XBM:
+				if (imagetypes() & IMG_XPM) {
+					self::$resource = imagecreatefromxbm($imagepath);
+				} else {
+					OC_Log::write('core','OC_Image::loadFromFile, XBM/XPM images not supported: '.$imagepath, OC_Log::DEBUG);
+				}
+				break;
+			case IMAGETYPE_WBMP:
+			case IMAGETYPE_BMP:
+				if (imagetypes() & IMG_WBMP) {
+					self::$resource = imagecreatefromwbmp($imagepath);
+				} else {
+					OC_Log::write('core','OC_Image::loadFromFile, (W)BMP images not supported: '.$imagepath, OC_Log::DEBUG);
+				}
+				break;
+			/*
+			case IMAGETYPE_TIFF_II: // (intel byte order)
+				break;
+			case IMAGETYPE_TIFF_MM: // (motorola byte order)
+				break;
+			case IMAGETYPE_JPC:
+				break;
+			case IMAGETYPE_JP2:
+				break;
+			case IMAGETYPE_JPX:
+				break;
+			case IMAGETYPE_JB2:
+				break;
+			case IMAGETYPE_SWC:
+				break;
+			case IMAGETYPE_IFF:
+				break;
+			case IMAGETYPE_ICO:
+				break;
+			case IMAGETYPE_SWF:
+				break;
+			case IMAGETYPE_PSD:
+				break;
+			*/
+			default:
+				self::$resource = imagecreatefromstring(file_get_contents($imagepath));
+				$itype = IMAGETYPE_PNG;
+				OC_Log::write('core','OC_Image::loadFromFile, Default', OC_Log::DEBUG);
+				break;
+		}
+		if($this->valid()) {
+			self::$imagetype = $itype;
+			self::$filepath = $imagepath;
+			self::$destroy = true;
+		}
+		return self::$resource;
+	}
+
+	/**
+	* @brief Loads an image from a string of data.
+	* @param $str A string of image data as read from a file.
+	* @returns An image resource or false on error
+	*/
+	public function loadFromData($str) {
+		if(is_resource($str)) {
+			return false;
+		}
+		self::$resource = imagecreatefromstring($str);
+		if(!self::$resource) {
+			OC_Log::write('core','OC_Image::loadFromData, couldn\'t load', OC_Log::DEBUG);
+			return false;
+		}
+		self::$destroy = true;
+		return self::$resource;
+	}
+
+	/**
+	* @brief Loads an image from a base64 encoded string.
+	* @param $str A string base64 encoded string of image data.
+	* @returns An image resource or false on error
+	*/
+	public function loadFromBase64($str) {
+		if(!is_string($str)) {
+			return false;
+		}
+		$data = base64_decode($str);
+		if($data) { // try to load from string data
+			self::$resource = imagecreatefromstring($data);
+			if(!self::$resource) {
+				OC_Log::write('core','OC_Image::loadFromBase64, couldn\'t load', OC_Log::DEBUG);
+				return false;
+			}
+			self::$destroy = true;
+			return self::$resource;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	* @brief Checks if image resource is valid and assigns it to self::$resource.
+	* @param $res An image resource.
+	* @returns An image resource or false on error
+	*/
+	public function loadFromResource($res) {
+		if(!is_resource($res)) {
+			return false;
+		}
+		self::$resource = $res;
+	}
+
+	/**
+	* @brief Resizes the image preserving ratio.
+	* @param $maxsize The maximum size of either the width or height.
+	* @returns bool
+	*/
+	public function resize($maxsize) {
+		if(!self::$resource) {
+			OC_Log::write('core','OC_Image::resize, No image loaded', OC_Log::ERROR);
+			return false;
+		}
+		$width_orig=imageSX(self::$resource);
+		$height_orig=imageSY(self::$resource);
+		$ratio_orig = $width_orig/$height_orig;
+		
+		if ($ratio_orig > 1) {
+			$new_height = round($maxsize/$ratio_orig);
+			$new_width = $maxsize;
+		} else {
+			$new_width = round($maxsize*$ratio_orig);
+			$new_height = $maxsize;
+		}
+
+		$process = imagecreatetruecolor(round($new_width), round($new_height));
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::resize. Error creating true color image',OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+
+		imagecopyresampled($process, self::$resource, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::resize. Error resampling process image '.$new_width.'x'.$new_height,OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		self::$resource = $process;
+		return true;
+	}
+
+	/**
+	* @brief Crops the image to the middle square. If the image is already square it just returns.
+	* @returns bool for success or failure
+	*/
+	public function centerCrop() {
+		if(!self::$resource) {
+			OC_Log::write('core','OC_Image::centerCrop, No image loaded', OC_Log::ERROR);
+			return false;
+		}
+		$width_orig=imageSX(self::$resource);
+		$height_orig=imageSY(self::$resource);
+		if($width_orig === $height_orig) {
+			return true;
+		}
+		$ratio_orig = $width_orig/$height_orig;
+		$width = $height = min($width_orig, $height_orig);
+
+		if ($ratio_orig > 1) {
+			$x = ($width_orig/2) - ($width/2);
+			$y = 0;
+		} else {
+			$y = ($height_orig/2) - ($height/2);
+			$x = 0;
+		}
+		$process = imagecreatetruecolor($width, $height);
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::centerCrop. Error creating true color image',OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $width, $height, $width, $height);
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::centerCrop. Error resampling process image '.$width.'x'.$height,OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		self::$resource = $process;
+		return true;
+	}
+
+	/**
+	* @brief Crops the image from point $x$y with dimension $wx$h.
+	* @param $x Horizontal position
+	* @param $y Vertical position
+	* @param $w Width
+	* @param $h Hight
+	* @returns bool for success or failure
+	*/
+	public function crop($x, $y, $w, $h) {
+		if(!self::$resource) {
+			OC_Log::write('core','OC_Image::crop, No image loaded', OC_Log::ERROR);
+			return false;
+		}
+		$width_orig=imageSX(self::$resource);
+		$height_orig=imageSY(self::$resource);
+		//OC_Log::write('core','OC_Image::crop. Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG);
+		$process = imagecreatetruecolor($w, $h);
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::crop. Error creating true color image',OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $w, $h, $w, $h);
+		if ($process == false) {
+			OC_Log::write('core','OC_Image::crop. Error resampling process image '.$w.'x'.$h,OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		self::$resource = $process;
+		return true;
+	}
+}
diff --git a/lib/setup.php b/lib/setup.php
index 8afe0070e9bdc7ed0f9bcd68a113ab94695dd5a1..b53c626c9a723fd6fa80470b5328990c307038cb 100644
--- a/lib/setup.php
+++ b/lib/setup.php
@@ -275,7 +275,7 @@ class OC_Setup {
 		$content.= "php_value post_max_size 512M\n";
 		$content.= "SetEnv htaccessWorking true\n";
 		$content.= "</IfModule>\n";
-		$content.= "<IfModule !mod_php5.c>\n";
+		$content.= "<IfModule mod_rewrite.c>";
 		$content.= "RewriteEngine on\n";
 		$content.= "RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]\n";
 		$content.= "</IfModule>\n";
diff --git a/lib/user.php b/lib/user.php
index 241d9aa8b1042c158b1829b307ff92e95a88768a..0a5881ec0f82c63d7ae73deca5d87e6aa6868674 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -120,7 +120,7 @@ class OC_User {
 			return false;
 		}
 		// No empty username
-		if( !$uid ){
+		if(trim($uid) == ''){
 			return false;
 		}
 		// Check if user already exists
diff --git a/settings/js/users.js b/settings/js/users.js
index 4fea52e4a1f38de0f552f774c9138b3d1ccb640c..79b4e80870a7065124825501dbccc8b84e4fba9f 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -126,7 +126,7 @@ $(document).ready(function(){
 	$('#newuser').submit(function(event){
 		event.preventDefault();
 		var username=$('#newusername').val();
-		if(username == '') {
+		if($.trim(username) == '') {
 			alert('Please provide a username!');
 			return false;
 		}