You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/12/02 07:22:01 UTC

[1/2] openmeetings git commit: [OPENMEETINGS-1738] tomcat and selenium versions are updated

Repository: openmeetings
Updated Branches:
  refs/heads/4.0.x 9a3009ef1 -> c106713a2


[OPENMEETINGS-1738] tomcat and selenium versions are updated


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/2de601aa
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/2de601aa
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/2de601aa

Branch: refs/heads/4.0.x
Commit: 2de601aaf7c419b36b831ee2aee75af455d95dde
Parents: 9a3009e
Author: Maxim Solodovnik <so...@gmail.com>
Authored: Sat Dec 2 14:14:05 2017 +0700
Committer: Maxim Solodovnik <so...@gmail.com>
Committed: Sat Dec 2 14:14:05 2017 +0700

----------------------------------------------------------------------
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/2de601aa/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 55f1cb9..8058b18 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,10 +65,10 @@
 		<red5-client.version>1.0.10-M4</red5-client.version>
 		<spring.version>4.3.12.RELEASE</spring.version>
 		<mina.version>2.0.16</mina.version>
-		<tomcat.version>9.0.1</tomcat.version>
+		<tomcat.version>9.0.2</tomcat.version>
 		<ical4j.version>2.1.5</ical4j.version>
 		<cxf.version>3.2.1</cxf.version>
-		<selenium.version>3.7.1</selenium.version>
+		<selenium.version>3.8.0</selenium.version>
 		<simple-xml.version>2.7.1</simple-xml.version>
 		<jettison.version>1.3.8</jettison.version>
 		<site.basedir>${project.basedir}</site.basedir>


[2/2] openmeetings git commit: [OPENMEETINGS-1769] room chat is improved

Posted by so...@apache.org.
[OPENMEETINGS-1769] room chat is improved


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/c106713a
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/c106713a
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/c106713a

Branch: refs/heads/4.0.x
Commit: c106713a285004ba8eb3ccd20f516c6f3933abf9
Parents: 2de601a
Author: Maxim Solodovnik <so...@gmail.com>
Authored: Sat Dec 2 14:21:43 2017 +0700
Committer: Maxim Solodovnik <so...@gmail.com>
Committed: Sat Dec 2 14:21:43 2017 +0700

----------------------------------------------------------------------
 .../core/ldap/LdapLoginManagement.java          |  6 +--
 .../openmeetings/core/remote/MobileService.java | 16 ++----
 .../openmeetings/core/util/WebSocketHelper.java | 15 ++++--
 .../db/dao/basic/ConfigurationDao.java          | 21 ++++++++
 .../openmeetings/db/dao/room/RoomDao.java       |  6 +--
 .../openmeetings/db/dao/user/UserDao.java       |  6 +--
 .../db/dto/calendar/AppointmentDTO.java         |  3 +-
 .../openmeetings/db/util/FormatHelper.java      | 15 ++++++
 .../openmeetings/db/util/TimezoneUtil.java      | 55 +++-----------------
 .../openmeetings/backup/BackupImport.java       |  6 +--
 .../installation/InstallationConfig.java        |  3 +-
 .../service/calendar/AppointmentLogic.java      | 11 ++--
 .../service/calendar/caldav/IcalUtils.java      | 10 ++--
 .../service/notifier/MailNotifier.java          |  9 ++--
 .../service/room/InvitationManager.java         |  8 ++-
 .../openmeetings/service/user/UserManager.java  |  6 +--
 .../util/OpenmeetingsVariables.java             |  9 ++++
 .../apache/openmeetings/web/app/WebSession.java | 14 ++---
 .../org/apache/openmeetings/web/common/main.js  |  4 ++
 .../apache/openmeetings/web/pages/HashPage.java |  3 +-
 .../web/room/activities/activities.js           |  2 +-
 .../web/room/menu/RoomMenuPanel.java            |  9 ++--
 .../apache/openmeetings/web/room/room-base.js   |  2 +-
 .../openmeetings/web/room/wb/WbPanel.java       |  9 ----
 .../apache/openmeetings/web/room/wb/wb-area.js  | 10 ++--
 .../apache/openmeetings/web/room/wb/wb-board.js | 10 ++--
 .../apache/openmeetings/web/user/chat/Chat.html | 24 +++++++++
 .../apache/openmeetings/web/user/chat/Chat.java | 20 ++++---
 .../openmeetings/web/user/chat/ChatForm.java    |  8 ++-
 .../openmeetings/web/user/chat/ChatToolbar.java |  2 +-
 .../openmeetings/web/user/chat/chat-base.js     | 44 +++++++---------
 .../web/user/profile/UserSearchPanel.java       |  4 +-
 openmeetings-web/src/main/webapp/css/chat.css   | 22 ++++++--
 .../src/main/webapp/css/general-rtl.css         | 20 ++++---
 .../openmeetings/webservice/UserWebService.java |  6 +--
 35 files changed, 219 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManagement.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManagement.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManagement.java
index 8ecc43e..9d70692 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManagement.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/ldap/LdapLoginManagement.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.core.ldap;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.openmeetings.db.util.LocaleHelper.validateCountry;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OmException.BAD_CREDENTIALS;
 import static org.apache.openmeetings.util.OmException.UNKNOWN;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_GROUP_ID;
