diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index dc16d9764c87df2b424876b34dfd99ebc728f7ee..0240207d79b731751970dc6e3fde0736ffd7bcf7 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -2,9 +2,11 @@
 	font-weight: bold;
 }*/
 #leftcontent { top: 3.5em !important; padding: 0; margin: 0; }
+#leftcontent a { padding: 0 0 0 25px; }
 #rightcontent { top: 3.5em !important; padding-top: 5px; }
-#contacts { background: #fff; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; position: fixed; overflow: auto; padding: 0; margin: 0; }
-#contacts a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; }
+#leftcontent h3 {background: #aaa; display: block; max-width: 100%; height: 2em; padding: 0.5em 0.8em;}
+.contacts { background: #fff; max-width: 100%; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; overflow: auto; padding: 0; margin: 0; }
+.contacts a { height: 23px; display: block; left: 12.5em; margin: 0 0 0 0; padding: 0 0 0 25px; }
 #bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;}
 #contacts_newcontact { float: left; margin: 0.2em 0 0 1em; }
 #chooseaddressbook { float: right; margin: 0.2em 1em 0 0; }
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index a1b9976006d9117b455e5bfb89daed7bc114d5ea..1c5139117d9b4e27121f3ba31bc7fdeae9106cf1 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -173,11 +173,11 @@ Contacts={
 			// Name has changed. Update it and reorder.
 			$('#fn').change(function(){
 				var name = $('#fn').val().strip_tags();
-				var item = $('#contacts [data-id="'+Contacts.UI.Card.id+'"]');
+				var item = $('.contacts [data-id="'+Contacts.UI.Card.id+'"]');
 				$(item).find('a').html(name);
 				Contacts.UI.Card.fn = name;
 				var added = false;
-				$('#contacts li').each(function(){
+				$('.contacts li').each(function(){
 					if ($(this).text().toLowerCase() > name.toLowerCase()) {
 						$(this).before(item).fadeIn('fast');
 						added = true;
@@ -248,12 +248,12 @@ Contacts={
 			update:function(id) {
 				var newid;
 				if(!id) {
-					newid = $('#contacts li:first-child').data('id');
+					newid = $('.contacts li:first-child').data('id');
 				} else {
 					newid = id;
 				}
 				var localLoadContact = function(id) {
-					if($('#contacts li').length > 0) {
+					if($('.contacts li').length > 0) {
 						$('#leftcontent li[data-id="'+newid+'"]').addClass('active');
 						$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){
 							if(jsondata.status == 'success'){
@@ -278,7 +278,7 @@ Contacts={
 						}
 					});
 				}
-				else if($('#contacts li').length == 0) {
+				else if($('.contacts li').length == 0) {
 					// load intro page
 					$.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
 						if(jsondata.status == 'success'){
@@ -384,7 +384,7 @@ Contacts={
 								this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
 								this.data = undefined;
 								
-								if($('#contacts li').length > 0) { // Load first in list.
+								if($('.contacts li').length > 0) { // Load first in list.
 									Contacts.UI.Card.update(newid);
 								} else {
 									// load intro page
@@ -1498,7 +1498,7 @@ Contacts={
 			update:function(){
 				$.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){
 					if(jsondata.status == 'success'){
-						$('#contacts').html(jsondata.data.page);
+						$('#leftcontent').html(jsondata.data.page);
 						Contacts.UI.Card.update();
 					}
 					else{
@@ -1506,8 +1506,8 @@ Contacts={
 					}
 				});
 				setTimeout(function() {
-					$('#contacts li').unbind('inview');
-					$('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
+					$('.contacts li').unbind('inview');
+					$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
 						if (isInView) {
 							if (!$(this).find('a').attr('style')) {
 								$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
@@ -1518,19 +1518,19 @@ Contacts={
 			},
 			// Add thumbnails to the contact list as they become visible in the viewport.
 			lazyupdate:function(){
-				$('#contacts li').live('inview', function(){
+				$('.contacts li').live('inview', function(){
 					if (!$(this).find('a').attr('style')) {
 						$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
 					}
 				});
 			},
 			refreshThumbnail:function(id){
-				var item = $('#contacts [data-id="'+id+'"]').find('a');
+				var item = $('.contacts [data-id="'+id+'"]').find('a');
 				item.html(Contacts.UI.Card.fn);
 				item.css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+id+'&refresh=1'+Math.random()+') no-repeat');
 			},
 			scrollTo:function(id){
-				$('#contacts').animate({
+				$('.contacts').animate({
 					scrollTop: $('#leftcontent li[data-id="'+id+'"]').offset().top-20}, 'slow','swing');
 			}
 		}
@@ -1552,12 +1552,12 @@ $(document).ready(function(){
 	$('#contacts_newcontact').keydown(Contacts.UI.Card.editNew);
 	
 	// Load a contact.
-	$('#contacts').keydown(function(event) {
+	$('.contacts').keydown(function(event) {
 		if(event.which == 13) {
-			$('#contacts').click();
+			$('.contacts').click();
 		}
 	});
-	$('#contacts').click(function(event){
+	$('.contacts').click(function(event){
 		var $tgt = $(event.target);
 		if ($tgt.is('li') || $tgt.is('a')) {
 			var item = $tgt.is('li')?$($tgt):($tgt).parent();
@@ -1565,7 +1565,7 @@ $(document).ready(function(){
 			item.addClass('active');
 			var oldid = $('#rightcontent').data('id');
 			if(oldid != 0){
-				$('#contacts li[data-id="'+oldid+'"]').removeClass('active');
+				$('.contacts li[data-id="'+oldid+'"]').removeClass('active');
 			}
 			$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
 				if(jsondata.status == 'success'){
@@ -1579,7 +1579,7 @@ $(document).ready(function(){
 		return false;
 	});
 
-	$('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
+	$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
 		if (isInView) { //NOTE: I've kept all conditions for future reference ;-)
 			// element is now visible in the viewport
 			if (visiblePartY == 'top') {
diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php
index 7d212e71ba830f096f8d8da68f1cb4168c69410b..82619601c2b9afab7fe176e55a4ab69470275b5c 100644
--- a/apps/contacts/templates/index.php
+++ b/apps/contacts/templates/index.php
@@ -3,10 +3,8 @@
 	var categories = <?php echo json_encode($_['categories']); ?>;
 	var lang = '<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'core', 'lang', 'en'); ?>';
 </script>
-<div id="leftcontent" class="leftcontent">
-	<ul id="contacts">
-		<?php echo $this->inc("part.contacts"); ?>
-	</ul>
+<div id="leftcontent">
+	<?php echo $this->inc("part.contacts"); ?>
 </div>
 <div id="bottomcontrols">
 	<form>
diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php
index 57517505405fdd63c640d293feb312d41d58dd9d..1e64119c055da384f184f9020318717b9ed715f4 100644
--- a/apps/contacts/templates/part.contacts.php
+++ b/apps/contacts/templates/part.contacts.php
@@ -1,12 +1,45 @@
-<?php foreach( $_['contacts'] as $contact ):
-	$display = trim($contact['fullname']);
-	if(!$display) {
-		$vcard = OC_Contacts_App::getContactVCard($contact['id']);
-		if(!is_null($vcard)) {
-			$struct = OC_Contacts_VCard::structureContact($vcard);
-			$display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]';
-		}
+<?php
+// get the names of the addressbooks
+$addressbook_names = OC_Contacts_Addressbook::all(OCP\USER::getUser());
+$contacts = array();
+
+// sort the contacts by addressbookid
+foreach( $_['contacts'] as $contact ):
+	if(is_null($contacts[$contact['addressbookid']])) {
+		$contacts[$contact['addressbookid']] = array();
 	}
+	$contacts[$contact['addressbookid']][] = $contact;
+endforeach;
+
+// print them out sorted by addressbook-name
+for($i=0; $i<count($addressbook_names); $i++) {
+	// a little ugly doing it this way but dunno how to do it else :)
+	if(!(is_null($contacts[$addressbook_names[$i]['id']]))) { // look if we got contacts from this adressbook
+		echo '<h3 class="addressbookname">'.$addressbook_names[$i]['displayname'].'</h3>';
+		echo '<div>
+			<ul class="contacts">';
+		foreach($contacts[$addressbook_names[$i]['id']] as $contact):
+			$display = trim($contact['fullname']);
+
+			if(!$display) {
+				$vcard = OC_Contacts_App::getContactVCard($contact['id']);
+				if(!is_null($vcard)) {
+					$struct = OC_Contacts_VCard::structureContact($vcard);
+					$display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]';
+				}
+			}
+			echo '<li role="button" book-id="'.$contact['addressbookid'].'" data-id="'.$contact['id'].'"><a href="index.php?id='.$contact['id'].'">'.htmlspecialchars($display).'</a></li>';
+
+		endforeach;
+		echo '</ul></div>';
+	}
+}
 ?>
-	<li role="button" book-id="<?php echo $contact['addressbookid']; ?>" data-id="<?php echo $contact['id']; ?>"><a href="index.php?id=<?php echo $contact['id']; ?>"><?php echo htmlspecialchars($display); ?></a></li>
-<?php endforeach; ?>
+<script language="Javascript">
+$(document).ready(function() {
+	$('#leftcontent .addressbookname').click(function(event) {
+		$(this).next().toggle('slow');
+		return false;
+	}).next().hide();
+});
+</script>