diff --git a/3rdparty/when/When.php b/3rdparty/when/When.php
index 5f97f0eb9bf3ed4e8c7a351efbf9f0e1684250c9..d54f296ed610b997c15ab7196ddff857d66ce462 100755
--- a/3rdparty/when/When.php
+++ b/3rdparty/when/When.php
@@ -586,7 +586,7 @@ class When
 				}
 			}
 		}
-		elseif($this->gobyday || $interval == "month")
+		elseif($this->gobyday && $interval == "month")
 		{
 			$_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year)));
 			foreach($_mdays as $_mday)
@@ -621,7 +621,13 @@ class When
 		
 		if($interval == "month")
 		{
-			$this->try_date->modify('last day of ' . $this->interval . ' ' . $interval);
+			
+			$this->try_date->modify('first day of next month');
+			if((int) date('t', $this->try_date->format('U')) > (int) $this->start_date->format('j')){
+				$this->try_date->modify('+' . (int) $this->start_date->format('j') - 1 . ' day'); 
+			}else{
+				$this->try_date->modify('+' . (int) date('t', $this->try_date->format('U')) - 1 . ' day'); 
+			}
 		}
 		else
 		{
diff --git a/apps/admin_dependencies_chk/settings.php b/apps/admin_dependencies_chk/settings.php
index 34028056dbea1457c164b8de30c6da17d2617aad..ce90dd604ca46d549dbbcab54a2f921e7ed89f81 100644
--- a/apps/admin_dependencies_chk/settings.php
+++ b/apps/admin_dependencies_chk/settings.php
@@ -44,12 +44,6 @@ $modules[] =array(
 	'modules'=> array('gallery'),
 	'message'=> $l->t('The php-gd module is needed to create thumbnails of your images'));
 
-$modules[] =array(
-	'status' => OC_Helper::canExecute("mp3info") ? 'ok' : 'warning',
-	'part'=> 'mp3info',
-	'modules'=> array('media'),
-	'message'=> $l->t('The program mp3info is useful to discover ID3 tags of your music files'));
-
 $modules[] =array(
 	'status' => function_exists("ldap_bind") ? 'ok' : 'error',
 	'part'=> 'php-ldap',
diff --git a/apps/admin_export/appinfo/info.xml b/apps/admin_export/appinfo/info.xml
index c4a2a9b398c4084b118d2ed127b75adcb2865c64..df8a07c2f5be7ec0985b7f7439909741a3cf4acf 100644
--- a/apps/admin_export/appinfo/info.xml
+++ b/apps/admin_export/appinfo/info.xml
@@ -7,4 +7,5 @@
 	<licence>AGPL</licence>
 	<author>Thomas Schmidt</author>
 	<require>2</require>
+	<default_enable/>
 </info>
diff --git a/apps/calendar/ajax/activation.php b/apps/calendar/ajax/activation.php
index 3c2bc6de23ffa82868af31463a35bdd403df15c0..ada2e44547bcf6ca46ac987c5e86c9d980d45955 100644
--- a/apps/calendar/ajax/activation.php
+++ b/apps/calendar/ajax/activation.php
@@ -7,9 +7,7 @@
  */
 
 require_once ("../../../lib/base.php");
-if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 $calendarid = $_POST['calendarid'];
 $calendar = OC_Calendar_App::getCalendar($calendarid);//access check
diff --git a/apps/calendar/ajax/choosecalendar.php b/apps/calendar/ajax/choosecalendar.php
index 0935a4c42ade0eb9036ba75ed714fffa6ccef44e..9281c8edbdcf5b1160be02998a2c7b7209cbe1e0 100644
--- a/apps/calendar/ajax/choosecalendar.php
+++ b/apps/calendar/ajax/choosecalendar.php
@@ -8,9 +8,7 @@
 
 require_once('../../../lib/base.php');
 $l10n = new OC_L10N('calendar');
-if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 $output = new OC_TEMPLATE("calendar", "part.choosecalendar");
 $output -> printpage();
diff --git a/apps/calendar/ajax/daysofweekend.php b/apps/calendar/ajax/daysofweekend.php
deleted file mode 100755
index 606d13b1e1c5b2bec990485297c0857b20cb0706..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/daysofweekend.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-echo OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'weekend', '{"Monday":"false","Tuesday":"false","Wednesday":"false","Thursday":"false","Friday":"false","Saturday":"true","Sunday":"true"}');
-?> 
diff --git a/apps/calendar/ajax/deletecalendar.php b/apps/calendar/ajax/deletecalendar.php
index fc308da6dadfc4415d56c33c62d4916a25ca436d..901cbbfcb08e95de7e1908e134a64ecf9b58a12a 100644
--- a/apps/calendar/ajax/deletecalendar.php
+++ b/apps/calendar/ajax/deletecalendar.php
@@ -7,9 +7,7 @@
  */
 require_once('../../../lib/base.php');
 
-if(!OC_USER::isLoggedIn()) {
-	die('<script type="text/javascript">document.location = oc_webroot;</script>');
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 
 $cal = $_POST["calendarid"];
diff --git a/apps/calendar/ajax/deleteevent.php b/apps/calendar/ajax/deleteevent.php
index 269f4a47f42d51f6dc573fa744a8a602079cd9c3..b25a5af1a291921659db3b3a78a6d87918b44a9c 100644
--- a/apps/calendar/ajax/deleteevent.php
+++ b/apps/calendar/ajax/deleteevent.php
@@ -9,9 +9,7 @@ require_once('../../../lib/base.php');
 
 $l10n = new OC_L10N('calendar');
 
-if(!OC_USER::isLoggedIn()) {
-	die('<script type="text/javascript">document.location = oc_webroot;</script>');
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 
 $id = $_POST['id'];
diff --git a/apps/calendar/ajax/duration.php b/apps/calendar/ajax/duration.php
deleted file mode 100644
index cdc41388abd232bb5501eab33ac29bc9d99e9510..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/duration.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-$duration = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'duration', "60");
-OC_JSON::encodedPrint(array("duration" => $duration));
-?> 
diff --git a/apps/calendar/ajax/editcalendar.php b/apps/calendar/ajax/editcalendar.php
index e44763c9aaac5931f226c5358e9037ecb3dfb32e..7aeb5bbe30557223e49a0fccc461a15ad8c0c713 100644
--- a/apps/calendar/ajax/editcalendar.php
+++ b/apps/calendar/ajax/editcalendar.php
@@ -7,9 +7,7 @@
  */
 
 require_once('../../../lib/base.php');
-if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 
 $calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
diff --git a/apps/calendar/ajax/editevent.php b/apps/calendar/ajax/editevent.php
index f00ab1d960b6a5be8725a376aeb360ddbfdcb8cc..5a487da17588ff369ab380badfe8dd5921df627c 100644
--- a/apps/calendar/ajax/editevent.php
+++ b/apps/calendar/ajax/editevent.php
@@ -7,9 +7,7 @@
  */
 
 require_once('../../../lib/base.php');
-if(!OC_USER::isLoggedIn()) {
-	die('<script type="text/javascript">document.location = oc_webroot;</script>');
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 
 $errarr = OC_Calendar_Object::validateRequest($_POST);
diff --git a/apps/calendar/ajax/editeventform.php b/apps/calendar/ajax/editeventform.php
index fe6c6f7357003804049542b0124c374f48ed7dde..95cae39c1c2cc877ce9379aeef48a2979f30bfcf 100644
--- a/apps/calendar/ajax/editeventform.php
+++ b/apps/calendar/ajax/editeventform.php
@@ -42,7 +42,6 @@ switch($dtstart->getDateType()) {
 $summary = $vevent->getAsString('SUMMARY');
 $location = $vevent->getAsString('LOCATION');
 $categories = $vevent->getAsArray('CATEGORIES');
-$repeat = $vevent->getAsString('CATEGORY');
 $description = $vevent->getAsString('DESCRIPTION');
 foreach($categories as $category){
 	if (!in_array($category, $category_options)){
@@ -55,10 +54,150 @@ if ($last_modified){
 }else{
 	$lastmodified = 0;
 }
+if($data['repeating'] == 1){
+	$rrule = explode(';', $vevent->getAsString('RRULE'));
+	$rrulearr = array();
+	foreach($rrule as $rule){
+		list($attr, $val) = explode('=', $rule);
+		$rrulearr[$attr] = $val;
+	}
+	if(!isset($rrulearr['INTERVAL']) || $rrulearr['INTERVAL'] == ''){
+		$rrulearr['INTERVAL'] = 1;
+	}
+	if(array_key_exists('BYDAY', $rrulearr)){
+		if(substr_count($rrulearr['BYDAY'], ',') == 0){
+			if(strlen($rrulearr['BYDAY']) == 2){
+				$repeat['weekdays'] = array($rrulearr['BYDAY']);
+			}elseif(strlen($rrulearr['BYDAY']) == 3){
+				$repeat['weekofmonth'] = substr($rrulearr['BYDAY'], 0, 1);
+				$repeat['weekdays'] = array(substr($rrulearr['BYDAY'], 1, 2));
+			}elseif(strlen($rrulearr['BYDAY']) == 4){
+				$repeat['weekofmonth'] = substr($rrulearr['BYDAY'], 0, 2);
+				$repeat['weekdays'] = array(substr($rrulearr['BYDAY'], 2, 2));
+			}
+		}else{
+			$byday_days = explode(',', $rrulearr['BYDAY']);
+			foreach($byday_days as $byday_day){
+				if(strlen($byday_day) == 2){
+					$repeat['weekdays'][] = $byday_day;
+				}elseif(strlen($byday_day) == 3){
+					$repeat['weekofmonth'] = substr($byday_day , 0, 1);
+					$repeat['weekdays'][] = substr($byday_day , 1, 2);
+				}elseif(strlen($byday_day) == 4){
+					$repeat['weekofmonth'] = substr($byday_day , 0, 2);
+					$repeat['weekdays'][] = substr($byday_day , 2, 2);
+				}
+			}
+		}
+	}
+	if(array_key_exists('BYMONTHDAY', $rrulearr)){
+		if(substr_count($rrulearr['BYMONTHDAY'], ',') == 0){
+			$repeat['bymonthday'][] = $rrulearr['BYMONTHDAY'];
+		}else{
+			$bymonthdays = explode(',', $rrulearr['BYMONTHDAY']);
+			foreach($bymonthdays as $bymonthday){
+				$repeat['bymonthday'][] = $bymonthday;
+			}
+		}
+	}
+	if(array_key_exists('BYYEARDAY', $rrulearr)){
+		if(substr_count($rrulearr['BYYEARDAY'], ',') == 0){
+			$repeat['byyearday'][] = $rrulearr['BYYEARDAY'];
+		}else{
+			$byyeardays = explode(',', $rrulearr['BYYEARDAY']);
+			foreach($byyeardays  as $yearday){
+				$repeat['byyearday'][] = $yearday;
+			}
+		}
+	}
+	if(array_key_exists('BYWEEKNO', $rrulearr)){
+		if(substr_count($rrulearr['BYWEEKNO'], ',') == 0){
+			$repeat['byweekno'][] = (string) $rrulearr['BYWEEKNO'];
+		}else{
+			$byweekno = explode(',', $rrulearr['BYWEEKNO']);
+			foreach($byweekno as $weekno){
+				$repeat['byweekno'][] = (string) $weekno;
+			}
+		}
+	}
+	if(array_key_exists('BYMONTH', $rrulearr)){
+		$months = OC_Calendar_App::getByMonthOptions();
+		if(substr_count($rrulearr['BYMONTH'], ',') == 0){
+			$repeat['bymonth'][] = $months[$month];
+		}else{
+			$bymonth = explode(',', $rrulearr['BYMONTH']);
+			foreach($bymonth as $month){
+				$repeat['bymonth'][] = $months[$month];
+			}
+		}
+	}
+	switch($rrulearr['FREQ']){
+		case 'DAILY':
+			$repeat['repeat'] = 'daily';
+			break;
+		case 'WEEKLY':
+			if($rrulearr['INTERVAL'] % 2 == 0){
+				$repeat['repeat'] = 'biweekly';
+				$rrulearr['INTERVAL'] = $rrulearr['INTERVAL'] / 2;
+			}elseif($rrulearr['BYDAY'] == 'MO,TU,WE,TH,FR'){
+				$repeat['repeat'] = 'weekday';
+			}else{
+				$repeat['repeat'] = 'weekly';
+			}
+			break;
+		case 'MONTHLY':
+			$repeat['repeat'] = 'monthly';
+			if(array_key_exists('BYDAY', $rrulearr)){
+				$repeat['month'] = 'weekday';
+			}else{
+				$repeat['month'] = 'monthday';
+			}
+			break;
+		case 'YEARLY':
+			$repeat['repeat'] = 'yearly';
+			if(array_key_exists('BYMONTH', $rrulearr)){
+				$repeat['year'] = 'bydaymonth';
+			}elseif(array_key_exists('BYWEEKNO', $rrulearr)){
+				$repeat['year'] = 'byweekno';
+			}else{
+				$repeat['year'] = 'byyearday';
+			}
+	}
+	$repeat['interval'] = $rrulearr['INTERVAL'];
+	if(array_key_exists('COUNT', $rrulearr)){
+		$repeat['end'] = 'count';
+		$repeat['count'] = $rrulearr['COUNT'];
+	}elseif(array_key_exists('UNTIL', $rrulearr)){
+		$repeat['end'] = 'date';
+		$endbydate_day = substr($rrulearr['UNTIL'], 6, 2);
+		$endbydate_month = substr($rrulearr['UNTIL'], 4, 2);
+		$endbydate_year = substr($rrulearr['UNTIL'], 0, 4);
+		$repeat['date'] = $endbydate_day . '-' .  $endbydate_month . '-' . $endbydate_year;
+	}else{
+		$repeat['end'] = 'never';
+	}
+	if(array_key_exists('weekdays', $repeat)){
+		$repeat_weekdays_ = array();
+		$days = OC_Calendar_App::getWeeklyOptions();
+		foreach($repeat['weekdays'] as $weekday){
+			$repeat_weekdays_[] = $days[$weekday];
+		}
+		$repeat['weekdays'] = $repeat_weekdays_;
+	}
+}
 
 $calendar_options = OC_Calendar_Calendar::allCalendars(OC_User::getUser());
 $category_options = OC_Calendar_App::getCategoryOptions();
 $repeat_options = OC_Calendar_App::getRepeatOptions();
+$repeat_end_options = OC_Calendar_App::getEndOptions();
+$repeat_month_options = OC_Calendar_App::getMonthOptions();
+$repeat_year_options = OC_Calendar_App::getYearOptions();
+$repeat_weekly_options = OC_Calendar_App::getWeeklyOptions();
+$repeat_weekofmonth_options = OC_Calendar_App::getWeekofMonth();
+$repeat_byyearday_options = OC_Calendar_App::getByYearDayOptions();
+$repeat_bymonth_options = OC_Calendar_App::getByMonthOptions();
+$repeat_byweekno_options = OC_Calendar_App::getByWeekNoOptions();
+$repeat_bymonthday_options = OC_Calendar_App::getByMonthDayOptions();
 
 $tmpl = new OC_Template('calendar', 'part.editevent');
 $tmpl->assign('id', $id);
@@ -66,6 +205,15 @@ $tmpl->assign('lastmodified', $lastmodified);
 $tmpl->assign('calendar_options', $calendar_options);
 $tmpl->assign('category_options', $category_options);
 $tmpl->assign('repeat_options', $repeat_options);
+$tmpl->assign('repeat_month_options', $repeat_month_options);
+$tmpl->assign('repeat_weekly_options', $repeat_weekly_options);
+$tmpl->assign('repeat_end_options', $repeat_end_options);
+$tmpl->assign('repeat_year_options', $repeat_year_options);
+$tmpl->assign('repeat_byyearday_options', $repeat_byyearday_options);
+$tmpl->assign('repeat_bymonth_options', $repeat_bymonth_options);
+$tmpl->assign('repeat_byweekno_options', $repeat_byweekno_options);
+$tmpl->assign('repeat_bymonthday_options', $repeat_bymonthday_options);
+$tmpl->assign('repeat_weekofmonth_options', $repeat_weekofmonth_options);
 
 $tmpl->assign('title', $summary);
 $tmpl->assign('location', $location);
@@ -76,8 +224,22 @@ $tmpl->assign('startdate', $startdate);
 $tmpl->assign('starttime', $starttime);
 $tmpl->assign('enddate', $enddate);
 $tmpl->assign('endtime', $endtime);
-$tmpl->assign('repeat', $repeat);
 $tmpl->assign('description', $description);
+
+$tmpl->assign('repeat', $repeat['repeat']);
+$tmpl->assign('repeat_month', $repeat['month']);
+$tmpl->assign('repeat_weekdays', $repeat['weekdays']);
+$tmpl->assign('repeat_interval', $repeat['interval']);
+$tmpl->assign('repeat_end', $repeat['end']);
+$tmpl->assign('repeat_count', $repeat['count']);
+$tmpl->assign('repeat_weekofmonth', $repeat['weekofmonth']);
+$tmpl->assign('repeat_date', $repeat['date']);
+$tmpl->assign('repeat_year', $repeat['year']);
+$tmpl->assign('repeat_byyearday', $repeat['byyearday']);
+$tmpl->assign('repeat_bymonthday', $repeat['bymonthday']);
+$tmpl->assign('repeat_bymonth', $repeat['bymonth']);
+$tmpl->assign('repeat_byweekno', $repeat['byweekno']);
 $tmpl->printpage();
+
 ?>
  
diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php
index 1430432b8a3fc69909dc37f89183461af0556b46..998991c2fb423b8e0e81798069800788428e9e56 100644
--- a/apps/calendar/ajax/events.php
+++ b/apps/calendar/ajax/events.php
@@ -58,7 +58,7 @@ foreach($events as $event){
 			}
 			if($return_event['allDay'] == true){
 				$return_event['start'] = $result->format('Y-m-d');
-				$return_event['end'] = date('Y-m-d', $result->format('U') + $duration--);
+				$return_event['end'] = date('Y-m-d', $result->format('U') + --$duration);
 			}else{
 				$return_event['start'] = $result->format('Y-m-d H:i:s');
 				$return_event['end'] = date('Y-m-d H:i:s', $result->format('U') + $duration);
diff --git a/apps/calendar/ajax/firstdayofweek.php b/apps/calendar/ajax/firstdayofweek.php
deleted file mode 100755
index eff82cece1de1a67c34fd69cfb8cef8359a4be93..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/firstdayofweek.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-$firstdayofweek = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'firstdayofweek', "1");
-OC_JSON::encodedPrint(array("firstdayofweek" => $firstdayofweek));
-?>
\ No newline at end of file
diff --git a/apps/calendar/ajax/gettimezonedetection.php b/apps/calendar/ajax/gettimezonedetection.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae58370712da2f0bcf12a3fbc15e7ffd5c6421b0
--- /dev/null
+++ b/apps/calendar/ajax/gettimezonedetection.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2011, 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+require_once ("../../../lib/base.php");
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('calendar');
+OC_JSON::success(array('detection' => OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezonedetection')));
\ No newline at end of file
diff --git a/apps/calendar/ajax/guesstimezone.php b/apps/calendar/ajax/guesstimezone.php
index a3594498b0f32749706d9ed51f083406d18b3bea..41aea26985ffd58799faf04ed82e2f6559180564 100755
--- a/apps/calendar/ajax/guesstimezone.php
+++ b/apps/calendar/ajax/guesstimezone.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * Copyright (c) 2011, 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -24,11 +24,20 @@ OC_JSON::checkAppEnabled('calendar');
 $l = new OC_L10N('calendar');
 $lat = $_GET['lat'];
 $long = $_GET['long'];
+if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'position') == $lat . '-' . $long && OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone') != null){
+	OC_JSON::success();
+	exit;
+}
+OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'position', $lat . '-' . $long);
 $geolocation = file_get_contents('http://ws.geonames.org/timezone?lat=' . $lat . '&lng=' . $long);
 //Information are by Geonames (http://www.geonames.org) and licensed under the Creative Commons Attribution 3.0 License
 $geoxml = simplexml_load_string($geolocation);
 $geoarray = make_array_out_of_xml($geoxml);
-if(isset($geoarray['timezone']['timezoneId']) && $geoarray['timezone']['timezoneId'] != ''){
+if($geoarray['timezone']['timezoneId'] == OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone')){
+	OC_JSON::success();
+	exit;
+}
+if(in_array($geoarray['timezone']['timezoneId'], DateTimeZone::listIdentifiers())){
 	OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezone', $geoarray['timezone']['timezoneId']);
 	$message = array('message'=> $l->t('New Timezone:') . $geoarray['timezone']['timezoneId']);
 	OC_JSON::success($message);
@@ -36,4 +45,4 @@ if(isset($geoarray['timezone']['timezoneId']) && $geoarray['timezone']['timezone
 	OC_JSON::error();
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/apps/calendar/ajax/importdialog.php b/apps/calendar/ajax/importdialog.php
index 232b4ba580741524b8700c43e6fa3dd2444d5864..983a3d95a8400de43bce6d91cdb8c9b0c3259f53 100644
--- a/apps/calendar/ajax/importdialog.php
+++ b/apps/calendar/ajax/importdialog.php
@@ -11,7 +11,7 @@ require_once('../../../lib/base.php');
 $l10n = new OC_L10N('calendar');
 
 if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
+	die('<script type="text/javascript">document.location = oc_webroot;</script>');
 }
 OC_JSON::checkAppEnabled('calendar');
 
diff --git a/apps/calendar/ajax/newcalendar.php b/apps/calendar/ajax/newcalendar.php
index a7935c956729c29e85da7d18a85dbaae3df1bad4..af3ba4fbbeabdc84f17d82a34c23aaec81f56b3a 100644
--- a/apps/calendar/ajax/newcalendar.php
+++ b/apps/calendar/ajax/newcalendar.php
@@ -8,9 +8,7 @@
 
 require_once('../../../lib/base.php');
 $l10n = new OC_L10N('calendar');
-if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 $calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
 $calendar = array(
diff --git a/apps/calendar/ajax/newevent.php b/apps/calendar/ajax/newevent.php
index 1a696cf7780f8e9a25392a7717227bd955af8960..c7c4d29943a0b3daf783b1801df20349197ff193 100644
--- a/apps/calendar/ajax/newevent.php
+++ b/apps/calendar/ajax/newevent.php
@@ -10,9 +10,7 @@ require_once('../../../lib/base.php');
 
 $l10n = new OC_L10N('calendar');
 
-if(!OC_USER::isLoggedIn()) {
-	die("<script type=\"text/javascript\">document.location = oc_webroot;</script>");
-}
+OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('calendar');
 
 $errarr = OC_Calendar_Object::validateRequest($_POST);
diff --git a/apps/calendar/ajax/neweventform.php b/apps/calendar/ajax/neweventform.php
index e12e99219e67ec0b3d8316df0a95e23d241956fd..3870c879b0ed513dc586e5439474a08608a95f88 100644
--- a/apps/calendar/ajax/neweventform.php
+++ b/apps/calendar/ajax/neweventform.php
@@ -34,14 +34,43 @@ $end->setTimezone(new DateTimeZone($timezone));
 $calendar_options = OC_Calendar_Calendar::allCalendars(OC_User::getUser());
 $category_options = OC_Calendar_App::getCategoryOptions();
 $repeat_options = OC_Calendar_App::getRepeatOptions();
+$repeat_end_options = OC_Calendar_App::getEndOptions();
+$repeat_month_options = OC_Calendar_App::getMonthOptions();
+$repeat_year_options = OC_Calendar_App::getYearOptions();
+$repeat_weekly_options = OC_Calendar_App::getWeeklyOptions();
+$repeat_weekofmonth_options = OC_Calendar_App::getWeekofMonth();
+$repeat_byyearday_options = OC_Calendar_App::getByYearDayOptions();
+$repeat_bymonth_options = OC_Calendar_App::getByMonthOptions();
+$repeat_byweekno_options = OC_Calendar_App::getByWeekNoOptions();
+$repeat_bymonthday_options = OC_Calendar_App::getByMonthDayOptions();
 
 $tmpl = new OC_Template('calendar', 'part.newevent');
 $tmpl->assign('calendar_options', $calendar_options);
 $tmpl->assign('category_options', $category_options);
+$tmpl->assign('repeat_options', $repeat_options);
+$tmpl->assign('repeat_month_options', $repeat_month_options);
+$tmpl->assign('repeat_weekly_options', $repeat_weekly_options);
+$tmpl->assign('repeat_end_options', $repeat_end_options);
+$tmpl->assign('repeat_year_options', $repeat_year_options);
+$tmpl->assign('repeat_byyearday_options', $repeat_byyearday_options);
+$tmpl->assign('repeat_bymonth_options', $repeat_bymonth_options);
+$tmpl->assign('repeat_byweekno_options', $repeat_byweekno_options);
+$tmpl->assign('repeat_bymonthday_options', $repeat_bymonthday_options);
+$tmpl->assign('repeat_weekofmonth_options', $repeat_weekofmonth_options);
+
 $tmpl->assign('startdate', $start->format('d-m-Y'));
 $tmpl->assign('starttime', $start->format('H:i'));
 $tmpl->assign('enddate', $end->format('d-m-Y'));
 $tmpl->assign('endtime', $end->format('H:i'));
 $tmpl->assign('allday', $allday);
+$tmpl->assign('repeat', 'doesnotrepeat');
+$tmpl->assign('repeat_month', 'monthday');
+$tmpl->assign('repeat_weekdays', array());
+$tmpl->assign('repeat_interval', 1);
+$tmpl->assign('repeat_end', 'never');
+$tmpl->assign('repeat_count', '10');
+$tmpl->assign('repeat_weekofmonth', 'auto');
+$tmpl->assign('repeat_date', '');
+$tmpl->assign('repeat_year', 'bydate');
 $tmpl->printpage();
 ?>
diff --git a/apps/calendar/ajax/setdaysofweekend.php b/apps/calendar/ajax/setdaysofweekend.php
deleted file mode 100755
index b5ef5f8573f2d96f5d7ee483d5696084b03ccb64..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/setdaysofweekend.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-$weekenddays = array("Monday"=>"false", "Tuesday"=>"false", "Wednesday"=>"false", "Thursday"=>"false", "Friday"=>"false", "Saturday"=>"false", "Sunday"=>"false");
-for($i = 0;$i < count($_POST["weekend"]); $i++){
-	switch ($_POST["weekend"][$i]){
-		case "Monday":
-		case "Tuesday":
-		case "Wednesday":
-		case "Thursday":
-		case "Friday":
-		case "Saturday":
-		case "Sunday":
-			break;
-		default:
-			OC_JSON::error();
-			exit;
-	}
-	$weekenddays[$_POST["weekend"][$i]] = "true";	
-}
-$setValue = json_encode($weekenddays);
-OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'weekend', $setValue);
-OC_JSON::success();
-?> 
diff --git a/apps/calendar/ajax/setduration.php b/apps/calendar/ajax/setduration.php
deleted file mode 100644
index a75c8faea4228fd3eae31500dce2321ec735cb99..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/setduration.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-if(isset($_POST["duration"])){
-	OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'duration', $_POST["duration"]);
-	OC_JSON::success();
-}else{
-	OC_JSON::error();
-}
-?> 
- 
diff --git a/apps/calendar/ajax/setfirstdayofweek.php b/apps/calendar/ajax/setfirstdayofweek.php
deleted file mode 100755
index 571b95af0e3dbb2c61899fd35595ee9175820a37..0000000000000000000000000000000000000000
--- a/apps/calendar/ajax/setfirstdayofweek.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-require_once('../../../lib/base.php');
-OC_JSON::checkLoggedIn();
-if(isset($_POST["firstdayofweek"])){
-	OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'firstdayofweek', $_POST["firstdayofweek"]);
-	OC_JSON::success();
-}else{
-	OC_JSON::error();
-}
-?> 
diff --git a/apps/calendar/ajax/timezonedetection.php b/apps/calendar/ajax/timezonedetection.php
new file mode 100644
index 0000000000000000000000000000000000000000..77e4c4f6ebe424be2e76b887601b042af426c683
--- /dev/null
+++ b/apps/calendar/ajax/timezonedetection.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright (c) 2011, 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+require_once ("../../../lib/base.php");
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('calendar');
+if($_POST['timezonedetection'] == 'on'){
+	OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezonedetection', 'true');
+}else{
+	OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezonedetection', 'false');
+}
+OC_JSON::success();
+
diff --git a/apps/calendar/appinfo/app.php b/apps/calendar/appinfo/app.php
index ee990723c0c0d9ed3b2a23215d22097e7ec2ca3a..267a74bf29a249287e90e7629c3c65d0b6c6878a 100644
--- a/apps/calendar/appinfo/app.php
+++ b/apps/calendar/appinfo/app.php
@@ -1,26 +1,23 @@
 <?php
-$l=new OC_L10N('calendar');
-OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
-OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
-OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
-OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
-OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
-OC_HOOK::connect('OC_User', 'post_createUser', 'OC_Calendar_Hooks', 'deleteUser');
-
-OC_Util::addScript('calendar','loader');
-
-OC_App::register( array( 
-  'order' => 10,
-  'id' => 'calendar',
-  'name' => 'Calendar' ));
-
-OC_App::addNavigationEntry( array( 
-  'id' => 'calendar_index',
-  'order' => 10,
-  'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
-  'icon' => OC_Helper::imagePath( 'calendar', 'icon.png' ),
-  'name' => $l->t('Calendar')));
-
-OC_App::registerPersonal('calendar', 'settings');
-
-require_once('apps/calendar/lib/search.php');
+if(version_compare(PHP_VERSION, '5.3.0', '>')){
+	$l=new OC_L10N('calendar');
+	OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
+	OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
+	OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
+	OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
+	OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
+	OC_HOOK::connect('OC_User', 'post_createUser', 'OC_Calendar_Hooks', 'deleteUser');
+	OC_Util::addScript('calendar','loader');
+	OC_App::register( array( 
+	  'order' => 10,
+	  'id' => 'calendar',
+	  'name' => 'Calendar' ));
+	OC_App::addNavigationEntry( array( 
+	  'id' => 'calendar_index',
+	  'order' => 10,
+	  'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
+	  'icon' => OC_Helper::imagePath( 'calendar', 'icon.png' ),
+	  'name' => $l->t('Calendar')));
+	OC_App::registerPersonal('calendar', 'settings');
+	require_once('apps/calendar/lib/search.php');
+}
diff --git a/apps/calendar/index.php b/apps/calendar/index.php
index 3313750d52e20ab41b36666473a67ad8f9c30ebc..e8e214c0b75e52ff934d1809e8577759f09a7900 100644
--- a/apps/calendar/index.php
+++ b/apps/calendar/index.php
@@ -32,7 +32,7 @@ if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'mont
 
 OC_Util::addScript('3rdparty/fullcalendar', 'fullcalendar');
 OC_Util::addStyle('3rdparty/fullcalendar', 'fullcalendar');
-if(OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone") == null){
+if(OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone") == null || OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezonedetection') == 'true'){
 	OC_UTIL::addScript('calendar', 'geo');
 }
 OC_Util::addScript('calendar', 'calendar');
@@ -42,4 +42,7 @@ OC_Util::addStyle('', 'jquery.multiselect');
 OC_App::setActiveNavigationEntry('calendar_index');
 $tmpl = new OC_Template('calendar', 'calendar', 'user');
 $tmpl->assign('eventSources', $eventSources);
-$tmpl->printPage();
\ No newline at end of file
+if(array_key_exists('showevent', $_GET)){
+	$tmpl->assign('showevent', $_GET['showevent']);
+}
+$tmpl->printPage();
diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js
index 6e0a450f6a8f980f50ae545ff8b5df881e3d634e..ae586661ccc85c910f9d48c18259103f607795fe 100644
--- a/apps/calendar/js/calendar.js
+++ b/apps/calendar/js/calendar.js
@@ -33,6 +33,19 @@ Calendar={
 					minWidth:'auto',
 					classes: 'category',
 			});
+			Calendar.UI.repeat('init');
+			$('#end').change(function(){
+				Calendar.UI.repeat('end');
+			});
+			$('#repeat').change(function(){
+				Calendar.UI.repeat('repeat');
+			});
+			$('#advanced_year').change(function(){
+				Calendar.UI.repeat('year');
+			});
+			$('#advanced_month').change(function(){
+				Calendar.UI.repeat('month');
+			});
 			$('#event').dialog({
 				width : 500,
 				close : function(event, ui) {
@@ -150,9 +163,16 @@ Calendar={
 			});
 		},
 		showadvancedoptions:function(){
-			$("#advanced_options").css("display", "block");
+			$("#advanced_options").slideDown('slow');
 			$("#advanced_options_button").css("display", "none");
 		},
+		showadvancedoptionsforrepeating:function(){
+			if($("#advanced_options_repeating").is(":hidden")){
+				$('#advanced_options_repeating').slideDown('slow');
+			}else{
+				$('#advanced_options_repeating').slideUp('slow');
+			}
+		},
 		getEventPopupText:function(event){
 			if (event.allDay){
 				var timespan = $.fullCalendar.formatDates(event.start, event.end, 'ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}', {monthNamesShort: monthNamesShort, monthNames: monthNames, dayNames: dayNames, dayNamesShort: dayNamesShort}); //t('calendar', "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}")
@@ -223,6 +243,108 @@ Calendar={
 				event.preventDefault();
 			}
 		},
+		repeat:function(task){
+			if(task=='init'){
+				$('#byweekno').multiselect({
+					header: false,
+					noneSelectedText: $('#advanced_byweekno').attr('title'),
+					selectedList: 2,
+					minWidth:'auto'
+				});
+				$('#weeklyoptions').multiselect({
+					header: false,
+					noneSelectedText: $('#weeklyoptions').attr('title'),
+					selectedList: 2,
+					minWidth:'auto'
+				});
+				$('input[name="bydate"]').datepicker({
+					dateFormat : 'dd-mm-yy'
+				});
+				$('#byyearday').multiselect({
+					header: false,
+					noneSelectedText: $('#byyearday').attr('title'),
+					selectedList: 2,
+					minWidth:'auto'
+				});
+				$('#bymonth').multiselect({
+					header: false,
+					noneSelectedText: $('#bymonth').attr('title'),
+					selectedList: 2,
+					minWidth:'auto'
+				});
+				$('#bymonthday').multiselect({
+					header: false,
+					noneSelectedText: $('#bymonthday').attr('title'),
+					selectedList: 2,
+					minWidth:'auto'
+				});
+				Calendar.UI.repeat('end');
+				Calendar.UI.repeat('month');
+				Calendar.UI.repeat('year');
+				Calendar.UI.repeat('repeat');
+			}
+			if(task == 'end'){
+				$('#byoccurrences').css('display', 'none');
+				$('#bydate').css('display', 'none');
+				if($('#end option:selected').val() == 'count'){
+					$('#byoccurrences').css('display', 'block');
+				}
+				if($('#end option:selected').val() == 'date'){
+					$('#bydate').css('display', 'block');
+				}
+			}
+			if(task == 'repeat'){
+				$('#advanced_month').css('display', 'none');
+				$('#advanced_weekday').css('display', 'none');
+				$('#advanced_weekofmonth').css('display', 'none');
+				$('#advanced_byyearday').css('display', 'none');
+				$('#advanced_bymonth').css('display', 'none');
+				$('#advanced_byweekno').css('display', 'none');
+				$('#advanced_year').css('display', 'none');
+				$('#advanced_bymonthday').css('display', 'none');
+				if($('#repeat option:selected').val() == 'monthly'){
+					$('#advanced_month').css('display', 'block');
+					Calendar.UI.repeat('month');
+				}
+				if($('#repeat option:selected').val() == 'weekly'){
+					$('#advanced_weekday').css('display', 'block');
+				}
+				if($('#repeat option:selected').val() == 'yearly'){
+					$('#advanced_year').css('display', 'block');
+					Calendar.UI.repeat('year');
+				}
+				if($('#repeat option:selected').val() == 'doesnotrepeat'){
+					$('#advanced_options_repeating').slideUp('slow');
+				}
+			}
+			if(task == 'month'){
+				$('#advanced_weekday').css('display', 'none');
+				$('#advanced_weekofmonth').css('display', 'none');
+				if($('#advanced_month_select option:selected').val() == 'weekday'){
+					$('#advanced_weekday').css('display', 'block');
+					$('#advanced_weekofmonth').css('display', 'block');
+				}
+			}
+			if(task == 'year'){
+				$('#advanced_weekday').css('display', 'none');
+				$('#advanced_byyearday').css('display', 'none');
+				$('#advanced_bymonth').css('display', 'none');
+				$('#advanced_byweekno').css('display', 'none');
+				$('#advanced_bymonthday').css('display', 'none');
+				if($('#advanced_year_select option:selected').val() == 'byyearday'){
+					//$('#advanced_byyearday').css('display', 'block');
+				}
+				if($('#advanced_year_select option:selected').val() == 'byweekno'){
+					$('#advanced_byweekno').css('display', 'block');
+				}
+				if($('#advanced_year_select option:selected').val() == 'bydaymonth'){
+					$('#advanced_bymonth').css('display', 'block');
+					$('#advanced_bymonthday').css('display', 'block');
+					$('#advanced_weekday').css('display', 'block');
+				}
+			}
+			
+		},
 		Calendar:{
 			overview:function(){
 				if($('#choosecalendar_dialog').dialog('isOpen') == true){
diff --git a/apps/calendar/js/geo.js b/apps/calendar/js/geo.js
index acea17c02690f9e58557fb5716928301dc91fb2e..ae6a971e938f94b4bd52bbd281bc87a40c3dc63d 100755
--- a/apps/calendar/js/geo.js
+++ b/apps/calendar/js/geo.js
@@ -8,8 +8,9 @@ if (navigator.geolocation) {
 	navigator.geolocation.getCurrentPosition(function(position) {
 		$.getJSON(OC.filePath('calendar', 'ajax', 'guesstimezone.php?lat=' + position.coords.latitude + '&long=' + position.coords.longitude + ''),
 		function(data){
-			if (data.status == 'success'){
+			if (data.status == 'success' && typeof(data.message) != 'undefined'){
 				$('#notification').html(data.message);
+				$('#notification').attr('title', 'CC BY 3.0 by Geonames.org');
 				$('#notification').slideDown();
 				window.setTimeout(function(){$('#notification').slideUp();}, 5000);
 			}else{
diff --git a/apps/calendar/js/settings.js b/apps/calendar/js/settings.js
index 6c00be06b3928ee9b61de301b9e89dcc385a806d..73300885565639c2b7d3c0c3311ee34411249629 100644
--- a/apps/calendar/js/settings.js
+++ b/apps/calendar/js/settings.js
@@ -1,63 +1,35 @@
 $(document).ready(function(){
-	$("#timezone").change( function(){
+	$('#timezone').change( function(){
 		OC.msg.startSaving('#calendar .msg')
 		// Serialize the data
-		var post = $( "#timezone" ).serialize();
+		var post = $( '#timezone' ).serialize();
 		$.post( OC.filePath('calendar', 'ajax', 'settimezone.php'), post, function(data){
 			//OC.msg.finishedSaving('#calendar .msg', data);
 		});
 		return false;
 	});
-	$("#timezone").chosen();
-	$("#firstdayofweek").change( function(){
-		var data = $("#firstdayofweek").serialize();
-		$.post( OC.filePath('calendar', 'ajax', 'setfirstdayofweek.php'), data, function(data){
-			if(data == "error"){
-				console.log("saving first day of week failed");
-			}
-		});
-	});
-	$.getJSON(OC.filePath('calendar', 'ajax', 'firstdayofweek.php'), function(jsondata, status) {
-		$("#select_" + jsondata.firstdayofweek).attr('selected',true);
-		$("#firstdayofweek").chosen();
-	});
-	$.getJSON(OC.filePath('calendar', 'ajax', 'daysofweekend.php'), function(jsondata, status) {
-		for(day in jsondata){
-			if(jsondata[day] == "true"){
-				$("#selectweekend_" + day).attr('selected',true);
-			}
-		}
-		$("#weekend").chosen();
-	});
-	$("#timeformat").change( function(){
-		var data = $("#timeformat").serialize();
+	$('#timezone').chosen();
+	$('#timeformat').change( function(){
+		var data = $('#timeformat').serialize();
 		$.post( OC.filePath('calendar', 'ajax', 'settimeformat.php'), data, function(data){
-			if(data == "error"){
-				console.log("saving timeformat failed");
+			if(data == 'error'){
+				console.log('saving timeformat failed');
 			}
 		});
 	});
-	$.getJSON(OC.filePath('calendar', 'ajax', 'timeformat.php'), function(jsondata, status) {
-		$("#" + jsondata.timeformat).attr('selected',true);
-		$("#timeformat").chosen();
-	});
-	$("#duration").blur( function(){
-		var data = $("#duration").val();
-		$.post( OC.filePath('calendar', 'ajax', 'setduration.php'), {duration: data}, function(data){
-			if(data == "error"){
-				console.log("saving duration failed");
-			}
+	$('#timezonedetection').change( function(){
+		var post = $('#timezonedetection').serialize();
+		$.post( OC.filePath('calendar', 'ajax', 'timezonedetection.php'), post, function(data){
+			
 		});
 	});
-	$.getJSON(OC.filePath('calendar', 'ajax', 'duration.php'), function(jsondata, status) {
-		$("#duration").val(jsondata.duration);
+	$.getJSON(OC.filePath('calendar', 'ajax', 'timeformat.php'), function(jsondata, status) {
+		$('#' + jsondata.timeformat).attr('selected',true);
+		$('#timeformat').chosen();
 	});
-	$("#weekend").change( function(){
-		var data = $("#weekend").serialize();
-		$.post( OC.filePath('calendar', 'ajax', 'setdaysofweekend.php'), data, function(data){
-			if(data == "error"){
-				console.log("saving days of weekend failed");
-			}
-		});
+	$.getJSON(OC.filePath('calendar', 'ajax', 'gettimezonedetection.php'), function(jsondata, status){
+		if(jsondata.detection == 'true'){
+			$('#timezonedetection').attr('checked', 'checked');
+		}
 	});
 });
diff --git a/apps/calendar/l10n/xgettextfiles b/apps/calendar/l10n/xgettextfiles
index 27b8e457193f5c340125bcc3e4e17b9980abc10e..a8c2601045f2e6da215fdaef9a7a3621056000f7 100644
--- a/apps/calendar/l10n/xgettextfiles
+++ b/apps/calendar/l10n/xgettextfiles
@@ -8,4 +8,5 @@
 ../templates/part.eventform.php
 ../templates/part.import.php
 ../templates/part.newevent.php
-../templates/settings.php
\ No newline at end of file
+../templates/settings.php
+../templates/lAfix.php
\ No newline at end of file
diff --git a/apps/calendar/lib/app.php b/apps/calendar/lib/app.php
index b023d531aa53ce1a293627f996210466badad05e..6e92cf67c5c6121918c3bfaad678b1c32bc0c692 100644
--- a/apps/calendar/lib/app.php
+++ b/apps/calendar/lib/app.php
@@ -75,8 +75,43 @@ class OC_Calendar_App{
 		);
 	}
 
-	public static function getRepeatOptions()
-	{
-		OC_Calendar_Object::getRepeatOptions(self::$l10n);
+	public static function getRepeatOptions(){
+		return OC_Calendar_Object::getRepeatOptions(self::$l10n);
+	}
+
+	public static function getEndOptions(){
+		return OC_Calendar_Object::getEndOptions(self::$l10n);
+	}
+
+	public static function getMonthOptions(){
+		return OC_Calendar_Object::getMonthOptions(self::$l10n);
+	}
+
+	public static function getWeeklyOptions(){
+		return OC_Calendar_Object::getWeeklyOptions(self::$l10n);
+	}
+
+	public static function getYearOptions(){
+		return OC_Calendar_Object::getYearOptions(self::$l10n);
+	}
+
+	public static function getByYearDayOptions(){
+		return OC_Calendar_Object::getByYearDayOptions();
+	}
+
+	public static function getByMonthOptions(){
+		return OC_Calendar_Object::getByMonthOptions(self::$l10n);
+	}
+	
+	public static function getByWeekNoOptions(){
+		return OC_Calendar_Object::getByWeekNoOptions();
+	}
+
+	public static function getByMonthDayOptions(){
+		return OC_Calendar_Object::getByMonthDayOptions();
+	}
+	
+	public static function getWeekofMonth(){
+		return OC_Calendar_Object::getWeekofMonth(self::$l10n);
 	}
 }
diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php
index 58fe60611ce2aeed6ff9f227df83941e09489ed8..cbb1badf80210432626e468acb25e351135528bf 100644
--- a/apps/calendar/lib/object.php
+++ b/apps/calendar/lib/object.php
@@ -356,9 +356,99 @@ class OC_Calendar_Object{
 			'weekday'       => $l10n->t('Every Weekday'),
 			'biweekly'      => $l10n->t('Bi-Weekly'),
 			'monthly'       => $l10n->t('Monthly'),
-			'yearly'        => $l10n->t('Yearly'),
+			'yearly'        => $l10n->t('Yearly')
 		);
 	}
+
+	public static function getEndOptions($l10n)
+	{
+		return array(
+			'never' => $l10n->t('never'),
+			'count' => $l10n->t('by occurrences'),
+			'date'  => $l10n->t('by date')
+		);
+	}
+
+	public static function getMonthOptions($l10n)
+	{
+		return array(
+			'monthday' => $l10n->t('by monthday'),
+			'weekday'  => $l10n->t('by weekday')
+		);
+	}
+
+	public static function getWeeklyOptions($l10n)
+	{
+		return array(
+			'MO' => $l10n->t('Monday'),
+			'TU' => $l10n->t('Tuesday'),
+			'WE' => $l10n->t('Wednesday'),
+			'TH' => $l10n->t('Thursday'),
+			'FR' => $l10n->t('Friday'),
+			'SA' => $l10n->t('Saturday'),
+			'SU' => $l10n->t('Sunday')
+		);
+	}
+
+	public static function getWeekofMonth($l10n)
+	{
+		return array(
+			'auto' => $l10n->t('events week of month'),
+			'1' => $l10n->t('first'),
+			'2' => $l10n->t('second'),
+			'3' => $l10n->t('third'),
+			'4' => $l10n->t('fourth'),
+			'5' => $l10n->t('fifth'),
+			'-1' => $l10n->t('last')
+		);
+	}
+
+	public static function getByYearDayOptions(){
+		$return = array();
+		foreach(range(1,366) as $num){
+			$return[(string) $num] = (string) $num;
+		}
+		return $return;
+	}
+
+	public static function getByMonthDayOptions(){
+		$return = array();
+		foreach(range(1,31) as $num){
+			$return[(string) $num] = (string) $num;
+		}
+		return $return;
+	}
+
+	public static function getByMonthOptions($l10n){
+		return array(
+			'1'  => $l10n->t('January'),
+			'2'  => $l10n->t('February'),
+			'3'  => $l10n->t('March'),
+			'4'  => $l10n->t('April'),
+			'5'  => $l10n->t('May'),
+			'6'  => $l10n->t('June'),
+			'7'  => $l10n->t('July'),
+			'8'  => $l10n->t('August'),
+			'9'  => $l10n->t('September'),
+			'10' => $l10n->t('October'),
+			'11' => $l10n->t('November'),
+			'12' => $l10n->t('December')
+		);
+	}
+
+	public static function getYearOptions($l10n){
+		return array(
+			'bydate' => $l10n->t('by events date'),
+			'byyearday' => $l10n->t('by yearday(s)'),
+			'byweekno'  => $l10n->t('by weeknumber(s)'),
+			'bydaymonth'  => $l10n->t('by day and month')
+		);
+	}
+
+	public static function getByWeekNoOptions(){
+		return range(1, 52);
+	}
+
 	public static function validateRequest($request)
 	{
 		$errnum = 0;
@@ -397,7 +487,91 @@ class OC_Calendar_Object{
 			$errarr['to'] = 'true';
 			$errnum++;
 		}
-		;
+		if($request['repeat'] != 'doesnotrepeat'){
+			if(is_nan($request['interval']) && $request['interval'] != ''){
+				$errarr['interval'] = 'true';
+				$ernum++;
+			}
+			if(array_key_exists('repeat', $request) && !array_key_exists($request['repeat'], self::getRepeatOptions(OC_Calendar_App::$l10n))){
+				$errarr['repeat'] = 'true';
+				$ernum++;
+			}
+			if(array_key_exists('advanced_month_select', $request) && !array_key_exists($request['advanced_month_select'], self::getMonthOptions(OC_Calendar_App::$l10n))){
+				$errarr['advanced_month_select'] = 'true';
+				$errnum++;
+			}
+			if(array_key_exists('advanced_year_select', $request) && !array_key_exists($request['advanced_year_select'], self::getYearOptions(OC_Calendar_App::$l10n))){
+				$errarr['advanced_year_select'] = 'true';
+				$errnum++;
+			}
+			if(array_key_exists('weekofmonthoptions', $request) && !array_key_exists($request['weekofmonthoptions'], self::getWeekofMonth(OC_Calendar_App::$l10n))){
+				$errarr['weekofmonthoptions'] = 'true';
+				$errnum++;
+			}
+			if($request['end'] != 'never'){
+				if(!array_key_exists($request['end'], self::getEndOptions(OC_Calendar_App::$l10n))){
+					$errarr['end'] = 'true';
+					$errnum++;
+				}
+				if($request['end'] == 'count' && is_nan($request['byoccurrences'])){
+					$errarr['byoccurrences'] = 'true';
+					$errnum++;
+				}
+				if($request['end'] == 'date'){
+					list($bydate_day, $bydate_month, $bydate_year) = explode('-', $request['bydate']);
+					if(!checkdate($bydate_month, $bydate_day, $bydate_year)){
+						$errarr['bydate'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+			if(array_key_exists('weeklyoptions', $request)){
+				foreach($request['weeklyoptions'] as $option){
+					if(!in_array($option, self::getWeeklyOptions(OC_Calendar_App::$l10n))){
+						$errarr['weeklyoptions'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+			if(array_key_exists('byyearday', $request)){
+				foreach($request['byyearday'] as $option){
+					if(!array_key_exists($option, self::getByYearDayOptions())){
+						$errarr['byyearday'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+			if(array_key_exists('weekofmonthoptions', $request)){
+				if(is_nan((double)$request['weekofmonthoptions'])){
+					$errarr['weekofmonthoptions'] = 'true';
+					$errnum++;
+				}
+			}
+			if(array_key_exists('bymonth', $request)){
+				foreach($request['bymonth'] as $option){
+					if(!in_array($option, self::getByMonthOptions(OC_Calendar_App::$l10n))){
+						$errarr['bymonth'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+			if(array_key_exists('byweekno', $request)){
+				foreach($request['byweekno'] as $option){
+					if(!array_key_exists($option, self::getByWeekNoOptions())){
+						$errarr['byweekno'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+			if(array_key_exists('bymonthday', $request)){
+				foreach($request['bymonthday'] as $option){
+					if(!array_key_exists($option, self::getByMonthDayOptions())){
+						$errarr['bymonthday'] = 'true';
+						$errnum++;
+					}
+				}
+			}
+		}
 		if(!$allday && self::checkTime(urldecode($request['totime']))) {
 			$errarr['totime'] = 'true';
 			$errnum++;
@@ -468,27 +642,148 @@ class OC_Calendar_Object{
 			$fromtime = $request['fromtime'];
 			$totime = $request['totime'];
 		}
+		$vevent = $vcalendar->VEVENT;
 		$description = $request["description"];
-		//$repeat = $request["repeat"];
-		/*switch($request["repeatfreq"]){
-			case "DAILY":
-				$repeatfreq = "DAILY";
-			case "WEEKLY":
-				$repeatfreq = "WEEKLY";
-			case "WEEKDAY":
-				$repeatfreq = "DAILY;BYDAY=MO,TU,WE,TH,FR"; //load weeksdayss from userconfig when weekdays are choosable
-			case "":
-				$repeatfreq = "";
-			case "":
-				$repeatfreq = "";
-			case "":
-				$repeatfreq = "";
-			default:
-				$repeat = "false";
-		}*/
-		$repeat = "false";
+		$repeat = $request["repeat"];
+		if($repeat != 'doesnotrepeat'){
+			$rrule = '';
+			$interval = $request['interval'];
+			$end = $request['end'];
+			$byoccurrences = $request['byoccurrences'];
+			switch($repeat){
+				case 'daily':
+					$rrule .= 'FREQ=DAILY';
+					break;
+				case 'weekly':
+					$rrule .= 'FREQ=WEEKLY';
+					if(array_key_exists('weeklyoptions', $request)){
+						$byday = '';
+						$daystrings = array_flip(self::getWeeklyOptions(OC_Calendar_App::$l10n));
+						foreach($request['weeklyoptions'] as $days){
+							if($byday == ''){
+								$byday .= $daystrings[$days];
+							}else{
+								$byday .= ',' .$daystrings[$days];
+							}
+						}
+						$rrule .= ';BYDAY=' . $byday;
+					}
+					break;
+				case 'weekday':
+					$rrule .= 'FREQ=WEEKLY';
+					$rrule .= ';BYDAY=MO,TU,WE,TH,FR';
+					break;
+				case 'biweekly':
+					$rrule .= 'FREQ=WEEKLY';
+					$interval = $interval * 2;
+					break;
+				case 'monthly':
+					$rrule .= 'FREQ=MONTHLY';
+					if($request['advanced_month_select'] == 'monthday'){
+						break;
+					}elseif($request['advanced_month_select'] == 'weekday'){
+						if($request['weekofmonthoptions'] == 'auto'){
+							list($_day, $_month, $_year) = explode('-', $from);
+							$weekofmonth = floor($_day/7);
+						}else{
+							$weekofmonth = $request['weekofmonthoptions'];
+						}
+						$days = array_flip(self::getWeeklyOptions(OC_Calendar_App::$l10n));
+						$byday = '';
+						foreach($request['weeklyoptions'] as $day){
+							if($byday == ''){
+								$byday .= $weekofmonth . $days[$day];
+							}else{
+								$byday .= ',' . $weekofmonth . $days[$day];
+							}
+						}
+						$rrule .= ';BYDAY=' . $byday;
+					}
+					break;
+				case 'yearly':
+					$rrule .= 'FREQ=YEARLY';
+					if($request['advanced_year_select'] == 'bydate'){
+						
+					}elseif($request['advanced_year_select'] == 'byyearday'){
+						list($_day, $_month, $_year) = explode('-', $from);
+						$byyearday = date('z', mktime(0,0,0, $_month, $_day, $_year)) + 1;
+						if(array_key_exists('byyearday', $request)){
+							foreach($request['byyearday'] as $yearday){
+								$byyearday .= ',' . $yearday;
+							}
+						}
+						$rrule .= ';BYYEARDAY=' . $byyearday;
+					}elseif($request['advanced_year_select'] == 'byweekno'){
+						list($_day, $_month, $_year) = explode('-', $from);
+						$rrule .= ';BYDAY=' . strtoupper(substr(date('l', mktime(0,0,0, $_month, $_day, $_year)), 0, 2));
+						$byweekno = '';
+						foreach($request['byweekno'] as $weekno){
+							if($byweekno == ''){
+								$byweekno = $weekno;
+							}else{
+								$byweekno .= ',' . $weekno;
+							}
+						}
+						$rrule .= ';BYWEEKNO=' . $byweekno;
+					}elseif($request['advanced_year_select'] == 'bydaymonth'){
+						if(array_key_exists('weeklyoptions', $request)){
+							$days = array_flip(self::getWeeklyOptions(OC_Calendar_App::$l10n));
+							$byday = '';
+							foreach($request['weeklyoptions'] as $day){
+								if($byday == ''){
+								      $byday .= $days[$day];
+								}else{
+								      $byday .= ',' . $days[$day];
+								}
+							}
+							$rrule .= ';BYDAY=' . $byday;
+						}
+						if(array_key_exists('bymonth', $request)){
+							$monthes = array_flip(self::getByMonthOptions(OC_Calendar_App::$l10n));
+							$bymonth = '';
+							foreach($request['bymonth'] as $month){
+								if($bymonth == ''){
+								      $bymonth .= $monthes[$month];
+								}else{
+								      $bymonth .= ',' . $monthes[$month];
+								}
+							}
+							$rrule .= ';BYMONTH=' . $bymonth;
+							
+						}
+						if(array_key_exists('bymonthday', $request)){
+							$bymonthday = '';
+							foreach($request['bymonthday'] as $monthday){
+								if($bymonthday == ''){
+								      $bymonthday .= $monthday;
+								}else{
+								      $bymonthday .= ',' . $monthday;
+								}
+							}
+							$rrule .= ';BYMONTHDAY=' . $bymonthday;
+							
+						}
+					}
+					break;
+				default:
+					break;
+			}
+			if($interval != ''){
+				$rrule .= ';INTERVAL=' . $interval;
+			}
+			if($end == 'count'){
+				$rrule .= ';COUNT=' . $byoccurrences;
+			}
+			if($end == 'date'){
+				list($bydate_day, $bydate_month, $bydate_year) = explode('-', $request['bydate']);
+				$rrule .= ';UNTIL=' . $bydate_year . $bydate_month . $bydate_day;
+			}
+			$vevent->setString('RRULE', $rrule);
+			$repeat = "true";
+		}else{
+			$repeat = "false";
+		}
 
-		$vevent = $vcalendar->VEVENT;
 
 		$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
 		$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
@@ -521,4 +816,4 @@ class OC_Calendar_Object{
 
 		return $vcalendar;
 	}
-}
+}
\ No newline at end of file
diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php
index 41faf49a51976bac9ba9bc80b8e1cb7a9f2c2062..425c93c7338eb2be0e200297ea0e6e87fcd5a681 100644
--- a/apps/calendar/lib/search.php
+++ b/apps/calendar/lib/search.php
@@ -12,15 +12,36 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
 		}else{
 			$searchquery[] = $query;
 		}
+		$user_timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+		$l = new OC_l10n('calendar');
 		foreach($calendars as $calendar){
 			$objects = OC_Calendar_Object::all($calendar['id']);
 			foreach($objects as $object){
-				if(substr_count(strtolower($object['summary']), strtolower($query)) > 0){//$name,$text,$link,$type
-					$results[]=new OC_Search_Result($object['summary'],'','#','Cal.');
+				if(substr_count(strtolower($object['summary']), strtolower($query)) > 0){
+					$calendardata = OC_VObject::parse($object['calendardata']);
+					$vevent = $calendardata->VEVENT;
+					$dtstart = $vevent->DTSTART;
+					$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
+					$start_dt = $dtstart->getDateTime();
+					$start_dt->setTimezone(new DateTimeZone($user_timezone));
+					$end_dt = $dtend->getDateTime();
+					$end_dt->setTimezone(new DateTimeZone($user_timezone));
+					if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
+						$end_dt->modify('-1 sec');
+						if($start_dt->format('d.m.Y') != $end_dt->format('d.m.Y')){
+							$info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y') . ' - ' . $end_dt->format('d.m.Y');
+						}else{
+							$info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y');
+						}
+					}else{
+						$info = $l->t('Date') . ': ' . $start_dt->format('d.m.y H:i') . ' - ' . $end_dt->format('d.m.y H:i');
+					}
+					$link = OC_Helper::linkTo('apps/calendar', 'index.php?showevent='.urlencode($object['id']));
+					$results[]=new OC_Search_Result($object['summary'],$info, $link,$l->t('Cal.'));//$name,$text,$link,$type
 				}
 			}
 		}
 		return $results;
 	}
 }
-new OC_Search_Provider_Calendar();
\ No newline at end of file
+new OC_Search_Provider_Calendar();
diff --git a/apps/calendar/resettimezone.php b/apps/calendar/resettimezone.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ef9591ae39d8f01f8bdc836b67ae20e3dab482e
--- /dev/null
+++ b/apps/calendar/resettimezone.php
@@ -0,0 +1,4 @@
+<?php
+require_once ("../../lib/base.php"); 
+OC_Preferences::deleteKey(OC_USER::getUser(), 'calendar', 'timezone');
+?>
\ No newline at end of file
diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php
index 13bc8bc1bb1659fab2298486b3cbc964425bf165..50d3d70347a791716d8f1a090b281f6410ee39cc 100755
--- a/apps/calendar/templates/calendar.php
+++ b/apps/calendar/templates/calendar.php
@@ -18,6 +18,17 @@
 				var missing_field_startsbeforeends = '<?php echo $l->t('The event ends before it starts') ?>';
 				var missing_field_dberror = '<?php echo $l->t('There was a database fail') ?>';
 				var totalurl = '<?php echo OC_Helper::linkTo('apps/calendar', 'caldav.php', null, true); ?>/calendars';
+				$(document).ready(function() {
+				<?php
+				if(array_key_exists('showevent', $_)){
+					$data = OC_Calendar_App::getEventObject($_['showevent']);
+					$date = substr($data['startdate'], 0, 10);
+					list($year, $month, $day) = explode('-', $date);
+					echo '$(\'#calendar_holder\').fullCalendar(\'gotoDate\', ' . $year . ', ' . --$month . ', ' . $day . ');';
+					echo '$(\'#dialog_holder\').load(OC.filePath(\'calendar\', \'ajax\', \'editeventform.php\') + \'?id=\' +  ' . $_['showevent'] . ' , Calendar.UI.startEventDialog);';
+				}
+				?>
+				});
 				</script>
 				<div id="loading"><img src="<?php echo OC_Helper::imagePath('core', 'loading.gif'); ?>" /></div>
 				<div id="controls">
diff --git a/apps/calendar/templates/lAfix.php b/apps/calendar/templates/lAfix.php
new file mode 100644
index 0000000000000000000000000000000000000000..61025ae6dea4350de23fccbc9f7bf11b674c6429
--- /dev/null
+++ b/apps/calendar/templates/lAfix.php
@@ -0,0 +1,39 @@
+<?php
+$l->t('Sunday');
+$l->t('Monday');
+$l->t('Tuesday');
+$l->t('Wednesday');
+$l->t('Thursday');
+$l->t('Friday');
+$l->t('Saturday');
+$l->t('Sun.');
+$l->t('Mon.');
+$l->t('Tue.');
+$l->t('Wed.');
+$l->t('Thu.');
+$l->t('Fri.');
+$l->t('Sat.');
+$l->t('January');
+$l->t('February');
+$l->t('March');
+$l->t('April');
+$l->t('May');
+$l->t('June');
+$l->t('July');
+$l->t('August');
+$l->t('September');
+$l->t('October');
+$l->t('November');
+$l->t('December');
+$l->t('Jan.');
+$l->t('Feb.');
+$l->t('Mar.');
+$l->t('Apr.');
+$l->t('May.');
+$l->t('Jun.');
+$l->t('Jul.');
+$l->t('Aug.');
+$l->t('Sep.');
+$l->t('Oct.');
+$l->t('Nov.');
+$l->t('Dec.');
\ No newline at end of file
diff --git a/apps/calendar/templates/part.eventform.php b/apps/calendar/templates/part.eventform.php
index dfa5fb8c78a9fded48a37e8a0065346925c3d5da..1f2073f4bc7c92e1008dfff3b864219836e385ed 100644
--- a/apps/calendar/templates/part.eventform.php
+++ b/apps/calendar/templates/part.eventform.php
@@ -2,92 +2,221 @@
 		<tr>
 			<th width="75px"><?php echo $l->t("Title");?>:</th>
 			<td>
-			<input type="text" style="width:350px;" size="100" placeholder="<?php echo $l->t("Title of the Event");?>" value="<?php echo isset($_['title']) ? $_['title'] : '' ?>" maxlength="100" name="title"/>
+				<input type="text" style="width:350px;" size="100" placeholder="<?php echo $l->t("Title of the Event");?>" value="<?php echo isset($_['title']) ? $_['title'] : '' ?>" maxlength="100" name="title"/>
 			</td>
 		</tr>
 	</table>
-	<table>
+	<table width="100%">
 		<tr>
 			<th width="75px"><?php echo $l->t("Category");?>:</th>
 			<td>
-			<select id="category" name="categories[]" multiple="multiple" title="<?php echo $l->t("Select category") ?>">
-				<?php
-				if (!isset($_['categories'])) {$_['categories'] = array();}
-				echo html_select_options($_['category_options'], $_['categories'], array('combine'=>true));
-				?>
-			</select></td>
+				<select id="category" name="categories[]" multiple="multiple" title="<?php echo $l->t("Select category") ?>">
+					<?php
+					if (!isset($_['categories'])) {$_['categories'] = array();}
+					echo html_select_options($_['category_options'], $_['categories'], array('combine'=>true));
+					?>
+				</select>
+			</td>
 			<th width="75px">&nbsp;&nbsp;&nbsp;<?php echo $l->t("Calendar");?>:</th>
 			<td>
-			<select style="width:140px;" name="calendar">
-				<?php
-				if (!isset($_['calendar'])) {$_['calendar'] = false;}
-				echo html_select_options($_['calendar_options'], $_['calendar'], array('value'=>'id', 'label'=>'displayname'));
-				?>
-			</select></td>
+				<select style="width:140px;" name="calendar">
+					<?php
+					if (!isset($_['calendar'])) {$_['calendar'] = false;}
+					echo html_select_options($_['calendar_options'], $_['calendar'], array('value'=>'id', 'label'=>'displayname'));
+					?>
+				</select>
+			</td>
 		</tr>
 	</table>
 	<hr>
-	<table>
+	<table width="100%">
 		<tr>
 			<th width="75px"></th>
 			<td>
-			<input onclick="Calendar.UI.lockTime();" type="checkbox"<?php if($_['allday']){echo 'checked="checked"';} ?> id="allday_checkbox" name="allday">
-			<label for="allday_checkbox"><?php echo $l->t("All Day Event");?></label></td>
+				<input onclick="Calendar.UI.lockTime();" type="checkbox"<?php if($_['allday']){echo 'checked="checked"';} ?> id="allday_checkbox" name="allday">
+				<label for="allday_checkbox"><?php echo $l->t("All Day Event");?></label>
+			</td>
 		</tr>
 		<tr>
-
 			<th width="75px"><?php echo $l->t("From");?>:</th>
 			<td>
-			<input type="text" value="<?php echo $_['startdate'];?>" name="from" id="from">
-			&nbsp;&nbsp;
-			<input type="time" value="<?php echo $_['starttime'];?>" name="fromtime" id="fromtime">
-			</td><!--use jquery-->
+				<input type="text" value="<?php echo $_['startdate'];?>" name="from" id="from">
+				&nbsp;&nbsp;
+				<input type="time" value="<?php echo $_['starttime'];?>" name="fromtime" id="fromtime">
+			</td>
 		</tr>
 		<tr>
 			<th width="75px"><?php echo $l->t("To");?>:</th>
 			<td>
-			<input type="text" value="<?php echo $_['enddate'];?>" name="to" id="to">
-			&nbsp;&nbsp;
-			<input type="time" value="<?php echo $_['endtime'];?>" name="totime" id="totime">
-			</td><!--use jquery-->
+				<input type="text" value="<?php echo $_['enddate'];?>" name="to" id="to">
+				&nbsp;&nbsp;
+				<input type="time" value="<?php echo $_['endtime'];?>" name="totime" id="totime">
+			</td>
 		</tr>
 	</table>
 	<input type="button" class="submit" value="<?php echo $l->t("Advanced options"); ?>" onclick="Calendar.UI.showadvancedoptions();" id="advanced_options_button">
 	<div id="advanced_options" style="display: none;">
-	<!--
-	<table>
-		<tr>
-			<th width="75px"><?php echo $l->t("Repeat");?>:</th>
-			<td>
-			<select name="repeat" style="width:350px;">
-				<?php
-				if (isset($_['repeat_options'])) {
+		<table style="width:100%">
+			<tr>
+				<th width="75px"><?php echo $l->t("Repeat");?>:</th>
+				<td>
+				<select id="repeat" name="repeat">
+					<?php
 					echo html_select_options($_['repeat_options'], $_['repeat']);
-				}
-				?>
-			</select></td>
-		</tr>-->
-	</table>
-	<hr>
-	<table><!--
-		<tr>
-			<th width="75px"><?php echo $l->t("Attendees");?>:</th>
-			<td style="height: 50px;"></td>
-		</tr>
-	</table>
-	<hr>-->
-	<table>
-		<tr>
-			<th width="85px"><?php echo $l->t("Location");?>:</th>
-			<td>
-			<input type="text" style="width:350px;" size="100" placeholder="<?php echo $l->t("Location of the Event");?>" value="<?php echo isset($_['location']) ? $_['location'] : '' ?>" maxlength="100"  name="location" />
-			</td>
-		</tr>
-	</table>
-	<table>
-		<tr>
-			<th width="85px" style="vertical-align: top;"><?php echo $l->t("Description");?>:</th>
-			<td><textarea style="width:350px;height: 150px;" placeholder="<?php echo $l->t("Description of the Event");?>" name="description"><?php echo isset($_['description']) ? $_['description'] : '' ?></textarea></td>
-		</tr>
-	</table>
+					?>
+				</select></td>
+				<td><input type="button" style="float:right;" class="submit" value="<?php echo $l->t("Advanced"); ?>" onclick="Calendar.UI.showadvancedoptionsforrepeating();" id="advanced_options_button"></td>
+			</tr>
+		</table>
+		<div id="advanced_options_repeating" style="display:none;">
+			<table style="width:100%">
+				<tr id="advanced_month" style="display:none;">
+					<th width="75px"></th>
+					<td>
+						<select id="advanced_month_select" name="advanced_month_select">
+							<?php
+							echo html_select_options($_['repeat_month_options'], $_['repeat_month']);
+							?>
+						</select>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_year" style="display:none;">
+					<th width="75px"></th>
+					<td>
+						<select id="advanced_year_select" name="advanced_year_select">
+							<?php
+							echo html_select_options($_['repeat_year_options'], $_['repeat_year']);
+							?>
+						</select>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_weekofmonth" style="display:none;">
+					<th width="75px"></th>
+					<td id="weekofmonthcheckbox">
+						<select id="weekofmonthoptions" name="weekofmonthoptions">
+							<?php
+							echo html_select_options($_['repeat_weekofmonth_options'], $_['repeat_weekofmonth']);
+							?>
+						</select>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_weekday" style="display:none;">
+					<th width="75px"></th>
+					<td id="weeklycheckbox">
+						<select id="weeklyoptions" name="weeklyoptions[]" multiple="multiple" title="<?php echo $l->t("Select weekdays") ?>">
+							<?php
+							if (!isset($_['weekdays'])) {$_['weekdays'] = array();}
+							echo html_select_options($_['repeat_weekly_options'], $_['repeat_weekdays'], array('combine'=>true));
+							?>
+						</select>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_byyearday" style="display:none;">
+					<th width="75px"></th>
+					<td id="byyeardaycheckbox">
+						<select id="byyearday" name="byyearday[]" multiple="multiple" title="<?php echo $l->t("Select days") ?>">
+							<?php
+							if (!isset($_['repeat_byyearday'])) {$_['repeat_byyearday'] = array();}
+							echo html_select_options($_['repeat_byyearday_options'], $_['repeat_byyearday'], array('combine'=>true));
+							?>
+						</select><?php echo $l->t('and the events day of year.'); ?>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_bymonthday" style="display:none;">
+					<th width="75px"></th>
+					<td id="bymonthdaycheckbox">
+						<select id="bymonthday" name="bymonthday[]" multiple="multiple" title="<?php echo $l->t("Select days") ?>">
+							<?php
+							if (!isset($_['repeat_bymonthday'])) {$_['repeat_bymonthday'] = array();}
+							echo html_select_options($_['repeat_bymonthday_options'], $_['repeat_bymonthday'], array('combine'=>true));
+							?>
+						</select><?php echo $l->t('and the events day of month.'); ?>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_bymonth" style="display:none;">
+					<th width="75px"></th>
+					<td id="bymonthcheckbox">
+						<select id="bymonth" name="bymonth[]" multiple="multiple" title="<?php echo $l->t("Select months") ?>">
+							<?php
+							if (!isset($_['repeat_bymonth'])) {$_['repeat_bymonth'] = array();}
+							echo html_select_options($_['repeat_bymonth_options'], $_['repeat_bymonth'], array('combine'=>true));
+							?>
+						</select>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr id="advanced_byweekno" style="display:none;">
+					<th width="75px"></th>
+					<td id="bymonthcheckbox">
+						<select id="byweekno" name="byweekno[]" multiple="multiple" title="<?php echo $l->t("Select weeks") ?>">
+							<?php
+							if (!isset($_['repeat_byweekno'])) {$_['repeat_byweekno'] = array();}
+							echo html_select_options($_['repeat_byweekno_options'], $_['repeat_byweekno'], array('combine'=>true));
+							?>
+						</select><?php echo $l->t('and the events week of year.'); ?>
+					</td>
+				</tr>
+			</table>
+			<table style="width:100%">
+				<tr>
+					<th width="75px"><?php echo $l->t('Interval'); ?>:</th>
+					<td>
+						<input style="width:350px;" type="number" min="1" size="4" max="1000" value="<?php echo isset($_['repeat_interval']) ? $_['repeat_interval'] : '1'; ?>" name="interval">
+					</td>
+				</tr>
+				<tr>
+					<th width="75px"><?php echo $l->t('End'); ?>:</th>
+					<td>
+						<select id="end" name="end">
+							<?php
+							echo html_select_options($_['repeat_end_options'], $_['repeat_end']); 
+							?>
+						</select>
+					</td>
+				</tr>
+				<tr>
+					<th></th>
+					<td id="byoccurrences" style="display:none;">
+						<input type="number" min="1" max="99999" id="until_count" name="byoccurrences" value="<?php echo $_['repeat_count']; ?>"><?php echo $l->t('occurrences'); ?>
+					</td>
+				</tr>
+				<tr>
+					<th></th>
+					<td id="bydate" style="display:none;">
+						<input type="text" name="bydate" value="<?php echo $_['repeat_date']; ?>">
+					</td>
+				</tr>
+			</table>
+		</div>
+		<hr>
+		<!-- support for attendees will be added in following versions --> 
+		<table>
+			<tr>
+				<th width="85px"><?php echo $l->t("Location");?>:</th>
+				<td>
+					<input type="text" style="width:350px;" size="100" placeholder="<?php echo $l->t("Location of the Event");?>" value="<?php echo isset($_['location']) ? $_['location'] : '' ?>" maxlength="100"  name="location" />
+				</td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<th width="85px" style="vertical-align: top;"><?php echo $l->t("Description");?>:</th>
+				<td>
+					<textarea style="width:350px;height: 150px;" placeholder="<?php echo $l->t("Description of the Event");?>" name="description"><?php echo isset($_['description']) ? $_['description'] : '' ?></textarea>
+				</td>
+			</tr>
+		</table>
 	</div>
diff --git a/apps/calendar/templates/settings.php b/apps/calendar/templates/settings.php
index 56fb55d235c7dd342d1b6ae26aa636fb6af89df3..fc8e0e061d966d995367ce7d8293b25c3b523eac 100644
--- a/apps/calendar/templates/settings.php
+++ b/apps/calendar/templates/settings.php
@@ -27,7 +27,7 @@
                     $continent=$ex[0];
                     echo '<option value="'.$timezone.'"'.($_['timezone'] == $timezone?' selected="selected"':'').'>'.$city.'</option>';
                 endforeach;?>
-            </select></td></tr>
+            </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;" id="timeformat" title="<?php echo "timeformat"; ?>" name="timeformat">
diff --git a/apps/gallery/ajax/cover.php b/apps/gallery/ajax/cover.php
index d83f4daaa52ef0f0fac5f6b58b4aef2e9f33ec0e..181a919375db977f3eb1d20604343648887e44c6 100644
--- a/apps/gallery/ajax/cover.php
+++ b/apps/gallery/ajax/cover.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/ajax/createAlbum.php b/apps/gallery/ajax/createAlbum.php
index 9413b54718abf46a9393ce957e6740182bb0b067..152f5834bcb4130d7f0f1db203c13f0aa521bbf0 100644
--- a/apps/gallery/ajax/createAlbum.php
+++ b/apps/gallery/ajax/createAlbum.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/ajax/galleryOp.php b/apps/gallery/ajax/galleryOp.php
index cd7cab202b118eda196ccc00532116943d8fe73c..3d1ed1f33cbc26e063be9ddc976e2d9efc144741 100644
--- a/apps/gallery/ajax/galleryOp.php
+++ b/apps/gallery/ajax/galleryOp.php
@@ -1,6 +1,28 @@
 <?
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
-require_once('../lib/album.php');
+require_once(OC::$CLASSPATH['OC_Gallery_Album']);
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
 
@@ -26,4 +48,4 @@ if ($_GET['operation']) {
      OC_JSON::error(array('cause' => "Unknown operation"));
   }
 }
-?>
\ No newline at end of file
+?>
diff --git a/apps/gallery/ajax/getAlbums.php b/apps/gallery/ajax/getAlbums.php
index e4736076fed346f5d30c4ea1d661b958f53f7551..9e9c6ef496c7b6a889db143a0ec1443da6d3341b 100644
--- a/apps/gallery/ajax/getAlbums.php
+++ b/apps/gallery/ajax/getAlbums.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/ajax/getCovers.php b/apps/gallery/ajax/getCovers.php
index db7c8e9fcdec977aff344fe630741e46a0dc7f8d..4db73d0fbf3594dd510da0566f308f912f719ba3 100644
--- a/apps/gallery/ajax/getCovers.php
+++ b/apps/gallery/ajax/getCovers.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/ajax/scanForAlbums.php b/apps/gallery/ajax/scanForAlbums.php
index f603cbb497173b95f02123f188db511552590494..b8ed639d9dc20ee5da64b26b73050f428bf25b24 100644
--- a/apps/gallery/ajax/scanForAlbums.php
+++ b/apps/gallery/ajax/scanForAlbums.php
@@ -1,10 +1,31 @@
 <?php
 
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
 
 OC_Gallery_Scanner::cleanUp();
-OC_JSON::success(array('albums' => OC_Gallery_Scanner::scan('')));
+OC_JSON::success(array('albums' => OC_Gallery_Scanner::scan('/')));
 
 ?>
diff --git a/apps/gallery/ajax/thumbnail.php b/apps/gallery/ajax/thumbnail.php
index d937691fa036607b94b8b4a80d2213a5964d872b..6d25c7a2536ad146f352e26b73cd67ea4d39b1ae 100644
--- a/apps/gallery/ajax/thumbnail.php
+++ b/apps/gallery/ajax/thumbnail.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/appinfo/app.php b/apps/gallery/appinfo/app.php
index 2b1ab857afcdacbe24dc0ef5f8d75582c0966160..9c665fd3500f34b6ffb3554a01d4a2ece3654cdf 100644
--- a/apps/gallery/appinfo/app.php
+++ b/apps/gallery/appinfo/app.php
@@ -1,7 +1,30 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 OC::$CLASSPATH['OC_Gallery_Album'] = 'apps/gallery/lib/album.php';
 OC::$CLASSPATH['OC_Gallery_Photo'] = 'apps/gallery/lib/photo.php';
 OC::$CLASSPATH['OC_Gallery_Scanner'] = 'apps/gallery/lib/scanner.php';
+OC::$CLASSPATH['OC_Gallery_Hooks_Handlers'] = 'apps/gallery/lib/hooks_handlers.php';
 
 OC_App::register(array(
   'order' => 20,
@@ -28,4 +51,6 @@ OC_App::addNavigationEntry( array(
 }
 
 new OC_GallerySearchProvider();
+
+require_once('apps/gallery/lib/hooks_handlers.php');
 ?>
diff --git a/apps/gallery/appinfo/database.xml b/apps/gallery/appinfo/database.xml
index fd55b3a6fb4cd320e8b3d8b34d11415185671d85..db88e4c1b5a875d0130894a16643806db423b1a4 100644
--- a/apps/gallery/appinfo/database.xml
+++ b/apps/gallery/appinfo/database.xml
@@ -27,6 +27,12 @@
 				<notnull>true</notnull>
 				<length>100</length>
 			</field>
+      <field>
+        <name>album_path</name>
+        <type>text</type>
+        <notnull>true</notnull>
+        <length>100</length>
+      </field>
 		</declaration>
 	</table>
 	<table>
diff --git a/apps/gallery/appinfo/info.xml b/apps/gallery/appinfo/info.xml
index 054ddb6f1398b544ce01bf1d1d0b296252aacd36..c275f39bb253c39a5772a2d05057d697427d01bf 100644
--- a/apps/gallery/appinfo/info.xml
+++ b/apps/gallery/appinfo/info.xml
@@ -2,9 +2,10 @@
 <info>
 	<id>gallery</id>
 	<name>Gallery</name>
-	<version>0.1</version>
+	<version>0.2</version>
 	<licence>AGPL</licence>
-	<author>Bartosz Przybylski</author>
+	<author>Bartek Przybylski</author>
 	<require>2</require>
-	<description></description>
-</info>
\ No newline at end of file
+	<description>Gallery application for ownCloud</description>
+	<default_enable/>
+</info>
diff --git a/apps/gallery/css/styles.css b/apps/gallery/css/styles.css
index 53c3c0901d96c6cf4f4ed82c78aa2596052bf6fb..cc343ba0d08515ffe3eff87cde109d03cc2433a4 100644
--- a/apps/gallery/css/styles.css
+++ b/apps/gallery/css/styles.css
@@ -1,60 +1,11 @@
-div#gallery_list {
-  margin: 90pt 20pt;
-}
-div#gallery_list.leftcontent {
-  padding-top: 15px;
-  margin: 0;
-  text-align: center;
-}
+div#gallery_list { margin: 90pt 20pt; }
+div#gallery_list.leftcontent { padding-top: 15px; margin: 0; text-align: center; }
+div#gallery_album_box { width: 200px; text-align: center; border: 0; display: inline-block; margin: 5pt; vertical-align: top; padding: 10px; border: solid 1px black; position: relative; overflow: hidden; color: #999; }
+div#gallery_album_box:hover { color: black; }
+.leftcontent div#gallery_album_box { margin: 5px; }
+div#gallery_album_box h1 { font-size: 12pt; font-family: Verdana; }
+div#gallery_album_cover { width: 199px; height: 199px; border: solid 1pt #999; padding: 0; }
+div#gallery_control_overlay { border: 0; position:absolute; right: 10pt; background-color: #333; opacity: 0.5; visibility:hidden; padding: 0 5pt; }
+div#gallery_control_overlay a { color:white; }
+#gallery_images { padding:10px 5px; }
 
-div#gallery_album_box {
-  width: 200px;
-  text-align: center;
-  border: 0;
-  display: inline-block;
-  margin: 5pt;
-  vertical-align: top;
-  padding: 10px;
-  border: solid 1px black;
-  position: relative;
-  overflow: hidden;
-  color: #999;
-}
-
-div#gallery_album_box:hover {
-  color: black; 
-}
-
-.leftcontent div#gallery_album_box {
-  margin: 5px;
-}
-
-div#gallery_album_box h1 {
-  font-size: 12pt;
-  font-family: Verdana;
-}
-
-div#gallery_album_cover {
-  width: 199px;
-  height: 199px;
-  border: solid 1pt #999;
-  padding: 0;
-}
-
-div#gallery_control_overlay {
-  border: 0;
-  position:absolute;
-  right: 10pt;
-  background-color: #333;
-  opacity: 0.5;
-  visibility:hidden;
-  padding: 0 5pt;
-}
-
-div#gallery_control_overlay a {
-  color:white;
-}
-
-#gallery_images {
-padding:10px 5px;
-}
diff --git a/apps/gallery/index.php b/apps/gallery/index.php
index 0cd795bac0137d470dae0bca4d9e4d05e0927801..822a5b8e143ec8d595837dc8b97177287064e612 100644
--- a/apps/gallery/index.php
+++ b/apps/gallery/index.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../lib/base.php');
 
 OC_Util::checkLoggedIn();
diff --git a/apps/gallery/js/album_cover.js b/apps/gallery/js/album_cover.js
index 619aa391c564cbea90e8a75b0cdca337e7c7e5da..f6cb2da3103fb739049240f1e8804a46f9eb5b91 100644
--- a/apps/gallery/js/album_cover.js
+++ b/apps/gallery/js/album_cover.js
@@ -31,7 +31,11 @@ function createNewAlbum() {
 }
 
 function scanForAlbums() {
+  $("#notification").fadeIn();
+  $("#notification").slideDown();
   $.getJSON('ajax/scanForAlbums.php', function(r) {
+    $("#notification").fadeOut();
+    $("#notification").slideUp();
     if (r.status == 'success') {
       window.location.reload(true);
     } else {
diff --git a/apps/gallery/lib/album.php b/apps/gallery/lib/album.php
index 0999429c5d5ca40f3487952cac9a496c2cb1112f..a94eff3acd7864abf4907883cd6a2b94672e7616 100644
--- a/apps/gallery/lib/album.php
+++ b/apps/gallery/lib/album.php
@@ -1,9 +1,30 @@
 <?php
 
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 class OC_Gallery_Album {
-	public static function create($owner, $name){
-		$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name) VALUES (?, ?)');
-		$stmt->execute(array($owner, $name));
+	public static function create($owner, $name, $path){
+		$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name, album_path) VALUES (?, ?, ?)');
+		$stmt->execute(array($owner, $name, $path));
 	}
 	
 	public static function rename($oldname, $newname, $owner) {
@@ -22,14 +43,21 @@ class OC_Gallery_Album {
 		return $stmt->execute($args);
 	}
 	
-	public static function find($owner, $name=null){
+  public static function find($owner, $name=null, $path=null){
 		$sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE uid_owner = ?';
 		$args = array($owner);
 		if (!is_null($name)){
 			$sql .= ' AND album_name = ?';
 			$args[] = $name;
-		}
+    }
+    if (!is_null($path)){
+      $sql .= ' AND album_path = ?';
+      $args[] = $path;
+    }
 		$stmt = OC_DB::prepare($sql);
 		return $stmt->execute($args);
 	}
+
 }
+
+?>
diff --git a/apps/gallery/lib/hooks_handlers.php b/apps/gallery/lib/hooks_handlers.php
new file mode 100644
index 0000000000000000000000000000000000000000..65f3faaeeaf3f57559289a9797c2d1e46b0b0e1c
--- /dev/null
+++ b/apps/gallery/lib/hooks_handlers.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
+OC_Hook::connect("OC_Filesystem", "post_write", "OC_Gallery_Hooks_Handlers", "addPhotoFromPath");
+OC_Hook::connect("OC_Filesystem", "delete", "OC_Gallery_Hooks_Handlers", "removePhoto");
+OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Gallery_Hooks_Handlers", "renamePhoto");
+
+require_once(OC::$CLASSPATH['OC_Gallery_Album']);
+require_once(OC::$CLASSPATH['OC_Gallery_Photo']);
+
+class OC_Gallery_Hooks_Handlers {
+  private static $APP_TAG = "Gallery";
+
+  private static function isPhoto($filename) {
+    OC_Log::write(self::$APP_TAG, "Checking file ".$filename." with mimetype ".OC_Filesystem::getMimeType($filename), OC_Log::DEBUG);
+    if (substr(OC_Filesystem::getMimeType($filename), 0, 6) == "image/")
+      return 1;
+    return 0;
+  }
+
+  private static function createAlbum($path) {
+    $new_album_name = trim(str_replace('/', '.', $path), '.');
+    if ($new_album_name == '')
+      $new_album_name = 'main';
+
+    OC_Log::write(self::$APP_TAG, 'Creating new album '.$new_album_name, OC_Log::DEBUG);
+    OC_Gallery_Album::create(OC_User::getUser(), $new_album_name, $path);
+
+    return OC_Gallery_Album::find(OC_User::getUser(), null, $path);
+  }
+
+  public static function addPhotoFromPath($params) {
+    if (!self::isPhoto($params['path'])) return;
+    $fullpath = $params['path'];
+    OC_Log::write(self::$APP_TAG, 'Adding file with path '. $fullpath, OC_Log::DEBUG);
+    $path = substr($fullpath, 0, strrpos($fullpath, '/'));
+    if ($path == '') $path = '/';
+    $album = OC_Gallery_Album::find(OC_User::getUser(), null, $path);
+
+    if ($album->numRows() == 0) {
+      $album = self::createAlbum($path);
+    }
+    $album = $album->fetchRow();
+    $albumId = $album['album_id'];
+    $photo = OC_Gallery_Photo::find($albumId, $fullpath);
+    if ($photo->numRows() == 0) { // don't duplicate photo entries
+      OC_Log::write(self::$APP_TAG, 'Adding new photo to album', OC_Log::DEBUG);
+      OC_Gallery_Photo::create($albumId, $fullpath);
+    }
+
+  }
+
+  public static function removePhoto($params) {
+    $path = $params['path'];
+    if (!self::isPhoto($path)) return;
+    OC_Gallery_Photo::removeByPath($path);
+  }
+
+  public static function renamePhoto($params) {
+    $olddir = substr($params['oldpath'], 0, strrpos($params['oldpath'], '/'));
+    $newdir = substr($params['newpath'], 0, strrpos($params['newpath'], '/'));
+    if ($olddir == '') $olddir = '/';
+    if ($newdir == '') $newdir = '/';
+    if (!self::isPhoto($params['newpath'])) return;
+    OC_Log::write(self::$APP_TAG, 'Moving photo from '.$params['oldpath'].' to '.$params['newpath'], OC_Log::DEBUG);
+    $album;
+    $newAlbumId;
+    $oldAlbumId;
+    if ($olddir == $newdir) {
+      // album changing is not needed
+      $album = OC_Gallery_Album::find(OC_User::getUser(), null, $olddir);
+      if ($album->numRows() == 0) {
+        $album = self::createAlbum($newdir);
+      }
+      $album = $album->fetchRow();
+      $newAlbumId = $oldAlbumId = $album['album_id'];
+    } else {
+      $newalbum = OC_Gallery_Album::find(OC_User::getUser(), null, $newdir);
+      $oldalbum = OC_Gallery_Album::find(OC_User::getUser(), null, $olddir);
+
+      if ($newalbum->numRows() == 0) {
+        $newalbum = self::createAlbum($newdir);
+      }
+      $newalbum = $newalbum->fetchRow();
+      if ($oldalbum->numRows() == 0) {
+        OC_Gallery_Photo::create($newalbum['album_id'], $params['newpath']);
+        return;
+      }
+      $oldalbum = $oldalbum->fetchRow();
+      $newAlbumId = $newalbum['album_id'];
+      $oldAlbumId = $oldalbum['album_id'];
+
+    }
+    OC_Gallery_Photo::changePath($oldAlbumId, $newAlbumId, $params['oldpath'], $params['newpath']);
+  }
+}
+
+?>
diff --git a/apps/gallery/lib/images_utils.php b/apps/gallery/lib/images_utils.php
index cb46bf3f16093bbf66487502079561cacf5e5f56..0cfa52eb56431f8510d637882c0c93cda8c77e74 100644
--- a/apps/gallery/lib/images_utils.php
+++ b/apps/gallery/lib/images_utils.php
@@ -1,4 +1,26 @@
 <?php
+
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('../../../lib/base.php');
 OC_JSON::checkLoggedIn();
 OC_JSON::checkAppEnabled('gallery');
diff --git a/apps/gallery/lib/photo.php b/apps/gallery/lib/photo.php
index 97d159935f543028aac257efb1cefed0e5dcf91e..23887098e0fe87c5d2b27dc43cf933634550c0d8 100644
--- a/apps/gallery/lib/photo.php
+++ b/apps/gallery/lib/photo.php
@@ -1,5 +1,26 @@
 <?php
 
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 class OC_Gallery_Photo{
 	public static function create($albumId, $img){
 		$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_photos (album_id, file_path) VALUES (?, ?)');
@@ -8,7 +29,6 @@ class OC_Gallery_Photo{
 	public static function find($albumId, $img=null){
 		$sql = 'SELECT * FROM *PREFIX*gallery_photos WHERE album_id = ?';
 		$args = array($albumId);
-		$args = array($albumId);
 		if (!is_null($img)){
 			$sql .= ' AND file_path = ?';
 			$args[] = $img;
@@ -25,4 +45,20 @@ class OC_Gallery_Photo{
 				.' AND photos.album_id = albums.album_id');
 		return $stmt->execute(array($owner, $album_name));
 	}
+
+  public static function removeByPath($path) {
+    $stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path = ?');
+    $stmt->execute(array($path));
+  }
+
+  public static function removeById($id) {
+    $stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE photo_id = ?');
+    $stmt->execute(array($id));
+  }
+
+  public static function changePath($oldAlbumId, $newAlbumId, $oldpath, $newpath) {
+    $stmt = OC_DB::prepare("UPDATE *PREFIX*gallery_photos SET file_path = ?, album_id = ? WHERE album_id = ? and file_path = ?");
+    $stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath));
+  }
 }
+
diff --git a/apps/gallery/lib/scanner.php b/apps/gallery/lib/scanner.php
index 59c34b8e69a075953c34e3c605890d7a2ae19db7..3eba9260ac7ff30f294fc6d1ee285a4159163901 100644
--- a/apps/gallery/lib/scanner.php
+++ b/apps/gallery/lib/scanner.php
@@ -1,5 +1,26 @@
 <?php
 
+/**
+* ownCloud - gallery application
+*
+* @author Bartek Przybylski
+* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
 require_once('base.php'); // base lib
 require_once('images_utils.php');
 
@@ -21,13 +42,13 @@ class OC_Gallery_Scanner {
   public static function scanDir($path, &$albums) {
     $current_album = array('name'=> $path, 'imagesCount' => 0, 'images' => array());
     $current_album['name'] = str_replace('/', '.', str_replace(OC::$CONFIG_DATADIRECTORY, '', $current_album['name']));
-    $current_album['name'] = ($current_album['name']==='') ?
+    $current_album['name'] = ($current_album['name']==='.') ?
                              'main' :
                              trim($current_album['name'],'.');
 
     if ($dh = OC_Filesystem::opendir($path)) {
       while (($filename = readdir($dh)) !== false) {
-        $filepath = $path.'/'.$filename;
+        $filepath = ($path[strlen($path)-1]=='/'?$path:$path.'/').$filename;
         if (substr($filename, 0, 1) == '.') continue;
         if (OC_Filesystem::is_dir($filepath)) {
           self::scanDir($filepath, $albums);
@@ -41,7 +62,7 @@ class OC_Gallery_Scanner {
 
     $result = OC_Gallery_Album::find(OC_User::getUser(), $current_album['name']);
     if ($result->numRows() == 0 && count($current_album['images'])) {
-	    OC_Gallery_Album::create(OC_User::getUser(), $current_album['name']);
+	    OC_Gallery_Album::create(OC_User::getUser(), $current_album['name'], $path);
 	    $result = OC_Gallery_Album::find(OC_User::getUser(), $current_album['name']);
     }
     $albumId = $result->fetchRow();
diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php
index 0e89e448768bfab117352aa774b6b41bf95db968..7c6e91a468eab23b3ea3212b55fc43b74f007cc0 100644
--- a/apps/gallery/templates/index.php
+++ b/apps/gallery/templates/index.php
@@ -4,9 +4,10 @@ OC_Util::addScript('gallery', 'albums');
 OC_Util::addScript('gallery', 'album_cover');
 ?>
 
+<div id="notification"><div id="gallery_notification_text">Creating thumbnails</div></div>
 <div id="controls">
-  <!--  <input type="button" value="New album" onclick="javascript:createNewAlbum();" />-->
-  <input type="button" value="Rescan" onclick="javascript:scanForAlbums();" /><br/>
+  <input type="button" value="Rescan" onclick="javascript:scanForAlbums();" />
+  <br/>
 </div>
 <div id="gallery_list">
 </div>
diff --git a/apps/media/css/music.css b/apps/media/css/music.css
index a6738058be3fe4f868b3ee1adbd5d678931fa86a..41ade44a66f15ae3488c948632e9755a5792eb3c 100644
--- a/apps/media/css/music.css
+++ b/apps/media/css/music.css
@@ -22,11 +22,11 @@ div.jp-volume-bar-value { background:#ccc; width:0; height:0.4em; }
 #collection li.album,#collection li.song { margin-left:3em; }
 #leftcontent img.remove { display:none; float:right; cursor:pointer; }
 #leftcontent li:hover img.remove { display:inline; }
-#leftcontent li {white-space: normal; }
+#leftcontent li div.label { float: left; width: 200px; overflow: hidden; text-overflow: ellipsis; }
 #collection li button { float:right; }
 #collection li,#playlist li { list-style-type:none; }
 .template { display:none; }
-.collection_playing { background:#eee; }
+.collection_playing { background:#eee; font-weight: bold; }
 
 #collection li { padding-right:10px; }
 #searchresults input.play, #searchresults input.add { float:left; height:1em; width:1em; }
diff --git a/apps/media/js/player.js b/apps/media/js/player.js
index 3c022e9f8c48ebf69a57ceaf37d54c0645fca1bd..1f76356fd9798de6870261b26a6b6adf0e4d44c7 100644
--- a/apps/media/js/player.js
+++ b/apps/media/js/player.js
@@ -93,9 +93,11 @@ var PlayList={
 			ended:PlayList.next,
 			pause:function(){
 				localStorage.setItem(oc_current_user+'oc_playlist_playing','false');
+				document.title = "ownCloud";
 			},
-			play:function(){
+			play:function(event){
 				localStorage.setItem(oc_current_user+'oc_playlist_playing','true');
+				document.title = "\u25b8 " + event.jPlayer.status.media.name + " - " + event.jPlayer.status.media.artist + " - ownCloud";
 			},
 			supplied:type,
 			ready:function(){
diff --git a/apps/media/js/playlist.js b/apps/media/js/playlist.js
index 57180b3be7b6323742105a896ad0e043f58e35fe..089065989aef2c3ba9f163ede2190a31d0357f7b 100644
--- a/apps/media/js/playlist.js
+++ b/apps/media/js/playlist.js
@@ -1,11 +1,23 @@
 PlayList.render=function(){
 	$('#playlist').show();
+
+	/*
+	 * We should not empty() PlayList.parent() but thorougly manage its
+	 * elements instead because some code might be attached to those.
+	 * JQuery tipsies are one of them. The following line make sure they
+	 * are all removed before we delete the associated <li/>.
+	 */
+	$(".tipsy").remove();
+
 	PlayList.parent.empty();
 	for(var i=0;i<PlayList.items.length;i++){
 		var item=PlayList.items[i];
 		var li=$('<li/>');
-		li.append(item.name);
-                li.attr('class', 'jp-playlist-' + i);
+		li.attr('class', 'jp-playlist-' + i);
+		li.attr('title', item.artist + ' - ' + item.name + '<br/>(' + item.album + ')');
+		var div = $('<div class="label">' + item.name + '</div>');
+		li.append(div);
+		$('.jp-playlist-' + i).tipsy({gravity:'w', fade:true, live:true, html:true});
 		var img=$('<img class="remove svg action" src="'+OC.imagePath('core','actions/delete')+'"/>');
 		img.click(function(event){
 			event.stopPropagation();
diff --git a/apps/media/lib_collection.php b/apps/media/lib_collection.php
index caa3ac3f47985b2da5e6c78a741f9434506fdc70..1240f1de2f00f4cdd99668cdea5159ba8f7a8a99 100644
--- a/apps/media/lib_collection.php
+++ b/apps/media/lib_collection.php
@@ -127,7 +127,7 @@ class OC_MEDIA_COLLECTION{
 			$search='%';
 		}
 		$query=OC_DB::prepare("SELECT DISTINCT *PREFIX*media_artists.artist_name AS artist_name , *PREFIX*media_artists.artist_id AS artist_id FROM *PREFIX*media_artists
-			INNER JOIN *PREFIX*media_songs ON *PREFIX*media_artists.artist_id=*PREFIX*media_songs.song_artist WHERE artist_name LIKE ? AND *PREFIX*media_songs.song_user=?");
+			INNER JOIN *PREFIX*media_songs ON *PREFIX*media_artists.artist_id=*PREFIX*media_songs.song_artist WHERE artist_name LIKE ? AND *PREFIX*media_songs.song_user=? ORDER BY artist_name");
 		return $query->execute(array($search,self::$uid))->fetchAll();
 	}
 	
@@ -160,7 +160,7 @@ class OC_MEDIA_COLLECTION{
 	*/
 	static public function getAlbums($artist=0,$search='%',$exact=false){
 		$cmd="SELECT DISTINCT *PREFIX*media_albums.album_name AS album_name , *PREFIX*media_albums.album_artist AS album_artist , *PREFIX*media_albums.album_id AS album_id
-			FROM *PREFIX*media_albums INNER JOIN *PREFIX*media_songs ON *PREFIX*media_albums.album_id=*PREFIX*media_songs.song_album WHERE *PREFIX*media_songs.song_user=? ";
+			FROM *PREFIX*media_albums INNER JOIN *PREFIX*media_songs ON *PREFIX*media_albums.album_id=*PREFIX*media_songs.song_album WHERE *PREFIX*media_songs.song_user=? ORDER BY album_name";
 		$params=array(self::$uid);
 		if($artist!=0){
 			$cmd.="AND *PREFIX*media_albums.album_artist = ? ";
@@ -233,7 +233,7 @@ class OC_MEDIA_COLLECTION{
 		}else{
 			$searchString='';
 		}
-		$query=OC_DB::prepare("SELECT * FROM *PREFIX*media_songs WHERE song_user=? $artistString $albumString $searchString");
+		$query=OC_DB::prepare("SELECT * FROM *PREFIX*media_songs WHERE song_user=? $artistString $albumString $searchString ORDER BY song_track, song_name");
 		return $query->execute($params)->fetchAll();
 	}
 	
@@ -378,4 +378,4 @@ class OC_MEDIA_COLLECTION{
 	}
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/apps/media/lib_scanner.php b/apps/media/lib_scanner.php
index c2bea2d836d95f5e0b85fe205be4611473ccf23d..4039cce09ee60b8767ec1d3b7272129b78db2f49 100644
--- a/apps/media/lib_scanner.php
+++ b/apps/media/lib_scanner.php
@@ -30,7 +30,6 @@ class OC_MEDIA_SCANNER{
 	//these are used to store which artists and albums we found, it can save a lot of addArtist/addAlbum calls
 	static private $artists=array();
 	static private $albums=array();//stored as "$artist/$album" to allow albums with the same name from different artists
-	static private $useMp3Info=null;
 	
 	/**
 	 * scan a folder for music
@@ -70,59 +69,55 @@ class OC_MEDIA_SCANNER{
 	 * @return boolean
 	 */
 	public static function scanFile($path){
-		if(is_null(self::$useMp3Info)){
-			self::$useMp3Info=OC_Helper::canExecute("mp3info");
-		}
 		$file=OC_Filesystem::getLocalFile($path);
-		if(substr($path,-3)=='mp3' and self::$useMp3Info){//use the command line tool id3info if possible
-			$output=array();
-			$size=filesize($file);
-			exec('mp3info -p "%a\n%l\n%t\n%n\n%S" "'.$file.'"',$output);
-			if(count($output)>4){
-				$artist=$output[0];
-				$album=$output[1];
-				$title=$output[2];
-				$track=$output[3];
-				$length=$output[4];
-			}else{
-				return; //invalid mp3 file
-			}
+		if(!self::isMusic($path)){
+			return;
+		}
+		if(!self::$getID3){
+			self::$getID3=@new getID3();
+			self::$getID3->encoding='UTF-8';
+		}
+		$data=@self::$getID3->analyze($file);
+		getid3_lib::CopyTagsToComments($data);
+		if(!isset($data['comments'])){
+			OC_Log::write('media',"error reading id3 tags in '$file'",OC_Log::WARN);
+			return;
+		}
+		if(!isset($data['comments']['artist'])){
+			OC_Log::write('media',"error reading artist tag in '$file'",OC_Log::WARN);
+			$artist='unknown';
 		}else{
-			if(!self::isMusic($path)){
-				return;
-			}
-			if(!self::$getID3){
-				self::$getID3=@new getID3();
-				self::$getID3->encoding='UTF-8';
-			}
-			$data=@self::$getID3->analyze($file);
-			getid3_lib::CopyTagsToComments($data);
-			if(!isset($data['comments'])){
-				OC_Log::write('media',"error reading id3 tags in '$file'",OC_Log::WARN);
-				return;
-			}
-			if(!isset($data['comments']['artist'])){
-				OC_Log::write('media',"error reading artist tag in '$file'",OC_Log::WARN);
-				$artist='unknown';
-			}else{
-				$artist=stripslashes($data['comments']['artist'][0]);
-			}
-			if(!isset($data['comments']['album'])){
-				OC_Log::write('media',"error reading album tag in '$file'",OC_Log::WARN);
-				$album='unknown';
-			}else{
-				$album=stripslashes($data['comments']['album'][0]);
-			}
-			if(!isset($data['comments']['title'])){
-				OC_Log::write('media',"error reading title tag in '$file'",OC_Log::WARN);
-				$title='unknown';
-			}else{
-				$title=stripslashes($data['comments']['title'][0]);
-			}
-			$size=$data['filesize'];
-			$track=(isset($data['comments']['track']))?$data['comments']['track'][0]:0;
-			$length=isset($data['playtime_seconds'])?round($data['playtime_seconds']):0;
+			$artist=stripslashes($data['comments']['artist'][0]);
+		}
+		if(!isset($data['comments']['album'])){
+			OC_Log::write('media',"error reading album tag in '$file'",OC_Log::WARN);
+			$album='unknown';
+		}else{
+			$album=stripslashes($data['comments']['album'][0]);
+		}
+		if(!isset($data['comments']['title'])){
+			OC_Log::write('media',"error reading title tag in '$file'",OC_Log::WARN);
+			$title='unknown';
+		}else{
+			$title=stripslashes($data['comments']['title'][0]);
 		}
+		$size=$data['filesize'];
+		if (isset($data['comments']['track']))
+		{
+			$track = $data['comments']['track'][0];
+		}
+		else if (isset($data['comments']['track_number']))
+		{
+			$track = $data['comments']['track_number'][0];
+			$track = explode('/',$track);
+			$track = $track[0];
+		}
+		else
+		{
+			$track = 0;
+		}
+		$length=isset($data['playtime_seconds'])?round($data['playtime_seconds']):0;
+
 		if(!isset(self::$artists[$artist])){
 			$artistId=OC_MEDIA_COLLECTION::addArtist($artist);
 			self::$artists[$artist]=$artistId;
diff --git a/l10n/templates/calendar.pot b/l10n/templates/calendar.pot
index 56fce2285ece4bcbd155e7b29aedef39d26526f7..7941082926bc81e2852ce08c19fb2a5eecd131f3 100644
--- a/l10n/templates/calendar.pot
+++ b/l10n/templates/calendar.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-10-22 13:05+0200\n"
+"POT-Creation-Date: 2012-01-07 18:29+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,8 +17,8 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ajax/editeventform.php:26
-msgid "Wrong calendar"
+#: ajax/guesstimezone.php:42
+msgid "New Timezone:"
 msgstr ""
 
 #: ajax/settimezone.php:22
@@ -29,171 +29,391 @@ msgstr ""
 msgid "Invalid request"
 msgstr ""
 
-#: appinfo/app.php:21 templates/calendar.php:11
-#: templates/part.eventform.php:21
+#: appinfo/app.php:20 templates/calendar.php:13
+#: templates/part.eventform.php:20
 msgid "Calendar"
 msgstr ""
 
-#: js/calendar.js:153
-msgid "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}"
-msgstr ""
-
-#: js/calendar.js:155
-msgid "ddd d MMMM[ yyyy] HH:mm{ -[ ddd d MMMM yyyy] HH:mm}"
+#: lib/app.php:19
+msgid "Wrong calendar"
 msgstr ""
 
-#: lib/object.php:344
+#: lib/app.php:60 lib/object.php:332
 msgid "Birthday"
 msgstr ""
 
-#: lib/object.php:345
+#: lib/app.php:61 lib/object.php:333
 msgid "Business"
 msgstr ""
 
-#: lib/object.php:346
+#: lib/app.php:62 lib/object.php:334
 msgid "Call"
 msgstr ""
 
-#: lib/object.php:347
+#: lib/app.php:63 lib/object.php:335
 msgid "Clients"
 msgstr ""
 
-#: lib/object.php:348
+#: lib/app.php:64 lib/object.php:336
 msgid "Deliverer"
 msgstr ""
 
-#: lib/object.php:349
+#: lib/app.php:65 lib/object.php:337
 msgid "Holidays"
 msgstr ""
 
-#: lib/object.php:350
+#: lib/app.php:66 lib/object.php:338
 msgid "Ideas"
 msgstr ""
 
-#: lib/object.php:351
+#: lib/app.php:67 lib/object.php:339
 msgid "Journey"
 msgstr ""
 
-#: lib/object.php:352
+#: lib/app.php:68 lib/object.php:340
 msgid "Jubilee"
 msgstr ""
 
-#: lib/object.php:353
+#: lib/app.php:69 lib/object.php:341
 msgid "Meeting"
 msgstr ""
 
-#: lib/object.php:354
+#: lib/app.php:70 lib/object.php:342
 msgid "Other"
 msgstr ""
 
-#: lib/object.php:355
+#: lib/app.php:71 lib/object.php:343
 msgid "Personal"
 msgstr ""
 
-#: lib/object.php:356
+#: lib/app.php:72 lib/object.php:344
 msgid "Projects"
 msgstr ""
 
-#: lib/object.php:357
+#: lib/app.php:73 lib/object.php:345
 msgid "Questions"
 msgstr ""
 
-#: lib/object.php:358
+#: lib/app.php:74 lib/object.php:346
 msgid "Work"
 msgstr ""
 
-#: lib/object.php:365
+#: lib/object.php:353
 msgid "Does not repeat"
 msgstr ""
 
-#: lib/object.php:366
+#: lib/object.php:354
 msgid "Daily"
 msgstr ""
 
-#: lib/object.php:367
+#: lib/object.php:355
 msgid "Weekly"
 msgstr ""
 
-#: lib/object.php:368
+#: lib/object.php:356
 msgid "Every Weekday"
 msgstr ""
 
-#: lib/object.php:369
+#: lib/object.php:357
 msgid "Bi-Weekly"
 msgstr ""
 
-#: lib/object.php:370
+#: lib/object.php:358
 msgid "Monthly"
 msgstr ""
 
-#: lib/object.php:371
+#: lib/object.php:359
 msgid "Yearly"
 msgstr ""
 
-#: lib/object.php:389
+#: lib/object.php:366
+msgid "never"
+msgstr ""
+
+#: lib/object.php:367
+msgid "by occurrences"
+msgstr ""
+
+#: lib/object.php:368
+msgid "by date"
+msgstr ""
+
+#: lib/object.php:375
+msgid "by monthday"
+msgstr ""
+
+#: lib/object.php:376
+msgid "by weekday"
+msgstr ""
+
+#: lib/object.php:383 templates/lAfix.php:3
+msgid "Monday"
+msgstr ""
+
+#: lib/object.php:384 templates/lAfix.php:4
+msgid "Tuesday"
+msgstr ""
+
+#: lib/object.php:385 templates/lAfix.php:5
+msgid "Wednesday"
+msgstr ""
+
+#: lib/object.php:386 templates/lAfix.php:6
+msgid "Thursday"
+msgstr ""
+
+#: lib/object.php:387 templates/lAfix.php:7
+msgid "Friday"
+msgstr ""
+
+#: lib/object.php:388 templates/lAfix.php:8
+msgid "Saturday"
+msgstr ""
+
+#: lib/object.php:389 templates/lAfix.php:2
+msgid "Sunday"
+msgstr ""
+
+#: lib/object.php:396
+msgid "events week of month"
+msgstr ""
+
+#: lib/object.php:397
+msgid "first"
+msgstr ""
+
+#: lib/object.php:398
+msgid "second"
+msgstr ""
+
+#: lib/object.php:399
+msgid "third"
+msgstr ""
+
+#: lib/object.php:400
+msgid "fourth"
+msgstr ""
+
+#: lib/object.php:401
+msgid "fifth"
+msgstr ""
+
+#: lib/object.php:402
+msgid "last"
+msgstr ""
+
+#: lib/object.php:424 templates/lAfix.php:16
+msgid "January"
+msgstr ""
+
+#: lib/object.php:425 templates/lAfix.php:17
+msgid "February"
+msgstr ""
+
+#: lib/object.php:426 templates/lAfix.php:18
+msgid "March"
+msgstr ""
+
+#: lib/object.php:427 templates/lAfix.php:19
+msgid "April"
+msgstr ""
+
+#: lib/object.php:428 templates/lAfix.php:20
+msgid "May"
+msgstr ""
+
+#: lib/object.php:429 templates/lAfix.php:21
+msgid "June"
+msgstr ""
+
+#: lib/object.php:430 templates/lAfix.php:22
+msgid "July"
+msgstr ""
+
+#: lib/object.php:431 templates/lAfix.php:23
+msgid "August"
+msgstr ""
+
+#: lib/object.php:432 templates/lAfix.php:24
+msgid "September"
+msgstr ""
+
+#: lib/object.php:433 templates/lAfix.php:25
+msgid "October"
+msgstr ""
+
+#: lib/object.php:434 templates/lAfix.php:26
+msgid "November"
+msgstr ""
+
+#: lib/object.php:435 templates/lAfix.php:27
+msgid "December"
+msgstr ""
+
+#: lib/object.php:441
+msgid "by events date"
+msgstr ""
+
+#: lib/object.php:442
+msgid "by yearday(s)"
+msgstr ""
+
+#: lib/object.php:443
+msgid "by weeknumber(s)"
+msgstr ""
+
+#: lib/object.php:444
+msgid "by day and month"
+msgstr ""
+
+#: lib/object.php:467
 msgid "Not an array"
 msgstr ""
 
-#: templates/calendar.php:8
+#: lib/search.php:32 lib/search.php:34 lib/search.php:37
+msgid "Date"
+msgstr ""
+
+#: lib/search.php:40
+msgid "Cal."
+msgstr ""
+
+#: templates/calendar.php:10
 msgid "All day"
 msgstr ""
 
-#: templates/calendar.php:9
+#: templates/calendar.php:11
 msgid "Missing fields"
 msgstr ""
 
-#: templates/calendar.php:10 templates/part.eventform.php:3
+#: templates/calendar.php:12 templates/part.eventform.php:3
 msgid "Title"
 msgstr ""
 
-#: templates/calendar.php:12
+#: templates/calendar.php:14
 msgid "From Date"
 msgstr ""
 
-#: templates/calendar.php:13
+#: templates/calendar.php:15
 msgid "From Time"
 msgstr ""
 
-#: templates/calendar.php:14
+#: templates/calendar.php:16
 msgid "To Date"
 msgstr ""
 
-#: templates/calendar.php:15
+#: templates/calendar.php:17
 msgid "To Time"
 msgstr ""
 
-#: templates/calendar.php:16
+#: templates/calendar.php:18
 msgid "The event ends before it starts"
 msgstr ""
 
-#: templates/calendar.php:17
+#: templates/calendar.php:19
 msgid "There was a database fail"
 msgstr ""
 
-#: templates/calendar.php:23
+#: templates/calendar.php:38
 msgid "Week"
 msgstr ""
 
-#: templates/calendar.php:24
+#: templates/calendar.php:39
 msgid "Month"
 msgstr ""
 
-#: templates/calendar.php:25
+#: templates/calendar.php:40
 msgid "List"
 msgstr ""
 
-#: templates/calendar.php:30
+#: templates/calendar.php:45
 msgid "Today"
 msgstr ""
 
-#: templates/calendar.php:31
+#: templates/calendar.php:46
 msgid "Calendars"
 msgstr ""
 
-#: templates/calendar.php:48
+#: templates/calendar.php:64
 msgid "There was a fail, while parsing the file."
 msgstr ""
 
+#: templates/lAfix.php:9
+msgid "Sun."
+msgstr ""
+
+#: templates/lAfix.php:10
+msgid "Mon."
+msgstr ""
+
+#: templates/lAfix.php:11
+msgid "Tue."
+msgstr ""
+
+#: templates/lAfix.php:12
+msgid "Wed."
+msgstr ""
+
+#: templates/lAfix.php:13
+msgid "Thu."
+msgstr ""
+
+#: templates/lAfix.php:14
+msgid "Fri."
+msgstr ""
+
+#: templates/lAfix.php:15
+msgid "Sat."
+msgstr ""
+
+#: templates/lAfix.php:28
+msgid "Jan."
+msgstr ""
+
+#: templates/lAfix.php:29
+msgid "Feb."
+msgstr ""
+
+#: templates/lAfix.php:30
+msgid "Mar."
+msgstr ""
+
+#: templates/lAfix.php:31
+msgid "Apr."
+msgstr ""
+
+#: templates/lAfix.php:32
+msgid "May."
+msgstr ""
+
+#: templates/lAfix.php:33
+msgid "Jun."
+msgstr ""
+
+#: templates/lAfix.php:34
+msgid "Jul."
+msgstr ""
+
+#: templates/lAfix.php:35
+msgid "Aug."
+msgstr ""
+
+#: templates/lAfix.php:36
+msgid "Sep."
+msgstr ""
+
+#: templates/lAfix.php:37
+msgid "Oct."
+msgstr ""
+
+#: templates/lAfix.php:38
+msgid "Nov."
+msgstr ""
+
+#: templates/lAfix.php:39
+msgid "Dec."
+msgstr ""
+
 #: templates/part.choosecalendar.php:1
 msgid "Choose active calendars"
 msgstr ""
@@ -216,7 +436,7 @@ msgid "Edit"
 msgstr ""
 
 #: templates/part.choosecalendar.rowfields.php:4
-#: templates/part.editevent.php:8
+#: templates/part.editevent.php:9
 msgid "Delete"
 msgstr ""
 
@@ -244,7 +464,7 @@ msgstr ""
 msgid "Save"
 msgstr ""
 
-#: templates/part.editcalendar.php:42 templates/part.editevent.php:7
+#: templates/part.editcalendar.php:42 templates/part.editevent.php:8
 #: templates/part.newevent.php:6
 msgid "Submit"
 msgstr ""
@@ -257,7 +477,7 @@ msgstr ""
 msgid "Edit an event"
 msgstr ""
 
-#: templates/part.editevent.php:9
+#: templates/part.editevent.php:10
 msgid "Export"
 msgstr ""
 
@@ -273,43 +493,83 @@ msgstr ""
 msgid "Select category"
 msgstr ""
 
-#: templates/part.eventform.php:39
+#: templates/part.eventform.php:37
 msgid "All Day Event"
 msgstr ""
 
-#: templates/part.eventform.php:43
+#: templates/part.eventform.php:41
 msgid "From"
 msgstr ""
 
-#: templates/part.eventform.php:51
+#: templates/part.eventform.php:49
 msgid "To"
 msgstr ""
 
-#: templates/part.eventform.php:59
+#: templates/part.eventform.php:57
 msgid "Advanced options"
 msgstr ""
 
-#: templates/part.eventform.php:64
+#: templates/part.eventform.php:61
 msgid "Repeat"
 msgstr ""
 
-#: templates/part.eventform.php:80
-msgid "Attendees"
+#: templates/part.eventform.php:68
+msgid "Advanced"
+msgstr ""
+
+#: templates/part.eventform.php:112
+msgid "Select weekdays"
 msgstr ""
 
-#: templates/part.eventform.php:87
+#: templates/part.eventform.php:125 templates/part.eventform.php:138
+msgid "Select days"
+msgstr ""
+
+#: templates/part.eventform.php:130
+msgid "and the events day of year."
+msgstr ""
+
+#: templates/part.eventform.php:143
+msgid "and the events day of month."
+msgstr ""
+
+#: templates/part.eventform.php:151
+msgid "Select months"
+msgstr ""
+
+#: templates/part.eventform.php:164
+msgid "Select weeks"
+msgstr ""
+
+#: templates/part.eventform.php:169
+msgid "and the events week of year."
+msgstr ""
+
+#: templates/part.eventform.php:175
+msgid "Interval"
+msgstr ""
+
+#: templates/part.eventform.php:181
+msgid "End"
+msgstr ""
+
+#: templates/part.eventform.php:193
+msgid "occurrences"
+msgstr ""
+
+#: templates/part.eventform.php:208
 msgid "Location"
 msgstr ""
 
-#: templates/part.eventform.php:89
+#: templates/part.eventform.php:210
 msgid "Location of the Event"
 msgstr ""
 
-#: templates/part.eventform.php:95
+#: templates/part.eventform.php:216
 msgid "Description"
 msgstr ""
 
-#: templates/part.eventform.php:96
+#: templates/part.eventform.php:218
 msgid "Description of the Event"
 msgstr ""
 
@@ -353,6 +613,10 @@ msgstr ""
 msgid "Timezone"
 msgstr ""
 
+#: templates/settings.php:30
+msgid "Check always for changes of the timezone"
+msgstr ""
+
 #: templates/settings.php:32
 msgid "Timeformat"
 msgstr ""
diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php
index c5c19a90fb52de158bf9bab7c318716809b39822..8f4e1312eb8f09faf456d22be3998a5ff490bd28 100644
--- a/lib/MDB2/Driver/Manager/sqlite3.php
+++ b/lib/MDB2/Driver/Manager/sqlite3.php
@@ -168,9 +168,6 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
         if (PEAR::isError($query_fields)) {
             return $query_fields;
         }
-        if (!empty($options['primary'])) {
-            $query_fields.= ', PRIMARY KEY ('.implode(', ', array_keys($options['primary'])).')';
-        }
         if (!empty($options['foreign_keys'])) {
             foreach ($options['foreign_keys'] as $fkname => $fkdef) {
                 if (empty($fkdef)) {
@@ -534,9 +531,26 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
             return MDB2_OK;
         }
 
+        if (empty($changes['remove']) and empty($changes['rename']) and empty($changes['change']) ){//if only rename or add changes are required, we can use ALTER TABLE
+			$query = '';
+			if (!empty($changes['name'])) {
+				$change_name = $db->quoteIdentifier($changes['name'], true);
+				$query = 'RENAME TO ' . $change_name;
+				$db->exec("ALTER TABLE $name $query");
+			}
+
+			if (!empty($changes['add']) && is_array($changes['add'])) {
+				foreach ($changes['add'] as $field_name => $field) {
+					$query= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
+					$db->exec("ALTER TABLE $name $query");
+				}
+			}
+			return MDB2_OK;
+        }
+
         $db->loadModule('Reverse', null, true);
 
-        // actually sqlite 2.x supports no ALTER TABLE at all .. so we emulate it
+        // for other operations we need to emulate them with sqlite3
         $fields = $db->manager->listTableFields($name);
         if (PEAR::isError($fields)) {
             return $fields;
@@ -636,44 +650,54 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
             }
         }
 
+		//rename the old table so we can create the new one
+        $db->exec("ALTER TABLE $name RENAME TO __$name");
         $data = null;
-        if (!empty($select_fields)) {
-            $query = 'SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier($name, true);
-            $data = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED);
-        }
 
-        $result = $this->dropTable($name);
-        if (PEAR::isError($result)) {
-            return $result;
-        }
 
         $result = $this->createTable($name_new, $fields, $options);
         if (PEAR::isError($result)) {
             return $result;
         }
 
-        foreach ($indexes as $index => $definition) {
-            $this->createIndex($name_new, $index, $definition);
-        }
+        //these seem to only give errors
 
-        foreach ($constraints as $constraint => $definition) {
-            $this->createConstraint($name_new, $constraint, $definition);
-        }
+//         foreach ($indexes as $index => $definition) {
+//             $this->createIndex($name_new, $index, $definition);
+//         }
 
-        if (!empty($select_fields) && !empty($data)) {
-            $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true);
-            $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')';
-            $query.=' VALUES (?'.str_repeat(', ?', (count($select_fields) - 1)).')';
-            $stmt =$db->prepare($query, null, MDB2_PREPARE_MANIP);
-            if (PEAR::isError($stmt)) {
-                return $stmt;
-            }
-            foreach ($data as $row) {
-                $result = $stmt->execute($row);
-                if (PEAR::isError($result)) {
-                    return $result;
-                }
-            }
+//         foreach ($constraints as $constraint => $definition) {
+//             $this->createConstraint($name_new, $constraint, $definition);
+//         }
+
+        //fill the new table with data from the old one
+        if (!empty($select_fields)) {
+			$query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true);
+			$query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')';
+            $query .= ' SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier('__'.$name, true);
+            $db->exec($query);
+        }
+
+//         if (!empty($select_fields) && !empty($data)) {
+//             $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true);
+//             $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')';
+//             $query.=' VALUES (?'.str_repeat(', ?', (count($select_fields) - 1)).')';
+//             $stmt =$db->prepare($query, null, MDB2_PREPARE_MANIP);
+//             if (PEAR::isError($stmt)) {
+//                 return $stmt;
+//             }
+//             foreach ($data as $row) {
+//                 $result = $stmt->execute($row);
+//                 if (PEAR::isError($result)) {
+//                     return $result;
+//                 }
+//             }
+//         }
+
+        //remove the old table
+        $result = $this->dropTable('__'.$name);
+        if (PEAR::isError($result)) {
+            return $result;
         }
         return MDB2_OK;
     }
@@ -798,7 +822,7 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
             return $db;
         }
 
-        $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
+        $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL AND name!='sqlite_sequence' ORDER BY name";
         $table_names = $db->queryCol($query);
         if (PEAR::isError($table_names)) {
             return $table_names;
diff --git a/lib/MDB2/Driver/Reverse/sqlite3.php b/lib/MDB2/Driver/Reverse/sqlite3.php
index d5595da84c54a53dac0987247e7f99a636b07359..33e5b59026895181e1c029e4264d2e6b3984fc6f 100644
--- a/lib/MDB2/Driver/Reverse/sqlite3.php
+++ b/lib/MDB2/Driver/Reverse/sqlite3.php
@@ -69,7 +69,7 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
             return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
                 'unexpected empty table column definition list', __FUNCTION__);
         }
-        $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i';
+        $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( AUTOINCREMENT)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i';
         $regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i';
         for ($i=0, $j=0; $i<$count; ++$i) {
             if (!preg_match($regexp, trim($column_sql[$i]), $matches)) {
@@ -90,11 +90,16 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
             if (isset($matches[8]) && strlen($matches[8])) {
                 $columns[$j]['unsigned'] = true;
             }
-            if (isset($matches[9]) && strlen($matches[9])) {
+            if (isset($matches[10]) && strlen($matches[10])) {
                 $columns[$j]['autoincrement'] = true;
+                $columns[$j]['notnull']=true;
             }
-            if (isset($matches[12]) && strlen($matches[12])) {
-                $default = $matches[12];
+            if (isset($matches[10]) && strlen($matches[10])) {
+                $columns[$j]['autoincrement'] = true;
+                $columns[$j]['notnull']=true;
+            }
+            if (isset($matches[13]) && strlen($matches[13])) {
+                $default = $matches[13];
                 if (strlen($default) && $default[0]=="'") {
                     $default = str_replace("''", "'", substr($default, 1, strlen($default)-2));
                 }
@@ -107,8 +112,8 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
                 $columns[$j]['notnull'] = ($matches[7] === ' NOT NULL');
             } else if (isset($matches[9]) && strlen($matches[9])) {
                 $columns[$j]['notnull'] = ($matches[9] === ' NOT NULL');
-            } else if (isset($matches[13]) && strlen($matches[13])) {
-                $columns[$j]['notnull'] = ($matches[13] === ' NOT NULL');
+            } else if (isset($matches[14]) && strlen($matches[14])) {
+                $columns[$j]['notnull'] = ($matches[14] === ' NOT NULL');
             }
             ++$j;
         }
diff --git a/lib/app.php b/lib/app.php
index b1aa8ba354df2580a2ebaf4ff1e3a08c22ced001..13c4cef32b41c5db59db6f890c799b2bb14302d6 100644
--- a/lib/app.php
+++ b/lib/app.php
@@ -94,7 +94,15 @@ class OC_App{
 	 */
 	public static function enable( $app ){
 		if(!OC_Installer::isInstalled($app)){
-			OC_Installer::installShippedApp($app);
+			// check if app is a shipped app or not. OCS apps have an integer as id, shipped apps use a string
+			if(!is_numeric($app)){
+				OC_Installer::installShippedApp($app);
+			}else{
+                                $download=OC_OCSClient::getApplicationDownload($app,1);
+				if(isset($download['downloadlink']) and $download['downloadlink']<>'') {
+					OC_Installer::installApp(array('source'=>'http','href'=>$download['downloadlink']));
+				}
+			}
 		}
 		OC_Appconfig::setValue( $app, 'enabled', 'yes' );
 	}
@@ -107,6 +115,7 @@ class OC_App{
 	 * This function set an app as disabled in appconfig.
 	 */
 	public static function disable( $app ){
+		// check if app is a shiped app or not. if not delete
 		OC_Appconfig::setValue( $app, 'enabled', 'no' );
 	}
 
@@ -362,4 +371,35 @@ class OC_App{
 		}
 		return $apps;
 	}
+	
+	/**
+	 * check if any apps need updating and update those
+	 */
+	public static function updateApps(){
+		// The rest comes here
+		$apps = OC_Appconfig::getApps();
+		foreach( $apps as $app ){
+			$installedVersion=OC_Appconfig::getValue($app,'installed_version');
+			$appInfo=OC_App::getAppInfo($app);
+			if (isset($appInfo['version'])) {
+				$currentVersion=$appInfo['version'];
+				if (version_compare($currentVersion, $installedVersion, '>')) {
+					OC_App::updateApp($app);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * update the database for the app and call the update script
+	 * @param string appid
+	 */
+	public static function updateApp($appid){
+		if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml')){
+			OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml');
+		}
+		if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php')){
+			include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php';
+		}
+	}
 }
diff --git a/lib/base.php b/lib/base.php
index 943ab5f24dc788572b299b1d46f4bc5fa510453d..e0f14b703dc81c2cffb90da7e99b7912a514bedf 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -70,6 +70,31 @@ class OC{
 		}
 	}
 
+	/**
+	 * autodetects the formfactor of the used device
+	 * default -> the normal desktop browser interface
+	 * mobile -> interface for smartphones
+	 * tablet -> interface for tablets
+	 * standalone -> the default interface but without header, footer and sidebar. just the application. useful to ue just a specific app on the desktop in a standalone window.
+	 */
+	public static function detectFormfactor(){
+		// please add more useragent strings for other devices
+		if(isset($_SERVER['HTTP_USER_AGENT'])){
+			if(stripos($_SERVER['HTTP_USER_AGENT'],'ipad')>0) {
+				$mode='tablet';
+			}elseif(stripos($_SERVER['HTTP_USER_AGENT'],'iphone')>0){
+				$mode='mobile';
+			}elseif((stripos($_SERVER['HTTP_USER_AGENT'],'N9')>0) and (stripos($_SERVER['HTTP_USER_AGENT'],'nokia')>0)){
+				$mode='mobile';
+			}else{
+				$mode='default';
+			}
+		}else{
+			$mode='default';
+		}
+		return($mode);
+	}
+
 	public static function init(){
 		// register autoloader
 		spl_autoload_register(array('OC','autoload'));
@@ -127,9 +152,30 @@ class OC{
 			}
 		}
 
+		if(OC_Config::getValue('installed', false)){
+			$installedVersion=OC_Config::getValue('version','0.0.0');
+			$currentVersion=implode('.',OC_Util::getVersion());
+			if (version_compare($currentVersion, $installedVersion, '>')) {
+				OC_DB::updateDbFromStructure('../db_structure.xml');
+				OC_Config::setValue('version',implode('.',OC_Util::getVersion()));
+			}
+
+			OC_App::updateApps();
+		}
+
 		ini_set('session.cookie_httponly','1;');
 		session_start();
 
+		// if the formfactor is not yet autodetected do the autodetection now. For possible forfactors check the detectFormfactor documentation
+		if(!isset($_SESSION['formfactor'])){
+			$_SESSION['formfactor']=OC::detectFormfactor();
+		}
+		// allow manual override via GET parameter
+		if(isset($_GET['formfactor'])){
+			$_SESSION['formfactor']=$_GET['formfactor'];
+		}
+
+
 		// Add the stuff we need always
 		OC_Util::addScript( "jquery-1.6.4.min" );
 		OC_Util::addScript( "jquery-ui-1.8.16.custom.min" );
@@ -195,8 +241,6 @@ if( !isset( $RUNTIME_NOAPPS )){
 	$RUNTIME_NOAPPS = false;
 }
 
-OC::init();
-
 if(!function_exists('get_temp_dir')) {
 	function get_temp_dir() {
 		if( $temp=ini_get('upload_tmp_dir') )        return $temp;
@@ -212,7 +256,11 @@ if(!function_exists('get_temp_dir')) {
 	}
 }
 
+OC::init();
+
 require_once('fakedirstream.php');
 
+
+
 // FROM search.php
 new OC_Search_Provider_File();
diff --git a/lib/db.php b/lib/db.php
index bcfe320665f51a433e2daecf1c971b0d4b68c0ad..b901cc8b513bedd4980cf02a02a5c2a9c6cd82b3 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -71,7 +71,14 @@ class OC_DB {
 	/**
 	 * connect to the database using pdo
 	 */
-	private static function connectPDO(){
+	public static function connectPDO(){
+		if(self::$connection){
+			if(self::$backend==self::BACKEND_MDB2){
+				self::disconnect();
+			}else{
+				return;
+			}
+		}
 		// The global data we need
 		$name = OC_Config::getValue( "dbname", "owncloud" );
 		$host = OC_Config::getValue( "dbhost", "" );
@@ -113,7 +120,14 @@ class OC_DB {
 	/**
 	 * connect to the database using mdb2
 	 */
-	static private function connectMDB2(){
+	public static function connectMDB2(){
+		if(self::$connection){
+			if(self::$backend==self::BACKEND_PDO){
+				self::disconnect();
+			}else{
+				return;
+			}
+		}
 		// The global data we need
 		$name = OC_Config::getValue( "dbname", "owncloud" );
 		$host = OC_Config::getValue( "dbhost", "" );
@@ -255,8 +269,8 @@ class OC_DB {
 				self::$connection->disconnect();
 			}
 			self::$connection=false;
-			self::$mdb2=false;
-			self::$pdo=false;
+			self::$MDB2=false;
+			self::$PDO=false;
 		}
 
 		return true;
@@ -279,7 +293,7 @@ class OC_DB {
 			'output' => $file,
 			'end_of_line' => "\n"
 		);
-		self::$schema->dumpDatabase( $definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE );
+		self::$schema->dumpDatabase( $definition, $dump_options, $mode );
 
 		return true;
 	}
@@ -338,7 +352,6 @@ class OC_DB {
 	 * @param $file file to read structure from
 	 */
 	public static function updateDbFromStructure($file){
-		$CONFIG_DBNAME  = OC_Config::getValue( "dbname", "owncloud" );
 		$CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" );
 		$CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
 
@@ -347,17 +360,17 @@ class OC_DB {
 		// read file
 		$content = file_get_contents( $file );
 		
+		$previousSchema = self::$schema->getDefinitionFromDatabase();
+
 		// Make changes and save them to a temporary file
 		$file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' );
-		$content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
+		$content = str_replace( '*dbname*', $previousSchema['name'], $content );
 		$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
 		if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't
 			$content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content );
 		}
 		file_put_contents( $file2, $content );
-		$previousSchema = self::$schema->getDefinitionFromDatabase();
-		$op = $schema->updateDatabase($file2, $previousSchema, array(), false);
-
+		$op = self::$schema->updateDatabase($file2, $previousSchema, array(), false);
 		if (PEAR::isError($op)) {
 		    $error = $op->getMessage();
 		    OC_Log::write('core','Failed to update database structure ('.$error.')',OC_Log::FATAL);
@@ -375,6 +388,8 @@ class OC_DB {
 	private static function connectScheme(){
 		// We need a mdb2 database connection
 		self::connectMDB2();
+		self::$MDB2->loadModule('Manager');
+		self::$MDB2->loadModule('Reverse');
 
 		// Connect if this did not happen before
 		if(!self::$schema){
diff --git a/lib/image.php b/lib/image.php
index e09486be0817e9b22105876f8d9ebe80d146b20a..45b6ad3918ddfacff854fdcf0a55d4b1134d05c9 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -42,8 +42,7 @@ function ellipsis($str, $maxlen) {
 }
 
 /**
- * Class for image manipulation
- * Ideas: imagerotate, chunk_split(base64_encode())
+ * Class for basic image manipulation
  *
  */
 class OC_Image {
@@ -125,7 +124,7 @@ class OC_Image {
 	*/
 
 	public function save($filepath=null) {
-		if($filepath === null && $this->filepath === null) {
+		if($filepath === null && self::$filepath === null) {
 			OC_Log::write('core','OC_Image::save. save() called with no path.', OC_Log::ERROR);
 			return false;
 		} elseif($filepath === null && $this->filepath !== null) {
@@ -138,15 +137,15 @@ class OC_Image {
 	* @brief Outputs/saves the image.
 	*/
 	private function _output($filepath=null, $really=false) {
-		header('Content-Type: '.self::mimeType());
 		if($really === false) {
+			header('Content-Type: '.self::mimeType());
 			$filepath = null; // Just being cautious ;-)
 		} else {
 			if(!is_writable(dirname($filepath))) {
-				OC_Log::write('core','OC_Image::save. Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
+				OC_Log::write('core','OC_Image::_output. Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
 				return false;
-			} elseif(is_writable(dirname($filepath)) && !is_writable($filepath)) {
-				OC_Log::write('core','OC_Image::save. File \''.$filepath.'\' is not writable.', OC_Log::ERROR);
+			} elseif(is_writable(dirname($filepath)) && file_exists($filepath) && !is_writable($filepath)) {
+				OC_Log::write('core','OC_Image::_output. File \''.$filepath.'\' is not writable.', OC_Log::ERROR);
 				return false;
 			}
 		}
@@ -200,6 +199,87 @@ class OC_Image {
 		return chunk_split(base64_encode(ob_get_clean()));
 	}
 
+	/**
+	* @brief Fixes orientation based on EXIF data.
+	* @returns bool.
+	*/
+	public function fixOrientation() {
+		if(!is_resource(self::$resource)) {
+			OC_Log::write('core','OC_Image::fixOrientation() No image loaded.', OC_Log::DEBUG);
+			return false;
+		}
+		if(is_null(self::$filepath) || !is_readable(self::$filepath)) {
+			OC_Log::write('core','OC_Image::fixOrientation() No readable file path set.', OC_Log::DEBUG);
+			return false;
+		}
+		$exif = exif_read_data(self::$filepath, 'IFD0');
+		if(!$exif) {
+			return false;
+		}
+		if(!isset($exif['Orientation'])) {
+			return true; // Nothing to fix
+		}
+		$o = $exif['Orientation'];
+		OC_Log::write('core','OC_Image::fixOrientation() Orientation: '.$o, OC_Log::DEBUG);
+		$rotate = 0;
+		$flip = false;
+		switch($o) {
+			case 1:
+				$rotate = 0;
+				$flip = false;
+				break;
+			case 2: // Not tested
+				$rotate = 0;
+				$flip = true;
+				break;
+			case 3:
+				$rotate = 180;
+				$flip = false;
+				break;
+			case 4: // Not tested
+				$rotate = 180;
+				$flip = true;
+				break;
+			case 5: // Not tested
+				$rotate = 90;
+				$flip = true;
+				break;
+			case 6:
+				//$rotate = 90;
+				$rotate = 270;
+				$flip = false;
+				break;
+			case 7: // Not tested
+				$rotate = 270;
+				$flip = true;
+				break;
+			case 8:
+				$rotate = 270;
+				$flip = false;
+				break;
+		}
+		if($rotate) {
+			$res = imagerotate(self::$resource, $rotate, -1);
+			if($res) {
+				if(imagealphablending($res, true)) {
+					if(imagesavealpha($res, true)) {
+						self::$resource = $res;
+						return true;
+					} else {
+						OC_Log::write('core','OC_Image::fixOrientation() Error during alphasaving.', OC_Log::DEBUG);
+						return false;
+					}
+				} else {
+					OC_Log::write('core','OC_Image::fixOrientation() Error during alphablending.', OC_Log::DEBUG);
+					return false;
+				}
+			} else {
+				OC_Log::write('core','OC_Image::fixOrientation() Error during oriention fixing.', OC_Log::DEBUG);
+				return false;
+			}
+		}
+	}
+
 	/**
 	* @brief Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function.
 	* @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
diff --git a/lib/ocsclient.php b/lib/ocsclient.php
index 072fd236fee18a70d5186a78d08febb4026e244a..9d5932fb720bd54d323c23a55dc3ee084e56281c 100644
--- a/lib/ocsclient.php
+++ b/lib/ocsclient.php
@@ -130,6 +130,33 @@ class OC_OCSClient{
 		return $app;
 	}
 
+        /**
+         * @brief Get the download url for an application from the OCS server
+         * @returns array with application data
+         *
+         * This function returns an download url for an applications from the OCS server
+         */
+        public static function getApplicationDownload($id,$item){
+                $url='http://api.apps.owncloud.com/v1/content/download/'.urlencode($id).'/'.urlencode($item);
+
+                $xml=@file_get_contents($url);
+                if($xml==FALSE){
+                        OC_Log::write('core','Unable to parse OCS content',OC_Log::FATAL);
+                        return NULL;
+                }
+                $data=simplexml_load_string($xml);
+
+                $tmp=$data->data->content;
+                $app=array();
+                if(isset($tmp->downloadlink)) { 
+	 		$app['downloadlink']=$tmp->downloadlink;
+		}else{
+	 		$app['downloadlink']='';
+		}
+                return $app;
+        }
+
+
 	/**
 	 * @brief Get all the knowledgebase entries from the OCS server
 	 * @returns array with q and a data
diff --git a/lib/setup.php b/lib/setup.php
index b53c626c9a723fd6fa80470b5328990c307038cb..ebe7a45a1f6f4e7c5488386957180a95e5b2080e 100644
--- a/lib/setup.php
+++ b/lib/setup.php
@@ -98,35 +98,45 @@ class OC_Setup {
 					);
 				}
 				else {
+					$oldUser=OC_Config::getValue('dbuser', false);
+					$oldPassword=OC_Config::getValue('dbpassword', false);
+					
 					$query="SELECT user FROM mysql.user WHERE user='$dbuser'"; //this should be enough to check for admin rights in mysql
 					if(mysql_query($query, $connection)) {
 						//use the admin login data for the new database user
 
 						//add prefix to the mysql user name to prevent collissions
-						$dbusername=substr('oc_mysql_'.$username,0,16);
-						//hash the password so we don't need to store the admin config in the config file
-						$dbpassword=md5(time().$password);
-						
-						self::createDBUser($dbusername, $dbpassword, $connection);
-						
-						OC_Config::setValue('dbuser', $dbusername);
-						OC_Config::setValue('dbpassword', $dbpassword);
+						$dbusername=substr('oc_'.$username,0,16);
+						if($dbusername!=$oldUser){
+							//hash the password so we don't need to store the admin config in the config file
+							$dbpassword=md5(time().$password);
+
+							self::createDBUser($dbusername, $dbpassword, $connection);
+
+							OC_Config::setValue('dbuser', $dbusername);
+							OC_Config::setValue('dbpassword', $dbpassword);
+						}
 
 						//create the database
 						self::createDatabase($dbname, $dbusername, $connection);
 					}
 					else {
-						OC_Config::setValue('dbuser', $dbuser);
-						OC_Config::setValue('dbpassword', $dbpass);
+						if($dbuser!=$oldUser){
+							OC_Config::setValue('dbuser', $dbuser);
+							OC_Config::setValue('dbpassword', $dbpass);
+						}
 
 						//create the database
 						self::createDatabase($dbname, $dbuser, $connection);
 					}
 
 					//fill the database if needed
-					$query="SELECT * FROM $dbname.{$dbtableprefix}users";
+					$query="select count(*) from information_schema.tables where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';";
 					$result = mysql_query($query,$connection);
-					if(!$result) {
+					if($result){
+						$row=mysql_fetch_row($result);
+					}
+					if(!$result or $row[0]==0) {
 						OC_DB::createDbFromStructure('db_structure.xml');
 					}
 					mysql_close($connection);
@@ -160,8 +170,8 @@ class OC_Setup {
 
 						//add prefix to the postgresql user name to prevent collissions
 						$dbusername='oc_'.$username;
-						//hash the password so we don't need to store the admin config in the config file
-						$dbpassword=md5(time().$password);
+						//create a new password so we don't need to store the admin config in the config file
+						$dbpassword=md5(time());
 						
 						self::pg_createDBUser($dbusername, $dbpassword, $connection);
 						
@@ -221,7 +231,7 @@ class OC_Setup {
 	}
 
 	public static function createDatabase($name,$user,$connection) {
-		//we cant user OC_BD functions here because we need to connect as the administrative user.
+		//we cant use OC_BD functions here because we need to connect as the administrative user.
 		$query = "CREATE DATABASE IF NOT EXISTS  `$name`";
 		$result = mysql_query($query, $connection);
 		if(!$result) {
@@ -243,7 +253,7 @@ class OC_Setup {
 	}
 
 	public static function pg_createDatabase($name,$user,$connection) {
-		//we cant user OC_BD functions here because we need to connect as the administrative user.
+		//we cant use OC_BD functions here because we need to connect as the administrative user.
 		$query = "CREATE DATABASE $name OWNER $user";
 		$result = pg_query($connection, $query);
 		if(!$result) {
diff --git a/lib/user.php b/lib/user.php
index 0a5881ec0f82c63d7ae73deca5d87e6aa6868674..34f44f572e0b1b533ff125dd4830eaec531542e4 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -169,7 +169,8 @@ class OC_User {
 			foreach( OC_Group::getUserGroups( $uid ) as $i ){
 				OC_Group::removeFromGroup( $uid, $i );
 			}
-
+			// Delete the user's keys in preferences
+			OC_Preferences::deleteUser($uid);
 			// Emit and exit
 			OC_Hook::emit( "OC_User", "post_deleteUser", array( "uid" => $uid ));
 			return true;
diff --git a/settings/apps.php b/settings/apps.php
index 12a7bf772025b2e234325d084fd9596331c83aa4..40b72639cd6dc0fa606061b60b5bd0f17f4fcb2d 100644
--- a/settings/apps.php
+++ b/settings/apps.php
@@ -51,22 +51,22 @@ function app_sort($a, $b){
 }
 usort($apps, 'app_sort');
 
-// dissabled for now
-// $catagoryNames=OC_OCSClient::getCategories();
-// if(is_array($catagoryNames)){
-// 	$categories=array_keys($catagoryNames);
-// 	$externalApps=OC_OCSClient::getApplications($categories);
-// 	foreach($externalApps as $app){
-// 		$apps[]=array(
-// 			'name'=>$app['name'],
-// 			'id'=>$app['id'],
-// 			'active'=>false,
-// 			'description'=>$app['description'],
-// 			'author'=>$app['personid'],
-// 			'license'=>$app['license'],
-// 		);
-// 	}
-// }
+// apps from external repo via OCS
+ $catagoryNames=OC_OCSClient::getCategories();
+ if(is_array($catagoryNames)){
+ 	$categories=array_keys($catagoryNames);
+ 	$externalApps=OC_OCSClient::getApplications($categories);
+ 	foreach($externalApps as $app){
+ 		$apps[]=array(
+ 			'name'=>$app['name'],
+ 			'id'=>$app['id'],
+ 			'active'=>false,
+ 			'description'=>$app['description'],
+ 			'author'=>$app['personid'],
+ 			'license'=>$app['license'],
+ 		);
+ 	}
+ }