diff --git a/apps/calendar/ajax/share/share.php b/apps/calendar/ajax/share/share.php
index 3ce2bf1e21756a142d5e07c6bcb9b795577a2cdf..629a7b6b79fb217d7c9b6ca1224303162ba4e1d3 100644
--- a/apps/calendar/ajax/share/share.php
+++ b/apps/calendar/ajax/share/share.php
@@ -13,7 +13,7 @@ switch($idtype){
 	case 'event':
 		break;
 	default:
-		OCP\JSON::error(array('message'=>'unexspected parameter'));
+		OCP\JSON::error(array('message'=>'unexpected parameter'));
 		exit;
 }
 if($idtype == 'calendar' && !OC_Calendar_App::getCalendar($id)){
@@ -32,7 +32,7 @@ switch($sharetype){
 	case 'public':
 		break;
 	default:
-		OCP\JSON::error(array('message'=>'unexspected parameter'));
+		OCP\JSON::error(array('message'=>'unexpected parameter'));
 		exit;
 }
 if($sharetype == 'user' && !OCP\User::userExists($sharewith)){
@@ -44,7 +44,7 @@ if($sharetype == 'group' && !OC_Group::groupExists($sharewith)){
 	exit;
 }
 if($sharetype == 'user' && OCP\USER::getUser() == $sharewith){
-	OCP\JSON::error(array('meesage'=>'you can not share with yourself'));
+	OCP\JSON::error(array('message'=>'you can not share with yourself'));
 }
 $success = OC_Calendar_Share::share(OCP\USER::getUser(), $sharewith, $sharetype, $id, (($idtype=='calendar') ? OC_Calendar_Share::CALENDAR : OC_Calendar_Share::EVENT));
 if($success){
diff --git a/apps/calendar/templates/settings.php b/apps/calendar/templates/settings.php
index 40cef0795932a84b4d765b05d35751182d9dada3..6d018f151101c94485313ee23a461670841ea94c 100644
--- a/apps/calendar/templates/settings.php
+++ b/apps/calendar/templates/settings.php
@@ -8,41 +8,41 @@
  */
 ?>
 <form id="calendar">
-        <fieldset class="personalblock">
+	<fieldset class="personalblock">
 	<legend><?php echo $l->t('Calendar'); ?></legend>
-        <table class="nostyle">
-            <tr><td><label for="timezone" class="bold"><?php echo $l->t('Timezone');?></label></td><td><select style="display: none;" id="timezone" name="timezone">
-                <?php
-                $continent = '';
-                foreach($_['timezones'] as $timezone):
-                    $ex=explode('/', $timezone, 2);//obtain continent,city
-                    if (!isset($ex[1])) {
-                            $ex[1] = $ex[0];
-                            $ex[0] = "Other";
-                    }
-                    if ($continent!=$ex[0]):
-                        if ($continent!="") echo '</optgroup>';
-                        echo '<optgroup label="'.$ex[0].'">';
-                    endif;
+		<table class="nostyle">
+			<tr><td><label for="timezone" class="bold"><?php echo $l->t('Timezone');?></label></td><td><select style="display: none;" id="timezone" name="timezone">
+				<?php
+				$continent = '';
+				foreach($_['timezones'] as $timezone):
+					$ex=explode('/', $timezone, 2);//obtain continent,city
+					if (!isset($ex[1])) {
+						$ex[1] = $ex[0];
+						$ex[0] = "Other";
+					}
+					if ($continent!=$ex[0]):
+						if ($continent!="") echo '</optgroup>';
+						echo '<optgroup label="'.$ex[0].'">';
+					endif;
 					$city=strtr($ex[1], '_', ' ');
-                    $continent=$ex[0];
-                    echo '<option value="'.$timezone.'"'.($_['timezone'] == $timezone?' selected="selected"':'').'>'.$city.'</option>';
-                endforeach;?>
-            </select><input type="checkbox" name="timezonedetection" id="timezonedetection"><label for="timezonedetection"><?php echo $l->t('Check always for changes of the timezone'); ?></label></td></tr>
+					$continent=$ex[0];
+					echo '<option value="'.$timezone.'"'.($_['timezone'] == $timezone?' selected="selected"':'').'>'.$city.'</option>';
+				endforeach;?>
+			</select><input type="checkbox" name="timezonedetection" id="timezonedetection"><label for="timezonedetection"><?php echo $l->t('Check always for changes of the timezone'); ?></label></td></tr>
 
-            <tr><td><label for="timeformat" class="bold"><?php echo $l->t('Timeformat');?></label></td><td>
-                <select style="display: none; width: 60px;" id="timeformat" title="<?php echo "timeformat"; ?>" name="timeformat">
-                    <option value="24" id="24h"><?php echo $l->t("24h"); ?></option>
-                    <option value="ampm" id="ampm"><?php echo $l->t("12h"); ?></option>
-                </select>
-            </td></tr>
+			<tr><td><label for="timeformat" class="bold"><?php echo $l->t('Timeformat');?></label></td><td>
+				<select style="display: none; width: 60px;" id="timeformat" title="<?php echo "timeformat"; ?>" name="timeformat">
+					<option value="24" id="24h"><?php echo $l->t("24h"); ?></option>
+					<option value="ampm" id="ampm"><?php echo $l->t("12h"); ?></option>
+				</select>
+			</td></tr>
 
-            <tr><td><label for="firstday" class="bold"><?php echo $l->t('First day of the week');?></label></td><td>
-                <select style="display: none;" id="firstday" title="<?php echo "First day"; ?>" name="firstday">
-                    <option value="mo" id="mo"><?php echo $l->t("Monday"); ?></option>
-                    <option value="su" id="su"><?php echo $l->t("Sunday"); ?></option>
-                </select>
-            </td></tr>
+			<tr><td><label for="firstday" class="bold"><?php echo $l->t('First day of the week');?></label></td><td>
+				<select style="display: none;" id="firstday" title="<?php echo "First day"; ?>" name="firstday">
+					<option value="mo" id="mo"><?php echo $l->t("Monday"); ?></option>
+					<option value="su" id="su"><?php echo $l->t("Sunday"); ?></option>
+				</select>
+			</td></tr>
 
             <tr><td><label for="" class="bold"><?php echo $l->t('Cache');?></label></td><td>
                 <input id="cleancalendarcache" type="button" class="button" value="<?php echo $l->t('Clear cache for repeating events');?>">
@@ -50,7 +50,12 @@
 
         </table>
 
-        <?php echo $l->t('Calendar CalDAV syncing address:');?>
-        <code><?php echo OCP\Util::linkToRemote('caldav'); ?></code><br />
+		<?php echo $l->t('Calendar CalDAV syncing addresses'); ?> (<a href="http://owncloud.org/synchronisation/" target="_blank"><?php echo $l->t('more info'); ?></a>)
+		<dl>
+		<dt><?php echo $l->t('Primary address (Kontact et al)'); ?></dt>
+		<dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?></code></dd>
+		<dt><?php echo $l->t('iOS/OS X'); ?></dt>
+		<dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd>
+		</dl>
         </fieldset>
 </form>
diff --git a/apps/contacts/ajax/addproperty.php b/apps/contacts/ajax/addproperty.php
index 4668c0d3a65384f0489661e46bbee36aa5d41878..2f932d752a77032ec05d881933b36f26d98adeec 100644
--- a/apps/contacts/ajax/addproperty.php
+++ b/apps/contacts/ajax/addproperty.php
@@ -33,7 +33,7 @@ $vcard = OC_Contacts_App::getContactVCard($id);
 
 if(!is_array($value)){
 	$value = trim($value);
-	if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'NICKNAME', 'NOTE'))) {
+	if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'URL', 'NICKNAME', 'NOTE'))) {
 		OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Cannot add empty property.'))));
 		exit();
 	}
