diff --git a/apps/contacts/appinfo/app.php b/apps/contacts/appinfo/app.php
new file mode 100644
index 0000000000000000000000000000000000000000..f38a45f2790c2286e3f38e162436b38a4c0e1b08
--- /dev/null
+++ b/apps/contacts/appinfo/app.php
@@ -0,0 +1,18 @@
+<?php
+
+OC::$CLASSPATH['OC_Contacts_Addressbook'] = 'apps/contacts/lib/addressbook.php';
+OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php';
+
+OC_App::register( array( 
+  'order' => 10,
+  'id' => 'contacts',
+  'name' => 'Contacts' ));
+
+OC_App::addNavigationEntry( array( 
+  'id' => 'contacts_index',
+  'order' => 10,
+  'href' => OC_Helper::linkTo( 'contacts', 'index.php' ),
+  'icon' => OC_Helper::imagePath( 'contacts', 'icon.png' ),
+  'name' => 'Addressbook' ));
+
+?>
diff --git a/apps/contacts/appinfo/info.xml b/apps/contacts/appinfo/info.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93463b9cf090cd418e9982f6a7b5b03292534645
--- /dev/null
+++ b/apps/contacts/appinfo/info.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?> 
+<info>
+	<id>contacts</id>
+	<name>Contacts</name>
+	<version>0.1</version>
+	<licence>AGPL</licence>
+	<author>Jakob Sack</author>
+	<require>2</require>
+</info>
diff --git a/apps/contacts/carddav.php b/apps/contacts/carddav.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae2c5b973635e091c290bf002513f356f1eefb58
--- /dev/null
+++ b/apps/contacts/carddav.php
@@ -0,0 +1,28 @@
+<?php
+
+// Do not load FS ...
+$RUNTIME_NOSETUPFS = true;
+
+require_once('../../lib/base.php');
+
+// Backends
+$authBackend = new OC_Connector_Sabre_Auth();
+$principalBackend = new OC_Connector_Sabre_Principal();
+$carddavBackend   = new OC_Connector_Sabre_CardDAV();
+
+// Root nodes
+$nodes = array(
+    new Sabre_DAVACL_PrincipalCollection($principalBackend),
+    new Sabre_CardDAV_AddressBookRoot($principalBackend, $carddavBackend),
+);
+
+// Fire up server
+$server = new Sabre_DAV_Server($nodes);
+$server->setBaseUri($WEBROOT.'/apps/contacts/carddav.php');
+// Add plugins
+$server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'));
+$server->addPlugin(new Sabre_CardDAV_Plugin());
+$server->addPlugin(new Sabre_DAVACL_Plugin());
+
+// And off we go!
+$server->exec();
diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..8d1c8b69c3fce7bea45c73efd06983e3c419a92f
--- /dev/null
+++ b/apps/contacts/css/styles.css
@@ -0,0 +1 @@
+ 
diff --git a/apps/contacts/details.php b/apps/contacts/details.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ab1b64de243ca5117adea203b0d7212296583ba
--- /dev/null
+++ b/apps/contacts/details.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * ownCloud - Addressbook
+ *
+ * @author Jakob Sack
+ * @copyright 2011 Jakob Sack mail@jakobsack.de
+ *
+ * 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/>.
+ *
+ */
+
+// Init owncloud
+require_once('../../lib/base.php');
+
+$id = $_GET['id'];
+
+$l10n = new OC_L10N('contacts');
+
+// Check if we are a user
+if( !OC_User::isLoggedIn()){
+	echo $l10n->t('You need to log in!');
+	exit();
+}
+
+
+$card = OC_Contacts_Addressbook::findCard( $id );
+if( $card === false ){
+	echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Can not find Contact!'))));
+	exit();
+}
+
+$addressbook = OC_Contacts_Addressbook::findAddressbook( $card['addressbookid'] );
+if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){
+	echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('This is not your contact!'))));
+	exit();
+}
+
+$vcard = Sabre_VObject_Reader::read($card['carddata']);
+$details = OC_Contacts_Addressbook::structureContact($vcard);
+
+$tmpl = new OC_Template('contacts','_details');
+$tmpl->assign('details',$details);
+$tmpl->assign('id',$id);
+$page = $tmpl->fetchPage();
+
+echo json_encode( array( 'status' => 'success', 'data' => array( 'page' => $page )));
diff --git a/apps/contacts/img/icon.png b/apps/contacts/img/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea2ed9e3335ea5be11896d705b6afaf92a691695
Binary files /dev/null and b/apps/contacts/img/icon.png differ
diff --git a/apps/contacts/index.php b/apps/contacts/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d5bcefd875a14ac8462885248fe026ba8736610
--- /dev/null
+++ b/apps/contacts/index.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * ownCloud - Addressbook
+ *
+ * @author Jakob Sack
+ * @copyright 2011 Jakob Sack mail@jakobsack.de
+ *
+ * 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/>.
+ *
+ */
+
+function contactsort($a,$b){
+	return strcmp($a['name'],$b['name']);
+}
+
+// Init owncloud
+require_once('../../lib/base.php');
+
+// Check if we are a user
+if( !OC_User::isLoggedIn()){
+	header( 'Location: '.OC_Helper::linkTo( '', 'index.php' ));
+	exit();
+}
+
+// Load the files we need
+OC_App::setActiveNavigationEntry( 'contacts_index' );
+
+// Load a specific user?
+$id = isset( $_GET['id'] ) ? $_GET['id'] : null;
+
+// Addressbooks to load
+$openaddressbooks = explode(';',OC_Preferences::getValue(OC_User::getUser(),'contacts','openaddressbooks',null));
+
+$contacts = array();
+foreach( $openaddressbooks as $addressbook ){
+	$addressbookcontacts = OC_Contacts_Addressbook::allCards($addressbook);
+	foreach( $addressbookcontacts as $contact ){
+		$contacts[] = array( 'name' => $contact['fullname'], 'id' => $contact['id'] );
+	}
+}
+
+
+usort($contacts,'contactsort');
+$details = array();
+
+if( !is_null($id) || count($contacts)){
+	$contact = OC_Contacts_Addressbook::findCard(is_null($id)?$contacts[0]['id']:$id);
+	$vcard = Sabre_VObject_Reader::read($contact['carddata']);
+	$details = OC_Contacts_Addressbook::structureContact($vcard);
+}
+
+// Process the template
+$tmpl = new OC_Template( 'contacts', 'index', 'user' );
+$tmpl->assign('contacts', $contacts);
+$tmpl->assign('details', $details );
+$tmpl->assign('id',$id);
+$tmpl->printPage();
diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js
new file mode 100644
index 0000000000000000000000000000000000000000..045562b496f190a9462b5f3c6a8590f336d5f145
--- /dev/null
+++ b/apps/contacts/js/interface.js
@@ -0,0 +1,14 @@
+$(document).ready(function(){
+	$('.contacts_contacts').find('li').live('click',function(){
+		var id = $(this).attr('x-id');
+		$.getJSON('details.php',{'id':id},function(jsondata){
+			if(jsondata.status == 'success'){
+				$('.contacts_details').html(jsondata.data.page);
+			}
+			else{
+				alert(jsondata.data.message);
+			}
+		});
+		return false;
+	});
+});
diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0f26c7df55f2a2511f324cf2acb54dab28d9ae8
--- /dev/null
+++ b/apps/contacts/lib/addressbook.php
@@ -0,0 +1,287 @@
+<?php
+/**
+ * ownCloud - Addressbook
+ *
+ * @author Jakob Sack
+ * @copyright 2011 Jakob Sack mail@jakobsack.de
+ *
+ * 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/>.
+ *
+ */
+/*
+ *
+ * The following SQL statement is just a help for developers and will not be
+ * executed!
+ *
+ * CREATE TABLE contacts_addressbooks (
+ * id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ * userid VARCHAR(255) NOT NULL,
+ * displayname VARCHAR(255),
+ * uri VARCHAR(100),
+ * description TEXT,
+ * ctag INT(11) UNSIGNED NOT NULL DEFAULT '1'
+ * );
+ * 
+ * CREATE TABLE contacts_cards (
+ * id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ * addressbookid INT(11) UNSIGNED NOT NULL,
+ * fullname VARCHAR(255),
+ * carddata TEXT,
+ * uri VARCHAR(100),
+ * lastmodified INT(11) UNSIGNED
+ * );
+ */
+
+/**
+ * This class manages our addressbooks.
+ */
+class OC_Contacts_Addressbook{
+	public static function allAddressbooks($uid){
+		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ?' );
+		$result = $stmt->execute(array($uid));
+		
+		$addressbooks = array();
+		while( $row = $result->fetchRow()){
+			$addressbooks[] = $row;
+		}
+
+		return $addressbooks;
+	}
+	
+	public static function allAddressbooksWherePrincipalURIIs($principaluri){
+		$uid = self::extractUserID($principaluri);
+		return self::allAddressbooks($uid);
+	}
+
+	public static function findAddressbook($id){
+		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
+		$result = $stmt->execute(array($id));
+
+		return $result->fetchRow();
+	}
+
+	public static function addAddressbook($userid,$name,$description){
+		$all = self::allAddressbooks($userid);
+		$uris = array();
+		foreach($all as $i){
+			$uris[] = $i['uri'];
+		}
+
+		$uri = self::createURI('name', $uris );
+
+		$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_addressbooks (userid,displayname,uri,description,ctag) VALUES(?,?,?,?,?)' );
+		$result = $stmt->execute(array($userid,$name,$uri,$description,1));
+
+		return OC_DB::insertid();
+	}
+
+	public static function addAddressbookFromDAVData($principaluri,$uri,$name,$description){
+		$userid = self::extractUserID($principaluri);
+		
+		$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_addressbooks (userid,displayname,uri,description,ctag) VALUES(?,?,?,?,?)' );
+		$result = $stmt->execute(array($userid,$name,$uri,$description,1));
+
+		return OC_DB::insertid();
+	}
+
+	public static function editAddressbook($id,$name,$description){
+		// Need these ones for checking uri
+		$addressbook = self::find($id);
+
+		if(is_null($name)){
+			$name = $addressbook['name'];
+		}
+		if(is_null($description)){
+			$description = $addressbook['description'];
+		}
+		
+		$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET displayname=?,description=?, ctag=ctag+1 WHERE id=?' );
+		$result = $stmt->execute(array($name,$description,$id));
+
+		return true;
+	}
+
+	public static function touchAddressbook($id){
+		$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET ctag = ctag + 1 WHERE id = ?' );
+		$stmt->execute(array($id));
+
+		return true;
+	}
+
+	public static function deleteAddressbook($id){
+		$stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE id = ?' );
+		$stmt->execute(array($id));
+		
+		$stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE addressbookid = ?' );
+		$stmt->execute(array($id));
+
+		return true;
+	}
+
+	public static function allCards($id){
+		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ?' );
+		$result = $stmt->execute(array($id));
+
+		$addressbooks = array();
+		while( $row = $result->fetchRow()){
+			$addressbooks[] = $row;
+		}
+
+		return $addressbooks;
+	}
+	
+	public static function findCard($id){
+		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE id = ?' );
+		$result = $stmt->execute(array($id));
+
+		return $result->fetchRow();
+	}
+
+	public static function findCardWhereDAVDataIs($aid,$uri){
+		$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri = ?' );
+		$result = $stmt->execute(array($aid,$uri));
+
+		return $result->fetchRow();
+	}
+
+	public static function addCard($id,$data){
+		$fn = null;
+		$uri = null;
+		$card = Sabre_VObject_Reader::read($data);
+		foreach($card->children as $property){
+			if($property->name == 'FN'){
+				$fn = $property->value;
+			}
+			elseif(is_null($uri) && $property->name == 'UID' ){
+				$uri = $property->value.'.vcf';
+			}
+		}
+		$uri = self::createUID().'.vcf';
+
+		$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
+		$result = $stmt->execute(array($id,$fn,$data,$uri,time()));
+
+		self::touch($id);
+
+		return OC_DB::insertid;
+	}
+
+	public static function addCardFromDAVData($id,$uri,$data){
+		$fn = null;
+		$card = Sabre_VObject_Reader::read($data);
+		foreach($card->children as $property){
+			if($property->name == 'FN'){
+				$fn = $property->value;
+			}
+		}
+
+		$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
+		$result = $stmt->execute(array($id,$fn,$data,$uri,time()));
+
+		self::touch($id);
+
+		return OC_DB::insertid;
+	}
+
+	public static function editCard($id, $data){
+		$oldcard = self::findCard($id,$aid,$uri);
+		$fn = null;
+		$card = Sabre_VObject_Reader::read($data);
+		foreach($card->children as $property){
+			if($property->name == 'FN'){
+				$fn = $property->value;
+			}
+		}
+
+		$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
+		$result = $stmt->execute(array($fn,$data,time(),$id));
+
+		self::touch($oldcard['addressbookid']);
+
+		return true;
+	}
+
+	public static function editCardFromDAVData($aid,$uri,$data){
+		$oldcard = self::findCardWhereDAVDataIs($aid,$uri);
+
+		$fn = null;
+		$card = Sabre_VObject_Reader::read($data);
+		foreach($card->children as $property){
+			if($property->name == 'FN'){
+				$fn = $property->value;
+			}
+		}
+
+		$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
+		$result = $stmt->execute(array($fn,$data,time(),$oldcard['id']));
+
+		self::touch($oldcard['addressbookid']);
+
+		return true;
+	}
+	
+	public static function deleteCard($id){
+		$stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
+		$stmt->execute(array($id));
+
+		return true;
+	}
+
+	public static function deleteCardFromDAVData($aid,$uri){
+		$stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE addressbookid = ? AND uri=?' );
+		$stmt->execute(array($aid,$uri));
+
+		return true;
+	}
+	
+	public static function createURI($name,$existing){
+		$name = strtolower($name);
+		$newname = $name;
+		$i = 1;
+		while(in_array($newname,$existing)){
+			$newname = $name.$i;
+			$i = $i + 1;
+		}
+		return $newname;
+	}
+
+	public static function createUID(){
+		return substr(md5(rand().time()),0,10);
+	}
+	
+	public static function extractUserID($principaluri){
+		list($prefix,$userid) = Sabre_DAV_URLUtil::splitPath($principaluri);
+		return $userid;
+	}
+
+	public static function structureContact($object){
+		$details = array();
+		foreach($object->children as $property){
+			$temp = array(
+				'name' => $property->name,
+				'value' => ($property->name == 'PHOTO' || $property->name == 'LOGO' ? null : $property->value ),
+				'parameters' => array());
+			foreach($property->parameters as $parameter){
+				$temp['parameters'][] = array( 'name' => $parameter->name, 'value' => $parameter->value);
+			}
+			if(array_key_exists($property->name,$details)){
+				$details[$property->name][] = $temp;
+			}
+			else{
+				$details[$property->name] = array($temp);
+			}
+		}
+		return $details;
+	}
+}
diff --git a/apps/contacts/lib/connector_sabre.php b/apps/contacts/lib/connector_sabre.php
new file mode 100644
index 0000000000000000000000000000000000000000..98e2598b3a75cd8e7d889c545762fcdb47e9f070
--- /dev/null
+++ b/apps/contacts/lib/connector_sabre.php
@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * PDO CardDAV backend
+ * 
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/) 
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+/**
+ * This CardDAV backend uses PDO to store addressbooks
+ */
+class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
+	/**
+	 * Returns the list of addressbooks for a specific user.
+	 *
+	 * @param string $principaluri
+	 * @return array
+	 */
+	public function getAddressBooksForUser($principaluri) {
+		$data = OC_Contacts_Addressbook::allAddressbooksWherePrincipalURIIs($principaluri);
+		$addressbooks = array();
+		
+		foreach($data as $i) {
+			$addressbooks[] = array(
+				'id'  => $i['id'],
+				'uri' => $i['uri'],
+				'principaluri' => 'principals/'.$i['userid'],
+				'{DAV:}displayname' => $i['displayname'],
+				'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $i['description'],
+				'{http://calendarserver.org/ns/}getctag' => $i['ctag'],
+			);
+		}
+
+		return $addressbooks;
+	}
+
+
+	/**
+	 * Updates an addressbook's properties
+	 *
+	 * See Sabre_DAV_IProperties for a description of the mutations array, as
+	 * well as the return value.
+	 *
+	 * @param mixed $addressbookid
+	 * @param array $mutations
+	 * @see Sabre_DAV_IProperties::updateProperties
+	 * @return bool|array
+	 */
+	public function updateAddressBook($addressbookid, array $mutations) {
+		$name = null;
+		$description = null;
+
+		foreach($mutations as $property=>$newvalue) {
+			switch($property) {
+				case '{DAV:}displayname' :
+					$name = $newvalue;
+					break;
+				case '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' :
+					$description = $newvalue;
+					break;
+				default :
+					// If any unsupported values were being updated, we must
+					// let the entire request fail.
+					return false;
+			}
+		}
+
+		OC_Contacts_Addressbook::editAddressbook($addressbookid,$name,$description);
+
+		return true;
+
+	}
+
+	/**
+	 * Creates a new address book
+	 *
+	 * @param string $principaluri
+	 * @param string $url Just the 'basename' of the url.
+	 * @param array $properties
+	 * @return void
+	 */
+	public function createAddressBook($principaluri, $url, array $properties) {
+
+		$displayname = null;
+		$description = null;
+
+		foreach($properties as $property=>$newvalue) {
+
+			switch($property) {
+				case '{DAV:}displayname' :
+					$displayname = $newvalue;
+					break;
+				case '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' :
+					$description = $newvalue;
+					break;
+				default :
+					throw new Sabre_DAV_Exception_BadRequest('Unknown property: ' . $property);
+			}
+
+		}
+
+		OC_Contacts_Addressbook::addAddressbookFromDAVData($principaluri,$url,$name,$description);
+	}
+
+	/**
+	 * Deletes an entire addressbook and all its contents
+	 *
+	 * @param int $addressbookid
+	 * @return void
+	 */
+	public function deleteAddressBook($addressbookid) {
+		OC_Contacts_Addressbook::deleteAddressbook($addressbookid);
+	}
+
+	/**
+	 * Returns all cards for a specific addressbook id.
+	 *
+	 * @param mixed $addressbookid
+	 * @return array
+	 */
+	public function getCards($addressbookid) {
+		$data = OC_Contacts_Addressbook::allCards($addressbookid);
+		$cards = array();
+		foreach($data as $i){
+			$cards[] = array(
+				'id' => $i['id'],
+				'carddata' => $i['carddata'],
+				'uri' => $i['uri'],
+				'lastmodified' => $i['lastmodified'] );
+		}
+
+		return $cards;
+	}
+	
+	/**
+	 * Returns a specfic card
+	 *
+	 * @param mixed $addressbookid
+	 * @param string $carduri
+	 * @return array
+	 */
+	public function getCard($addressbookid, $carduri) {
+		return OC_Contacts_Addressbook::findCardWhereDAVDataIs($addressbookid,$carduri);
+
+	}
+
+	/**
+	 * Creates a new card
+	 *
+	 * @param mixed $addressbookid
+	 * @param string $carduri
+	 * @param string $carddata
+	 * @return bool
+	 */
+	public function createCard($addressbookid, $carduri, $carddata) {
+		OC_Contacts_Addressbook::addCardFromDAVData($addressbookid, $carduri, $carddata);
+		return true;
+	}
+
+	/**
+	 * Updates a card
+	 *
+	 * @param mixed $addressbookid
+	 * @param string $carduri
+	 * @param string $carddata
+	 * @return bool
+	 */
+	public function updateCard($addressbookid, $carduri, $carddata) {
+		return OC_Contacts_Addressbook::editCardFromDAVData($addressbookid, $carduri, $carddata);
+	}
+
+	/**
+	 * Deletes a card
+	 *
+	 * @param mixed $addressbookid
+	 * @param string $carduri
+	 * @return bool
+	 */
+	public function deleteCard($addressbookid, $carduri) {
+		return OC_Contacts_Addressbook::deleteCardFromDAVData($addressbookid, $carduri);
+	}
+}
diff --git a/apps/contacts/photo.php b/apps/contacts/photo.php
new file mode 100644
index 0000000000000000000000000000000000000000..62386421cdcff836cefe5c2464409ae7c6e7b2db
--- /dev/null
+++ b/apps/contacts/photo.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * ownCloud - Addressbook
+ *
+ * @author Jakob Sack
+ * @copyright 2011 Jakob Sack mail@jakobsack.de
+ *
+ * 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/>.
+ *
+ */
+
+// Init owncloud
+require_once('../../lib/base.php');
+
+$id = $_GET['id'];
+
+$l10n = new OC_L10N('contacts');
+
+// Check if we are a user
+if( !OC_User::isLoggedIn()){
+	echo $l10n->t('You need to log in!');
+	exit();
+}
+
+
+$card = OC_Contacts_Addressbook::findCard( $id );
+if( $card === false ){
+	echo $l10n->t('Can not find Contact!');
+	exit();
+}
+
+$addressbook = OC_Contacts_Addressbook::findAddressbook( $card['addressbookid'] );
+if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){
+	echo $l10n->t('This is not your contact!');
+	exit();
+}
+
+$content = Sabre_VObject_Reader::read($card['carddata']);
+
+// Photo :-)
+foreach($content->children as $child){
+	if($child->name == 'PHOTO'){
+		$mime = 'image/jpeg';
+		foreach($child->parameters as $parameter){
+			if( $parameter->name == 'TYPE' ){
+				$mime = $parameter->value;
+			}
+		}
+		$photo = base64_decode($child->value);
+		header('Content-Type: '.$mime);
+		header('Content-Length: ' . strlen($photo));
+		echo $photo;
+		exit();
+	}
+}
+// Logo :-/
+foreach($content->children as $child){
+	if($child->name == 'PHOTO'){
+		$mime = 'image/jpeg';
+		foreach($child->parameters as $parameter){
+			if($parameter->name == 'TYPE'){
+				$mime = $parameter->value;
+			}
+		}
+		$photo = base64_decode($child->value());
+		header('Content-Type: '.$mime);
+		header('Content-Length: ' . strlen($photo));
+		echo $photo;
+		exit();
+	}
+}
+
+// Not found :-(
+echo $l10n->t('This card does not contain photo data!');
diff --git a/apps/contacts/templates/_contacts.php b/apps/contacts/templates/_contacts.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf633b79b047890620869fe6d458ec595cc6c2cc
--- /dev/null
+++ b/apps/contacts/templates/_contacts.php
@@ -0,0 +1,3 @@
+<?php foreach( $_['contacts'] as $contact ): ?>
+	<li x-id="<?php echo $contact['id']; ?>"><a href="index.php?id=<?php echo $contact['id']; ?>"><?php echo $contact['name']; ?></a></li>
+<?php endforeach; ?>
diff --git a/apps/contacts/templates/_details.php b/apps/contacts/templates/_details.php
new file mode 100644
index 0000000000000000000000000000000000000000..e27b17ef2ebe5c86ee6676de37c05f1886bd8536
--- /dev/null
+++ b/apps/contacts/templates/_details.php
@@ -0,0 +1,4 @@
+Name <?php echo $_['details']['FN'][0]['value']; ?>
+<?php if(array_key_exists('PHOTO',$_['details'])): ?>
+	<img src="photo.php?id=<?php echo $_['id']; ?>">
+<?php endif; ?>
\ No newline at end of file
diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..0cd214bfb18ae95a1d38d4778c916fe7ed8ffa9a
--- /dev/null
+++ b/apps/contacts/templates/index.php
@@ -0,0 +1,13 @@
+<?php // Include Style and Script
+OC_Util::addScript('contacts','interface');
+OC_Util::addStyle('contacts','styles');
+?>
+
+<div class="contacts_contacts leftcontent">
+	<ul>
+		<?php echo $this->inc("_contacts"); ?>
+	</ul>
+</div>
+<div class="contacts_details rightcontent">
+	<?php echo $this->inc("_details"); ?>
+</div>