@@ -63,7 +64,6 @@ import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Type;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.util.OmException;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.wicket.util.string.Strings;
@@ -135,8 +135,6 @@ public class LdapLoginManagement {
 	private UserDao userDao;
 	@Autowired
 	private GroupDao groupDao;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	private static void bindAdmin(LdapConnection conn, LdapOptions options) throws LdapException {
 		if (!Strings.isEmpty(options.adminDn)) {
@@ -370,7 +368,7 @@ public class LdapLoginManagement {
 			if (tz == null) {
 				tz = options.tz;
 			}
-			u.setTimeZoneId(timezoneUtil.getTimeZone(tz).getID());
+			u.setTimeZoneId(getTimeZone(tz).getID());
 			if (!Strings.isEmpty(options.pictureUri)) {
 				u.setPictureuri(options.pictureUri);
 			}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index 7fa8107..8dcfbce 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -63,7 +63,7 @@ import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.LocaleHelper;
+import org.apache.openmeetings.db.util.FormatHelper;
 import org.apache.openmeetings.util.OmException;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
@@ -397,9 +397,9 @@ public class MobileService {
 		m.setToRoom(r);
 		m.setNeedModeration(r.isChatModerated() && !isModerator(c));
 		chatDao.update(m);
-		FastDateFormat fmt = getFmt(u);
+		FastDateFormat fmt = FormatHelper.getDateTimeFormat(u);
 		sendChatMessage(c, m, fmt);
-		WebSocketHelper.sendRoom(m, WebSocketHelper.getMessage(u.getId(), Arrays.asList(m), fmt, null));
+		WebSocketHelper.sendRoom(m, WebSocketHelper.getMessage(u, Arrays.asList(m), null));
 	}
 
 	public void sendChatMessage(String uid, ChatMessage m, FastDateFormat fmt) {
@@ -430,14 +430,6 @@ public class MobileService {
 		return c.isMod() || c.isSuperMod();
 	}
 
-	private static FastDateFormat getFmt(User u) {
-		return FastDateFormat.getDateTimeInstance(
-				FastDateFormat.SHORT
-				, FastDateFormat.SHORT
-				, TimeZone.getTimeZone(u.getTimeZoneId())
-				, LocaleHelper.getLocale(u));
-	}
-
 	private static Map<String, Object> encodeChatMessage(ChatMessage m, FastDateFormat fmt) {
 		Map<String, Object> mm = new HashMap<>();
 		mm.put("from", String.format("%s %s", m.getFromUser().getFirstname(), m.getFromUser().getLastname()));
@@ -457,7 +449,7 @@ public class MobileService {
 
 			Room r = roomDao.get(roomId);
 			User u = userDao.get(c.getUserId());
-			FastDateFormat fmt = getFmt(u);
+			FastDateFormat fmt = FormatHelper.getDateTimeFormat(u);
 			for (ChatMessage m : chatDao.getRoom(roomId, 0, 30, !r.isChatModerated() || isModerator(c))) {
 				myChatList.add(encodeChatMessage(m, fmt));
 			}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
index 100b213..f0ea547 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
@@ -41,6 +41,7 @@ import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.db.util.FormatHelper;
 import org.apache.openmeetings.db.util.ws.RoomMessage;
 import org.apache.openmeetings.db.util.ws.TextRoomMessage;
 import org.apache.openmeetings.util.ws.IClusterWsMessage;
@@ -82,8 +83,11 @@ public class WebSocketHelper {
 		return o.put("scope", scope).put("scopeName", scopeName);
 	}
 
-	public static JSONObject getMessage(long curUserId, List<ChatMessage> list, FastDateFormat fmt, BiConsumer<JSONObject, User> uFmt) {
+	public static JSONObject getMessage(User curUser, List<ChatMessage> list, BiConsumer<JSONObject, User> uFmt) {
 		JSONArray arr = new JSONArray();
+		final FastDateFormat fullFmt = FormatHelper.getDateTimeFormat(curUser);
+		final FastDateFormat dateFmt = FormatHelper.getDateFormat(curUser);
+		final FastDateFormat timeFmt = FormatHelper.getTimeFormat(curUser);
 		for (ChatMessage m : list) {
 			String smsg = m.getMessage();
 			smsg = smsg == null ? smsg : " " + smsg.replaceAll("&nbsp;", " ") + " ";
@@ -93,12 +97,15 @@ public class WebSocketHelper {
 			if (uFmt != null) {
 				uFmt.accept(from, m.getFromUser());
 			}
-			arr.put(setScope(new JSONObject(), m, curUserId)
+			arr.put(setScope(new JSONObject(), m, curUser.getId())
 				.put("id", m.getId())
 				.put("message", smsg)
 				.put("from", from)
-				.put("actions", curUserId == m.getFromUser().getId() ? "short" : "full")
-				.put("sent", fmt.format(m.getSent())));
+				.put("actions", curUser.getId() == m.getFromUser().getId() ? "short" : "full")
+				.put("sent", fullFmt.format(m.getSent()))
+				.put("date", dateFmt.format(m.getSent()))
+				.put("time", timeFmt.format(m.getSent()))
+				);
 		}
 		return new JSONObject()
 			.put("type", "chat")

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
index fbee826..c5e4345 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
@@ -23,6 +23,7 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICAT
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICATION_NAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CRYPT;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_TIMEZONE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_EXT_PROCESS_TTL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_CAM_QUALITY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FLASH_ECHO_PATH;
@@ -79,6 +80,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Properties;
+import java.util.TimeZone;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
@@ -95,6 +97,7 @@ import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.Configuration;
 import org.apache.openmeetings.util.DaoHelper;
 import org.apache.openmeetings.util.OmFileHelper;
+import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.crypt.CryptProvider;
 import org.apache.wicket.Application;
 import org.red5.logging.Red5LoggerFactory;
@@ -335,6 +338,10 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 				reloadAudioRate();
 				break;
 			case CONFIG_MP4_AUDIO_BITRATE:
+				reloadAudioBitrate();
+				break;
+			case CONFIG_DEFAULT_TIMEZONE:
+				reloadTimezone();
 				break;
 		}
 		return entity;
@@ -390,6 +397,19 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 		setAudioBitrate(getString(CONFIG_MP4_AUDIO_BITRATE, "32k"));
 	}
 
+	private void reloadTimezone() {
+		String defaultTzName = getString(CONFIG_DEFAULT_TIMEZONE, "Europe/Berlin");
+
+		TimeZone timeZoneByOmTimeZone = TimeZone.getTimeZone(defaultTzName);
+
+		if (timeZoneByOmTimeZone == null) { //this seems to be impossible
+			// If everything fails take the servers default one
+			log.error("There is no correct time zone set in the configuration of OpenMeetings for the key default.timezone or key is missing in table, using default locale!");
+			defaultTzName = TimeZone.getDefault().getID();
+		}
+		OpenmeetingsVariables.setDefaultTimezone(defaultTzName);
+	}
+
 	public void reinit() {
 		reloadMaxUpload();
 		reloadCrypt();
@@ -400,6 +420,7 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 		reloadGaCode();
 		reloadAudioRate();
 		reloadAudioBitrate();
+		reloadTimezone();
 		reloadRoomSettings();
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
index af190ee..0300f57 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.db.dao.room;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SIP_ROOM_PREFIX;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.RECENT_ROOMS_COUNT;
@@ -49,7 +50,6 @@ import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.Room.Type;
 import org.apache.openmeetings.db.entity.room.RoomFile;
 import org.apache.openmeetings.db.entity.room.RoomGroup;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.util.DaoHelper;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -71,8 +71,6 @@ public class RoomDao implements IGroupAdminDataProviderDao<Room> {
 	private SipDao sipDao;
 	@Autowired
 	private UserDao userDao;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	@Override
 	public Room get(long id) {
@@ -191,7 +189,7 @@ public class RoomDao implements IGroupAdminDataProviderDao<Room> {
 	public List<Room> getAppointedRoomsByUser(long userId) {
 		log.debug("getAppointedRoomsByUser : UserID - " + userId);
 
-		TimeZone timeZone = timezoneUtil.getTimeZone(userDao.get(userId));
+		TimeZone timeZone = getTimeZone(userDao.get(userId));
 
 		Calendar startCal = Calendar.getInstance(timeZone);
 		startCal.set(Calendar.MINUTE, 0);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/UserDao.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/UserDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/UserDao.java
index a808549..647c840 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/UserDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/UserDao.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.db.dao.user;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.db.util.UserHelper.getMinLoginLength;
 import static org.apache.openmeetings.util.DaoHelper.getStringParam;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
@@ -53,7 +54,6 @@ import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Salutation;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.db.util.UserHelper;
 import org.apache.openmeetings.util.DaoHelper;
 import org.apache.openmeetings.util.OmException;
@@ -83,8 +83,6 @@ public class UserDao implements IGroupAdminDataProviderDao<User> {
 
 	@Autowired
 	private ConfigurationDao cfgDao;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	public static Set<Right> getDefaultRights() {
 		Set<Right> rights = new HashSet<>();
@@ -105,7 +103,7 @@ public class UserDao implements IGroupAdminDataProviderDao<User> {
 		user.setSalutation(Salutation.mr);
 		user.setRights(getDefaultRights());
 		user.setLanguageId(getDefaultLang());
-		user.setTimeZoneId(timezoneUtil.getTimeZone(currentUser).getID());
+		user.setTimeZoneId(getTimeZone(currentUser).getID());
 		user.setForceTimeZoneCheck(false);
 		user.setSendSMS(false);
 		user.setAge(new Date());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
index a036969..d6ea7da 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
@@ -38,6 +38,7 @@ import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.db.util.TimezoneUtil;
 
 import com.github.openjson.JSONObject;
 
@@ -73,7 +74,7 @@ public class AppointmentDTO implements Serializable {
 		id = a.getId();
 		title = a.getTitle();
 		location = a.getLocation();
-		TimeZone tz = TimeZone.getTimeZone(a.getOwner().getTimeZoneId());
+		TimeZone tz = TimezoneUtil.getTimeZone(a.getOwner());
 		start = Calendar.getInstance(tz);
 		start.setTime(a.getStart());
 		end = Calendar.getInstance(tz);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/FormatHelper.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/FormatHelper.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/FormatHelper.java
index 4f0264e..3a98027 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/FormatHelper.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/FormatHelper.java
@@ -18,10 +18,13 @@
  */
 package org.apache.openmeetings.db.util;
 
+import static java.text.DateFormat.SHORT;
 import static org.apache.commons.text.StringEscapeUtils.escapeHtml4;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 
 import java.util.regex.Pattern;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.db.entity.user.User;
 
 public class FormatHelper {
@@ -79,4 +82,16 @@ public class FormatHelper {
 		}
 		return user;
 	}
+
+	public static FastDateFormat getDateFormat(User u) {
+		return FastDateFormat.getDateInstance(SHORT, getTimeZone(u), LocaleHelper.getLocale(u));
+	}
+
+	public static FastDateFormat getTimeFormat(User u) {
+		return FastDateFormat.getTimeInstance(SHORT, getTimeZone(u), LocaleHelper.getLocale(u));
+	}
+
+	public static FastDateFormat getDateTimeFormat(User u) {
+		return FastDateFormat.getDateTimeInstance(SHORT, SHORT, getTimeZone(u), LocaleHelper.getLocale(u));
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/TimezoneUtil.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/TimezoneUtil.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/TimezoneUtil.java
index 7e83560..08a0476 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/TimezoneUtil.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/TimezoneUtil.java
@@ -18,27 +18,15 @@
  */
 package org.apache.openmeetings.db.util;
 
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_TIMEZONE;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getDefaultTimezone;
 
 import java.util.TimeZone;
 
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.wicket.util.string.Strings;
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
-@Component
 public class TimezoneUtil {
-	private static final Logger log = Red5LoggerFactory.getLogger(TimezoneUtil.class, getWebAppRootKey());
-
-	@Autowired
-	private ConfigurationDao cfgDao;
-
+	private TimezoneUtil() {}
 	/**
 	 *
 	 * @param timeZoneId
@@ -49,29 +37,8 @@ public class TimezoneUtil {
 	 * @return the specified TimeZone, or the GMT zone if the given ID cannot be
 	 *         understood.
 	 */
-	public TimeZone getTimeZone(String timeZoneId) {
-		if (Strings.isEmpty(timeZoneId)) {
-			return getDefaultTimeZone();
-		}
-		return TimeZone.getTimeZone(timeZoneId);
-	}
-
-	/**
-	 * @return The current server configured time zone in the table configuration key: {@link OpenmeetingsVariables#CONFIG_DEFAULT_TIMEZONE}
-	 */
-	public TimeZone getDefaultTimeZone() {
-		String defaultTzName = cfgDao.getString(CONFIG_DEFAULT_TIMEZONE, "Europe/Berlin");
-
-		TimeZone timeZoneByOmTimeZone = TimeZone.getTimeZone(defaultTzName);
-
-		if (timeZoneByOmTimeZone != null) {
-			return timeZoneByOmTimeZone;
-		}
-
-		// If everything fails take the servers default one
-		log.error("There is no correct time zone set in the configuration of OpenMeetings for the key default.timezone or key is missing in table, using default locale!");
-		return TimeZone.getDefault();
-
+	public static TimeZone getTimeZone(String timeZoneId) {
+		return TimeZone.getTimeZone(Strings.isEmpty(timeZoneId) ? getDefaultTimezone() : timeZoneId);
 	}
 
 	/**
@@ -80,17 +47,7 @@ public class TimezoneUtil {
 	 * @param user
 	 * @return
 	 */
-	public TimeZone getTimeZone(User user) {
-		if (user != null && user.getTimeZoneId() != null) {
-
-			TimeZone timeZone = TimeZone.getTimeZone(user.getTimeZoneId());
-
-			if (timeZone != null) {
-				return timeZone;
-			}
-
-		}
-		// if user has not time zone get one from the server configuration
-		return getDefaultTimeZone();
+	public static TimeZone getTimeZone(User user) {
+		return getTimeZone(user == null ? null : user.getTimeZoneId());
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
index 3bd1f99..2ef1311 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
@@ -21,6 +21,7 @@ package org.apache.openmeetings.backup;
 import static org.apache.openmeetings.db.entity.user.PrivateMessage.INBOX_FOLDER_ID;
 import static org.apache.openmeetings.db.entity.user.PrivateMessage.SENT_FOLDER_ID;
 import static org.apache.openmeetings.db.entity.user.PrivateMessage.TRASH_FOLDER_ID;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.db.util.UserHelper.getMinLoginLength;
 import static org.apache.openmeetings.util.OmFileHelper.BCKP_RECORD_FILES;
 import static org.apache.openmeetings.util.OmFileHelper.BCKP_ROOM_FILES;
@@ -185,7 +186,6 @@ import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Salutation;
 import org.apache.openmeetings.db.entity.user.UserContact;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.util.CalendarPatterns;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.util.StoredFile;
@@ -314,8 +314,6 @@ public class BackupImport {
 	@Autowired
 	private ConfigurationDao cfgDao;
 	@Autowired
-	private TimezoneUtil tzUtil;
-	@Autowired
 	private ChatDao chatDao;
 	@Autowired
 	private OAuth2Dao auth2Dao;
@@ -1395,7 +1393,7 @@ public class BackupImport {
 					String name = item2.getName();
 					String val = item2.getValue();
 					if (u.getTimeZoneId() == null && "omTimeZone".equals(name)) {
-						u.setTimeZoneId(val == null ? null : tzUtil.getTimeZone(val).getID());
+						u.setTimeZoneId(val == null ? null : getTimeZone(val).getID());
 					}
 					if ("level_id".equals(name)) {
 						levelId = val;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/InstallationConfig.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/InstallationConfig.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/InstallationConfig.java
index 34346fa..a8d41aa 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/InstallationConfig.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/InstallationConfig.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.installation;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_APP_NAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_BASE_URL;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getDefaultTimezone;
 
 import java.io.Serializable;
 
@@ -35,7 +36,7 @@ public class InstallationConfig implements Serializable {
 	private String group;
 	private boolean allowFrontendRegister = true;
 	private boolean createDefaultObjects = true;
-	private String timeZone = "Europe/Berlin";
+	private String timeZone = getDefaultTimezone();
 
 	private String cryptClassName = SCryptImplementation.class.getCanonicalName();
 	//email

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/AppointmentLogic.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/AppointmentLogic.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/AppointmentLogic.java
index 1bed7ef..6fbaa61 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/AppointmentLogic.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/AppointmentLogic.java
@@ -18,10 +18,10 @@
  */
 package org.apache.openmeetings.service.calendar;
 
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICATION_BASE_URL;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPOINTMENT_REMINDER_MINUTES;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_BASE_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_MINUTES_REMINDER_SEND;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getBaseUrl;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
 
 import java.util.Calendar;
@@ -36,7 +36,6 @@ import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -51,8 +50,6 @@ public class AppointmentLogic {
 	@Autowired
 	private ConfigurationDao cfgDao;
 	@Autowired
-	private TimezoneUtil timezoneUtil;
-	@Autowired
 	private InvitationDao invitationDao;
 	@Autowired
 	private NotifierService notifierService;
@@ -80,7 +77,7 @@ public class AppointmentLogic {
 	 */
 	// ----------------------------------------------------------------------------------------------
 	public void doScheduledMeetingReminder() {
-		String baseUrl = cfgDao.getString(CONFIG_APPLICATION_BASE_URL, DEFAULT_BASE_URL);
+		String baseUrl = getBaseUrl();
 		if (baseUrl == null || baseUrl.length() < 1) {
 			log.error("Error retrieving baseUrl for application");
 			return;
@@ -108,7 +105,7 @@ public class AppointmentLogic {
 			if (a.isReminderEmailSend()) {
 				continue;
 			}
-			TimeZone ownerZone = timezoneUtil.getTimeZone(a.getOwner().getTimeZoneId());
+			TimeZone ownerZone = getTimeZone(a.getOwner());
 			Calendar aNow = Calendar.getInstance(ownerZone);
 			Calendar aStart = a.startCalendar(ownerZone);
 			aStart.add(Calendar.MINUTE, -minutesReminderSend);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
index 6901815..827911a 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.service.calendar.caldav;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
 
 import java.net.URI;
@@ -37,7 +38,6 @@ import org.apache.openmeetings.db.entity.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.calendar.OmCalendar;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.wicket.protocol.http.WebSession;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
@@ -80,8 +80,6 @@ public class IcalUtils {
 	public static final String PROD_ID = "-//Events Calendar//Apache Openmeetings//EN";
 
 	@Autowired
-	private TimezoneUtil timezoneUtil;
-	@Autowired
 	private UserDao userDao;
 
 	/**
@@ -291,11 +289,11 @@ public class IcalUtils {
 			if (timezone != null) {
 				Property tzid = timezone.getProperty(Property.TZID);
 				if (tzid != null) {
-					return timezoneUtil.getTimeZone(tzid.getValue());
+					return getTimeZone(tzid.getValue());
 				}
 			}
 		}
-		return timezoneUtil.getTimeZone(owner);
+		return getTimeZone(owner);
 	}
 
 	/**
@@ -316,7 +314,7 @@ public class IcalUtils {
 		if (tzid == null) {
 			return parseDate(dt.getValue(), acceptedFormats, timeZone);
 		} else {
-			return parseDate(dt.getValue(), acceptedFormats, timezoneUtil.getTimeZone(tzid.getValue()));
+			return parseDate(dt.getValue(), acceptedFormats, getTimeZone(tzid.getValue()));
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
index 188019f..0185964 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.service.notifier;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
+
 import java.util.TimeZone;
 
 import javax.annotation.PostConstruct;
@@ -29,9 +31,8 @@ import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.TimezoneUtil;
-import org.apache.openmeetings.service.mail.template.subject.SubjectEmailTemplate;
 import org.apache.openmeetings.service.mail.template.subject.AppointmentReminderTemplate;
+import org.apache.openmeetings.service.mail.template.subject.SubjectEmailTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -41,8 +42,6 @@ public class MailNotifier implements INotifier {
 	private NotifierService notifier;
 	@Autowired
 	private IInvitationManager invitationManager;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	@PostConstruct
 	private void register() {
@@ -51,7 +50,7 @@ public class MailNotifier implements INotifier {
 
 	@Override
 	public void notify(User u, Appointment a, Invitation inv) throws Exception {
-		TimeZone tz = timezoneUtil.getTimeZone(u.getTimeZoneId());
+		TimeZone tz = getTimeZone(u);
 		SubjectEmailTemplate t = AppointmentReminderTemplate.get(u, a, tz);
 		invitationManager.sendInvitationLink(inv, MessageType.Create, t.getSubject(), t.getEmail(), false);
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
index 9631919..0ea48f1 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
@@ -19,6 +19,7 @@
 package org.apache.openmeetings.service.room;
 
 import static org.apache.openmeetings.db.util.ApplicationHelper.ensureApplication;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
 
 import java.util.ArrayList;
@@ -42,7 +43,6 @@ import org.apache.openmeetings.db.entity.room.Invitation.Valid;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.service.mail.template.InvitationTemplate;
 import org.apache.openmeetings.service.mail.template.subject.CanceledAppointmentTemplate;
 import org.apache.openmeetings.service.mail.template.subject.CreatedAppointmentTemplate;
@@ -69,8 +69,6 @@ public class InvitationManager implements IInvitationManager {
 	private InvitationDao invitationDao;
 	@Autowired
 	private MailHandler mailHandler;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	/**
 	 * @author vasya
@@ -84,7 +82,7 @@ public class InvitationManager implements IInvitationManager {
 	private void sendInvitionLink(Appointment a, MeetingMember mm, MessageType type, boolean ical) throws Exception	{
 		User owner = a.getOwner();
 		String invitorName = owner.getFirstname() + " " + owner.getLastname();
-		TimeZone tz = timezoneUtil.getTimeZone(mm.getUser());
+		TimeZone tz = getTimeZone(mm.getUser());
 		SubjectEmailTemplate t;
 		switch (type) {
 			case Cancel:
@@ -132,7 +130,7 @@ public class InvitationManager implements IInvitationManager {
 			Appointment a = i.getAppointment();
 			// Create ICal Message
 			String meetingId = handler.addNewMeeting(a.getStart(), a.getEnd(), a.getTitle(), atts, invitationLink,
-					organizerAttendee, a.getIcalId(), timezoneUtil.getTimeZone(owner).getID());
+					organizerAttendee, a.getIcalId(), getTimeZone(owner).getID());
 
 			// Writing back meetingUid
 			if (Strings.isEmpty(a.getIcalId())) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
index bd15862..b68d58e 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.service.user;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.db.util.UserHelper.getMinLoginLength;
 import static org.apache.openmeetings.util.OmException.UNKNOWN;
 import static org.apache.openmeetings.util.OmFileHelper.HIBERNATE;
@@ -58,7 +59,6 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Salutation;
 import org.apache.openmeetings.db.entity.user.User.Type;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.service.mail.EmailManager;
 import org.apache.openmeetings.util.OmException;
 import org.apache.wicket.util.string.Strings;
@@ -91,8 +91,6 @@ public class UserManager implements IUserManager {
 	private ScopeApplicationAdapter scopeAdapter;
 	@Autowired
 	private ISessionManager sessionManager;
-	@Autowired
-	private TimezoneUtil timezoneUtil;
 
 	/**
 	 * Method to register a new User, User will automatically be added to the
@@ -141,7 +139,7 @@ public class UserManager implements IUserManager {
 						userpass, lastname, firstname, email, age, street,
 						additionalname, fax, zip, country, town, languageId,
 						true, Arrays.asList(cfgDao.getLong(CONFIG_DEFAULT_GROUP_ID, null)), phone,
-						sendSMS, sendConfirmation, timezoneUtil.getTimeZone(jNameTimeZone), false, "", "", false, true, null);
+						sendSMS, sendConfirmation, getTimeZone(jNameTimeZone), false, "", "", false, true, null);
 
 				if (user instanceof User && sendConfirmation) {
 					return -40L;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
----------------------------------------------------------------------
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
index 6aa3aa7..e2b9436 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
@@ -127,6 +127,7 @@ public class OpenmeetingsVariables {
 	private static Long defaultLang = 1L;
 	private static int audioRate = 22050;
 	private static String audioBitrate = "32k";
+	private static String defaultTimezone = "Europe/Berlin";
 
 	private OpenmeetingsVariables() {}
 
@@ -245,4 +246,12 @@ public class OpenmeetingsVariables {
 	public static void setAudioBitrate(String bitrate) {
 		audioBitrate = bitrate;
 	}
+
+	public static String getDefaultTimezone() {
+		return defaultTimezone;
+	}
+
+	public static void setDefaultTimezone(String timezone) {
+		defaultTimezone = timezone;
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
index b329557..9483562 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.web.app;
 
-import static java.text.DateFormat.SHORT;
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.CalendarPatterns.ISO8601_FULL_FORMAT_STRING;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_MYROOMS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_RSS;
@@ -61,8 +61,8 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
+import org.apache.openmeetings.db.util.FormatHelper;
 import org.apache.openmeetings.db.util.LocaleHelper;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.util.OmException;
 import org.apache.openmeetings.web.user.dashboard.MyRoomsWidget;
 import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor;
@@ -302,10 +302,10 @@ public class WebSession extends AbstractAuthenticatedWebSession implements IWebS
 		}
 		languageId = u.getLanguageId();
 		externalType = u.getExternalType();
-		tz = getBean(TimezoneUtil.class).getTimeZone(u);
+		tz = getTimeZone(u);
 		ISO8601FORMAT = FastDateFormat.getInstance(ISO8601_FULL_FORMAT_STRING, tz);
 		setLocale(LocaleHelper.getLocale(u));
-		sdf = createDateFormat(u);
+		sdf = FormatHelper.getDateTimeFormat(u);
 	}
 
 	public boolean signIn(String login, String password, Type type, Long domainId) throws OmException {
@@ -563,10 +563,4 @@ public class WebSession extends AbstractAuthenticatedWebSession implements IWebS
 	public ExtendedClientProperties getExtendedProperties() {
 		return extProps;
 	}
-
-	public static FastDateFormat createDateFormat(User u) {
-		return FastDateFormat.getDateTimeInstance(SHORT, SHORT
-				, getBean(TimezoneUtil.class).getTimeZone(u)
-				, LocaleHelper.getLocale(u));
-	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
index 9fa9b08..a6536e0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
@@ -46,8 +46,12 @@ var OmUtil = (function() {
 		});
 		return confirm;
 	}
+	function _tmpl(tmplId, newId) {
+		return $(tmplId).clone().attr('id', newId || '');
+	}
 
 	self.confirmDlg = _confirmDlg;
+	self.tmpl = _tmpl;
 	return self;
 })();
 Wicket.BrowserInfo.collectExtraInfo = function(info) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index c7c3ef1..ffa1823 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -32,6 +32,7 @@ import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Invitation.Valid;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.util.FormatHelper;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.IUpdatable;
 import org.apache.openmeetings.web.common.MainPanel;
@@ -106,7 +107,7 @@ public class HashPage extends BaseInitedPage implements IUpdatable {
 			if (i == null) {
 				errorMsg = getString("error.hash.invalid");
 			} else if (!i.isAllowEntry()) {
-				FastDateFormat sdf = WebSession.createDateFormat(i.getInvitee());
+				FastDateFormat sdf = FormatHelper.getDateTimeFormat(i.getInvitee());
 				errorMsg = Valid.OneTime == i.getValid()
 						? getString("error.hash.used")
 						: String.format("%s %s - %s, %s", getString("error.hash.period")

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
index d528ff9..733fb87 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
@@ -110,7 +110,7 @@ var Activities = function() {
 		, add: function(obj) {
 			if (!inited) return;
 			const _id = _getId(obj.id);
-			area.append($('#activity-stub').clone().attr('id', _id).data(obj));
+			area.append(OmUtil.tmpl('#activity-stub', _id).data(obj));
 			const a = $('#' + _id).addClass(obj.cssClass);
 			a.find('.activity-close,.activity-accept,.activity-decline,.activity-find').addClass(Settings.isRtl ? 'align-left' : 'align-right');
 			const acpt = a.find('.activity-accept');

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 62a33da..feaa09b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -23,8 +23,8 @@ import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_PDF;
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_PNG;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_TITLE;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICATION_BASE_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_REDIRECT_URL_FOR_EXTERNAL;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getBaseUrl;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.isSipEnabled;
 import static org.apache.openmeetings.web.app.Application.exitRoom;
 import static org.apache.openmeetings.web.app.Application.getBean;
@@ -379,14 +379,11 @@ public class RoomMenuPanel extends Panel {
 			room.getMainPanel().updateContents(ROOMS_PUBLIC, handler);
 		} else {
 			String url = getBean(ConfigurationDao.class).getString(CONFIG_REDIRECT_URL_FOR_EXTERNAL, "");
-			if (Strings.isEmpty(url)) {
-				url = getBean(ConfigurationDao.class).getString(CONFIG_APPLICATION_BASE_URL, "");
-			}
-			throw new RedirectToUrlException(url);
+			throw new RedirectToUrlException(Strings.isEmpty(url) ? getBaseUrl() : url);
 		}
 	}
 
 	private static void download(AjaxRequestTarget target, String type) {
-		target.appendJavaScript(String.format("WbArea.download('%s');", EXTENSION_PDF));
+		target.appendJavaScript(String.format("WbArea.download('%s');", type));
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
index 36f2d44..6b268bb 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room-base.js
@@ -199,7 +199,7 @@ var Video = (function() {
 			, opts = Room.getOptions();
 		{ //scope
 			const cont = opts.interview ? $('.pod.pod-' + c.pod) : $('.room.box');
-			cont.append($('#user-video').clone().attr('id', _id).attr('title', name)
+			cont.append(OmUtil.tmpl('#user-video', _id).attr('title', name)
 					.attr('data-client-uid', c.type + c.cuid).data(self));
 		}
 		v = $('#' + _id);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 715f3a3..95441f5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -659,15 +659,6 @@ public class WbPanel extends AbstractWbPanel {
 		return wb.save(f.getFile().toPath());
 	}
 
-	public void loadWhiteboards(Whiteboards wbs, Set<Entry<Long, Whiteboard>> boardSet) {
-		for (Entry<Long, Whiteboard> entry : boardSet) {
-			final Whiteboard wb = entry.getValue();
-			sendWbAll(WbAction.create, getAddWbJson(wb));
-			sendWbAll(WbAction.createObj, new JSONObject().put("wbId", wb.getId())
-					.put("obj", getArray(wb.toJson(), null)));
-		}
-	}
-
 	private static StringBuilder loadWhiteboards(StringBuilder sb, Client cl, Whiteboards wbs, Set<Entry<Long, Whiteboard>> boardSet) {
 		for (Entry<Long, Whiteboard> entry : boardSet) {
 			Whiteboard wb = entry.getValue();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-area.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-area.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-area.js
index a4251cd..7dadc57 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-area.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-area.js
@@ -80,7 +80,7 @@ var DrawWbArea = function() {
 		if (role !== PRESENTER) {
 			return;
 		}
-		li.append($('#wb-tab-close').clone().attr('id', ''));
+		li.append(OmUtil.tmpl('#wb-tab-close'));
 		li.find('button').click(function() {
 			OmUtil.confirmDlg('wb-confirm-remove', function() { wbAction('removeWb', JSON.stringify({wbId: li.data().wbId})); });
 		});
@@ -122,8 +122,8 @@ var DrawWbArea = function() {
 		if (role === PRESENTER) {
 			if (prev.length === 0) {
 				const cc = tabs.find('.wb-tabbar .scroll-container')
-					, left = $('#wb-tabbar-ctrls-left').clone().attr('id', '')
-					, right = $('#wb-tabbar-ctrls-right').clone().attr('id', '');
+					, left = OmUtil.tmpl('#wb-tabbar-ctrls-left')
+					, right = OmUtil.tmpl('#wb-tabbar-ctrls-right');
 				cc.before(left).after(right);
 				tabs.find('.add.om-icon').click(function() {
 					wbAction('createWb');
@@ -188,8 +188,8 @@ var DrawWbArea = function() {
 	self.create = function(obj) {
 		if (!_inited) return;
 		const tid = self.getWbTabId(obj.wbId)
-			, wb = $('#wb-area').clone().attr('id', tid)
-			, li = $('#wb-area-tab').clone().attr('id', '').data('wb-id', obj.wbId).attr('data-wb-id', obj.wbId)
+			, wb = OmUtil.tmpl('#wb-area', tid)
+			, li = OmUtil.tmpl('#wb-area-tab').data('wb-id', obj.wbId).attr('data-wb-id', obj.wbId)
 				.contextmenu(function(e) {
 					if (role !== PRESENTER) {
 						return;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-board.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-board.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-board.js
index f846e13..5a76dcd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-board.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb-board.js
@@ -36,7 +36,7 @@ var Wb = function() {
 		}
 	}
 	function initCliparts() {
-		const c = $('#wb-area-cliparts').clone().attr('id', '');
+		const c = OmUtil.tmpl('#wb-area-cliparts');
 		getBtn('arrow').after(c);
 		c.find('a').prepend(c.find('div.om-icon.big:first'));
 		c.find('.om-icon.clipart').each(function() {
@@ -554,14 +554,14 @@ var Wb = function() {
 			a.find('.wb-zoom').remove();
 			role = _role;
 			const sc = a.find('.scroll-container');
-			z = $('#wb-zoom').clone().attr('id', '')
+			z = OmUtil.tmpl('#wb-zoom')
 				.attr('style', 'position: absolute; top: 0px; ' + (Settings.isRtl ? 'right' : 'left') + ': 80px;');
 			if (role === NONE) {
-				t = $('#wb-tools-readonly').clone().attr('id', '');
+				t = OmUtil.tmpl('#wb-tools-readonly');
 				sc.off('scroll', scrollHandler);
 			} else {
-				t = $('#wb-tools').clone().attr('id', '');
-				s = $("#wb-settings").clone().attr('id', '')
+				t = OmUtil.tmpl('#wb-tools');
+				s = OmUtil.tmpl("#wb-settings")
 					.attr('style', 'display: none; bottom: 100px; ' + (Settings.isRtl ? 'left' : 'right') + ': 100px;');
 				a.append(s);
 				sc.on('scroll', scrollHandler);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
index 8d390f7..0fe311b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
@@ -33,5 +33,29 @@
 			<input type="hidden" wicket:id="activeTab" id="activeChatTab"/>
 		</div>
 	</form>
+	<div style="display: none">
+		<div id="chat-date-template" class='date-row'></div>
+		<div id="chat-msg-template" class='msg-row'>
+			<div class='user-row'>
+				<div class='from'></div>
+				<div class='clear icons'></div>
+				<span class='time'></span>
+				<div class="clear"></div>
+			</div>
+			<div class='msg'></div>
+		</div>
+		<div id="chat-accept-template" class='tick om-icon clickable' wicket:message="title:1190"
+			onclick='const e=$(this);chatActivity("accept", e.data("roomid"), e.data("msgid")); e.parent().remove();'></div>
+		<div id="chat-info-template" class='user om-icon clickable' wicket:message="title:1167"
+			onclick='const e=$(this);showUserInfo(e.data("userId"));'></div>
+		<div id="chat-add-template" class='add om-icon clickable' wicket:message="title:1186"
+			onclick='const e=$(this);addContact(e.data("userId"));'></div>
+		<div id="chat-message-template" class='new-email om-icon clickable' wicket:message="title:1253"
+			onclick='const e=$(this);privateMessage(e.data("userId"));'></div>
+		<div id="chat-invite-template" class='invite om-icon clickable' wicket:message="title:1131"
+			onclick='const e=$(this);inviteUser(e.data("userId"));'></div>
+		<span id="chat-close-block" class='ui-icon ui-icon-close' wicket:message="title:85"
+			role='presentation'></span>
+	</div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
index b3cc7d6..7f3dca5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
@@ -23,7 +23,6 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOAR
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getUserRooms;
-import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.room.RoomPanel.isModerator;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
@@ -41,8 +40,11 @@ import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ChatDao;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.ChatMessage;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.MainPanel;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -106,16 +108,22 @@ public class Chat extends Panel {
 		add(new ChatForm("sendForm"));
 	}
 
+	private Client getClient() {
+		return findParent(MainPanel.class).getClient();
+	}
+
 	private String getUid() {
-		return findParent(MainPanel.class).getClient().getUid();
+		return getClient().getUid();
 	}
 
-	public static JSONObject getMessage(List<ChatMessage> list) {
-		return getMessage(getUserId(), list);
+	public JSONObject getMessage(List<ChatMessage> list) {
+		final Client c = getClient();
+		final User curUser = c == null ? getBean(UserDao.class).get(getUserId()) : c.getUser();
+		return getMessage(curUser, list);
 	}
 
-	public static JSONObject getMessage(Long userId, List<ChatMessage> list) {
-		return WebSocketHelper.getMessage(userId, list, getDateFormat(), (o, u) -> o.put("img", getUrl(RequestCycle.get(), u)));
+	public static JSONObject getMessage(User curUser, List<ChatMessage> list) {
+		return WebSocketHelper.getMessage(curUser, list, (o, u) -> o.put("img", getUrl(RequestCycle.get(), u)));
 	}
 
 	public static CharSequence getReinit() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatForm.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatForm.java
index fe1d033..b2d40e7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatForm.java
@@ -91,6 +91,10 @@ public class ChatForm extends Form<Void> {
 					});
 				}
 
+				private Chat getChat() {
+					return findParent(Chat.class);
+				}
+
 				@Override
 				protected void onSubmit(AjaxRequestTarget target) {
 					final String txt = chatMessage.getDefaultModelObjectAsString();
@@ -121,13 +125,13 @@ public class ChatForm extends Form<Void> {
 						return;
 					};
 					dao.update(m);
-					JSONObject msg = Chat.getMessage(Arrays.asList(m));
+					JSONObject msg = getChat().getMessage(Arrays.asList(m));
 					if (m.getToRoom() != null) {
 						getBean(MobileService.class).sendChatMessage(getUid(), m, getDateFormat()); //let's send to mobile users
 						WebSocketHelper.sendRoom(m, msg);
 					} else if (m.getToUser() != null) {
 						WebSocketHelper.sendUser(getUserId(), msg.toString());
-						msg = Chat.getMessage(m.getToUser().getId(), Arrays.asList(m));
+						msg = Chat.getMessage(m.getToUser(), Arrays.asList(m));
 						WebSocketHelper.sendUser(m.getToUser().getId(), msg.toString());
 					} else {
 						WebSocketHelper.sendAll(msg.toString());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
index 9cb74f5..e387238 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
@@ -211,7 +211,7 @@ public class ChatToolbar extends Panel implements IWysiwygToolbar {
 				}));
 	}
 
-	private void clean(AjaxRequestTarget target, String scope) {
+	private static void clean(AjaxRequestTarget target, String scope) {
 		target.appendJavaScript("$('#" + scope + "').html('')");
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat-base.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat-base.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat-base.js
index 1007e64..98826bd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat-base.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat-base.js
@@ -2,14 +2,7 @@
 var Chat = function() {
 	const align = Settings.isRtl ? 'align-right' : 'align-left'
 		, alignIco = Settings.isRtl ? 'align-left' : 'align-right'
-		, tabTemplate = "<li><a href='#{href}'>#{label}</a></li>"
-		, msgTemplate = "<div class='clear msg-row' id='chat-msg-id-#{id}'><img class='profile " + align + "' src='#{imgSrc}'/><span class='from " + align + "' data-user-id='#{userId}'>#{from}</span><span class='" + align + "'>#{msg}</span><span class='date " + alignIco + "'>#{sent}</span></div>"
-		, acceptTemplate = "<div class='tick om-icon " + alignIco + " clickable' data-msgid='#{msgid}' data-roomid='#{roomid}' onclick='const e=$(this);chatActivity('accept',e.data(\"roomid\"),e.data(\"msgid\"));e.parent().remove();'></div>"
-		, infoTemplate = "<div class='user om-icon " + alignIco + " clickable' data-user-id='#{userId}' onclick='const e=$(this);showUserInfo(e.data(\"userId\"));'></div>"
-		, addTemplate = "<div class='add om-icon " + alignIco + " clickable' data-user-id='#{userId}' onclick='const e=$(this);addContact(e.data(\"userId\"));'></div>"
-		, messageTemplate = "<div class='new-email om-icon " + alignIco + " clickable' data-user-id='#{userId}' onclick='const e=$(this);privateMessage(e.data(\"userId\"));'></div>"
-		, inviteTemplate = "<div class='invite om-icon " + alignIco + " clickable' data-user-id='#{userId}' onclick='const e=$(this);inviteUser(e.data(\"userId\"));'></div>"
-		, closeBlock = "<span class='ui-icon ui-icon-close' role='presentation'></span>"
+		, msgIdPrefix = 'chat-msg-id-'
 		, closedSize = 20
 		, closedSizePx = closedSize + "px"
 		, emoticon = new CSSEmoticon()
@@ -21,7 +14,7 @@ var Chat = function() {
 		;
 	let p, pp, ctrl, icon, tabs, openedHeight = "345px", openedWidth = "300px", allPrefix = "All"
 		, roomPrefix = "Room ", typingTimer, audio, roomMode = false, globalWidth = 600
-		, editor = $('#chatMessage .wysiwyg-editor')
+		, editor = $('#chatMessage .wysiwyg-editor'), lastDate
 		;
 
 	try {
@@ -166,9 +159,9 @@ var Chat = function() {
 		if (!label) {
 			label = id === "chatTab-all" ? allPrefix : roomPrefix + id.substr(9);
 		}
-		const li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{label\}/g, label));
+		const li = $('<li>').append($('<a>').attr('href', '#' + id).text(label));
 		if (id.indexOf("chatTab-r") !== 0) {
-			li.append(closeBlock);
+			li.append(OmUtil.tmpl('#chat-close-block'));
 		}
 		tabs.find(".ui-tabs-nav").append(li);
 		tabs.append("<div class='messageArea' id='" + id + "'></div>");
@@ -197,21 +190,21 @@ var Chat = function() {
 			let msg, cm;
 			while (!!(cm = m.msg.pop())) {
 				let area = $('#' + cm.scope);
-				msg = $(msgTemplate.replace(/#\{id\}/g, cm.id)
-						.replace(/#\{userId\}/g, cm.from.id)
-						.replace(/#\{imgSrc\}/g, !!cm.from.img ? cm.from.img : './profile/' + cm.from.id + '?anticache=' + Date.now())
-						.replace(/#\{from\}/g, cm.from.name)
-						.replace(/#\{sent\}/g, cm.sent)
-						.replace(/#\{msg\}/g, emoticon.emoticonize(!!cm.message ? cm.message : "")));
-				const date = msg.children('.date');
-				date.after(infoTemplate.replace(/#\{userId\}/g, cm.from.id));
-				if ("full" === cm.actions) {
-					date.after(addTemplate.replace(/#\{userId\}/g, cm.from.id));
-					date.after(messageTemplate.replace(/#\{userId\}/g, cm.from.id));
-					date.after(inviteTemplate.replace(/#\{userId\}/g, cm.from.id));
+				msg = OmUtil.tmpl('#chat-msg-template', msgIdPrefix + cm.id)
+				msg.find('.user-row').css('background-image', 'url(' + (!!cm.from.img ? cm.from.img : './profile/' + cm.from.id + '?anticache=' + Date.now()) + ')');
+				msg.find('.from').addClass(align).data('user-id', cm.from.id).html(cm.from.name);
+				msg.find('.msg').addClass(align).html(emoticon.emoticonize(!!cm.message ? cm.message : ""));
+				msg.find('.time').addClass(alignIco).html(cm.time).attr('title', cm.sent);
+				const icons = msg.find('.icons').addClass(align)
+					.append(OmUtil.tmpl('#chat-info-template').addClass(alignIco).data('user-id', cm.from.id));
+				if ('full' === cm.actions) {
+					icons.append(OmUtil.tmpl('#chat-add-template').addClass(alignIco).data('user-id', cm.from.id))
+						.append(OmUtil.tmpl('#chat-message-template').addClass(alignIco).data('user-id', cm.from.id))
+						.append(OmUtil.tmpl('#chat-invite-template').addClass(alignIco).data('user-id', cm.from.id));
 				}
 				if (cm.needModeration) {
-					msg.append(acceptTemplate.replace(/#\{msgid\}/g, cm.id).replace(/#\{roomid\}/g, cm.scope.substring(9)));
+					msg.append(OmUtil.tmpl('#chat-accept-template')
+							.data('msgid', cm.id).data('roomid', cm.scope.substring(9)).find('.tick').addClass(alignIco));
 				}
 				if (!area.length) {
 					_addTab(cm.scope, cm.scopeName);
@@ -221,6 +214,9 @@ var Chat = function() {
 					$('#chat-msg-id-' + cm.id).remove();
 				}
 				const btm = area.scrollTop() + area.innerHeight() >= area[0].scrollHeight;
+				if (lastDate !== cm.date) {
+					area.append(OmUtil.tmpl('#chat-date-template').html(cm.date));
+				}
 				area.append(msg);
 				if (btm) {
 					area.animate({

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
index 9d103a4..941c7f3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/UserSearchPanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.web.user.profile;
 
+import static org.apache.openmeetings.db.util.TimezoneUtil.getTimeZone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.isUserOnline;
@@ -32,7 +33,6 @@ import java.util.List;
 import org.apache.openmeetings.db.dao.user.UserContactDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.web.common.PagingNavigatorPanel;
 import org.apache.openmeetings.web.common.UserBasePanel;
 import org.apache.wicket.AttributeModifier;
@@ -118,7 +118,7 @@ public class UserSearchPanel extends UserBasePanel {
 				final long userId = u.getId();
 				item.add(new WebMarkupContainer("status").add(AttributeModifier.append(ATTR_CLASS, isUserOnline(userId) ? "online" : "offline")));
 				item.add(new Label("name", getName(u)));
-				item.add(new Label("tz", getBean(TimezoneUtil.class).getTimeZone(u).getID()));
+				item.add(new Label("tz", getTimeZone(u).getID()));
 				item.add(new Label("offer", u.getUserOffers()));
 				item.add(new Label("search", u.getUserSearchs()));
 				item.add(new WebMarkupContainer("view").add(addOnClick(String.format("showUserInfo(%s);", userId))));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/webapp/css/chat.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/chat.css b/openmeetings-web/src/main/webapp/css/chat.css
index 6a5f10f..5299eab 100644
--- a/openmeetings-web/src/main/webapp/css/chat.css
+++ b/openmeetings-web/src/main/webapp/css/chat.css
@@ -55,21 +55,33 @@
 	width: 70px;
 	padding-left: 5px;
 }
-#chat .messageArea .date {
+#chat .messageArea .time {
 	margin-right: 5px;
 	font-style: italic;
 	font-size: smaller;
 }
-#chat .messageArea img.profile {
-	vertical-align: middle;
-	max-height: 38px;
-	max-width: 38px;
+#chat .messageArea .user-row {
+	background-size: 38px, 38px;
+	background-repeat: no-repeat;
+	padding-left: 40px;
+	min-height: 40px;
+}
+#chat .messageArea .user-row .icons {
+	display: none;
+}
+#chat .messageArea .user-row:hover .icons {
+	display: block;
 }
 #chat .messageArea .from {
 	margin-left: 5px;
 	margin-right: 5px;
 	font-weight: bold;
 }
+#chat .messageArea .date-row {
+	text-align: center;
+	font-style: italic;
+	padding: 5px 0;
+}
 .ui-tabs .ui-tabs-panel.messageArea {
 	height: 165px;
 	overflow-y: auto;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-web/src/main/webapp/css/general-rtl.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/general-rtl.css b/openmeetings-web/src/main/webapp/css/general-rtl.css
index 01823c2..dd4a51b 100644
--- a/openmeetings-web/src/main/webapp/css/general-rtl.css
+++ b/openmeetings-web/src/main/webapp/css/general-rtl.css
@@ -36,14 +36,6 @@
 	right: initial !important;
 	left: 0 !important;
 }
-#chatPanel {
-	right: initial !important;
-	left: 10px;
-}
-#chatPanel.room {
-	right: initial !important;
-	left: 0px;
-}
 .ui-tabs .ui-tabs-nav li {
 	float: right !important;
 }
@@ -103,6 +95,14 @@ form .input {
 .btn-toolbar .btn, .btn-toolbar .btn-group, .btn-toolbar .input-group {
 	float: right !important;
 }
+#chatPanel {
+	right: initial !important;
+	left: 10px;
+}
+#chatPanel.room {
+	right: initial !important;
+	left: 0px;
+}
 #chat .chat-btn {
 	float: left !important;
 }
@@ -120,6 +120,10 @@ form .input {
 	right: initial !important;
 	left: 0;
 }
+#chat .messageArea .user-row {
+	padding-left: initial !important;
+	padding-right: 40px !important;
+}
 .room.sidebar .tab.om-icon.big {
 	padding: 0em 2.5em 0 1em !important;
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/c106713a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
index bbc68e7..86b8764 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/UserWebService.java
@@ -20,7 +20,7 @@ package org.apache.openmeetings.webservice;
 
 import static org.apache.openmeetings.db.dto.basic.ServiceResult.UNKNOWN;
 import static org.apache.openmeetings.db.util.UserHelper.getMinPasswdLength;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_TIMEZONE;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getDefaultTimezone;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
 import static org.apache.openmeetings.webservice.Constants.TNS;
 import static org.apache.openmeetings.webservice.Constants.USER_SERVICE_NAME;
@@ -160,10 +160,9 @@ public class UserWebService extends BaseWebService {
 				throw new ServiceException("User does already exist!");
 			}
 
-			ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
 			String tz = user.getTimeZoneId();
 			if (Strings.isEmpty(tz)) {
-				tz = cfgDao.getString(CONFIG_DEFAULT_TIMEZONE, "");
+				tz = getDefaultTimezone();
 			}
 			if (user.getAddress() == null) {
 				user.setAddress(new Address());
@@ -172,6 +171,7 @@ public class UserWebService extends BaseWebService {
 			if (user.getLanguageId() == null) {
 				user.setLanguageId(1L);
 			}
+			ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
 			IValidator<String> passValidator = new StrongPasswordValidator(true, getMinPasswdLength(cfgDao), user.get(userDao));
 			Validatable<String> passVal = new Validatable<>(user.getPassword());
 			passValidator.validate(passVal);