diff --git a/apps/contacts/ajax/saveproperty.php b/apps/contacts/ajax/saveproperty.php
index 8409ffe47f2f85e197d864de9cebd65f2a6d64aa..d8400734710eac4eb3f88435e8a29b7be0acbc2d 100644
--- a/apps/contacts/ajax/saveproperty.php
+++ b/apps/contacts/ajax/saveproperty.php
@@ -98,15 +98,6 @@ if(!$value) {
 } else {
 	/* setting value */
 	switch($element) {
-		case 'BDAY':
-		case 'FN':
-		case 'N':
-		case 'ORG':
-		case 'NOTE':
-		case 'NICKNAME':
-			debug('Setting string:'.$name.' '.$value);
-			$vcard->setString($name, $value);
-			break;
 		case 'CATEGORIES':
 			debug('Setting string:'.$name.' '.$value);
 			$vcard->children[$line]->setValue($value);
@@ -128,6 +119,10 @@ if(!$value) {
 				}
 			}
 			break;
+		default:
+			debug('Setting string:'.$name.' '.$value);
+			$vcard->setString($name, $value);
+			break;
 	}
 	// Do checksum and be happy
 	$checksum = md5($vcard->children[$line]->serialize());
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 1d02b3722ddc37990cb102ac611789ee0fa9ba97..8de68fbf0522a61569790aa5876deb4c0c988a69 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -31,8 +31,9 @@ dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; }
 .form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom; color: #bbb;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ }
 .form dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0px; white-space: nowrap; vertical-align: text-bottom; }
 label:hover, dt:hover { color: #333; }
-#address.form dt { min-width: 5em; }
-#address.form dl { min-width: 10em; }
+/*::-webkit-input-placeholder { color: #bbb; }
+:-moz-placeholder { color: #bbb; }
+:-ms-input-placeholder { color: #bbb; }*/
 .droptarget { margin: 0.5em; padding: 0.5em; border: thin solid #ccc; -moz-border-radius:.3em; -webkit-border-radius:.3em; border-radius:.3em; }
 .droppable { margin: 0.5em; padding: 0.5em; border: thin dashed #333; -moz-border-radius:.3em; -webkit-border-radius:.3em; border-radius:.3em; }
 .loading { background: url('%webroot%/core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; }
@@ -79,10 +80,17 @@ label:hover, dt:hover { color: #333; }
 #addressdisplay { padding: 0.5em; }
 dl.addresscard { background-color: #fff; float: left; width: auto; margin: 0 0.3em 0.3em 0.3em; padding: 0; border: 0; }
 dl.addresscard dd {}
-dl.addresscard dt { padding: 0.3em; font-weight: bold; clear: both; color: #bbb;}
+dl.addresscard dt { padding: 0.3em; font-weight: bold; clear: both; color: #aaa; }
 dl.addresscard dt:hover { color:#777; }
 dl.addresscard dd > ul { margin: 0.3em; padding: 0.3em; }
 dl.addresscard .action { float: right; }
+#address dt { width: 30%; white-space:nowrap; }
+#address dd { width: 66%; }
+#address input { width: 12em; padding: 0.6em 0.5em 0.4em; }
+#address input:-moz-placeholder { color: #aaa; }
+#address input::-webkit-input-placeholder { color: #aaa; }
+#address input:-ms-input-placeholder { color: #aaa; }
+#address input:placeholder { color: #aaa; }
 #adr_type {} /* Select */
 #adr_pobox {}
 #adr_extended {}
diff --git a/apps/contacts/export.php b/apps/contacts/export.php
index 4e4ade2f2ba6c015cf38c5a3bb84dfdd6e89c2a8..f84a10c13888e81aebbbb17a4f370d46537dc745 100644
--- a/apps/contacts/export.php
+++ b/apps/contacts/export.php
@@ -23,7 +23,7 @@ if(isset($bookid)){
 	}
 }elseif(isset($contactid)){
 	$data = OC_Contacts_App::getContactObject($contactid);
-	header('Content-Type: text/directory');
+	header('Content-Type: text/vcard');
 	header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $data['fullname']) . '.vcf'); 
 	echo $data['carddata'];
 }
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 458c9ab8fc45676de9d4d3dfb49cada19dc39c29..35d4a4a216de156bd0575fb9adda59f5aac04520 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -110,10 +110,21 @@ Contacts={
 				obj.tipsy('hide');
 				Contacts.UI.Card.deleteProperty(obj, 'single');
 			}
+			
+			var goToUrl = function(obj) {
+				var url = Contacts.UI.propertyContainerFor(obj).find('#url').val();
+				if(url != '') {
+					var newWindow = window.open(url,'_blank');
+					newWindow.focus();
+				}
+			}
+			
 			$('#identityprops a.delete').click( function() { deleteItem($(this)) });
 			$('#identityprops a.delete').keydown( function() { deleteItem($(this)) });
 			$('#categories_value a.edit').click( function() { $(this).tipsy('hide');OCCategories.edit(); } );
 			$('#categories_value a.edit').keydown( function() { $(this).tipsy('hide');OCCategories.edit(); } );
+			$('#url_value a.globe').click( function() { $(this).tipsy('hide');goToUrl($(this)); } );
+			$('#url_value a.globe').keydown( function() { $(this).tipsy('hide');goToUrl($(this)); } );
 			$('#fn_select').combobox({
 				'id': 'fn',
 				'name': 'value',
@@ -427,7 +438,7 @@ Contacts={
 				}
 			},
 			loadSingleProperties:function() {
-				var props = ['BDAY', 'NICKNAME', 'ORG', 'CATEGORIES'];
+				var props = ['BDAY', 'NICKNAME', 'ORG', 'URL', 'CATEGORIES'];
 				// Clear all elements
 				$('#ident .propertycontainer').each(function(){
 					if(props.indexOf($(this).data('element')) > -1) {
@@ -438,40 +449,22 @@ Contacts={
 					}
 				});
 				for(var prop in props) {
-					if(this.data[props[prop]] != undefined) {
-						$('#contacts_propertymenu_dropdown a[data-type="'+props[prop]+'"]').parent().hide();
-						var property = this.data[props[prop]][0];
+					var propname = props[prop];
+					if(this.data[propname] != undefined) {
+						$('#contacts_propertymenu_dropdown a[data-type="'+propname+'"]').parent().hide();
+						var property = this.data[propname][0];
 						var value = property['value'], checksum = property['checksum'];
-						switch(props[prop]) {
-							case 'BDAY':
-								var val = $.datepicker.parseDate('yy-mm-dd', value.substring(0, 10));
-								value = $.datepicker.formatDate('dd-mm-yy', val);
-								$('#contact_identity').find('#bday').val(value);
-								$('#contact_identity').find('#bday_value').data('checksum', checksum);
-								$('#contact_identity').find('#bday_label').show();
-								$('#contact_identity').find('#bday_value').show();
-								break;
-							case 'NICKNAME':
-								$('#contact_identity').find('#nickname').val(value);
-								$('#contact_identity').find('#nickname_value').data('checksum', checksum);
-								$('#contact_identity').find('#nickname_label').show();
-								$('#contact_identity').find('#nickname_value').show();
-								break;
-							case 'ORG':
-								$('#contact_identity').find('#org').val(value);
-								$('#contact_identity').find('#org_value').data('checksum', checksum);
-								$('#contact_identity').find('#org_label').show();
-								$('#contact_identity').find('#org_value').show();
-								break;
-							case 'CATEGORIES':
-								$('#contact_identity').find('#categories').val(value);
-								$('#contact_identity').find('#categories_value').data('checksum', checksum);
-								$('#contact_identity').find('#categories_label').show();
-								$('#contact_identity').find('#categories_value').show();
-								break;
+						
+						if(propname == 'BDAY') {
+							var val = $.datepicker.parseDate('yy-mm-dd', value.substring(0, 10));
+							value = $.datepicker.formatDate('dd-mm-yy', val);
 						}
+						$('#contact_identity').find('#'+propname.toLowerCase()).val(value);
+						$('#contact_identity').find('#'+propname.toLowerCase()+'_value').data('checksum', checksum);
+						$('#contact_identity').find('#'+propname.toLowerCase()+'_label').show();
+						$('#contact_identity').find('#'+propname.toLowerCase()+'_value').show();
 					} else {
-						$('#contacts_propertymenu_dropdown a[data-type="'+props[prop]+'"]').parent().show();
+						$('#contacts_propertymenu_dropdown a[data-type="'+propname+'"]').parent().show();
 					}
 				}
 			},
@@ -700,6 +693,7 @@ Contacts={
 						Contacts.UI.Card.editAddress('new', true);
 						break;
 					case 'NICKNAME':
+					case 'URL':
 					case 'ORG':
 					case 'BDAY':
 					case 'CATEGORIES':
@@ -1287,7 +1281,7 @@ Contacts={
 		},
 		Addressbooks:{
 			droptarget:undefined,
-			droptext:t('contacts', 'Drop a VCF file to import contacts.'),
+			droptext:t('contacts', 'Drop a VCF file<br />to import contacts.'),
 			overview:function(){
 				if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
 					$('#chooseaddressbook_dialog').dialog('moveToTop');
@@ -1296,7 +1290,7 @@ Contacts={
 					$.getJSON(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(jsondata){
 						if(jsondata.status == 'success'){
 							$('#addressbook_dialog').html(jsondata.data.page).find('#chooseaddressbook_dialog').dialog({
-								width : 600,
+								minWidth : 600,
 								close : function(event, ui) {
 									$(this).dialog('destroy').remove();
 									$('#addressbook_dialog').remove();
diff --git a/apps/contacts/js/jquery.combobox.js b/apps/contacts/js/jquery.combobox.js
index f12d1d7dd20ef3934bd054950f79e7dee94f8615..d9959eb6cdee7bb1133cac828dbcd0f61626013d 100644
--- a/apps/contacts/js/jquery.combobox.js
+++ b/apps/contacts/js/jquery.combobox.js
@@ -23,16 +23,16 @@
 					minLength: 0,
 					source: function( request, response ) {
 						var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
-						response( select.children( "option" ).map(function() {
+						response( select.children('option').map(function() {
 							var text = $( this ).text();
 							if ( this.value && ( !request.term || matcher.test(text) ) )
 								return {
 									label: text.replace(
 										new RegExp(
-											"(?![^&;]+;)(?!<[^<>]*)(" +
+											'(?![^&;]+;)(?!<[^<>]*)(' +
 											$.ui.autocomplete.escapeRegex(request.term) +
-											")(?![^<>]*>)(?![^&;]+;)", "gi"
-										), "<strong>$1</strong>" ),
+											')(?![^<>]*>)(?![^&;]+;)', 'gi'
+										), '<strong>$1</strong>'),
 									value: text,
 									option: this
 								};
@@ -42,17 +42,17 @@
 						self.input.val($(ui.item.option).text());
 						self.input.trigger('change');
 						ui.item.option.selected = true;
-						self._trigger( "selected", event, {
+						self._trigger('selected', event, {
 							item: ui.item.option
 						});
 					},
 					change: function( event, ui ) {
 						if ( !ui.item ) {
-							var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
+							var matcher = new RegExp( '^' + $.ui.autocomplete.escapeRegex( $(this).val() ) + '$', 'i' ),
 								valid = false;
 							self.input.val($(this).val());
 							//self.input.trigger('change');
-							select.children( "option" ).each(function() {
+							select.children('option').each(function() {
 								if ( $( this ).text().match( matcher ) ) {
 									this.selected = valid = true;
 									return false;
@@ -62,36 +62,41 @@
 								// remove invalid value, as it didn't match anything
 								$( this ).val( "" );
 								select.val( "" );
-								input.data( "autocomplete" ).term = "";
+								input.data('autocomplete').term = '';
 								return false;
 							}
 						}
 					}
 				})
-				.addClass( "ui-widget ui-widget-content ui-corner-left" );
+				.addClass('ui-widget ui-widget-content ui-corner-left');
 
-			input.data( "autocomplete" )._renderItem = function( ul, item ) {
-				return $( "<li></li>" )
-					.data( "item.autocomplete", item )
-					.append( "<a>" + item.label + "</a>" )
+			input.data('autocomplete')._renderItem = function( ul, item ) {
+				return $('<li></li>')
+					.data('item.autocomplete', item )
+					.append('<a>' + item.label + '</a>')
 					.appendTo( ul );
 			};
 			$.each(this.options, function(key, value) {
 				self._setOption(key, value);
 			});
 
+			input.dblclick(function() {
+				// pass empty string as value to search for, displaying all results
+				input.autocomplete('search', '');
+			});
+			
 			if(this.options['showButton']) {
-				this.button = $( "<button type='button'>&nbsp;</button>" )
-					.attr( "tabIndex", -1 )
-					.attr( "title", "Show All Items" )
+				this.button = $('<button type="button">&nbsp;</button>')
+					.attr('tabIndex', -1 )
+					.attr('title', 'Show All Items')
 					.insertAfter( input )
 					.addClass('svg')
 					.addClass('action')
 					.addClass('combo-button')
 					.click(function() {
 						// close if already visible
-						if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
-							input.autocomplete( "close" );
+						if ( input.autocomplete('widget').is(':visible') ) {
+							input.autocomplete('close');
 							return;
 						}
 
@@ -99,7 +104,7 @@
 						$( this ).blur();
 
 						// pass empty string as value to search for, displaying all results
-						input.autocomplete( "search", "" );
+						input.autocomplete('search', '');
 						input.focus();
 					});
 			}
diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php
index 74522be37c41333712fd7f618547e01cf0e307a1..fee5be080046d0c6deb4363fb9ce74649e50f5a6 100644
--- a/apps/contacts/templates/part.contact.php
+++ b/apps/contacts/templates/part.contact.php
@@ -34,6 +34,8 @@ $id = isset($_['id']) ? $_['id'] : '';
 		<dd class="propertycontainer hidden" id="org_value" data-element="ORG"><input id="org" required="required" name="value[ORG]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Organization'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
 		<dt class="hidden" id="nickname_label" data-element="NICKNAME"><label for="nickname"><?php echo $l->t('Nickname'); ?></label></dt>
 		<dd class="propertycontainer hidden" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
+		<dt class="hidden" id="url_label" data-element="URL"><label for="nickname"><?php echo $l->t('Web site'); ?></label></dt>
+		<dd class="propertycontainer hidden" id="url_value" data-element="URL"><input id="url" required="required" name="value[URL]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('http://www.somesite.com'); ?>" /><a role="button" class="action globe" title="<?php echo $l->t('Go to web site'); ?>"><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
 		<dt class="hidden" id="bday_label" data-element="BDAY"><label for="bday"><?php echo $l->t('Birthday'); ?></label></dt>
 		<dd class="propertycontainer hidden" id="bday_value" data-element="BDAY"><input id="bday"  required="required" name="value" type="text" class="contacts_property big" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
 		<dt class="hidden" id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Groups'); ?></label></dt>
@@ -108,6 +110,7 @@ $id = isset($_['id']) ? $_['id'] : '';
 		<li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li>
 		<li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li>
 		<li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li>
+		<li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li>
 		<li><a role="menuitem" data-type="CATEGORIES"><?php echo $l->t('Groups'); ?></a></li>
 	</ul>
 	</div>
diff --git a/apps/contacts/templates/part.edit_address_dialog.php b/apps/contacts/templates/part.edit_address_dialog.php
index 8b3425033cc079b7925a0e6860ec111d28cc3d23..7684795f3488ac77b0277a9a2e24e7cb25de68bf 100644
--- a/apps/contacts/templates/part.edit_address_dialog.php
+++ b/apps/contacts/templates/part.edit_address_dialog.php
@@ -24,18 +24,17 @@ foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):arra
 			<dd>
 				<input type="text" id="adr_pobox" name="value[ADR][0]" placeholder="<?php echo $l->t('PO Box'); ?>" value="<?php echo isset($adr['value'][0])?$adr['value'][0]:''; ?>">
 			</dd>
-			<dd>
 			<dt>
-				<label class="label" for="adr_extended"><?php echo $l->t('Extended'); ?></label>
+				<label class="label" for="adr_street"><?php echo $l->t('Street address'); ?></label>
 			</dt>
 			<dd>
-				<input type="text" id="adr_extended" name="value[ADR][1]" placeholder="<?php echo $l->t('Extended'); ?>" value="<?php echo isset($adr['value'][1])?$adr['value'][1]:''; ?>">
+				<input type="text" id="adr_street" name="value[ADR][2]" placeholder="<?php echo $l->t('Street and number'); ?>" value="<?php echo isset($adr['value'][2])?$adr['value'][2]:''; ?>">
 			</dd>
 			<dt>
-				<label class="label" for="adr_street"><?php echo $l->t('Street'); ?></label>
+				<label class="label" for="adr_extended"><?php echo $l->t('Extended'); ?></label>
 			</dt>
 			<dd>
-				<input type="text" id="adr_street" name="value[ADR][2]" placeholder="<?php echo $l->t('Street'); ?>" value="<?php echo isset($adr['value'][2])?$adr['value'][2]:''; ?>">
+				<input type="text" id="adr_extended" name="value[ADR][1]" placeholder="<?php echo $l->t('Apartment number etc.'); ?>" value="<?php echo isset($adr['value'][1])?$adr['value'][1]:''; ?>">
 			</dd>
 			<dt>
 				<label class="label" for="adr_city"><?php echo $l->t('City'); ?></label>
@@ -47,13 +46,13 @@ foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):arra
 				<label class="label" for="adr_region"><?php echo $l->t('Region'); ?></label>
 			</dt>
 			<dd>
-				<input type="text" id="adr_region" name="value[ADR][4]" placeholder="<?php echo $l->t('Region'); ?>" value="<?php echo isset($adr['value'][4])?$adr['value'][4]:''; ?>">
+				<input type="text" id="adr_region" name="value[ADR][4]" placeholder="<?php echo $l->t('E.g. state or province'); ?>" value="<?php echo isset($adr['value'][4])?$adr['value'][4]:''; ?>">
 			</dd>
 			<dt>
 				<label class="label" for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
 			</dt>
 			<dd>
-				<input type="text" id="adr_zipcode" name="value[ADR][5]" placeholder="<?php echo $l->t('Zipcode'); ?>" value="<?php echo isset($adr['value'][5])?$adr['value'][5]:''; ?>">
+				<input type="text" id="adr_zipcode" name="value[ADR][5]" placeholder="<?php echo $l->t('Postal code'); ?>" value="<?php echo isset($adr['value'][5])?$adr['value'][5]:''; ?>">
 			</dd>
 			<dt>
 				<label class="label" for="adr_country"><?php echo $l->t('Country'); ?></label>
diff --git a/apps/contacts/templates/part.importaddressbook.php b/apps/contacts/templates/part.importaddressbook.php
index 6702262f231625e39e4ff61bebbf9cea917e4f8e..0e2956ddaf461a55068dd74d9a3f862440eebb73 100644
--- a/apps/contacts/templates/part.importaddressbook.php
+++ b/apps/contacts/templates/part.importaddressbook.php
@@ -22,7 +22,7 @@ if(OCP\App::isEnabled('files_encryption')) {
 			echo OCP\html_select_options($contacts_options, $contacts_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
 			?>
 			</select>
-			<span id="import_drop_target" class="droptarget float"><?php echo $l->t("Drop a VCF file to import contacts."); ?> (Max. <?php echo  $_['uploadMaxHumanFilesize']; ?>)</span>
+			<span id="import_drop_target" class="droptarget float"><?php echo $l->t("Drop a VCF file<br />to import contacts."); ?> (Max. <?php echo  $_['uploadMaxHumanFilesize']; ?>)</span>
 			<a class="svg upload float" title="<?php echo $l->t('Select from HD'); ?>">
 			<input class="float" id="import_upload_start" type="file" accept="text/*" name="importfile" /></a>
 			<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_['uploadMaxFilesize'] ?>" id="max_upload">
@@ -36,5 +36,7 @@ if(OCP\App::isEnabled('files_encryption')) {
 <?php } ?>
 </td>
 <script type="text/javascript">
-Contacts.UI.Addressbooks.loadImportHandlers();
+$(document).ready(function(){
+	Contacts.UI.Addressbooks.loadImportHandlers();
+});
 </script>
\ No newline at end of file
diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php
index 0668a6191f4da50be543ef91f3a5024ccb83229f..c5c37914c6a68c005e6c1df2b3795f397671eca6 100644
--- a/apps/files/ajax/newfolder.php
+++ b/apps/files/ajax/newfolder.php
@@ -13,7 +13,7 @@ if(trim($foldername) == '') {
 	OCP\JSON::error(array("data" => array( "message" => "Empty Foldername" )));
 	exit();
 }
-if(strpos($filename,'/')!==false){
+if(strpos($foldername,'/')!==false){
 	OCP\JSON::error(array("data" => array( "message" => "Invalid Foldername" )));
 	exit();
 }
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index f5e6d78e7761ab3699fc4524021cee126216d1f5..f594fbb880d951a8682f8ddce97ce72035aa7d40 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -13,6 +13,7 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
 	private $user;
 	private $host;
 	private $root;
+	private $share;
 
 	private static $tempFiles=array();
 
@@ -20,17 +21,32 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
 		$this->host=$params['host'];
 		$this->user=$params['user'];
 		$this->password=$params['password'];
+		$this->share=$params['share'];
 		$this->root=isset($params['root'])?$params['root']:'/';
+		if(substr($this->root,-1,1)!='/'){
+			$this->root.='/';
+		}
+		if(substr($this->root,0,1)!='/'){
+			$this->root='/'.$this->root;
+		}
+		if(substr($this->share,0,1)!='/'){
+			$this->share='/'.$this->share;
+		}
+		if(substr($this->share,-1,1)=='/'){
+			$this->share=substr($this->share,0,-1);
+		}
 
 		//create the root folder if necesary
-		$this->mkdir('');
+		if(!$this->is_dir('')){
+			$this->mkdir('');
+		}
 	}
 
 	public function constructUrl($path){
 		if(substr($path,-1)=='/'){
 			$path=substr($path,0,-1);
 		}
-		return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
+		return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->share.$this->root.$path;
 		
 	}
 }
diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php
index 970008d642c90eac5732c65601cd6fc4788d9c63..e58a87fabdf69e5e0a84e15b2b6461d225c3b72a 100644
--- a/apps/files_external/tests/config.php
+++ b/apps/files_external/tests/config.php
@@ -34,7 +34,8 @@ return array(
 		'user'=>'test',
 		'password'=>'test',
 		'host'=>'localhost',
-		'root'=>'/test',
+		'share'=>'/test',
+		'root'=>'/test/',
 	),
 	'amazons3'=>array(
 		'run'=>false,
diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php
index 52e1700b0191e7047794fbc3732d2d98b1bd7814..e1495b7480dfaa1ace26de23b115e6488a6bdd64 100644
--- a/apps/files_external/tests/smb.php
+++ b/apps/files_external/tests/smb.php
@@ -19,7 +19,7 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']){
 		public function setUp(){
 			$id=uniqid();
 			$this->config=include('apps/files_external/tests/config.php');
-			$this->config['smb']['root'].='/'.$id;//make sure we have an new empty folder to work in
+			$this->config['smb']['root'].=$id;//make sure we have an new empty folder to work in
 			$this->instance=new OC_Filestorage_SMB($this->config['smb']);
 		}
 
diff --git a/apps/gallery/ajax/galleryOp.php b/apps/gallery/ajax/galleryOp.php
index b49e52f0bd2d49c560874e87b37492eab558aea2..7cbe3e46e2175dc4d5ff1b2bafca9f442df183bb 100644
--- a/apps/gallery/ajax/galleryOp.php
+++ b/apps/gallery/ajax/galleryOp.php
@@ -42,7 +42,7 @@ function handleRemove($name) {
 
 function handleGetThumbnails($albumname) {
   OCP\Response::enableCaching(3600 * 24); // 24 hour
-  $view = OCP\App::getStorage('gallery');
+  $view = OCP\Files::getStorage('gallery');
   $thumbnail = $view->fopen(urldecode($albumname).'.png', 'r');
   header('Content-Type: '.OC_Image::getMimeTypeForFile($thumbnail));
   OCP\Response::sendFile($thumbnail);
diff --git a/apps/gallery/ajax/sharing.php b/apps/gallery/ajax/sharing.php
index 304757b9e9141712eaf8b87b365d174629665fea..7134d19e78a903f9ff78fd37551f11bee5380936 100644
--- a/apps/gallery/ajax/sharing.php
+++ b/apps/gallery/ajax/sharing.php
@@ -80,7 +80,7 @@ function handleGetThumbnail($token, $imgpath) {
 function handleGetAlbumThumbnail($token, $albumname)
 {
   $owner = OC_Gallery_Sharing::getTokenOwner($token);
-  $view = OCP\App::getStorage('gallery');
+  $view = OCP\Files::getStorage('gallery');
   $file = $view->fopen($albumname.'.png', 'r');
   $image = new OC_Image($file);
   if ($image->valid()) {
@@ -94,7 +94,7 @@ function handleGetAlbumThumbnail($token, $albumname)
 
 function handleGetPhoto($token, $photo) {
   $owner = OC_Gallery_Sharing::getTokenOwner($token);
-  $view = OCP\App::getStorage('files');
+  $view = OCP\Files::getStorage('files');
   $file = $view->fopen(urldecode($photo), 'r');
   header('Content-Type: '.OC_Image::getMimeTypeForFile($file));
   OCP\Response::sendFile($file);
diff --git a/apps/gallery/ajax/thumbnail.php b/apps/gallery/ajax/thumbnail.php
index ff0cb44022ceedd403790df7c32ef6fe4c8e3ce2..4fc9eba992d9eb25f12f98c976f19a34e751fb4e 100644
--- a/apps/gallery/ajax/thumbnail.php
+++ b/apps/gallery/ajax/thumbnail.php
@@ -20,14 +20,15 @@
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
-
  
 OCP\JSON::checkLoggedIn();
 OCP\JSON::checkAppEnabled('gallery');
+require_once('apps/gallery/lib/managers.php');
+
 
-$img = $_GET['img'];
+$img = $_GET['filepath'];
 
-$image = OC_Gallery_Photo::getThumbnail($img);
+$image = \OC\Pictures\ThumbnailsManager::getInstance()->getThumbnail($img);
 if ($image) {
 	OCP\Response::enableCaching(3600 * 24); // 24 hour
 	$image->show();
diff --git a/apps/gallery/appinfo/database.xml b/apps/gallery/appinfo/database.xml
index f370e1521e43976e3a2534aaac711705d79a3a7a..d1ccd6b5a24b5b927f7ef23716f462bdb82c1f6e 100644
--- a/apps/gallery/appinfo/database.xml
+++ b/apps/gallery/appinfo/database.xml
@@ -5,16 +5,8 @@
 	 <overwrite>false</overwrite>
 	 <charset>latin1</charset>
 	 <table>
-		<name>*dbprefix*gallery_albums</name>
+		<name>*dbprefix*pictures_images_cache</name>
 		<declaration>
-			<field>
-				<name>album_id</name>
-				<type>integer</type>
-				<default>0</default>
-				<notnull>true</notnull>
-				<autoincrement>1</autoincrement>
-				<length>4</length>
-			</field>
 			<field>
 				<name>uid_owner</name>
 				<type>text</type>
@@ -22,49 +14,23 @@
 				<length>64</length>
 			</field>
 			<field>
-				<name>album_name</name>
-				<type>text</type>
-				<notnull>true</notnull>
-				<length>100</length>
-			</field>
-			<field>
-				<name>album_path</name>
-				<type>text</type>
-				<notnull>true</notnull>
-				<length>256</length>
-			</field>
-			<field>
-				<name>parent_path</name>
+				<name>path</name>
 				<type>text</type>
 				<notnull>true</notnull>
 				<length>256</length>
 			</field>
-		</declaration>
-	</table>
-	<table>
-		<name>*dbprefix*gallery_photos</name>
-		<declaration>
 			<field>
-				<name>photo_id</name>
+				<name>width</name>
 				<type>integer</type>
-				<default>0</default>
 				<notnull>true</notnull>
-				<autoincrement>1</autoincrement>
 				<length>4</length>
 			</field>
 			<field>
-				<name>album_id</name>
+				<name>height</name>
 				<type>integer</type>
-				<default>0</default>
 				<notnull>true</notnull>
 				<length>4</length>
 			</field>
-			<field>
-				<name>file_path</name>
-				<type>text</type>
-				<notnull>true</notnull>
-				<length>256</length>
-			</field>
 		</declaration>
 	</table>
   <table>
diff --git a/apps/gallery/appinfo/update.php b/apps/gallery/appinfo/update.php
new file mode 100644
index 0000000000000000000000000000000000000000..a0997ab5e86f88e46ff11a7dabfa24d8599af680
--- /dev/null
+++ b/apps/gallery/appinfo/update.php
@@ -0,0 +1,11 @@
+<?php
+
+$currentVersion=OC_Appconfig::getValue('gallery', 'installed_version');
+if (version_compare($currentVersion, '0.5.0', '<')) {
+	$stmt = OCP\DB::prepare('DROP TABLE IF EXISTS *PREFIX*gallery_photos');
+	$stmt->execute();
+	$stmt = OCP\DB::prepare('DROP TABLE IF EXISTS *PREFIX*gallery_albums');
+	$stmt->execute();
+
+	\OC_DB::createDbFromStructure(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml');
+}
diff --git a/apps/gallery/appinfo/version b/apps/gallery/appinfo/version
index 17b2ccd9bf9050efdf57d7800677e87919b9b5b9..8f0916f768f0487bcf8d33827ce2c8dcecb645c1 100644
--- a/apps/gallery/appinfo/version
+++ b/apps/gallery/appinfo/version
@@ -1 +1 @@
-0.4.3
+0.5.0
diff --git a/apps/gallery/index.php b/apps/gallery/index.php
index a9fe200c4e4ba44e2e683c9bb0a0f53b39e347f1..9d4654a7cc5f648f146aabd077a10d8daef1f6f8 100644
--- a/apps/gallery/index.php
+++ b/apps/gallery/index.php
@@ -27,26 +27,6 @@ OCP\User::checkLoggedIn();
 OCP\App::checkAppEnabled('gallery');
 OCP\App::setActiveNavigationEntry( 'gallery_index' );
 
-if (!isset($_GET['view'])) {
-  $result = OC_Gallery_Album::find(OCP\USER::getUser());
-
-  $r = array();
-  while ($row = $result->fetchRow())
-    $r[] = $row;
-
-  $tmpl = new OCP\Template( 'gallery', 'index', 'user' );
-  $tmpl->assign('r', $r);
-  $tmpl->printPage();
-} else {
-  $result = OC_Gallery_Photo::findForAlbum(OCP\USER::getUser(), $_GET['view']);
-
-  $photos = array();
-  while ($p = $result->fetchRow())
-    $photos[] = $p['file_path'];
-  
-  $tmpl = new OCP\Template( 'gallery', 'view_album', 'user' );
-  $tmpl->assign('photos', $photos);
-  $tmpl->assign('albumName', $_GET['view']);
-  $tmpl->printPage();
-}
+$tmpl = new OCP\Template( 'gallery', 'index', 'user' );
+$tmpl->printPage();
 ?>
diff --git a/apps/gallery/lib/album.php b/apps/gallery/lib/album.php
index 8ac27b1a70dca912560e16d0b5486a4470ab3348..39d6d3aded1b0c35f8b26ba658acc6e4d6d465a0 100644
--- a/apps/gallery/lib/album.php
+++ b/apps/gallery/lib/album.php
@@ -90,7 +90,7 @@ class OC_Gallery_Album {
 	}
 
 	public static function changeThumbnailPath($oldname, $newname) {
-		$view = OCP\App::getStorage('gallery');
+		$view = OCP\Files::getStorage('gallery');
 		$view->rename($oldname.'.png', $newname.'.png');
 	}
 
diff --git a/apps/gallery/lib/managers.php b/apps/gallery/lib/managers.php
new file mode 100644
index 0000000000000000000000000000000000000000..2444659d0a47096f7d09460eb8b237ea9c5d8bc2
--- /dev/null
+++ b/apps/gallery/lib/managers.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace OC\Pictures;
+
+require_once('lib/base.php');
+
+\OCP\JSON::checkLoggedIn();
+\OCP\JSON::checkAppEnabled('gallery');
+
+class DatabaseManager {
+	private static $instance = null;
+	const TAG = 'DatabaseManager';
+	
+	public static function getInstance() {
+		if (self::$instance === null)
+			self::$instance = new DatabaseManager();
+		return self::$instance;
+	}
+	
+	public function getFileData($path) {
+		$gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery';
+		$path = $gallery_path.$path;
+		$stmt = \OCP\DB::prepare('SELECT * FROM *PREFIX*pictures_images_cache WHERE uid_owner LIKE ? AND path = ?');
+		$result = $stmt->execute(array(\OCP\USER::getUser(), $path));
+		if (($row = $result->fetchRow()) != false) {
+			return $row;
+		}
+		$image = new \OC_Image();
+		if (!$image->loadFromFile($path)) {
+			return false;
+		}
+		\OCP\DB::beginTransaction();
+		$stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)');
+		$stmt->execute(array(\OCP\USER::getUser(), $path, $image->width(), $image->height()));
+		\OCP\DB::commit();
+    $ret = array('filepath' => $path, 'width' => $image->width(), 'height' => $image->height());
+		unset($image);
+    return $ret;
+	}
+	
+	private function __construct() {}
+}
+
+class ThumbnailsManager {
+	
+	private static $instance = null;
+	const TAG = 'ThumbnailManager';
+	
+	public static function getInstance() {
+		if (self::$instance === null)
+			self::$instance = new ThumbnailsManager();
+		return self::$instance;
+	}
+
+	public function getThumbnail($path) {
+		$gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery';
+		if (file_exists($gallery_path.$path)) {
+			return new \OC_Image($gallery_path.$path);
+		}
+		if (!\OC_Filesystem::file_exists($path)) {
+			\OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN);
+			return false;
+		}
+		$image = new \OC_Image();
+		$image->loadFromFile(\OC_Filesystem::getLocalFile($path));
+		if (!$image->valid()) return false;
+
+		$image->fixOrientation();
+
+		$ret = $image->preciseResize(floor((150*$image->width())/$image->height()), 150);
+		
+		if (!$ret) {
+			\OC_Log::write(self::TAG, 'Couldn\'t resize image', \OC_Log::ERROR);
+			unset($image);
+			return false;
+		}
+
+		$image->save($gallery_path.'/'.$path);
+		return $image;
+	}
+	
+	public function getThumbnailInfo($path) {
+		$arr = DatabaseManager::getInstance()->getFileData($path);
+		$ret = array('filepath' => $arr['path'],
+		             'width' => $arr['width'],
+		             'height' => $arr['height']);
+		return $ret;
+	}
+	
+	public function delete($path) {
+		unlink(\OC::$CONFIG_DATADIRECTORY_ROOT.'/'.\OC_User::getUser()."/gallery".$path);
+	}
+	
+	private function __construct() {}
+
+}
+?>
diff --git a/apps/gallery/lib/photo.php b/apps/gallery/lib/photo.php
index b4b37236b0e71fcec00dcbfeaa71617edf90f47c..f9527cb5fdbe8301ad70265b25c40e2e01a5ca58 100644
--- a/apps/gallery/lib/photo.php
+++ b/apps/gallery/lib/photo.php
@@ -68,7 +68,7 @@ class OC_Gallery_Photo {
 
 	public static function getThumbnail($image_name, $owner = null) {
 		if (!$owner) $owner = OCP\USER::getUser();
-		$view = OCP\App::getStorage('gallery');
+		$view = OCP\Files::getStorage('gallery');
 		$save_dir = dirname($image_name);
 		if (!$view->is_dir($save_dir)) {
 			$view->mkdir($save_dir);
diff --git a/apps/gallery/lib/scanner.php b/apps/gallery/lib/scanner.php
index e11ba1da454dc49ccefac1166e49a765c60c5c79..233fa20bca7aea21fb5d7ab3f08e46313aee6ee4 100644
--- a/apps/gallery/lib/scanner.php
+++ b/apps/gallery/lib/scanner.php
@@ -81,7 +81,7 @@ class OC_Gallery_Scanner {
 				$image->destroy();
 			}
 		}
-		$view = OCP\App::getStorage('gallery');
+		$view = OCP\Files::getStorage('gallery');
 		imagepng($thumbnail, $view->getLocalFile($albumName.'.png'));
 		imagedestroy($thumbnail);
 	}
diff --git a/apps/gallery/lib/tiles.php b/apps/gallery/lib/tiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff9519142ac8a058623636850e181e9d7256c451
--- /dev/null
+++ b/apps/gallery/lib/tiles.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace OC\Pictures;
+
+require_once('lib/base.php');
+require_once('managers.php');
+
+const TAG = 'Pictures';
+const IMAGE_WIDTH = 150;
+
+class TileBase {
+	public function getWidth() { return false; }
+
+	public function getHeight() { return IMAGE_WIDTH; }
+
+	public function getOnHoverAction() { return false; }
+	
+	public function getOnOutAction() { return false; }
+	
+	public function getOnClickAction() { return false; }
+
+	public function getDisplayedLayer() { return false; }
+
+	public function getTileProportion() { return false; }
+	
+	public function get() { return false; }
+}
+
+class TilesLine {
+
+	public function __construct() {
+		$this->tiles_array = array();
+	}
+
+	public function setAvailableSpace($space) {
+		$available_space = $space;
+	}
+
+	public function getTilesCount() {
+		return count($this->tiles_array);
+	}
+
+	public function addTile($tile) {
+		array_push($this->tiles_array, $tile);
+	}
+
+	public function getLeftSpace() {
+		$occupied_space = 0;
+		for ($i = 0; $i < count($this->tiles_array); $i++) {
+			$occupied_space += $this->tiles_array[$i]->getWidth();
+		}
+		return $this->available_space - $occupied_space;
+	}
+
+	public function tileWillFit($tile) {
+		return $this->getLeftSpace() > $tile->getWidth();
+	}
+	
+	public function get() {
+		$r = '<div class="line gallery_div">';
+		
+		for ($i = 0; $i < count($this->tiles_array); $i++) {
+				$img_w = $this->tiles_array[$i]->getWidth();
+				$extra = '';
+				if ($img_w != IMAGE_WIDTH) $extra = ' style="width:'.$img_w.'px"';
+			$r .= '<div class="gallery_div" '.$extra.' onmouseover="'.$this->tiles_array[$i]->getOnHoverAction().'" onmouseout="'.$this->tiles_array[$i]->getOnOutAction().'" onclick="'.$this->tiles_array[$i]->getOnClickAction().'">'.$this->tiles_array[$i]->get().'</div>';
+		}
+		
+		$r .= '</div>';
+		return $r;
+	}
+
+	private $tiles_array;
+	private $available_space;
+}
+
+class TileSingle extends TileBase {
+
+	public function __construct($path) {
+		\OC_Log::write(TAG, 'Loading file from path '.$path, \OC_Log::DEBUG);
+		$this->file_path = $path;
+/*		$this->image = new \OC_Image();
+		if (!$this->image->loadFromFile($this->file_path)) {
+			\OC_Log::write(TAG, 'Loading file filed', \OC_Log::ERROR);
+			return;
+		}
+		$this->image->fixOrientation();*/
+	}
+
+	public function getWidth() {
+		$a = ThumbnailsManager::getInstance()->getThumbnailInfo($this->file_path);
+		return $a['width'];
+	}
+	
+	public function get($extra = '') {
+		//	!HACK! file path needs to be encoded twice because files app decode twice url, so any special chars like + or & in filename
+		//	!HACK! will result in failing of opening them 
+		return '<a rel="images" title="'.basename($this->getPath()).'" href="'.\OCP\Util::linkTo('files', 'download.php').'?file='.urlencode(urlencode($this->getPath())).'"><img rel="images" src="'.\OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()).'" '.$extra.'></a>';
+	}
+	
+	public function getMiniatureSrc() {
+		return \OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath());
+	}
+
+	public function getPath() {
+		return $this->file_path;
+	}
+	
+	public function getOnClickAction() {
+		return '';//'javascript:openFile(\''.$this->file_path.'\');';
+	}
+
+	private $file_path;
+	private $image;
+}
+
+class TileStack extends TileBase {
+
+	const STACK_REPRESENTATIVES = 3;
+
+	public function __construct($path_array, $stack_name) {
+		$this->tiles_array = array();
+		$this->stack_name = $stack_name;
+		for ($i = 0; $i < count($path_array) && $i < self::STACK_REPRESENTATIVES; $i++) {
+		$tile = new TileSingle($path_array[$i]);
+			array_push($this->tiles_array, $tile);
+		}
+	}
+	
+	public function forceSize($width_must_fit=false) {
+		for ($i = 0; $i < count($this->tiles_array); $i++)
+			$this->tiles_array[$i]->forceSize(true);
+	}
+
+	public function getWidth() {
+		$max = 0;
+		for ($i = 0; $i < count($this->tiles_array); $i++) {
+			$max = max($max, $this->tiles_array[$i]->getWidth());
+		}
+		return min(IMAGE_WIDTH, $max);
+	}
+
+	public function get() {
+		$r = '<div class="title gallery_div">'.$this->stack_name.'</div>';
+		for ($i = 0; $i < count($this->tiles_array); $i++) {
+			$top = rand(-5, 5);
+			$left = rand(-5, 5);
+			$img_w = $this->tiles_array[$i]->getWidth();
+			$extra = '';
+			if ($img_w < IMAGE_WIDTH) {
+				$extra = 'width:'.$img_w.'px;';
+			}
+			$r .= '<div class="miniature_border gallery_div" style="background-image:url(\''.$this->tiles_array[$i]->getMiniatureSrc().'\');margin-top:'.$top.'px; margin-left:'.$left.'px;'.$extra.'"></div>';
+		}
+		return $r;
+	}
+
+	public function getOnHoverAction() {
+		return 'javascript:t(this);return false;';
+	}
+	
+	public function getOnOutAction() {
+		return 'javascript:o(this);return false;';
+	}
+
+	public function getCount() {
+		return count($this->tiles_array);
+	}
+	
+	public function getOnClickAction() {
+		return 'javascript:openNewGal(\''.$this->stack_name.'\');';
+	}
+
+	private $tiles_array;
+	private $stack_name;
+}
+
+?>
diff --git a/apps/gallery/lib/tiles_test.php b/apps/gallery/lib/tiles_test.php
new file mode 100644
index 0000000000000000000000000000000000000000..022a88f75cc2095ce03705ce0c9b778c39d68544
--- /dev/null
+++ b/apps/gallery/lib/tiles_test.php
@@ -0,0 +1,87 @@
+<?php
+$l = OC_L10N::get('gallery');
+?>
+<style>
+div.gallery_div {position:relative; display: inline-block; height: 202px; width: 200px; margin: 5px;}
+div.miniature_border {position:absolute; height: 200px; -webkit-transition-duration: .2s; background-position: 50%;}
+div.line {display:inline-block; border: 0; width: auto; height: 210px}
+div.gallery_div img{position:absolute; top: 1; left: 0; -webkit-transition-duration: 0.3s; height:200px; width: auto;}
+div.gallery_div img.shrinker {width:80px !important;}
+div.title { opacity: 0; text-align: center; vertical-align: middle; font-family: Arial; font-size: 12px; border: 0; position: absolute; text-overflow: ellipsis; bottom: 20px; left:10px; height:auto; padding: 5px; width: 170px; background-color: black; color: white; -webkit-transition: opacity 0.5s;  z-index:1000; border-radius: 7px}
+div.visible { opacity: 0.8;}
+</style>
+<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
+<script type="text/javascript">
+function t(element) {
+	$('div', element).each(function(index, elem) {
+	 	if ($(elem).hasClass('title')) {
+		 	$(elem).addClass('visible');
+	 	} else {
+			$(elem).css('margin-top', Math.floor(30-(Math.random()*60)) + 'px')
+			       .css('margin-left', Math.floor(30-(Math.random()*60))+ 'px')
+			       .css('z-index', '999');
+		}
+	});
+}
+
+function o(element) {
+	$('div', element).each(function(index, elem) {
+	 	if ($(elem).hasClass('title')) {
+		 	$(elem).removeClass('visible');
+	 	} else {
+			$(elem).css('margin-top', Math.floor(5-(Math.random()*10)) + 'px')
+		    	   .css('margin-left', Math.floor(5-(Math.random()*10))+ 'px')
+		    	   .css('z-index', '3');
+		}
+	});
+}
+
+</script>
+
+<?php
+
+include('apps/gallery/lib/tiles.php');
+$root = empty($_GET['root'])?'/':$_GET['root'];
+
+$images = \OC_FileCache::searchByMime('image', null, '/bartek/files'.$root);
+sort($images);
+
+$arr = array();
+$tl = new \OC\Pictures\TilesLine();
+$ts = new \OC\Pictures\TileStack(array(), '');
+$previous_element = $images[0];
+for($i = 0; $i < count($images); $i++) {
+    error_log($images[$i]);
+	$prev_dir_arr = explode('/', $previous_element);
+	$dir_arr = explode('/', $images[$i]);
+
+	if (count($dir_arr)==1) {
+		$tl->addTile(new \OC\Pictures\TileSingle($images[$i]));
+		continue;
+	}
+	if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) {
+		$tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0]));
+		$arr = array();
+	}
+	$arr[] = $root.$images[$i];
+	$previous_element = $images[$i];
+}
+
+$dir_arr = explode('/', $previous_element);
+
+if (count($dir_arr)==0) {
+	$tl->addTile(new \OC\Pictures\TileSingle($previous_element));
+} else if (count($dir_arr) && $ts->getCount() == 0){
+    $ts = new \OC\Pictures\TileStack(array($previous_element), $dir_arr[0]);
+} else {
+	$arr[] = $previous_element;
+	$ts->addTile($arr);
+}
+
+if ($ts->getCount() != 0) {
+	$tl->addTile($ts);
+}
+
+echo $tl->get();
+
+?>
diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php
index 99af3bda0a3a00978669c29f70b029b8cf999921..39e3bbf47b304706586910d1b2eec0ee8f7338ab 100644
--- a/apps/gallery/templates/index.php
+++ b/apps/gallery/templates/index.php
@@ -1,31 +1,105 @@
 <?php
-OCP\Util::addStyle('gallery', 'styles');
-OCP\Util::addscript('gallery', 'albums');
-OCP\Util::addscript('gallery', 'scanner');
-OCP\Util::addscript('gallery', 'album_cover');
-OCP\Util::addStyle('files', 'files');
-OCP\Util::addscript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack');
-OCP\Util::addscript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
-OCP\Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' );
+
 $l = OC_L10N::get('gallery');
 ?>
-<script type="text/javascript">var gallery_scanning_root='<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'gallery', 'root', '/'); ?>'; var gallery_default_order = '<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'gallery', 'order', 'ASC'); ?>';</script>
-<div id="controls">
-	<div id="scan">
-		<div id="scanprogressbar"></div>
-		<input type="button" class="start" value="<?php echo $l->t('Rescan');?>" onclick="javascript:scanForAlbums();" />
-    <input type="button" class="stop" style="display:none" value="<?php echo $l->t('Stop');?>" onclick="javascript:Scanner.stop();" />
-    <input type="button" id="g-share-button" value="<?php echo $l->t('Share'); ?>" onclick="javascript:shareGallery();" />
-		<input type="button" id="g-settings-button" value="<?php echo $l->t('Settings');?>" onclick="javascript:settings();"/>
-	</div>
-	<div id="g-album-navigation">
-		<div class="crumb last" style="background-image:url('<?php echo OC::$WEBROOT;?>/core/img/breadcrumb.png')">
-			<a href="javascript:returnToElement(0);">main</a>
-		</div>
-	</div>
-	<div id="g-album-loading" class="crumb" style="display:none">
-		<img src="<?php echo OCP\Util::linkTo('gallery', 'img/loading.gif'); ?>">
-	</div>
-</div>
-<div id="gallery_list">
-</div>
+<style>
+div.gallery_div {position:relative; display: inline-block; height: 152px; width: 150px; margin: 5px;}
+div.miniature_border {position:absolute; height: 150px; -webkit-transition-duration: .2s; background-position: 50%;}
+div.line {display:inline-block; border: 0; width: auto; height: 160px}
+div.gallery_div img{position:absolute; top: 1; left: 0; -webkit-transition-duration: 0.3s; height:150px; width: auto;}
+div.gallery_div img.shrinker {width:80px !important;}
+div.title { opacity: 0; text-align: center; vertical-align: middle; font-family: Arial; font-size: 12px; border: 0; position: absolute; text-overflow: ellipsis; bottom: 20px; left:5px; height:auto; padding: 5px; width: 140px; background-color: black; color: white; -webkit-transition: opacity 0.5s;  z-index:1000; border-radius: 7px}
+div.visible { opacity: 0.8;}
+</style>
+<script type="text/javascript">
+
+var root = "<?php echo !empty($_GET['root']) ? $_GET['root'] : '/'; ?>";
+
+function t(element) {
+	$('div', element).each(function(index, elem) {
+	 	if ($(elem).hasClass('title')) {
+		 	$(elem).addClass('visible');
+	 	} else {
+			$(elem).css('margin-top', Math.floor(30-(Math.random()*60)) + 'px')
+			       .css('margin-left', Math.floor(30-(Math.random()*60))+ 'px')
+			       .css('z-index', '999');
+		}
+	});
+}
+
+function o(element) {
+	$('div', element).each(function(index, elem) {
+	 	if ($(elem).hasClass('title')) {
+		 	$(elem).removeClass('visible');
+	 	} else {
+			$(elem).css('margin-top', Math.floor(5-(Math.random()*10)) + 'px')
+		    	   .css('margin-left', Math.floor(5-(Math.random()*10))+ 'px')
+		    	   .css('z-index', '3');
+		}
+	});
+}
+
+function openNewGal(album_name) {
+	root = root + album_name + "/";
+	var url = window.location.toString().replace(window.location.search, '');
+  url = url + "?app=gallery&root="+encodeURIComponent(root);
+	
+	window.location = url;
+}
+
+$(document).ready(function() {
+		$("a[rel=images]").fancybox({
+			'titlePosition': 'inside'
+		});
+});
+
+</script>
+
+<?php
+
+include('apps/gallery/lib/tiles.php');
+$root = empty($_GET['root'])?'/':$_GET['root'];
+
+$images = \OC_FileCache::searchByMime('image', null, '/'.\OCP\USER::getUser().'/files'.$root);
+sort($images);
+
+$arr = array();
+$tl = new \OC\Pictures\TilesLine();
+$ts = new \OC\Pictures\TileStack(array(), '');
+$previous_element = $images[0];
+for($i = 0; $i < count($images); $i++) {
+	$prev_dir_arr = explode('/', $previous_element);
+	$dir_arr = explode('/', $images[$i]);
+
+	if (count($dir_arr)==1) {
+		$tl->addTile(new \OC\Pictures\TileSingle($root.$images[$i]));
+		continue;
+	}
+	if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) {
+		$tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0]));
+		$arr = array();
+	}
+	$arr[] = $root.$images[$i];
+	$previous_element = $images[$i];
+}
+
+$dir_arr = explode('/', $previous_element);
+
+if (count($images)>1) {
+  if (count($dir_arr)==0) {
+    $tl->addTile(new \OC\Pictures\TileSingle($previous_element));
+  } else if (count($dir_arr) && $ts->getCount() == 0){
+      $ts = new \OC\Pictures\TileStack(array($root.$previous_element), $dir_arr[0]);
+  } else {
+    $arr[] = $previous_element;
+    $ts->addTile($arr);
+  }
+}
+
+if ($ts->getCount() != 0) {
+	$tl->addTile($ts);
+}
+
+echo $tl->get();
+
+?>
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index baca1d32bad50806aeb2283e8f9600a79a910f9a..62e7c8ca6bc495a4c01e9cb8d5e9c7ef73be1061 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -27,6 +27,11 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 	protected $ldapGroupMemberAssocAttr;
 	protected $configured = 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');
@@ -48,6 +53,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		if(!$this->configured) {
 			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);
 		// just in case
@@ -64,8 +72,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		//TODO: this can be done with one LDAP query
 		if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
 			$dns = array();
-			foreach($members as $uid) {
-				$filter = str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'));
+			foreach($members as $mid) {
+				$filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter'));
 				$ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
 				if(count($ldap_users) < 1) {
 					continue;
@@ -75,7 +83,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 			$members = $dns;
 		}
 
-		return in_array($dn_user, $members);
+		$this->_group_user[$gid][$uid] = in_array($dn_user, $members);
+		return $this->_group_user[$gid][$uid];
 	}
 
 	/**
@@ -90,8 +99,12 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		if(!$this->configured) {
 			return array();
 		}
+		if(isset($this->_user_groups[$uid])) {
+			return $this->_user_groups[$uid];
+		}
 		$userDN = OC_LDAP::username2dn($uid);
 		if(!$userDN) {
+			$this->_user_groups[$uid] = array();
 			return array();
 		}
 
@@ -112,9 +125,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 			$this->ldapGroupMemberAssocAttr.'='.$uid
 		));
 		$groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
-		$userGroups = OC_LDAP::ownCloudGroupNames($groups);
+		$this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING);
 
-		return array_unique($userGroups, SORT_LOCALE_STRING);
+		return $this->_user_groups[$uid];
 	}
 
 	/**
@@ -125,14 +138,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		if(!$this->configured) {
 			return array();
 		}
+		if(isset($this->_group_users[$gid])) {
+			return $this->_group_users[$gid];
+		}
 
 		$groupDN = OC_LDAP::groupname2dn($gid);
 		if(!$groupDN) {
+			$this->_group_users[$gid] = array();
 			return array();
 		}
 
 		$members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr);
 		if(!$members) {
+			$this->_group_users[$gid] = array();
 			return array();
 		}
 
@@ -154,7 +172,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		if(!$isMemberUid) {
 			$result = array_intersect($result, OCP\User::getUsers());
 		}
-		return array_unique($result, SORT_LOCALE_STRING);
+		$this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING);
+		return $this->_group_users[$gid];
 	}
 
 	/**
@@ -167,10 +186,11 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
 		if(!$this->configured) {
 			return array();
 		}
-
-		$ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
-		$groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
-		return $groups;
+		if(is_null($this->_groups)) {
+			$ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
+			$this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+		}
+		return $this->groups;
 	}
 
 	/**
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
index b900a67ec312d14940c4c480d93d4ce64f641810..22d464b65a21229192580df54783f939cceff51d 100644
--- a/apps/user_ldap/lib_ldap.php
+++ b/apps/user_ldap/lib_ldap.php
@@ -52,6 +52,8 @@ class OC_LDAP {
 	static protected $ldapGroupDisplayName;
 	static protected $ldapLoginFilter;
 
+	static protected $__d;
+
 	/**
 	 * @brief initializes the LDAP backend
 	 * @param $force read the config settings no matter what
@@ -59,6 +61,9 @@ class OC_LDAP {
 	 * 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();
 	}
@@ -258,7 +263,7 @@ class OC_LDAP {
 			$key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
 
 			//everything is fine when we know the group
-			if($key) {
+			if($key !== false) {
 				$ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
 				continue;
 			}
@@ -329,30 +334,6 @@ class OC_LDAP {
 		return $query->execute()->fetchAll();
 	}
 
-	/**
-	 * @brief inserts a new group into the mappings table
-	 * @param $dn the record in question
-	 * @param $ocname the name to use in ownCloud
-	 * @returns true on success, false otherwise
-	 *
-	 * inserts a new group into the mappings table
-	 */
-	static private function mapGroup($dn, $ocname) {
-		return self::mapComponent($dn, $ocname, false);
-	}
-
-	/**
-	 * @brief inserts a new user into the mappings table
-	 * @param $dn the record in question
-	 * @param $ocname the name to use in ownCloud
-	 * @returns true on success, false otherwise
-	 *
-	 * inserts a new user into the mappings table
-	 */
-	static private function mapUser($dn, $ocname) {
-		return self::mapComponent($dn, $ocname, true);
-	}
-
 	/**
 	 * @brief inserts a new user or group into the mappings table
 	 * @param $dn the record in question
@@ -380,12 +361,22 @@ class OC_LDAP {
 					SELECT 1
 					FROM '.$table.'
 					WHERE ldap_dn = ?
-						AND owncloud_name = ? )
+						OR owncloud_name = ? )
 		');
 
 		$res = $insert->execute(array($dn, $ocname, $dn, $ocname));
 
-		return !OCP\DB::isError($res);
+		if(OCP\DB::isError($res)) {
+			return false;
+		}
+
+		$insRows = $res->numRows();
+
+		if($insRows == 0) {
+			return false;
+		}
+
+		return true;
 	}
 
 	static public function fetchListOfUsers($filter, $attr) {
@@ -530,7 +521,7 @@ class OC_LDAP {
 
 	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+/',',',$dn);
+		$dn = preg_replace('/([^\\\]),(\s+)/','\1,',$dn);
 
 		//make comparisons and everything work
 		$dn = strtolower($dn);
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index ba66c7a9ca8443147a3943aaec9f821f0de962da..9281aebe81d90b718d96e049d564cf5fe1c6f2f0 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -34,6 +34,9 @@ class OC_USER_LDAP extends OC_User_Backend {
 	// will be retrieved from LDAP server
 	protected $ldap_dc = false;
 
+	// 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', '');
@@ -108,9 +111,11 @@ class OC_USER_LDAP extends OC_User_Backend {
 	 * Get a list of all users.
 	 */
 	public function getUsers(){
-		$ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn'));
-		$users = OC_LDAP::ownCloudUserNames($ldap_users);
-		return $users;
+		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);
+		}
+		return $this->_users;
 	}
 
 	/**
@@ -119,7 +124,7 @@ class OC_USER_LDAP extends OC_User_Backend {
 	 * @return boolean
 	 */
 	public function userExists($uid){
-		return in_array($uid, self::getUsers());
+		return in_array($uid, $this->getUsers());
 	}
 
 }
diff --git a/apps/user_migrate/js/export.js b/apps/user_migrate/js/export.js
index 2d660b2de6b4c154116d09db8ef60c4889b79ef1..aef45c45a7b05a204f5fe2c85e5286fe87d3afde 100644
--- a/apps/user_migrate/js/export.js
+++ b/apps/user_migrate/js/export.js
@@ -9,7 +9,7 @@ $(document).ready(function(){
 			function(result){
 				if(result.status == 'success'){
 					// Download the file
-					window.location = OC.filePath('user_migrate','ajax','export.php?operation=download')	;
+					window.location = OC.linkTo('user_migrate','ajax/export.php') + '?operation=download';
 					$('.loading').hide();
 					$('#exportbtn').val(t('user_migrate', 'Export'));
 				} else {
diff --git a/config/config.sample.php b/config/config.sample.php
index 7ab327e2bce9da619c590e5ebfba0e6fded74371..c81e4a34eba1d1cdfd5420fa917a57c025d4000e 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -3,37 +3,66 @@
 define("DEBUG", true);
 
 $CONFIG = array(
+/* Flag to indicate OwnCloud is successfully installed (true = installed) */
 "installed" => false,
+/* Type of database, can be sqlite, mysql or pgsql */
 "dbtype" => "sqlite",
+/* Name of the OwnCloud database */
 "dbname" => "owncloud",
+/* User to access the OwnCloud database */
 "dbuser" => "",
+/* Password to access the OwnCloud database */
 "dbpassword" => "",
+/* Host running the OwnCloud database */
 "dbhost" => "",
+/* Prefix for the OwnCloud tables in the database */
 "dbtableprefix" => "",
+/* Force use of HTTPS connection (true = use HTTPS) */
 "forcessl" => false,
-"enablebackup" => false,
+/* Theme to use for OwnCloud */
 "theme" => "",
+/* Path to the 3rdparty directory */
 "3rdpartyroot" => "",
+/* URL to the 3rdparty directory, as seen by the browser */
 "3rdpartyurl" => "",
+/* Default app to load on login */
 "defaultapp" => "files",
+/* Enable the help menu item in the settings */
 "knowledgebaseenabled" => true,
-"knowledgebaseurl" => "",
+/* URL to use for the help page, server should understand OCS */
+"knowledgebaseurl" => "http://api.apps.owncloud.com/v1",
+/* Enable installing apps from the appstore */
 "appstoreenabled" => true,
-"appstoreurl" => "",
+/* URL of the appstore to use, server should understand OCS */
+"appstoreurl" => "http://api.apps.owncloud.com/v1",
+/* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
 "mail_smtpmode" => "sendmail",
+/* Host to use for sending mail, depends on mail_smtpmode if this is used */
 "mail_smtphost" => "127.0.0.1",
+/* authentication needed to send mail, depends on mail_smtpmode if this is used
+ * (false = disable authentication)
+ */
 "mail_smtpauth" => false,
+/* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
 "mail_smtpname" => "",
+/* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
 "mail_smtppassword" => "",
+/* Check 3rdparty apps for malicious code fragments */
 "appcodechecker" => "",
-"log_type" => "",
+/* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
+"log_type" => "owncloud",
+/* File for the owncloud logger to log to, (default is ownloud.log in the data dir */
 "logfile" => "",
+/* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
 "loglevel" => "",
 /* Set this to false to disable the check for writable apps dir.
  * If the apps dir is not writable, you can't download&install extra apps
  * in the admin apps menu.
  */
 "writable_appsdir" => true,
+/* The directory where the user data is stored, default to data in the owncloud
+ * directory. The sqlite database is also stored here, when sqlite is used.
+ */
 // "datadirectory" => ""
 );
 ?>
diff --git a/core/lostpassword/index.php b/core/lostpassword/index.php
index f1d90eaeffea646816d7843555949ac24f80c097..6bed7bdd93f7412568cb96c6ba6d96e234aaa488 100644
--- a/core/lostpassword/index.php
+++ b/core/lostpassword/index.php
@@ -23,7 +23,6 @@ if (isset($_POST['user'])) {
 			$msg = $tmpl->fetchPage();
 			$l = OC_L10N::get('core');
 			$from = 'lostpassword-noreply@' . OCP\Util::getServerHost();
-			$r=mail($email, $l->t('Owncloud password reset'), $msg, 'From:' . $from);
 			OC_MAIL::send($email,$_POST['user'],$l->t('ownCloud password reset'),$msg,$from,'ownCloud');
 			echo('sent');
 
diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php
index 7f5a4d50fc6b827d9f84019f32c7f03e545c0f71..55cc8008d9a483e805d911741955b63debb4cbb0 100644
--- a/core/templates/layout.guest.php
+++ b/core/templates/layout.guest.php
@@ -4,7 +4,7 @@
 		<title>ownCloud</title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 		<link rel="shortcut icon" href="<?php echo image_path('', 'favicon.png'); ?>" /><link rel="apple-touch-icon-precomposed" href="<?php echo image_path('', 'favicon-touch.png'); ?>" />
-		<?php if (!defined('DEBUG') || !DEBUG): ?>
+		<?php if (!empty(OC_Util::$core_styles)): ?>
 		<link rel="stylesheet" href="<?php echo OC_Helper::linkToRemote('core.css', false) ?>" type="text/css" media="screen" />
 		<?php endif ?>
 		<?php foreach($_['cssfiles'] as $cssfile): ?>
@@ -14,7 +14,7 @@
 			var oc_webroot = '<?php echo OC::$WEBROOT; ?>';
 			var oc_appswebroot = '<?php echo OC::$APPSWEBROOT; ?>';
 		</script>
-		<?php if (!defined('DEBUG') || !DEBUG): ?>
+		<?php if (!empty(OC_Util::$core_scripts)): ?>
 		<script type="text/javascript" src="<?php echo OC_Helper::linkToRemote('core.js', false) ?>"></script>
 		<?php endif ?>
 		<?php foreach($_['jsfiles'] as $jsfile): ?>
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 8f6c029007fc59b4e3b3954bfba06c13e6667faa..e04fcabf137ee0ddfd6503b58818db974de82443 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -4,7 +4,7 @@
 		<title><?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getUser()?' ('.OC_User::getUser().') ':'' ?></title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 		<link rel="shortcut icon" href="<?php echo image_path('', 'favicon.png'); ?>" /><link rel="apple-touch-icon-precomposed" href="<?php echo image_path('', 'favicon-touch.png'); ?>" />
-		<?php if (!defined('DEBUG') || !DEBUG): ?>
+		<?php if (!empty(OC_Util::$core_styles)): ?>
 		<link rel="stylesheet" href="<?php echo OC_Helper::linkToRemote('core.css', false) ?>" type="text/css" media="screen" />
 		<?php endif ?>
 		<?php foreach($_['cssfiles'] as $cssfile): ?>
@@ -15,7 +15,7 @@
 			var oc_appswebroot = '<?php echo OC::$APPSWEBROOT; ?>';
 			var oc_current_user = '<?php echo OC_User::getUser() ?>';
 		</script>
-		<?php if (!defined('DEBUG') || !DEBUG): ?>
+		<?php if (!empty(OC_Util::$core_scripts)): ?>
 		<script type="text/javascript" src="<?php echo OC_Helper::linkToRemote('core.js', false) ?>"></script>
 		<?php endif ?>
 		<?php foreach($_['jsfiles'] as $jsfile): ?>
diff --git a/lib/app.php b/lib/app.php
index 667633e2647f5e72ae07dbd1da8d4f31431e66f0..e8a5a1291d912e3706ec0708d52e65f0e166a52d 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -67,6 +67,11 @@ class OC_App{
 				OC_Util::$scripts = array();
 				OC_Util::$core_styles = OC_Util::$styles;
 				OC_Util::$styles = array();
+
+				if (!OC_AppConfig::getValue('core', 'remote_core.css', false)) {
+					OC_AppConfig::setValue('core', 'remote_core.css', '/core/minimizer.php');
+					OC_AppConfig::setValue('core', 'remote_core.js', '/core/minimizer.php');
+				}
 			}
 		}
 		// return
diff --git a/lib/base.php b/lib/base.php
index a439651f4a6178c641e570123a9fa700fe5b5928..4bd165862bb5ded1cdacc1ec132b1fb4f02ba31a 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -271,7 +271,7 @@ class OC{
 		ini_set('session.cookie_httponly','1;');
 		session_start();
 	}
-	
+
 	public static function loadapp(){
 		if(file_exists(OC::$APPSROOT . '/apps/' . OC::$REQUESTEDAPP . '/index.php')){
 			require_once(OC::$APPSROOT . '/apps/' . OC::$REQUESTEDAPP . '/index.php');
@@ -279,7 +279,7 @@ class OC{
 			trigger_error('The requested App was not found.', E_USER_ERROR);//load default app instead?
 		}
 	}
-	
+
 	public static function loadfile(){
 		if(file_exists(OC::$APPSROOT . '/apps/' . OC::$REQUESTEDAPP . '/' . OC::$REQUESTEDFILE)){
 			if(substr(OC::$REQUESTEDFILE, -3) == 'css'){
@@ -289,7 +289,7 @@ class OC{
 				exit;
 			}elseif(substr(OC::$REQUESTEDFILE, -3) == 'php'){
 				require_once(OC::$APPSROOT . '/apps/' . OC::$REQUESTEDAPP . '/' . OC::$REQUESTEDFILE);
-			}	
+			}
 		}else{
 			header('HTTP/1.0 404 Not Found');
 			exit;
@@ -300,7 +300,7 @@ class OC{
 		// register autoloader
 		spl_autoload_register(array('OC','autoload'));
 		setlocale(LC_ALL, 'en_US.UTF-8');
-		
+
 		// set some stuff
 		//ob_start();
 		error_reporting(E_ALL | E_STRICT);
@@ -320,7 +320,7 @@ class OC{
 		//try to configure php to enable big file uploads.
 		//this doesn´t work always depending on the webserver and php configuration.
 		//Let´s try to overwrite some defaults anyways
-		
+
 		//try to set the maximum execution time to 60min
 		@set_time_limit(3600);
 		@ini_set('max_execution_time',3600);
@@ -350,7 +350,7 @@ class OC{
 			$_SERVER['PHP_AUTH_USER'] = strip_tags($name);
 			$_SERVER['PHP_AUTH_PW'] = strip_tags($password);
 		}
-		
+
 		self::initPaths();
 
 		// register the stream wrappers
@@ -368,7 +368,7 @@ class OC{
 		if(isset($refererhost['host'])) $refererhost=$refererhost['host']; else $refererhost='';
 		$server=OC_Helper::serverHost();
 		$serverhost=explode(':',$server);
-		$serverhost=$serverhost['0']; 
+		$serverhost=$serverhost['0'];
 		if(!self::$CLI){
 			if(($_SERVER['REQUEST_METHOD']=='POST') and ($refererhost<>$serverhost)) {
 				$url = OC_Helper::serverProtocol().'://'.$server.OC::$WEBROOT.'/index.php';
@@ -419,18 +419,13 @@ class OC{
 				OC_App::loadApps();
 			}
 		}
-		
+
 		// Check for blacklisted files
 		OC_Hook::connect('OC_Filesystem','write','OC_Filesystem','isBlacklisted');
 
 		//make sure temporary files are cleaned up
 		register_shutdown_function(array('OC_Helper','cleanTmp'));
 
-		if (!OC_AppConfig::getValue('core', 'remote_core.css', false)) {
-			OC_AppConfig::setValue('core', 'remote_core.css', '/core/minimizer.php');
-			OC_AppConfig::setValue('core', 'remote_core.js', '/core/minimizer.php');
-		}
-
 		//parse the given parameters
 		self::$REQUESTEDAPP = (isset($_GET['app'])?str_replace(array('\0', '/', '\\', '..'), '', strip_tags($_GET['app'])):OC_Config::getValue('defaultapp', 'files'));
 		if(substr_count(self::$REQUESTEDAPP, '?') != 0){
@@ -482,7 +477,7 @@ if(!function_exists('get_temp_dir')) {
 			return dirname($temp);
 		}
 		if( $temp=sys_get_temp_dir())    return $temp;
-		
+
 		return null;
 	}
 }
diff --git a/lib/cache.php b/lib/cache.php
index 70f11f35518c551f6b0e88d8a8425e55f8076dbe..55d5b064c41efe893b8511a47ba18a27949c0264 100644
--- a/lib/cache.php
+++ b/lib/cache.php
@@ -10,7 +10,17 @@ class OC_Cache {
 	static protected $cache;
 
 	static protected function init() {
+		$fast_cache = null;
+		if (!$fast_cache && function_exists('xcache_set')) {
+			$fast_cache = new OC_Cache_XCache();
+		}
+		if (!$fast_cache && function_exists('apc_store')) {
+			$fast_cache = new OC_Cache_APC();
+		}
 		self::$cache = new OC_Cache_File();
+		if ($fast_cache) {
+			self::$cache = new OC_Cache_Broker($fast_cache, self::$cache);
+		}
 	}
 
 	static public function get($key) {
diff --git a/lib/cache/broker.php b/lib/cache/broker.php
new file mode 100644
index 0000000000000000000000000000000000000000..62a7cd96d15db7c1e682fb31f490159bf65d42b8
--- /dev/null
+++ b/lib/cache/broker.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_Cache_Broker {
+	protected $fast_cache;
+	protected $slow_cache;
+
+	public function __construct($fast_cache, $slow_cache) {
+		$this->fast_cache = $fast_cache;
+		$this->slow_cache = $slow_cache;
+	}
+
+	public function get($key) {
+		if ($r = $this->fast_cache->get($key)) {
+			return $r;
+		}
+		return $this->slow_cache->get($key);
+	}
+
+	public function set($key, $value, $ttl=0) {
+		$set_slow = strlen($value) > 8192;
+		if ($set_slow) {
+			if ($this->fast_cache->hasKey($key)) {
+				$this->fast_cache->remove($key);
+			}
+			$this->slow_cache->set($key, $value, $ttl);
+		} else {
+			$this->fast_cache->set($key, $value, $ttl);
+		}
+	}
+
+	public function hasKey($key) {
+		if ($this->fast_cache->hasKey($key)) {
+			return true;
+		}
+		return $this->slow_cache->hasKey($key);
+	}
+
+	public function remove($key) {
+		if ($this->fast_cache->remove($key)) {
+			return true;
+		}
+		return $this->slow_cache->remove($key);
+	}
+
+	public function clear(){
+		$this->fast_cache->clear();
+		$this->slow_cache->clear();
+	}
+}
diff --git a/lib/image.php b/lib/image.php
index a6bb92cea27a38fdbe4c41daa06581532c0706b7..af61f9424e9748602365bec440740137a00c61e1 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -136,6 +136,8 @@ class OC_Image {
 	*/
 	private function _output($filepath=null) {
 		if($filepath) {
+			if (!file_exists(dirname($filepath)))
+				mkdir(dirname($filepath), 0777, true);
 			if(!is_writable(dirname($filepath))) {
 				OC_Log::write('core',__METHOD__.'(): Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
 				return false;
@@ -426,7 +428,7 @@ class OC_Image {
 		if(is_resource($str)) {
 			return false;
 		}
-		$this->resource = imagecreatefromstring($str);
+		$this->resource = @imagecreatefromstring($str);
 		if(!$this->resource) {
 			OC_Log::write('core','OC_Image->loadFromData, couldn\'t load', OC_Log::DEBUG);
 			return false;
@@ -445,7 +447,7 @@ class OC_Image {
 		}
 		$data = base64_decode($str);
 		if($data) { // try to load from string data
-			$this->resource = imagecreatefromstring($data);
+			$this->resource = @imagecreatefromstring($data);
 			if(!$this->resource) {
 				OC_Log::write('core','OC_Image->loadFromBase64, couldn\'t load', OC_Log::DEBUG);
 				return false;
@@ -496,6 +498,32 @@ class OC_Image {
 		return true;
 	}
 
+	public function preciseResize($width, $height) {
+		if (!$this->valid()) {
+			OC_Log::write('core',__METHOD__.'(): No image loaded', OC_Log::ERROR);
+			return false;			
+		}
+		$width_orig=imageSX($this->resource);
+		$height_orig=imageSY($this->resource);
+		$process = imagecreatetruecolor($width, $height);
+
+		if ($process == false) {
+			OC_Log::write('core',__METHOD__.'(): Error creating true color image',OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+
+		imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
+		if ($process == false) {
+			OC_Log::write('core',__METHOD__.'(): Error resampling process image '.$width.'x'.$height,OC_Log::ERROR);
+			imagedestroy($process);
+			return false;
+		}
+		imagedestroy($this->resource);
+		$this->resource = $process;
+		return true;
+	}
+
 	/**
 	* @brief Crops the image to the middle square. If the image is already square it just returns.
 	* @param int maximum size for the result (optional)
diff --git a/lib/l10n.php b/lib/l10n.php
index 682e15f0e9b44ebae4735988eff9494d24b6a8fc..3596c992baede8d07ff3d368f61f05d4f738861b 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -77,6 +77,10 @@ class OC_L10N{
 	 * language.
 	 */
 	public function __construct($app, $lang = null){
+		$this->init($app, $lang);
+	}
+		
+	protected function init($app, $lang = null){
 		// Find the right language
 		if(is_null($lang)){
 			$lang = self::findLanguage($app);
diff --git a/lib/mail.php b/lib/mail.php
index b46f73bd94b86202c36b07d4bbb1235f7fa0654a..7343f5f0d97a7271b8035e4c7913318aa3586124 100644
--- a/lib/mail.php
+++ b/lib/mail.php
@@ -88,19 +88,8 @@ class OC_Mail {
 
 
 	/**
-	 * sending a mail based on a template
+	 * return the footer for a mail
 	 *
-	 * @param texttemplate $texttemplate
-	 * @param htmltemplate $htmltemplate
-	 * @param data $data
-	 * @param To $toaddress
-	 * @param ToName $toname
-	 * @param Subject $subject
-	 * @param From $fromaddress
-	 * @param FromName $fromname
-	 * @param ccaddress $ccaddress
-	 * @param ccname $ccname
-	 * @param bcc $bcc
 	 */
 	public static function getfooter() {
 
diff --git a/lib/ocsclient.php b/lib/ocsclient.php
index 33308553be02eb632eca7ecfb19186d04a75ac22..8e976171e937468182c7df2d00d26ea5bedd8032 100644
--- a/lib/ocsclient.php
+++ b/lib/ocsclient.php
@@ -35,12 +35,7 @@ class OC_OCSClient{
 	 * This function returns the url of the OCS AppStore server. It´s possible to set it in the config file or it will fallback to the default
 	 */
 	private static function getAppStoreURL(){
-		$configurl=OC_Config::getValue('appstoreurl', '');
-		if($configurl<>'') {
-			$url=$configurl;
-		}else{
-			$url='http://api.apps.owncloud.com/v1';
-		}
+		$url = OC_Config::getValue('appstoreurl', 'http://api.apps.owncloud.com/v1');
 		return($url);
 	}
 
@@ -50,12 +45,7 @@ class OC_OCSClient{
          * This function returns the url of the OCS knowledge base server. It´s possible to set it in the config file or it will fallback to the default
          */
         private static function getKBURL(){
-                $configurl=OC_Config::getValue('knowledgebaseurl', '');
-                if($configurl<>'') {
-                        $url=$configurl;
-                }else{
-                        $url='http://api.apps.owncloud.com/v1';
-                }
+                $url = OC_Config::getValue('knowledgebaseurl', 'http://api.apps.owncloud.com/v1');
                 return($url);
         }
 
diff --git a/settings/templates/help.php b/settings/templates/help.php
index a53ec76d681a28fb805cb0987728873e4c9e404f..cf61207e6015bf3ac3978570627104b60b3841df 100644
--- a/settings/templates/help.php
+++ b/settings/templates/help.php
@@ -26,9 +26,9 @@
 	<?php foreach($_["kbe"] as $kb): ?>
 	<div class="helpblock">
 		<?php if($kb["preview1"] <> "") { echo('<img class="preview" src="'.$kb["preview1"].'" />'); } ?>
-		<?php if($kb['detailpage']<>'') echo('<p><a target="_blank" href="'.$kb['detailpage'].'"><strong>'.$kb["name"].'</strong></a></p>');?>
-		<p><?php echo $kb['description'];?></p>
-		<?php if($kb['answer']<>'') echo('<p><strong>'.$l->t('Answer').':</strong><p>'.$kb['answer'].'</p>');?>
+		<?php if($kb['detailpage']<>'') echo('<p><a target="_blank" href="'.$kb['detailpage'].'"><strong>'.htmlentities($kb["name"]).'</strong></a></p>');?>
+		<p><?php echo htmlentities($kb['description']);?></p>
+		<?php if($kb['answer']<>'') echo('<p><strong>'.$l->t('Answer').':</strong><p>'.htmlentities($kb['answer']).'</p>');?>
 	</div>
 	<?php endforeach;
 endif?>