Index: eprms-model/pom.xml
===================================================================
--- eprms-model/pom.xml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/pom.xml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -6,5 +6,5 @@
 	<groupId>info.ajanovski.eprms</groupId>
 	<artifactId>model</artifactId>
-	<version>0.0.3-SNAPSHOT</version>
+	<version>0.0.4-SNAPSHOT</version>
 
 	<name>EPRMS - Educational Project and Resource Management System - Model</name>
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Activity.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Activity.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Activity.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -53,5 +53,5 @@
 	}
 
-	@Column(name = "title")
+	@Column(name = "title", length = 4000)
 	public String getTitle() {
 		return this.title;
@@ -62,5 +62,5 @@
 	}
 
-	@Column(name = "description")
+	@Column(name = "description", length = 1000000)
 	public String getDescription() {
 		return this.description;
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/ActivityType.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/ActivityType.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/ActivityType.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -50,5 +50,5 @@
 	}
 
-	@Column(name = "title")
+	@Column(name = "title", length = 4000)
 	public String getTitle() {
 		return this.title;
@@ -59,5 +59,5 @@
 	}
 
-	@Column(name = "description")
+	@Column(name = "description", length = 1000000)
 	public String getDescription() {
 		return this.description;
@@ -78,5 +78,5 @@
 
 	@ManyToOne(fetch = FetchType.LAZY)
-	@JoinColumn(name = "activity_type_id", nullable = true, foreignKey = @ForeignKey(name = "fk_activity_type_activity_type"))
+	@JoinColumn(name = "super_activity_type_id", nullable = true, foreignKey = @ForeignKey(name = "fk_activity_type_activity_type"))
 	public ActivityType getSuperActivityType() {
 		return this.superActivityType;
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/CourseActivityType.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/CourseActivityType.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/CourseActivityType.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -28,8 +28,8 @@
 */
 @Entity
-@Table (schema="", name="course_activity_type")
+@Table (schema="epm_main", name="course_activity_type")
 public class CourseActivityType implements java.io.Serializable {
 	private long courseActivityTypeId;
-	private int order;
+	private int positionNumber;
 	private ActivityType activityType;
 	private Course course;
@@ -48,11 +48,11 @@
 	}
 
-	@Column(name = "order", nullable = false)
-	public int getOrder() {
-		return this.order;
+	@Column(name = "position_number", nullable = false)
+	public int getPositionNumber() {
+		return this.positionNumber;
 	}
 
-	public void setOrder(int order) {
-		this.order=order;
+	public void setPositionNumber(int positionNumber) {
+		this.positionNumber=positionNumber;
 	}
 
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Person.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Person.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Person.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -22,6 +22,15 @@
 package info.ajanovski.eprms.model.entities;
 
-import java.util.*;
-import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
 
 /*
@@ -36,5 +45,4 @@
 	private String userName;
 	private String authString;
-
 
 	@Id
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Project.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Project.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Project.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -56,5 +56,5 @@
 	}
 
-	@Column(name = "title", unique = true, nullable = false)
+	@Column(name = "title", unique = true, nullable = false, length = 4000)
 	public String getTitle() {
 		return this.title;
@@ -65,5 +65,5 @@
 	}
 
-	@Column(name = "description")
+	@Column(name = "description", length = 1000000)
 	public String getDescription() {
 		return this.description;
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/TeamMember.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/TeamMember.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/TeamMember.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -31,5 +31,5 @@
 public class TeamMember implements java.io.Serializable {
 	private long teamMemberId;
-	private Long positionNumber;
+	private Integer positionNumber;
 	private String role;
 	private Person person;
@@ -50,9 +50,9 @@
 
 	@Column(name = "position_number")
-	public Long getPositionNumber() {
+	public Integer getPositionNumber() {
 		return this.positionNumber;
 	}
 
-	public void setPositionNumber(Long positionNumber) {
+	public void setPositionNumber(Integer positionNumber) {
 		this.positionNumber=positionNumber;
 	}
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Translation.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Translation.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/Translation.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,74 @@
+package info.ajanovski.eprms.model.entities;
+
+import java.util.*;
+import javax.persistence.*;
+
+/*
+*/
+@Entity
+@Table (schema="epm_util", name="translations")
+public class Translation implements java.io.Serializable {
+
+	private long	translationId;
+	private String className;
+	private long	originalObjectId;
+	private String	locale;
+	private String	attributeCode;
+	private String	translatedText;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	@Column(name = "translation_id", unique = true, nullable = false)
+	public long getTranslationId() {
+		return this.translationId;
+	}
+
+	public void setTranslationId(long translationId) {
+		this.translationId = translationId;
+	}
+
+	@Column(name = "class_name", nullable = false)
+	public String getClassName() {
+		return this.className;
+	}
+
+	public void setClassName(String className) {
+		this.className=className;
+	}
+
+	@Column(name = "original_object_id", nullable = false)
+	public long getOriginalObjectId() {
+		return this.originalObjectId;
+	}
+
+	public void setOriginalObjectId(long originalObjectId) {
+		this.originalObjectId = originalObjectId;
+	}
+
+	@Column(name = "locale", nullable = false)
+	public String getLocale() {
+		return this.locale;
+	}
+
+	public void setLocale(String locale) {
+		this.locale = locale;
+	}
+
+	@Column(name = "attribute_code", nullable = false)
+	public String getAttributeCode() {
+		return this.attributeCode;
+	}
+
+	public void setAttributeCode(String attributeCode) {
+		this.attributeCode = attributeCode;
+	}
+
+	@Column(name = "translated_text", nullable = false)
+	public String getTranslatedText() {
+		return this.translatedText;
+	}
+
+	public void setTranslatedText(String translatedText) {
+		this.translatedText = translatedText;
+	}
+}
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkEvaluation.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkEvaluation.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkEvaluation.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -25,4 +25,6 @@
 import javax.persistence.*;
 
+import info.ajanovski.eprms.model.util.ModelConstants;
+
 /*
 */
@@ -38,4 +40,5 @@
 	private WorkReport workReport;
 	private Person person;
+	private String status = ModelConstants.EvaluationStatusCreated;
 
 
@@ -52,5 +55,5 @@
 	}
 
-	@Column(name = "title")
+	@Column(name = "title", length = 4000)
 	public String getTitle() {
 		return this.title;
@@ -61,5 +64,5 @@
 	}
 
-	@Column(name = "description")
+	@Column(name = "description", length = 1000000)
 	public String getDescription() {
 		return this.description;
@@ -96,4 +99,14 @@
 		this.evaluationDate=evaluationDate;
 	}
+
+	@Column(name = "status", nullable = false, columnDefinition = "default 'CREATED'")
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	
 	@ManyToOne(fetch = FetchType.LAZY)
 	@JoinColumn(name = "work_report_id", nullable = false, foreignKey = @ForeignKey(name = "fk_work_evaluation_work_report"))
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkReport.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkReport.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/entities/WorkReport.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -54,5 +54,5 @@
 	}
 
-	@Column(name = "title")
+	@Column(name = "title", length = 4000)
 	public String getTitle() {
 		return this.title;
@@ -63,5 +63,5 @@
 	}
 
-	@Column(name = "description")
+	@Column(name = "description", length = 1000000)
 	public String getDescription() {
 		return this.description;
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityComparatorViaType.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityComparatorViaType.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityComparatorViaType.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,11 @@
+package info.ajanovski.eprms.model.util;
+
+import java.util.Comparator;
+
+import info.ajanovski.eprms.model.entities.Activity;
+
+public class ActivityComparatorViaType implements Comparator<Activity> {
+	public int compare(Activity a1, Activity a2) {
+		return a1.getActivityType().getCode().compareTo(a2.getActivityType().getCode());
+	}
+}
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityTypeHierarchicalComparator.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityTypeHierarchicalComparator.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/util/ActivityTypeHierarchicalComparator.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,19 @@
+package info.ajanovski.eprms.model.util;
+
+import java.util.Comparator;
+
+import info.ajanovski.eprms.model.entities.ActivityType;
+
+public class ActivityTypeHierarchicalComparator implements Comparator<ActivityType> {
+	public String getPath(ActivityType at) {
+		if (at.getSuperActivityType() != null) {
+			return getPath(at.getSuperActivityType()) + "." + at.getCode();
+		} else {
+			return at.getCode();
+		}
+	}
+
+	public int compare(ActivityType a1, ActivityType a2) {
+		return getPath(a1).compareTo(getPath(a2));
+	}
+}
Index: eprms-model/src/main/java/info/ajanovski/eprms/model/util/ModelConstants.java
===================================================================
--- eprms-model/src/main/java/info/ajanovski/eprms/model/util/ModelConstants.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-model/src/main/java/info/ajanovski/eprms/model/util/ModelConstants.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -38,3 +38,6 @@
 	public static final String ProjectStatusFinished = "FINISHED";
 	public static final String ProjectStatusStopped = "STOPPED";
+	
+	public static final String EvaluationStatusCreated = "CREATED";
+	public static final String EvaluationStatusPublished = "PUBLISHED";
 }
Index: eprms-mq/pom.xml
===================================================================
--- eprms-mq/pom.xml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-mq/pom.xml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,50 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>info.ajanovski.eprms</groupId>
+	<artifactId>mq</artifactId>
+	<version>0.0.2-SNAPSHOT</version>
+
+	<developers>
+		<developer>
+			<id>vangel.ajanovski</id>
+			<name>Vangel V. Ajanovski</name>
+			<url>https://ajanovski.info</url>
+			<timezone>Europe/Skopje</timezone>
+			<roles>
+				<role>Project Lead</role>
+				<role>Main Developer</role>
+			</roles>
+		</developer>
+	</developers>
+
+	<properties>
+		<maven.compiler.source>15</maven.compiler.source>
+		<maven.compiler.target>15</maven.compiler.target>
+		<java.version>15</java.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>info.ajanovski.eprms</groupId>
+			<artifactId>model</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>com.rabbitmq</groupId>
+			<artifactId>amqp-client</artifactId>
+			<version>5.12.0</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.inject</groupId>
+			<artifactId>javax.inject</artifactId>
+			<version>1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.glassfish</groupId>
+			<artifactId>javax.json</artifactId>
+			<version>1.1.4</version>
+		</dependency>
+	</dependencies>
+</project>
Index: eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingService.java
===================================================================
--- eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingService.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingService.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,17 @@
+package info.ajanovski.eprms.mq;
+
+import info.ajanovski.eprms.model.entities.Database;
+import info.ajanovski.eprms.model.entities.Repository;
+import info.ajanovski.eprms.model.entities.WorkEvaluation;
+
+public interface MessagingService {
+
+	public void setupMQHost(String host);
+
+	public void sendWorkEvaluationNotification(WorkEvaluation we);
+
+	public void sendDatabaseNotification(Database newDb);
+
+	public void sendRepositoryNotification(Repository newRp);
+
+}
Index: eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingServiceImpl.java
===================================================================
--- eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingServiceImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-mq/src/main/java/info/ajanovski/eprms/mq/MessagingServiceImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,93 @@
+package info.ajanovski.eprms.mq;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+
+import org.slf4j.Logger;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+
+import info.ajanovski.eprms.model.entities.Database;
+import info.ajanovski.eprms.model.entities.Repository;
+import info.ajanovski.eprms.model.entities.WorkEvaluation;
+
+public class MessagingServiceImpl implements MessagingService {
+
+	@Inject
+	private Logger logger;
+
+	private ConnectionFactory factory;
+
+	private static String exchangeMain = "EPRMS";
+
+	public MessagingServiceImpl() {
+		factory = new ConnectionFactory();
+	}
+
+	public void setupMQHost(String host) {
+		factory.setHost(host);
+	}
+
+	public JsonValue processValue(String value) {
+		return ((value == null) ? JsonValue.NULL : Json.createValue(value));
+	}
+
+	public void prepareAndSendMessage(JsonObject jsonObject, String tag, String destination) {
+		try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			Json.createWriter(baos).writeObject(jsonObject);
+			channel.exchangeDeclare(destination, "topic", true);
+			channel.basicPublish(destination, tag, null, baos.toByteArray());
+		} catch (Exception e) {
+			throw new RuntimeException(e.getMessage());
+		}
+	}
+
+	public void sendWorkEvaluationNotification(WorkEvaluation we) {
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		builder.add("title", processValue(we.getTitle()));
+		builder.add("description", processValue(we.getDescription()));
+		builder.add("points", processValue(we.getPoints().toString()));
+		builder.add("action", "create");
+		prepareAndSendMessage(builder.build(), "workeval.create", exchangeMain);
+	}
+
+	@Override
+	public void sendDatabaseNotification(Database newDb) {
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		builder.add("dbType", processValue(newDb.getType()));
+		builder.add("dbServer", processValue(newDb.getServer()));
+		builder.add("dbPort", processValue(newDb.getPort()));
+		builder.add("dbName", processValue(newDb.getName()));
+		builder.add("dbOwner", processValue(newDb.getOwner()));
+		builder.add("dbPass", processValue(newDb.getPassword()));
+		builder.add("dbTunServer", processValue(newDb.getTunnelServer()));
+		builder.add("dbTunUser", processValue(newDb.getTunnelUser()));
+		builder.add("dbTunPassword", processValue(newDb.getTunnelPassword()));
+		builder.add("action", "create");
+		prepareAndSendMessage(builder.build(), "db.create", exchangeMain);
+	}
+
+	@Override
+	public void sendRepositoryNotification(Repository newRp) {
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		builder.add("rpName", processValue(newRp.getTitle()));
+		builder.add("rpType", processValue(newRp.getType()));
+		builder.add("rpUrl", processValue(newRp.getUrl()));
+		if (newRp.getPerson() != null) {
+			builder.add("rpOwner", processValue(newRp.getPerson().getUserName()));
+		} else {
+			builder.add("rpOwner", processValue(null));
+		}
+		builder.add("action", "create");
+		prepareAndSendMessage(builder.build(), "repo.create", exchangeMain);
+	}
+
+}
Index: eprms-tap/pom.xml
===================================================================
--- eprms-tap/pom.xml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/pom.xml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -8,5 +8,5 @@
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>2.3.9.RELEASE</version>
+		<version>2.5.3</version>
 		<relativePath />
 	</parent>
@@ -14,5 +14,5 @@
 	<groupId>info.ajanovski.eprms</groupId>
 	<artifactId>eprms-tap</artifactId>
-	<version>0.0.2-SNAPSHOT</version>
+	<version>0.0.4-T5.7.3</version>
 	<name>EPRMS - Educational Project and Resource Management System</name>
 
@@ -32,4 +32,5 @@
 	</developers>
 
+
 	<properties>
 		<maven.compiler.source>15</maven.compiler.source>
@@ -37,8 +38,10 @@
 		<java.version>15</java.version>
 
-		<tapestry-version>5.7.2</tapestry-version>
+		<spring-boot-version>2.5.3</spring-boot-version>
+		<tapestry-version>5.7.3</tapestry-version>
 		<tapestry-testify-version>1.0.4</tapestry-testify-version>
 		<tapestry-xpath-version>1.0.1</tapestry-xpath-version>
-		<jackson-version>2.12.1</jackson-version>
+
+		<jackson-version>2.12.4</jackson-version>
 		<geb-version>2.3.1</geb-version>
 		<htmlunit-driver-version>2.33.3</htmlunit-driver-version>
@@ -47,8 +50,7 @@
 		<servlet-api-version>3.0.1</servlet-api-version>
 		<spock-version>1.3-groovy-2.5</spock-version>
-		<spring-boot-version>2.3.9.RELEASE</spring-boot-version>
-		<yasson-version>1.0.8</yasson-version>
-
-		<postgresql-version>42.2.19</postgresql-version>
+		<yasson-version>1.0.9</yasson-version>
+
+		<postgresql-version>42.2.23</postgresql-version>
 		<cas-client-version>3.6.2</cas-client-version>
 
@@ -64,8 +66,15 @@
 	</repositories>
 
+
 	<dependencies>
 		<dependency>
 			<groupId>info.ajanovski.eprms</groupId>
 			<artifactId>model</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>info.ajanovski.eprms</groupId>
+			<artifactId>mq</artifactId>
 			<version>0.0.2-SNAPSHOT</version>
 		</dependency>
@@ -92,15 +101,25 @@
 					<artifactId>spring-boot-starter-logging</artifactId>
 				</exclusion>
+				<exclusion>
+					<groupId>org.springframework.boot</groupId>
+					<artifactId>spring-boot-starter-tomcat</artifactId>
+				</exclusion>
 			</exclusions>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-tomcat</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-log4j2</artifactId>
 			<scope>compile</scope>
 		</dependency>
+
 		<!-- Apache Tapestry -->
 		<dependency>
 			<groupId>org.apache.tapestry</groupId>
-			<artifactId>tapestry-core</artifactId>
+			<artifactId>tapestry-hibernate</artifactId>
 			<version>${tapestry-version}</version>
 			<scope>compile</scope>
@@ -115,20 +134,9 @@
 		<dependency>
 			<groupId>org.apache.tapestry</groupId>
-			<artifactId>tapestry-hibernate</artifactId>
-			<version>${tapestry-version}</version>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.tapestry</groupId>
-			<artifactId>tapestry-beanvalidator</artifactId>
-			<version>${tapestry-version}</version>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.tapestry</groupId>
 			<artifactId>tapestry-upload</artifactId>
 			<version>${tapestry-version}</version>
 			<scope>compile</scope>
 		</dependency>
+
 		<!-- Unit Testing -->
 		<dependency>
@@ -168,4 +176,5 @@
 			<scope>test</scope>
 		</dependency>
+
 		<!-- Integration Testing -->
 		<dependency>
@@ -196,4 +205,5 @@
 			<scope>test</scope>
 		</dependency>
+
 		<!-- Miscellaneous -->
 		<dependency>
@@ -224,24 +234,20 @@
 		</dependency>
 		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-annotations</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>javax.servlet</groupId>
 			<artifactId>javax.servlet-api</artifactId>
+			<version>${servlet-api-version}</version>
 			<scope>provided</scope>
 		</dependency>
+
 		<!-- PostgreSQL is used as the main DBMS engine for this app -->
 		<dependency>
 			<groupId>org.postgresql</groupId>
 			<artifactId>postgresql</artifactId>
-			<version>${postgresql-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.hibernate</groupId>
-			<artifactId>hibernate-core</artifactId>
-			<version>5.1.17.Final</version>
-		</dependency>
-		<dependency>
-			<groupId>org.hibernate</groupId>
-			<artifactId>hibernate-validator</artifactId>
-			<version>5.4.3.Final</version>
-		</dependency>
+		</dependency>
+
 		<dependency>
 			<groupId>org.jasig.cas.client</groupId>
@@ -249,5 +255,6 @@
 			<version>${cas-client-version}</version>
 		</dependency>
-		<!-- other -->
+
+		<!-- webjars -->
 		<dependency>
 			<groupId>org.webjars.npm</groupId>
@@ -255,8 +262,29 @@
 			<version>3.0.5</version>
 		</dependency>
+		<dependency>
+			<groupId>org.webjars</groupId>
+			<artifactId>webjars-locator</artifactId>
+			<version>0.42</version>
+		</dependency>
+		<dependency>
+			<groupId>org.webjars.npm</groupId>
+			<artifactId>feather-icons</artifactId>
+			<version>4.28.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.webjars</groupId>
+			<artifactId>ckeditor</artifactId>
+			<version>4.16.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.webjars.npm</groupId>
+			<artifactId>firacode</artifactId>
+			<version>1.205.0</version>
+		</dependency>
+
 	</dependencies>
 
 	<build>
-		<finalName>epm</finalName>
+		<finalName>eprms</finalName>
 
 		<resources>
@@ -323,20 +351,11 @@
 			</plugin>
 			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-resources-plugin</artifactId>
-				<configuration>
-					<encoding>UTF-8</encoding>
-				</configuration>
+				<version>2.6</version>
 			</plugin>
-			<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> 
-				<executions> <execution> <id>unpack</id> <phase>process-sources</phase> <goals> 
-				<goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> 
-				<groupId>org.freedesktop.tango</groupId> <artifactId>tango-icon-theme</artifactId> 
-				<type>jar</type> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}/${project.build.finalName}/images/tango-icon-theme</outputDirectory> 
-				<includes>**/*</includes> </artifactItem> <artifactItem> <groupId>org.webjars.npm</groupId> 
-				<artifactId>fontsource-fira-sans</artifactId> <type>jar</type> <overWrite>true</overWrite> 
-				<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory> 
-				<includes>**/*</includes> </artifactItem> </artifactItems> </configuration> 
-				</execution> </executions> </plugin> -->
 		</plugins>
+
 	</build>
+
 </project>
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/AppConfiguration.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/AppConfiguration.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/AppConfiguration.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -38,12 +38,8 @@
 import org.springframework.boot.web.servlet.ServletContextInitializer;
 import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
-import org.springframework.context.MessageSource;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.ReloadableResourceBundleMessageSource;
 import org.springframework.http.HttpStatus;
-import org.springframework.web.servlet.LocaleResolver;
-import org.springframework.web.servlet.i18n.CookieLocaleResolver;
 
 import info.ajanovski.eprms.tap.util.AppConfig;
@@ -63,16 +59,10 @@
 						"info.ajanovski.eprms.tap.services.DevelopmentModule");
 				servletContext.setInitParameter("tapestry.qa-modules", "info.ajanovski.eprms.tap.services.QaModule");
-				// servletContext.setInitParameter("tapestry.use-external-spring-context",
-				// "true");
 
 				servletContext.setInitParameter("artifactParameterName", "ticket");
-
 				servletContext.setInitParameter("casServerLogoutUrl",
 						AppConfig.getString("cas.server") + "/cas/logout");
-
 				servletContext.setInitParameter("casServerLoginUrl", AppConfig.getString("cas.server") + "/cas/login");
-
 				servletContext.setInitParameter("casServerUrlPrefix", AppConfig.getString("cas.server") + "/cas");
-
 				servletContext.setInitParameter("service",
 						AppConfig.getString("app.server") + servletContext.getContextPath());
@@ -84,13 +74,10 @@
 						.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR), false,
 								"/*");
-
 				servletContext.addFilter("CAS Authentication Filter", AuthenticationFilter.class)
 						.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR), false,
 								"/*");
-
 				servletContext.addFilter("CAS Validation Filter", Cas20ProxyReceivingTicketValidationFilter.class)
 						.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR), false,
 								"/*");
-
 				servletContext.addFilter("CAS HttpServletRequest Wrapper Filter", HttpServletRequestWrapperFilter.class)
 						.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR), false,
@@ -102,9 +89,4 @@
 				servletContext.addListener(SingleSignOutHttpSessionListener.class);
 
-				servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
-
-				// servletContext.addFilter("app",
-				// TapestrySpringFilter.class).addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST,
-				// DispatcherType.ERROR), false, "/*");
 				servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
 			}
@@ -119,18 +101,18 @@
 	}
 
-	@Bean(name = "messageSource")
-	public MessageSource getMessageResource() {
-		ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
-		messageResource.setBasename("classpath:app");
-		messageResource.setDefaultEncoding("UTF-8");
-		return messageResource;
-	}
-
-	@Bean(name = "localeResolver")
-	public LocaleResolver getLocaleResolver() {
-		CookieLocaleResolver resolver = new CookieLocaleResolver();
-		resolver.setCookieDomain("localeCookie");
-		resolver.setCookieMaxAge(60 * 60);
-		return resolver;
-	}
+//	@Bean(name = "messageSource")
+//	public MessageSource getMessageResource() {
+//		ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
+//		messageResource.setBasename("classpath:app");
+//		messageResource.setDefaultEncoding("UTF-8");
+//		return messageResource;
+//	}
+//
+//	@Bean(name = "localeResolver")
+//	public LocaleResolver getLocaleResolver() {
+//		CookieLocaleResolver resolver = new CookieLocaleResolver();
+//		resolver.setCookieDomain("localeCookie");
+//		resolver.setCookieMaxAge(60 * 60);
+//		return resolver;
+//	}
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/Layout.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/Layout.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/Layout.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -81,11 +81,13 @@
 
 	public String[] getStudentPageNames() {
-		return new String[] { "Index", "MyProjectReports", "MyDatabases", "MyRepositories", "MyRepositoryAuth" };
+		return new String[] { "user/MyProfile", "user/MyProjectReports", "user/MyDatabases", "user/MyRepositories",
+				"user/MyRepositoryAuth" };
 	}
 
 	public String[] getAdminPageNames() {
 		if (userInfo.isAdministrator()) {
-			return new String[] { "admin/OverallCourseReport", "admin/ManageProjects", "admin/ManageTeams",
-					"admin/ManageDatabases", "admin/ManageRepositories" };
+			return new String[] { "admin/ProjectAutomation", "admin/OverallCourseReport", "admin/ManageActivityTypes",
+					"admin/ManageProjects", "admin/ManageTeams", "admin/ManageDatabases", "admin/ManageRepositories",
+					"admin/ManagePersons" };
 		} else {
 			return null;
@@ -111,22 +113,21 @@
 	private PersistentLocale persistentLocale;
 
-	void onActionFromLocaleToggle() {
-		if (persistentLocale.isSet()) {
-			if ("mk".equalsIgnoreCase(persistentLocale.get().getLanguage())) {
-				persistentLocale.set(new Locale("en"));
-			} else {
-				persistentLocale.set(new Locale("mk"));
-			}
-		} else {
+	void setupRender() {
+		if (persistentLocale.get() == null) {
 			persistentLocale.set(new Locale("mk"));
 		}
 	}
 
+	public Object onActionFromLocaleToggle() {
+		if ("en".equalsIgnoreCase(persistentLocale.get().getLanguage())) {
+			persistentLocale.set(new Locale("mk"));
+		} else {
+			persistentLocale.set(new Locale("en"));
+		}
+		return this;
+	}
+
 	public String getDisplayLanguage() {
-		Locale loc = persistentLocale.get();
-		if (loc == null)
-			return "";
-		else
-			return loc.getLanguage().toUpperCase();
+		return persistentLocale.get().toLanguageTag();
 	}
 
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/ModalBox.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/ModalBox.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/ModalBox.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,56 @@
+package info.ajanovski.eprms.tap.components;
+
+//Based on http://readyareyou.blogspot.com.au/2012/11/tapestry5-bootstrap-modal-dialog.html .
+
+import javax.inject.Inject;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ClientElement;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.http.services.Request;
+import org.apache.tapestry5.json.JSONObject;
+import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
+import org.apache.tapestry5.services.ajax.JavaScriptCallback;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+@Import(module = { "ModalBox" })
+public class ModalBox implements ClientElement {
+
+	@Parameter(name = "componentClientId", value = "prop:componentResources.id",
+			defaultPrefix = BindingConstants.LITERAL) private String																									componentClientId;
+
+	@Inject private JavaScriptSupport																																		javaScriptSupport;
+	@Inject private AjaxResponseRenderer																																	ajaxResponseRenderer;
+	@Inject private Request																																						request;
+
+	@Override
+	public String getClientId() {
+		return componentClientId;
+	}
+
+	void setupRender() {
+		JSONObject json = new JSONObject();
+		json.put("keyboard", true);
+		json.put("backdrop", "static");
+		json.put("focus", true);
+		javaScriptSupport.require("ModalBox").invoke("activate")
+				.with(componentClientId, json);
+	}
+
+	public void hide() {
+		if (request.isXHR()) {
+			ajaxResponseRenderer.addCallback(makeScriptToHideModal());
+		}
+	}
+
+	private JavaScriptCallback makeScriptToHideModal() {
+		return new JavaScriptCallback() {
+			public void run(JavaScriptSupport javascriptSupport) {
+				javaScriptSupport.require("ModalBox").invoke("hide")
+						.with(componentClientId);
+			}
+		};
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/PublicLayout.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/PublicLayout.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/PublicLayout.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.components;
+
+import java.util.Locale;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.commons.Messages;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.services.PersistentLocale;
+import org.slf4j.Logger;
+
+import info.ajanovski.eprms.tap.annotations.PublicPage;
+
+@Import(stylesheet = { "site-overrides.css" }, module = { "bootstrap/dropdown", "bootstrap/collapse" })
+@PublicPage
+public class PublicLayout {
+
+	@Inject
+	private ComponentResources resources;
+
+	@Property
+	@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
+	private String title;
+
+	@Property
+	private String pageName;
+
+	@Property
+	@Inject
+	@Symbol(SymbolConstants.APPLICATION_VERSION)
+	private String appVersion;
+
+	@Inject
+	private Logger logger;
+
+	public String[] getPublicPageNames() {
+		return new String[] {};
+	}
+
+	public String getClassForPageName() {
+		logger.debug("respgname:{}", resources.getPageName() + " " + resources.getCompleteId());
+		if (resources.getPageName().equalsIgnoreCase(pageName)) {
+			return "active";
+		} else {
+			return " ";
+		}
+	}
+
+	@Inject
+	private Messages messages;
+
+	public String getPageNameTitle() {
+		return messages.get(pageName + "-pagelink");
+	}
+
+	@Inject
+	private PersistentLocale persistentLocale;
+
+	void onActionFromLocaleToggle() {
+		if (persistentLocale.isSet()) {
+			if ("mk".equalsIgnoreCase(persistentLocale.get().getLanguage())) {
+				persistentLocale.set(new Locale("en"));
+			} else {
+				persistentLocale.set(new Locale("mk"));
+			}
+		} else {
+			persistentLocale.set(new Locale("mk"));
+		}
+	}
+
+	public String getDisplayLanguage() {
+		Locale loc = persistentLocale.get();
+		if (loc == null)
+			return "";
+		else
+			return loc.getLanguage().toUpperCase();
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/TeamMembersGrid.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/TeamMembersGrid.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/components/TeamMembersGrid.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -78,6 +78,6 @@
 		bm.add("lastName", pcs.create(TeamMember.class, "person.lastName"));
 		bm.add("firstName", pcs.create(TeamMember.class, "person.firstName"));
-		bm.reorder("positionNumber", "lastName", "role");
-		bm.add("actions",null);
+		bm.reorder("positionNumber", "role", "lastName", "firstName", "userName");
+		bm.add("actions", null);
 		return bm;
 	}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/GenericDaoImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/GenericDaoImpl.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/GenericDaoImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -27,8 +27,5 @@
 
 import org.apache.tapestry5.ioc.annotations.Inject;
-import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.criterion.MatchMode;
-import org.hibernate.criterion.Restrictions;
 import org.hibernate.exception.DataException;
 import org.slf4j.Logger;
@@ -38,4 +35,8 @@
 	@Inject
 	private Session session;
+
+	private Session getEntityManager() {
+		return session.getSession();
+	}
 
 	@Inject
@@ -60,8 +61,8 @@
 	public List<Object> getQueryResult(String guery) {
 		try {
-			Query q = session.createQuery(guery);
+			javax.persistence.Query q = getEntityManager().createQuery(guery);
 			List<Object> l = new ArrayList<Object>();
 
-			for (Iterator<?> it = q.iterate(); it.hasNext();) {
+			for (Iterator<?> it = q.getResultList().iterator(); it.hasNext();) {
 				Object[] row = (Object[]) it.next();
 				for (int i = 0; i < row.length; i++) {
@@ -94,10 +95,11 @@
 	@Override
 	public List<?> getAll(Class<?> classToLoad) {
-		return session.createCriteria(classToLoad).list();
+		return getEntityManager().createQuery("from " + classToLoad.getName()).getResultList();
 	}
 
 	@Override
 	public Object getByCode(Class<?> classToLoad, String code) {
-		List<?> l = session.createCriteria(classToLoad).add(Restrictions.eq("code", code)).list();
+		List<?> l = getEntityManager().createQuery("from " + classToLoad.getName() + "where code=:code")
+				.setParameter("code", code).getResultList();
 		if (l.size() > 0) {
 			return l.get(0);
@@ -110,6 +112,7 @@
 	public List<?> getByTitleSubstring(Class<?> classToSearch, String searchSubString) {
 		if (searchSubString != null) {
-			return (List<?>) session.createCriteria(classToSearch)
-					.add(Restrictions.ilike("title", searchSubString, MatchMode.ANYWHERE)).list();
+			return (List<?>) getEntityManager()
+					.createQuery("from " + classToSearch.getName() + "where title ilike :searchSubString")
+					.setParameter("searchSubString", searchSubString).getResultList();
 		} else {
 			return null;
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDao.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDao.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDao.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -26,4 +26,5 @@
 import info.ajanovski.eprms.model.entities.Person;
 import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.entities.Role;
 
 public interface PersonDao {
@@ -40,3 +41,5 @@
 	public List<PersonRole> getPersonRolesForPerson(long personId);
 
+	public List<Role> getRolesForPerson(long personId);
+
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDaoImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDaoImpl.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/PersonDaoImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -24,9 +24,8 @@
 import java.util.List;
 
+import javax.persistence.Query;
+
 import org.apache.tapestry5.ioc.annotations.Inject;
-import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.criterion.Order;
-import org.hibernate.criterion.Restrictions;
 import org.hibernate.exception.DataException;
 import org.slf4j.Logger;
@@ -34,4 +33,5 @@
 import info.ajanovski.eprms.model.entities.Person;
 import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.entities.Role;
 import info.ajanovski.eprms.tap.util.UsefulMethods;
 
@@ -43,9 +43,13 @@
 	private Session session;
 
+	private Session getEntityManager() {
+		return session.getSession();
+	}
+
 	@Override
 	public List<Person> getAllPersons() {
 		try {
 			return UsefulMethods.castList(Person.class,
-					session.createCriteria(Person.class).addOrder(Order.asc("lastName")).list());
+					getEntityManager().createQuery("from Person order by lastName").getResultList());
 		} catch (DataException e) {
 			logger.error("Exception - DataAccessException occurs : {} on complete getAllPersons().", e.getMessage());
@@ -56,6 +60,6 @@
 	@Override
 	public Person getPersonByUsername(String username) {
-		return (Person) session.createCriteria(Person.class).add(Restrictions.eq("userName", username))
-				.setReadOnly(true).setCacheable(true).uniqueResult();
+		return (Person) getEntityManager().createQuery("from Person where userName=:username")
+				.setParameter("username", username).setReadOnly(true).setCacheable(true).uniqueResult();
 	}
 
@@ -63,14 +67,15 @@
 	public List<Person> getPersonByFilter(String filter) {
 		String f = "%" + filter.toLowerCase() + "%";
-		Query q = session
+		Query q = getEntityManager()
 				.createQuery("select p from Person p  where (lower(concat(userName,firstName,lastName)) like :filter)");
 		q.setParameter("filter", f);
-		return UsefulMethods.castList(Person.class, q.list());
+		return UsefulMethods.castList(Person.class, q.getResultList());
 	}
 
 	@Override
 	public List<PersonRole> getPersonRolesForPerson(long personId) {
-		return (List<PersonRole>) session.createCriteria(PersonRole.class, "pr")
-				.add(Restrictions.eq("pr.person.personId", personId)).list();
+		return (List<PersonRole>) getEntityManager()
+				.createQuery("from PersonRole pr where pr.person.personId=:personId").setParameter("personId", personId)
+				.getResultList();
 	}
 
@@ -85,3 +90,9 @@
 	}
 
+	@Override
+	public List<Role> getRolesForPerson(long personId) {
+		return getEntityManager().createQuery("select pr.role from PersonRole pr where pr.person.personId=:personId")
+				.setParameter("personId", personId).getResultList();
+	}
+
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ProjectDaoImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ProjectDaoImpl.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ProjectDaoImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -37,8 +37,12 @@
 	private Session session;
 
+	private Session getEntityManager() {
+		return session.getSession();
+	}
+
 	@Override
 	@SuppressWarnings("unchecked")
 	public List<Project> getAllProjectsOrderByTitle() {
-		return session.createQuery("from Project order by title").list();
+		return getEntityManager().createQuery("from Project order by title").getResultList();
 	}
 
@@ -47,6 +51,6 @@
 	public List<CourseProject> getProjectCourses(Project p) {
 		if (p != null) {
-			return session.createQuery("from CourseProject cp where cp.project.projectId=:projectId")
-					.setParameter("projectId", p.getProjectId()).list();
+			return getEntityManager().createQuery("from CourseProject cp where cp.project.projectId=:projectId")
+					.setParameter("projectId", p.getProjectId()).getResultList();
 		} else {
 			return null;
@@ -58,5 +62,5 @@
 	public Float sumPoints(Project p) {
 		if (p != null) {
-			List<Float> lista = session.createQuery("""
+			List<Float> lista = getEntityManager().createQuery("""
 								select max(we.points) as maxpoints
 								from WorkEvaluation as we
@@ -66,5 +70,5 @@
 								where p.projectId=:projectId
 								group by a
-					""").setParameter("projectId", p.getProjectId()).list();
+					""").setParameter("projectId", p.getProjectId()).getResultList();
 			Float output = 0.0f;
 			for (Float o : lista) {
@@ -83,5 +87,5 @@
 	public List<Project> getCourseProjectsOrderByTitle(Course selectedCourse) {
 		if (selectedCourse != null) {
-			return session.createQuery("""
+			return getEntityManager().createQuery("""
 					select p
 					from Project p
@@ -90,5 +94,5 @@
 					where c.courseId=:courseId
 					order by p.title
-					""").setParameter("courseId", selectedCourse.getCourseId()).list();
+					""").setParameter("courseId", selectedCourse.getCourseId()).getResultList();
 		} else {
 			return null;
@@ -100,5 +104,5 @@
 	public List<Project> getProjectByPerson(Long personId) {
 		if (personId != null) {
-			return session.createQuery("""
+			return getEntityManager().createQuery("""
 					select p
 					from Project p
@@ -109,5 +113,5 @@
 					where person.personId=:personId
 					order by p.title
-					""").setParameter("personId", personId).list();
+					""").setParameter("personId", personId).getResultList();
 		} else {
 			return null;
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ResourceDaoImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ResourceDaoImpl.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/data/ResourceDaoImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -36,9 +36,13 @@
 	private Session session;
 
+	private Session getEntityManager() {
+		return session.getSession();
+	}
+
 	@Override
 	public List<Repository> getRepositoriesByPerson(long personId) {
 		try {
-			return session.createQuery("from Repository r where r.person.personId=:personId")
-					.setLong("personId", personId).list();
+			return getEntityManager().createQuery("from Repository r where r.person.personId=:personId")
+					.setParameter("personId", personId).getResultList();
 		} catch (Exception e) {
 			return new ArrayList<Repository>();
@@ -49,8 +53,8 @@
 	public List<Repository> getRepositoriesByTeam(long personId) {
 		try {
-			return session.createQuery("""
+			return getEntityManager().createQuery("""
 					select r from Repository r join r.team t, TeamMember tm join tm.person p
 					where tm.team.teamId=t.teamId and r.person.personId=:personId
-					""").setLong("personId", personId).list();
+					""").setParameter("personId", personId).getResultList();
 		} catch (Exception e) {
 			return new ArrayList<Repository>();
@@ -61,10 +65,10 @@
 	public List<Repository> getRepositoriesByProject(long personId) {
 		try {
-			return session.createQuery("""
+			return getEntityManager().createQuery("""
 					select r from Repository r join r.project pr,
 					Responsibility res join res.team t, TeamMember tm join tm.person p
 					where pr.projectId=res.project.projectId and tm.team.teamId=t.teamId and
 					tm.person.personId=:personId
-					""").setLong("personId", personId).list();
+					""").setParameter("personId", personId).getResultList();
 		} catch (Exception e) {
 			return new ArrayList<Repository>();
@@ -75,10 +79,10 @@
 	public List<Database> getDatabasesByProject(long personId) {
 		try {
-			return session.createQuery("""
+			return getEntityManager().createQuery("""
 					select d from Database d join d.project pr,
 					Responsibility res join res.team t, TeamMember tm join tm.person p
 					where pr.projectId=res.project.projectId and tm.team.teamId=t.teamId and
 					tm.person.personId=:personId
-					""").setLong("personId", personId).list();
+					""").setParameter("personId", personId).getResultList();
 		} catch (Exception e) {
 			return new ArrayList<Database>();
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/mixins/WebEditor.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/mixins/WebEditor.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/mixins/WebEditor.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the dbLearnStar system (hereinafter: dbLearn*).
+ *     
+ * dbLearn* is free software: you can redistribute it and/or modify it under the 
+ * terms of the GNU General Public License as published by the Free Software 
+ * Foundation, either version 3 of the License, or (at your option) any later 
+ * version.
+ *     
+ * dbLearn* 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 General Public License for more 
+ * details.
+ *     
+ * You should have received a copy of the GNU General Public License along 
+ * with dbLearn*.  If not, see <https://www.gnu.org/licenses/>.
+ * 
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.mixins;
+
+import org.apache.tapestry5.Asset;
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.annotations.InjectContainer;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Path;
+import org.apache.tapestry5.corelib.components.TextArea;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONObject;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+public class WebEditor {
+
+	@InjectContainer
+	private TextArea field;
+
+	@Parameter(defaultPrefix = BindingConstants.LITERAL)
+	String areaType;
+
+	@Inject
+	private JavaScriptSupport javaScriptSupport;
+
+	@Inject
+	@Path("webeditor-custom.css")
+	private Asset asset;
+
+	public void afterRender() {
+		JSONObject json = new JSONObject();
+		json.put("id", field.getClientId());
+		json.put("csspath", asset.toClientURL());
+		if (areaType.equals("ADMIN")) {
+			javaScriptSupport.require("webeditor-config-admin").with(json);
+		} else {
+			javaScriptSupport.require("webeditor-config").with(json);
+		}
+	}
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/Index.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/Index.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/Index.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -21,16 +21,8 @@
 package info.ajanovski.eprms.tap.pages;
 
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SessionState;
-
 import info.ajanovski.eprms.tap.annotations.PublicPage;
-import info.ajanovski.eprms.tap.util.UserInfo;
 
 @PublicPage
 public class Index {
 
-	@SessionState
-	@Property
-	private UserInfo userInfo;
-
 }
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/pages/Logout.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/Logout.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*******************************************************************************
- * Copyright (C) 2021 Vangel V. Ajanovski
- *     
- * This file is part of the EPRMS - Educational Project and Resource 
- * Management System (hereinafter: EPRMS).
- *     
- * EPRMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *     
- * EPRMS 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 General Public License for more details.
- *     
- * You should have received a copy of the GNU General Public License
- * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
- ******************************************************************************/
-
-package info.ajanovski.eprms.tap.pages;
-
-import org.apache.tapestry5.annotations.Persist;
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.commons.Messages;
-import org.apache.tapestry5.http.services.Context;
-import org.apache.tapestry5.http.services.Request;
-import org.apache.tapestry5.http.services.RequestGlobals;
-import org.apache.tapestry5.http.services.Session;
-import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.services.Cookies;
-import org.slf4j.Logger;
-
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.util.AppConfig;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-@StudentPage
-@InstructorPage
-@AdministratorPage
-public class Logout {
-	@Inject
-	private Logger logger;
-
-	@Inject
-	private Request request;
-
-	@Inject
-	private RequestGlobals requestGlobals;
-
-	@Inject
-	private Cookies cookies;
-
-	@Persist
-	@Property
-	private UserInfo userInfo;
-
-	@Inject
-	private Context ctx;
-
-	@Property
-	private String casServer;
-	@Property
-	private String appServer;
-	@Property
-	private String logoutRedirectToServer;
-
-	@Inject
-	private Messages messages;
-
-	void onActivate() {
-		casServer = ctx.getInitParameter("casServerLogoutUrl");
-		appServer = ctx.getInitParameter("service");
-		logoutRedirectToServer = AppConfig.getString("logout.redirectToServer");
-
-		// Clear session
-		Session session = request.getSession(false);
-		if (session != null) {
-			session.invalidate();
-			userInfo = null;
-			logger.debug("Session successfully invalidated!");
-		}
-
-		clearCookie();
-	}
-
-	private void clearCookie() {
-	}
-
-}
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyDatabases.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyDatabases.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*******************************************************************************
- * Copyright (C) 2021 Vangel V. Ajanovski
- *     
- * This file is part of the EPRMS - Educational Project and Resource 
- * Management System (hereinafter: EPRMS).
- *     
- * EPRMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *     
- * EPRMS 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 General Public License for more details.
- *     
- * You should have received a copy of the GNU General Public License
- * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
- ******************************************************************************/
-
-package info.ajanovski.eprms.tap.pages;
-
-import java.util.List;
-
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SessionState;
-import org.apache.tapestry5.ioc.annotations.Inject;
-
-import info.ajanovski.eprms.model.entities.Database;
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.services.GenericService;
-import info.ajanovski.eprms.tap.services.ResourceManager;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-@StudentPage
-@InstructorPage
-@AdministratorPage
-public class MyDatabases {
-	@Property
-	@SessionState
-	private UserInfo userInfo;
-
-	@Inject
-	private GenericService genericService;
-
-	@Inject
-	private ResourceManager resourceManager;
-
-	@Property
-	private Database database;
-
-	public List<Database> getProjectDatabases() {
-		return resourceManager.getActiveDatabasesByProject(userInfo.getPersonId());
-	}
-
-}
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyProjectReports.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyProjectReports.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,47 +1,0 @@
-package info.ajanovski.eprms.tap.pages;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SessionState;
-
-import info.ajanovski.eprms.model.entities.Activity;
-import info.ajanovski.eprms.model.entities.Project;
-import info.ajanovski.eprms.model.entities.WorkEvaluation;
-import info.ajanovski.eprms.model.entities.WorkReport;
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.services.ProjectManager;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-@StudentPage
-@InstructorPage
-@AdministratorPage
-public class MyProjectReports {
-	@SessionState
-	@Property
-	private UserInfo userInfo;
-
-	@Inject
-	private ProjectManager projectManager;
-
-	public List<Project> getMyProjects() {
-		return projectManager.getProjectByPerson(userInfo.getPersonId());
-	}
-
-	@Property
-	private Project project;
-
-	@Property
-	private Activity activity;
-
-	@Property
-	private WorkReport workReport;
-
-	@Property
-	private WorkEvaluation workEvaluation;
-
-}
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyRepositories.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyRepositories.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*******************************************************************************
- * Copyright (C) 2021 Vangel V. Ajanovski
- *     
- * This file is part of the EPRMS - Educational Project and Resource 
- * Management System (hereinafter: EPRMS).
- *     
- * EPRMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *     
- * EPRMS 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 General Public License for more details.
- *     
- * You should have received a copy of the GNU General Public License
- * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
- ******************************************************************************/
-
-package info.ajanovski.eprms.tap.pages;
-
-import java.util.List;
-
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SessionState;
-import org.apache.tapestry5.ioc.annotations.Inject;
-
-import info.ajanovski.eprms.model.entities.Repository;
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.services.GenericService;
-import info.ajanovski.eprms.tap.services.ResourceManager;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-@StudentPage
-@InstructorPage
-@AdministratorPage
-public class MyRepositories {
-
-	@Property
-	@SessionState
-	private UserInfo userInfo;
-
-	@Inject
-	private GenericService genericService;
-
-	@Inject
-	private ResourceManager resourceManager;
-
-	public List<Repository> getPersonalRepositories() {
-		return resourceManager.getActiveRepositoriesByPerson(userInfo.getPersonId());
-	}
-
-	public List<Repository> getTeamRepositories() {
-		return resourceManager.getActiveRepositoriesByTeam(userInfo.getPersonId());
-	}
-
-	public List<Repository> getProjectRepositories() {
-		return resourceManager.getActiveRepositoriesByProject(userInfo.getPersonId());
-	}
-
-}
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyRepositoryAuth.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/MyRepositoryAuth.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,91 +1,0 @@
-/*******************************************************************************
- * Copyright (C) 2021 Vangel V. Ajanovski
- *     
- * This file is part of the EPRMS - Educational Project and Resource 
- * Management System (hereinafter: EPRMS).
- *     
- * EPRMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *     
- * EPRMS 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 General Public License for more details.
- *     
- * You should have received a copy of the GNU General Public License
- * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
- ******************************************************************************/
-
-package info.ajanovski.eprms.tap.pages;
-
-import java.security.MessageDigest;
-import java.util.Base64;
-
-import javax.validation.constraints.NotNull;
-
-import org.apache.tapestry5.annotations.InjectComponent;
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SessionState;
-import org.apache.tapestry5.corelib.components.Form;
-import org.apache.tapestry5.corelib.components.PasswordField;
-import org.apache.tapestry5.hibernate.annotations.CommitAfter;
-import org.apache.tapestry5.ioc.annotations.Inject;
-
-import info.ajanovski.eprms.model.entities.Person;
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.services.GenericService;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-@StudentPage
-@InstructorPage
-@AdministratorPage
-public class MyRepositoryAuth {
-
-	@Property
-	@SessionState
-	private UserInfo userInfo;
-
-	@Inject
-	private GenericService genericService;
-
-	@Property
-	@NotNull
-	private String password;
-
-	@Property
-	@NotNull
-	private String confirmPassword;
-
-	@InjectComponent("AuthForm")
-	private Form authForm;
-
-	@InjectComponent("confirmPassword")
-	private PasswordField pfConfirmPassword;
-
-	public void onValidateFromAuthForm() {
-		if (password != null && confirmPassword != null && !password.equals(confirmPassword)) {
-			authForm.recordError(pfConfirmPassword, "Enter two identical and non-empty passwords.");
-		}
-	}
-
-	@CommitAfter
-	public void onSuccessFromAuthForm() {
-		if (password != null && confirmPassword != null && password.equals(confirmPassword)) {
-			Person myself = genericService.getByPK(Person.class, userInfo.getPersonId());
-			try {
-				MessageDigest md = MessageDigest.getInstance("SHA-1");
-				md.reset();
-				md.update(password.getBytes("UTF-8"));
-				myself.setAuthString("{SHA}" + Base64.getEncoder().encodeToString(md.digest()));
-				genericService.save(myself);
-			} catch (Exception e) {
-				System.out.println(e);
-			}
-		}
-	}
-
-}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,85 @@
+package info.ajanovski.eprms.tap.pages.admin;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.tapestry5.SelectModel;
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.corelib.components.Zone;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.apache.tapestry5.services.SelectModelFactory;
+
+import info.ajanovski.eprms.model.entities.ActivityType;
+import info.ajanovski.eprms.model.util.ActivityTypeHierarchicalComparator;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+
+@AdministratorPage
+@InstructorPage
+public class ManageActivityTypes {
+
+	@Persist
+	@Property
+	private ActivityType newActivityType;
+
+	@Property
+	private ActivityType activityType;
+
+	@Property
+	private ActivityType activityType2;
+
+	@Inject
+	private GenericService genericService;
+
+	public void onActionFromNewActivityType() {
+		newActivityType = new ActivityType();
+	}
+
+	public void onActionFromEditActivityType(ActivityType at) {
+		newActivityType = at;
+	}
+
+	@InjectComponent
+	private Zone zoneActivityTypes;
+
+	@CommitAfter
+	public void onSuccessFromNewActivityTypeForm() {
+		genericService.saveOrUpdate(newActivityType);
+		newActivityType = null;
+	}
+
+	@Inject
+	private SelectModelFactory selectModelFactory;
+
+	public SelectModel getListTypes() {
+		return selectModelFactory.create(genericService.getAll(ActivityType.class), "title");
+	}
+
+	public List<ActivityType> getAllActivityTypes() {
+		ActivityTypeHierarchicalComparator athc = new ActivityTypeHierarchicalComparator();
+		List<ActivityType> lista = (List<ActivityType>) genericService.getAll(ActivityType.class);
+		lista.sort(athc);
+		return lista;
+	}
+
+	@Persist
+	@Property
+	private ActivityType selectedActivityType;
+
+	public Long getDepth(ActivityType at) {
+		if (at.getSuperActivityType() != null) {
+			return getDepth(at.getSuperActivityType()) + 1;
+		} else {
+			return 0L;
+		}
+	}
+
+	public long getHierarchicalDepth() {
+		return (3*getDepth(activityType));
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManagePersons.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManagePersons.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManagePersons.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,143 @@
+package info.ajanovski.eprms.tap.pages.admin;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.corelib.components.Form;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.slf4j.Logger;
+
+import info.ajanovski.eprms.model.entities.Person;
+import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.entities.Role;
+import info.ajanovski.eprms.model.util.ModelConstants;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.services.PersonManager;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@AdministratorPage
+public class ManagePersons {
+
+	@SessionState
+	private UserInfo userInfo;
+
+	@Inject
+	private PersonManager personManager;
+
+	@Inject
+	private GenericService genericService;
+
+	@Inject
+	private Logger logger;
+
+	@Property
+	private Person person;
+
+	@Property
+	@Persist
+	private String personListToImport;
+
+	public List<Person> getAllPersons() {
+		return personManager.getAllPersons();
+	}
+
+	public void onActionFromImportPersons() {
+		personListToImport = "firstName,lastName,email,userName";
+	}
+
+	@InjectComponent
+	private Form frmImport;
+
+	@Persist
+	@Property
+	private String errors;
+
+	@CommitAfter
+	public void onSuccessFromFrmImport() {
+		if (personListToImport != null) {
+			errors = new String();
+			Role r = (Role) genericService.getAll(Role.class).stream()
+					.filter(role -> ((Role) role).getName().equals(ModelConstants.RoleStudent)).findFirst().get();
+			if (r != null) {
+				for (String line : personListToImport.split("\\r?\\n")) {
+					logger.info(">>> Importing {} <<<", line);
+					String[] lineFields = line.split("[,\t]");
+					Person p;
+					try {
+						p = personManager.getPersonByUsername(lineFields[3]);
+						if (p != null) {
+							errors += ">>> Person " + p.getUserName() + " already exists, skipping.";
+						} else {
+							p = new Person();
+							p.setFirstName(lineFields[0]);
+							p.setLastName(lineFields[1]);
+							p.setEmail(lineFields[2]);
+							p.setUserName(lineFields[3]);
+							genericService.save(p);
+							PersonRole pr = new PersonRole();
+							pr.setPerson(p);
+							pr.setRole(r);
+							genericService.save(pr);
+						}
+					} catch (Exception e) {
+						errors += ">>> Person " + lineFields[3] + " can not be imported due to: "
+								+ e.getLocalizedMessage();
+					}
+				}
+			} else {
+				errors += "Role STUDENT does not exist";
+			}
+			if (!(errors.length() > 0)) {
+				errors = "OK";
+			}
+		}
+	}
+
+	@CommitAfter
+	public void onActionFromDeletePerson(Person p) {
+		for (PersonRole pr : personManager.getPersonRolesForPerson(p.getPersonId())) {
+			genericService.delete(pr);
+		}
+		genericService.delete(p);
+	}
+
+	@Persist
+	@Property
+	private Person personToEdit;
+
+	public void onActionFromNewPerson() {
+		personToEdit = new Person();
+	}
+
+	public void onActionFromEditPerson(Person p) {
+		personToEdit = p;
+	}
+
+	@CommitAfter
+	public void saveChanges() {
+		genericService.saveOrUpdate(personToEdit);
+	}
+
+	private Boolean cancelForm = false;
+
+	public void onCanceledFromFrmNewPerson() {
+		cancelForm = true;
+	}
+
+	public void onValidateFromFrmNewPerson() {
+		if (!cancelForm) {
+			saveChanges();
+		}
+	}
+
+	public void onSuccessFromFrmNewPerson() {
+		personToEdit = null;
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageProjects.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageProjects.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ManageProjects.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -33,4 +33,5 @@
 import org.apache.tapestry5.hibernate.annotations.CommitAfter;
 import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.PersistentLocale;
 import org.apache.tapestry5.services.SelectModelFactory;
 
@@ -44,8 +45,11 @@
 import info.ajanovski.eprms.model.entities.Team;
 import info.ajanovski.eprms.model.entities.TeamMember;
+import info.ajanovski.eprms.mq.MessagingService;
 import info.ajanovski.eprms.tap.annotations.AdministratorPage;
 import info.ajanovski.eprms.tap.annotations.InstructorPage;
 import info.ajanovski.eprms.tap.services.GenericService;
 import info.ajanovski.eprms.tap.services.ProjectManager;
+import info.ajanovski.eprms.tap.services.TranslationService;
+import info.ajanovski.eprms.tap.util.AppConfig;
 import info.ajanovski.eprms.tap.util.UserInfo;
 
@@ -61,5 +65,74 @@
 
 	@Inject
+	private MessagingService messagingService;
+
+	@Inject
 	private GenericService genericService;
+
+	@Inject
+	private SelectModelFactory selectModelFactory;
+
+	@Inject
+	private TranslationService translationService;
+
+	@Inject
+	private PersistentLocale persistentLocale;
+
+	@Inject
+	private Messages messages;
+
+	@Property
+	private Project project;
+
+	@Persist
+	@Property
+	private Project selectedProject;
+
+	@Property
+	private Responsibility responsibility;
+
+	@Property
+	private TeamMember teamMember;
+
+	@Property
+	private Database database;
+
+	@Property
+	private Repository repository;
+
+	@Persist
+	@Property
+	private TeamMember newTm;
+
+	@Persist
+	@Property
+	private Project newProject;
+
+	@Persist
+	@Property
+	private Team newTeam;
+
+	@Persist
+	@Property
+	private Responsibility newResponsibility;
+
+	@Persist
+	@Property
+	private Database newDb;
+
+	@Persist
+	@Property
+	private Repository newRp;
+
+	@Persist
+	@Property
+	private List<Course> inCourses;
+
+	@Persist
+	@Property
+	private Project copyActivitiesFromProject;
+
+	void onActivate() {
+	}
 
 	public List<Project> getAllProjects() {
@@ -77,47 +150,4 @@
 	}
 
-	@Property
-	private Project project;
-
-	@Persist
-	@Property
-	private Project selectedProject;
-
-	@Property
-	private Responsibility responsibility;
-
-	@Property
-	private TeamMember teamMember;
-
-	@Property
-	private Database database;
-
-	@Property
-	private Repository repository;
-
-	@Persist
-	@Property
-	private TeamMember newTm;
-
-	@Persist
-	@Property
-	private Project newProject;
-
-	@Persist
-	@Property
-	private Team newTeam;
-
-	@Persist
-	@Property
-	private Responsibility newResponsibility;
-
-	@Persist
-	@Property
-	private Database newDb;
-
-	@Persist
-	@Property
-	private Repository newRp;
-
 	public void onActionFromAddTeamMember(Team t) {
 		newTm = new TeamMember();
@@ -127,4 +157,5 @@
 	public void onActionFromNewProject() {
 		newProject = new Project();
+		inCourses = new ArrayList<Course>();
 	}
 
@@ -155,11 +186,4 @@
 		return (List<Course>) genericService.getAll(Course.class);
 	}
-
-	@Persist
-	@Property
-	private List<Course> inCourses;
-
-	@Inject
-	private Messages messages;
 
 	public SelectModel getCoursesModel() {
@@ -210,4 +234,6 @@
 	public void onSuccessFromNewDatabaseForm() {
 		genericService.save(newDb);
+		messagingService.setupMQHost(AppConfig.getString("MQHost"));
+		messagingService.sendDatabaseNotification(newDb);
 		newDb = null;
 	}
@@ -216,4 +242,6 @@
 	public void onSuccessFromNewRepositoryForm() {
 		genericService.save(newRp);
+		messagingService.setupMQHost(AppConfig.getString("MQHost"));
+		messagingService.sendRepositoryNotification(newRp);
 		newRp = null;
 	}
@@ -225,7 +253,4 @@
 		return (List<Person>) genericService.getAll(Person.class);
 	}
-
-	@Inject
-	private SelectModelFactory selectModelFactory;
 
 	public SelectModel getPersonModel() {
@@ -244,8 +269,4 @@
 				.collect(Collectors.toList());
 	}
-
-	@Persist
-	@Property
-	private Project copyActivitiesFromProject;
 
 	public void onActionFromCopyActivities(Project p) {
@@ -272,3 +293,23 @@
 	}
 
+	public String getCourseTitle() {
+		String trans = translationService.getTranslation(Course.class.getSimpleName(), "title", course.getCourseId(),
+				persistentLocale.get().getLanguage());
+		if (trans == null) {
+			return course.getTitle();
+		} else {
+			return trans;
+		}
+	}
+
+	@CommitAfter
+	void onActionFromDeleteResponsibility(Responsibility r) {
+		Team t = r.getTeam();
+		genericService.delete(r);
+		genericService.delete(t);
+	}
+
+	void onActionFromEditTeam(Team t) {
+		newTeam = t;
+	}
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -1,27 +1,41 @@
 package info.ajanovski.eprms.tap.pages.admin;
 
+import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.tapestry5.SelectModel;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.InjectComponent;
 import org.apache.tapestry5.annotations.Persist;
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.corelib.components.Zone;
 import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.apache.tapestry5.http.services.Request;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.services.SelectModelFactory;
+import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
+import org.slf4j.Logger;
 
 import info.ajanovski.eprms.model.entities.Activity;
 import info.ajanovski.eprms.model.entities.Course;
+import info.ajanovski.eprms.model.entities.CourseActivityType;
+import info.ajanovski.eprms.model.entities.Person;
 import info.ajanovski.eprms.model.entities.Project;
 import info.ajanovski.eprms.model.entities.WorkEvaluation;
 import info.ajanovski.eprms.model.entities.WorkReport;
+import info.ajanovski.eprms.model.util.ModelConstants;
+import info.ajanovski.eprms.mq.MessagingService;
 import info.ajanovski.eprms.tap.annotations.AdministratorPage;
 import info.ajanovski.eprms.tap.annotations.InstructorPage;
 import info.ajanovski.eprms.tap.services.GenericService;
 import info.ajanovski.eprms.tap.services.ProjectManager;
+import info.ajanovski.eprms.tap.util.AppConfig;
 import info.ajanovski.eprms.tap.util.UserInfo;
 
 @InstructorPage
 @AdministratorPage
+@Import(module = { "bootstrap/modal", "bootstrap/collapse", "zoneUpdateEffect" })
 public class OverallCourseReport {
 	@SessionState
@@ -30,14 +44,31 @@
 
 	@Inject
+	private Logger logger;
+
+	@Inject
 	private ProjectManager projectManager;
+
+	@Inject
+	private MessagingService messagingService;
 
 	@Inject
 	private GenericService genericService;
 
+	@Inject
+	private Request request;
+
+	@Inject
+	private AjaxResponseRenderer ajaxResponseRenderer;
+
+	@InjectComponent
+	private Zone zNewWorkReportModal, zNewWorkEvaluationModal;
+
 	public List<Project> getAllProjects() {
 		if (selectedCourse == null) {
-			return (List<Project>) projectManager.getAllProjectsOrderByTitle();
+			return ((List<Project>) projectManager.getAllProjectsOrderByTitle()).stream()
+					.filter(c -> c.getStatus() != null && c.getStatus().equals("Active")).collect(Collectors.toList());
 		} else {
-			return (List<Project>) projectManager.getCourseProjectsOrderByTitle(selectedCourse);
+			return ((List<Project>) projectManager.getCourseProjectsOrderByTitle(selectedCourse)).stream()
+					.filter(c -> c.getStatus() != null && c.getStatus().equals("Active")).collect(Collectors.toList());
 		}
 	}
@@ -46,8 +77,16 @@
 	private Project project;
 
+	public Activity getActivity() {
+		return project.getActivities().stream().filter(a -> a.getActivityType()
+				.getActivityTypeId() == courseActivityType.getActivityType().getActivityTypeId()).findFirst()
+				.orElse(null);
+	}
+
 	@Property
-	private Activity activity;
+	private CourseActivityType courseActivityType;
+
 	@Property
 	private WorkReport workReport;
+
 	@Property
 	private WorkEvaluation workEvaluation;
@@ -61,4 +100,7 @@
 		newWorkReport = new WorkReport();
 		newWorkReport.setActivity(a);
+		if (request.isXHR()) {
+			ajaxResponseRenderer.addRender(zNewWorkReportModal);
+		}
 	}
 
@@ -77,5 +119,10 @@
 		newWorkReport = null;
 		newWorkEvaluation = new WorkEvaluation();
+		newWorkEvaluation.setEvaluationDate(new Date());
+		newWorkEvaluation.setPerson(genericService.getByPK(Person.class, userInfo.getPersonId()));
 		newWorkEvaluation.setWorkReport(wr);
+		if (request.isXHR()) {
+			ajaxResponseRenderer.addRender(zNewWorkEvaluationModal);
+		}
 	}
 
@@ -83,4 +130,17 @@
 		newWorkReport = null;
 		newWorkEvaluation = wa;
+		if (request.isXHR()) {
+			ajaxResponseRenderer.addRender(zNewWorkEvaluationModal);
+		}
+	}
+
+	@CommitAfter
+	public void onActionFromToggleWorkEvaluationStatus(WorkEvaluation wa) {
+		if (wa.getStatus().equals(ModelConstants.EvaluationStatusCreated)) {
+			wa.setStatus(ModelConstants.EvaluationStatusPublished);
+		} else {
+			wa.setStatus(ModelConstants.EvaluationStatusCreated);
+		}
+		genericService.saveOrUpdate(wa);
 	}
 
@@ -88,4 +148,5 @@
 	public void onSuccessFromFrmAddWorkEvaluation() {
 		genericService.saveOrUpdate(newWorkEvaluation);
+		messagingService.sendWorkEvaluationNotification(newWorkEvaluation);
 		newWorkReport = null;
 		newWorkEvaluation = null;
@@ -111,3 +172,10 @@
 	private Course selectedCourse;
 
+	public void onActivate() {
+		if (selectedCourse != null) {
+			selectedCourse = genericService.getByPK(Course.class, selectedCourse.getCourseId());
+		}
+		messagingService.setupMQHost(AppConfig.getString("MQHost"));
+	}
+
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,50 @@
+package info.ajanovski.eprms.tap.pages.admin;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+import info.ajanovski.eprms.model.entities.Project;
+import info.ajanovski.eprms.model.entities.Responsibility;
+import info.ajanovski.eprms.model.entities.TeamMember;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@InstructorPage
+@AdministratorPage
+public class ProjectAutomation {
+	@SessionState
+	@Property
+	private UserInfo userInfo;
+
+	@Inject
+	private GenericService genericService;
+
+	@Property
+	private Project project;
+
+	@Property
+	private Responsibility responsibility;
+
+	@Property
+	private TeamMember member;
+
+	public List<Project> getProjects() {
+		return ((List<Project>) genericService.getAll(Project.class)).stream()
+				.filter(p -> p.getStatus() != null && p.getStatus().equals("Creation")).collect(Collectors.toList());
+	}
+
+	@CommitAfter
+	public void onActionFromActivateAllListed() {
+		for (Project p : getProjects()) {
+			p.setStatus("Active");
+		}
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Login.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Login.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Login.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,20 @@
+package info.ajanovski.eprms.tap.pages.user;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class Login {
+
+	@SessionState
+	@Property
+	private UserInfo userInfo;
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Logout.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Logout.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/Logout.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.pages.user;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.commons.Messages;
+import org.apache.tapestry5.http.services.Request;
+import org.apache.tapestry5.http.services.RequestGlobals;
+import org.apache.tapestry5.http.services.Session;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.Cookies;
+import org.slf4j.Logger;
+
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.util.AppConfig;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class Logout {
+	@Inject
+	private Logger logger;
+
+	@Inject
+	private Request request;
+
+	@Inject
+	private RequestGlobals requestGlobals;
+
+	@Inject
+	private Cookies cookies;
+
+	@Persist
+	@Property
+	private UserInfo userInfo;
+
+	@Property
+	private String casLogoutLink;
+
+	@Inject
+	private Messages messages;
+
+	void onActivate() {
+		casLogoutLink = AppConfig.getString("cas.server") + "/cas/logout?service=" + AppConfig.getString("app.server");
+
+		// Clear session
+		Session session = request.getSession(false);
+		if (session != null) {
+			session.invalidate();
+			userInfo = null;
+			logger.debug("Session successfully invalidated!");
+		}
+
+		clearCookie();
+	}
+
+	private void clearCookie() {
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyDatabases.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyDatabases.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyDatabases.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.pages.user;
+
+import java.util.List;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+import info.ajanovski.eprms.model.entities.Database;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.services.ResourceManager;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class MyDatabases {
+	@Property
+	@SessionState
+	private UserInfo userInfo;
+
+	@Inject
+	private GenericService genericService;
+
+	@Inject
+	private ResourceManager resourceManager;
+
+	@Property
+	private Database database;
+
+	public List<Database> getProjectDatabases() {
+		return resourceManager.getActiveDatabasesByProject(userInfo.getPersonId());
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProfile.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProfile.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProfile.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.pages.user;
+
+import javax.inject.Inject;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+
+import info.ajanovski.eprms.model.entities.Person;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class MyProfile {
+
+	@SessionState
+	@Property
+	private UserInfo userInfo;
+
+	@Inject
+	private GenericService genericService;
+
+	public Person getPerson() {
+		return genericService.getByPK(Person.class, userInfo.getPersonId());
+	}
+
+	@Persist
+	@Property
+	private Person editPerson;
+
+	public void onActionFromEditProfile() {
+		editPerson = getPerson();
+	}
+
+	@CommitAfter
+	public void onSuccessFromFrmEditPerson() {
+		genericService.saveOrUpdate(editPerson);
+		editPerson=null;
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProjectReports.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProjectReports.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyProjectReports.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,132 @@
+package info.ajanovski.eprms.tap.pages.user;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.corelib.components.Zone;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.apache.tapestry5.http.services.Request;
+import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
+import org.slf4j.Logger;
+
+import info.ajanovski.eprms.model.entities.Activity;
+import info.ajanovski.eprms.model.entities.Person;
+import info.ajanovski.eprms.model.entities.Project;
+import info.ajanovski.eprms.model.entities.WorkEvaluation;
+import info.ajanovski.eprms.model.entities.WorkReport;
+import info.ajanovski.eprms.model.util.ActivityComparatorViaType;
+import info.ajanovski.eprms.model.util.ModelConstants;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.services.ProjectManager;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+@Import(module = { "bootstrap/modal", "bootstrap/collapse", "zoneUpdateEffect" })
+public class MyProjectReports {
+	@SessionState
+	@Property
+	private UserInfo userInfo;
+
+	@Inject
+	private Logger logger;
+
+	@Inject
+	private Request request;
+
+	@Inject
+	private AjaxResponseRenderer ajaxResponseRenderer;
+
+	@InjectComponent
+	private Zone zModal;
+
+	@Inject
+	private ProjectManager projectManager;
+
+	@Inject
+	private GenericService genericService;
+
+	public List<Project> getMyProjects() {
+		return projectManager.getProjectByPerson(userInfo.getPersonId());
+	}
+
+	@Property
+	private Project project;
+
+	@Property
+	private Activity activity;
+
+	@Property
+	private WorkReport workReport;
+
+	@Property
+	private WorkEvaluation workEvaluation;
+
+	@Persist
+	@Property
+	private WorkReport newWorkReport;
+
+	public void onActionFromAddReport(Activity a) {
+		newWorkReport = new WorkReport();
+		newWorkReport.setPerson(genericService.getByPK(Person.class, userInfo.getPersonId()));
+		newWorkReport.setActivity(a);
+		newWorkReport.setSubmissionDate(new Date());
+	}
+
+	@CommitAfter
+	private void saveChangesToReport() {
+		genericService.saveOrUpdate(newWorkReport);
+	}
+
+	private Boolean cancelForm = false;
+
+	public void onCanceledFromFrmNewWorkReport() {
+		cancelForm = true;
+	}
+
+	public void onValidateFromFrmNewWorkReport() {
+		if (!cancelForm) {
+			saveChangesToReport();
+		}
+	}
+
+	public void onSuccessFromFrmNewWorkReport() {
+		newWorkReport = null;
+		if (request.isXHR()) {
+			ajaxResponseRenderer.addRender(zModal);
+		}
+	}
+
+	public void onActionFromEditWorkReport(WorkReport wr) {
+		newWorkReport = wr;
+	}
+
+	@CommitAfter
+	public void onActionFromDeleteWorkReport(WorkReport wr) {
+		genericService.delete(wr);
+		newWorkReport = null;
+	}
+
+	public List<Activity> getProjectActivities() {
+		ActivityComparatorViaType acr = new ActivityComparatorViaType();
+		List<Activity> lista = project.getActivities();
+		lista.sort(acr);
+		return lista;
+	}
+
+	public boolean isEvaluationPublished() {
+		return workEvaluation.getStatus().equals(ModelConstants.EvaluationStatusPublished);
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositories.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositories.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositories.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.pages.user;
+
+import java.util.List;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+import info.ajanovski.eprms.model.entities.Repository;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.services.ResourceManager;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class MyRepositories {
+
+	@Property
+	@SessionState
+	private UserInfo userInfo;
+
+	@Inject
+	private GenericService genericService;
+
+	@Inject
+	private ResourceManager resourceManager;
+
+	public List<Repository> getPersonalRepositories() {
+		return resourceManager.getActiveRepositoriesByPerson(userInfo.getPersonId());
+	}
+
+	public List<Repository> getTeamRepositories() {
+		return resourceManager.getActiveRepositoriesByTeam(userInfo.getPersonId());
+	}
+
+	public List<Repository> getProjectRepositories() {
+		return resourceManager.getActiveRepositoriesByProject(userInfo.getPersonId());
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.pages.user;
+
+import java.security.MessageDigest;
+import java.util.Base64;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.corelib.components.Form;
+import org.apache.tapestry5.corelib.components.PasswordField;
+import org.apache.tapestry5.hibernate.annotations.CommitAfter;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+import info.ajanovski.eprms.model.entities.Person;
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.services.GenericService;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+@StudentPage
+@InstructorPage
+@AdministratorPage
+public class MyRepositoryAuth {
+
+	@Property
+	@SessionState
+	private UserInfo userInfo;
+
+	@Inject
+	private GenericService genericService;
+
+	@Property
+	private String password;
+
+	@Property
+	private String confirmPassword;
+
+	@InjectComponent("AuthForm")
+	private Form authForm;
+
+	@InjectComponent("confirmPassword")
+	private PasswordField pfConfirmPassword;
+
+	public void onValidateFromAuthForm() {
+		if (password != null && confirmPassword != null && !password.equals(confirmPassword)) {
+			authForm.recordError(pfConfirmPassword, "Enter two identical and non-empty passwords.");
+		}
+	}
+
+	@CommitAfter
+	public void onSuccessFromAuthForm() {
+		if (password != null && confirmPassword != null && password.equals(confirmPassword)) {
+			Person myself = genericService.getByPK(Person.class, userInfo.getPersonId());
+			try {
+				MessageDigest md = MessageDigest.getInstance("SHA-1");
+				md.reset();
+				md.update(password.getBytes("UTF-8"));
+				myself.setAuthString("{SHA}" + Base64.getEncoder().encodeToString(md.digest()));
+				genericService.save(myself);
+			} catch (Exception e) {
+				System.out.println(e);
+			}
+		}
+	}
+
+}
Index: rms-tap/src/main/java/info/ajanovski/eprms/tap/services/AccessController.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AccessController.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,139 +1,0 @@
-/*******************************************************************************
- * Copyright (C) 2021 Vangel V. Ajanovski
- *     
- * This file is part of the EPRMS - Educational Project and Resource 
- * Management System (hereinafter: EPRMS).
- *     
- * EPRMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *     
- * EPRMS 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 General Public License for more details.
- *     
- * You should have received a copy of the GNU General Public License
- * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
- ******************************************************************************/
-
-package info.ajanovski.eprms.tap.services;
-
-import java.io.IOException;
-
-import org.apache.tapestry5.http.services.Response;
-import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.ApplicationStateManager;
-import org.apache.tapestry5.services.ComponentEventRequestParameters;
-import org.apache.tapestry5.services.ComponentRequestFilter;
-import org.apache.tapestry5.services.ComponentRequestHandler;
-import org.apache.tapestry5.services.ComponentSource;
-import org.apache.tapestry5.services.PageRenderLinkSource;
-import org.apache.tapestry5.services.PageRenderRequestParameters;
-import org.slf4j.Logger;
-
-import info.ajanovski.eprms.tap.annotations.AdministratorPage;
-import info.ajanovski.eprms.tap.annotations.InstructorPage;
-import info.ajanovski.eprms.tap.annotations.PublicPage;
-import info.ajanovski.eprms.tap.annotations.StudentPage;
-import info.ajanovski.eprms.tap.pages.Index;
-import info.ajanovski.eprms.tap.util.AppConstants;
-import info.ajanovski.eprms.tap.util.UserInfo;
-
-public class AccessController implements ComponentRequestFilter {
-
-	private ApplicationStateManager applicationStateManager;
-	private final ComponentSource componentSource;
-
-	@Inject
-	private Logger logger;
-
-	@Inject
-	private Response response;
-
-	@Inject
-	private PageRenderLinkSource linkSource;
-
-	public AccessController(ApplicationStateManager asm, ComponentSource componentSource) {
-		this.applicationStateManager = asm;
-		this.componentSource = componentSource;
-	}
-
-	public boolean checkAccess(String pageName) throws IOException {
-		boolean hasAccessAnnotation = false;
-		logger.debug("check access for {}", pageName);
-		if (pageName.equals("") || pageName.equals("/")) {
-			pageName = AppConstants.PageIndex;
-		}
-
-		Component page = null;
-		page = componentSource.getPage(pageName);
-
-		boolean publicPage = page.getClass().getAnnotation(PublicPage.class) != null;
-		boolean studentPage = page.getClass().getAnnotation(StudentPage.class) != null;
-		boolean instructorPage = page.getClass().getAnnotation(InstructorPage.class) != null;
-		boolean adminPage = page.getClass().getAnnotation(AdministratorPage.class) != null;
-
-		hasAccessAnnotation = publicPage | studentPage | instructorPage | adminPage;
-		UserInfo userInfo = applicationStateManager.getIfExists(UserInfo.class);
-
-		boolean canAccess = false;
-		if (publicPage) {
-			logger.debug("Accessing a public page.");
-			canAccess = true;
-		} else {
-			if (userInfo == null) {
-				logger.debug("UserInfo is null");
-			} else {
-				logger.debug("userInfo is not null");
-				if (studentPage) {
-					logger.debug("studentPage");
-					canAccess = canAccess || userInfo.isStudent();
-				}
-				if (adminPage) {
-					logger.debug("adminPage");
-					canAccess = canAccess || userInfo.isAdministrator();
-				}
-			}
-		}
-
-		if (canAccess && hasAccessAnnotation) {
-			logger.debug("checkAccess: ACCESS GRANTED to page:{} canaccess:{} hasaccessannotation:{} ", pageName,
-					canAccess, hasAccessAnnotation);
-			return true;
-		} else {
-			logger.debug("checkAccess: ACCESS DENIED to page:{} canaccess:{} hasaccessannotation:{} ", pageName,
-					canAccess, hasAccessAnnotation);
-			return false;
-		}
-	}
-
-	@Override
-	public void handleComponentEvent(ComponentEventRequestParameters parameters, ComponentRequestHandler handler)
-			throws IOException {
-		boolean accessOK = checkAccess(parameters.getContainingPageName());
-		if (accessOK) {
-			handler.handleComponentEvent(parameters);
-		} else {
-			logger.error("handleComponentEvent: ACCESS DENIED TO {} {} {}", parameters.getEventType(),
-					parameters.getNestedComponentId(), parameters.getContainingPageName());
-
-			response.sendRedirect(linkSource.createPageRenderLink(Index.class));
-		}
-	}
-
-	@Override
-	public void handlePageRender(PageRenderRequestParameters parameters, ComponentRequestHandler handler)
-			throws IOException {
-		boolean accessOK = checkAccess(parameters.getLogicalPageName());
-		if (accessOK) {
-			handler.handlePageRender(parameters);
-		} else {
-			logger.error("handlePageRender: ACCESS DENIED TO {}", parameters.getLogicalPageName());
-
-			response.sendRedirect(linkSource.createPageRenderLink(Index.class));
-		}
-	}
-}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AccessControllerRequestFilter.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AccessControllerRequestFilter.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AccessControllerRequestFilter.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the EPRMS - Educational Project and Resource 
+ * Management System (hereinafter: EPRMS).
+ *     
+ * EPRMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *     
+ * EPRMS 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 General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License
+ * along with EPRMS.  If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+
+package info.ajanovski.eprms.tap.services;
+
+import java.io.IOException;
+
+import org.apache.tapestry5.http.services.Response;
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.services.ApplicationStateManager;
+import org.apache.tapestry5.services.ComponentEventRequestParameters;
+import org.apache.tapestry5.services.ComponentRequestFilter;
+import org.apache.tapestry5.services.ComponentRequestHandler;
+import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.PageRenderLinkSource;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
+import org.slf4j.Logger;
+
+import info.ajanovski.eprms.tap.annotations.AdministratorPage;
+import info.ajanovski.eprms.tap.annotations.InstructorPage;
+import info.ajanovski.eprms.tap.annotations.PublicPage;
+import info.ajanovski.eprms.tap.annotations.StudentPage;
+import info.ajanovski.eprms.tap.pages.Index;
+import info.ajanovski.eprms.tap.util.AppConstants;
+import info.ajanovski.eprms.tap.util.UserInfo;
+
+public class AccessControllerRequestFilter implements ComponentRequestFilter {
+
+	private final ApplicationStateManager applicationStateManager;
+	private final ComponentSource componentSource;
+	private final Logger logger;
+
+	private Response response;
+	private PageRenderLinkSource linkSource;
+
+	public AccessControllerRequestFilter(final ApplicationStateManager asm, final ComponentSource componentSource,
+			final Logger logger) {
+		logger.info("AccessController ComponentRequestFilter constructor");
+		this.applicationStateManager = asm;
+		this.componentSource = componentSource;
+		this.logger = logger;
+	}
+
+	@Override
+	public void handleComponentEvent(ComponentEventRequestParameters parameters, ComponentRequestHandler handler)
+			throws IOException {
+		logger.debug("handleComponentEvent entered");
+		boolean accessOK = checkAccess(parameters.getActivePageName());
+		if (accessOK) {
+			logger.debug("handleComponentEvent access granted");
+			handler.handleComponentEvent(parameters);
+		} else {
+			logger.error("handleComponentEvent: ACCESS DENIED TO {} {} {}", parameters.getEventType(),
+					parameters.getNestedComponentId(), parameters.getContainingPageName());
+			response.sendRedirect(linkSource.createPageRenderLink(Index.class));
+		}
+	}
+
+	@Override
+	public void handlePageRender(PageRenderRequestParameters parameters, ComponentRequestHandler handler)
+			throws IOException {
+		logger.debug("handlePageRender entered");
+		boolean accessOK = checkAccess(parameters.getLogicalPageName());
+		if (accessOK) {
+			logger.debug("handlePageRender access denied");
+			handler.handlePageRender(parameters);
+		} else {
+			logger.error("handlePageRender: ACCESS DENIED TO {}", parameters.getLogicalPageName());
+			response.sendRedirect(linkSource.createPageRenderLink(Index.class));
+		}
+	}
+
+	public boolean checkAccess(String pageName) throws IOException {
+		boolean hasAccessAnnotation = false;
+		logger.debug("checkAccess: page {}", pageName);
+		if (pageName.equals("") || pageName.equals("/")) {
+			pageName = AppConstants.PageIndex;
+		}
+
+		Component page = null;
+		page = componentSource.getPage(pageName);
+
+		boolean publicPage = page.getClass().isAnnotationPresent(PublicPage.class);
+		boolean studentPage = page.getClass().isAnnotationPresent(StudentPage.class);
+		boolean instructorPage = page.getClass().isAnnotationPresent(InstructorPage.class);
+		boolean adminPage = page.getClass().isAnnotationPresent(AdministratorPage.class);
+
+		hasAccessAnnotation = publicPage | studentPage | instructorPage | adminPage;
+		logger.debug("checkAccess: page has access annotation: {}", hasAccessAnnotation);
+
+		boolean canAccess = false;
+		if (publicPage) {
+			logger.debug("checkAccess: Accessing a public page.");
+			canAccess = true;
+		} else {
+			logger.debug("checkAccess: Accessing a not for public page.");
+			UserInfo userInfo = applicationStateManager.getIfExists(UserInfo.class);
+			if (userInfo == null) {
+				logger.debug("checkAccess: UserInfo is null");
+			} else {
+				logger.debug("checkAccess: userInfo is not null");
+				if (studentPage) {
+					logger.debug("checkAccess: studentPage");
+					canAccess = canAccess || userInfo.isStudent();
+				}
+				if (adminPage) {
+					logger.debug("checkAccess: adminPage");
+					canAccess = canAccess || userInfo.isAdministrator();
+				}
+			}
+		}
+
+		if (canAccess && hasAccessAnnotation) {
+			logger.debug("checkAccess: ACCESS GRANTED to page:{} canaccess:{} hasaccessannotation:{} ", pageName,
+					canAccess, hasAccessAnnotation);
+			return true;
+		} else {
+			logger.info("checkAccess: ACCESS DENIED to page:{} canaccess:{} hasaccessannotation:{} ", pageName,
+					canAccess, hasAccessAnnotation);
+			return false;
+		}
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AppModule.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AppModule.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/AppModule.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -21,5 +21,7 @@
 package info.ajanovski.eprms.tap.services;
 
-import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
 import java.util.UUID;
 
@@ -29,20 +31,27 @@
 import org.apache.tapestry5.commons.OrderedConfiguration;
 import org.apache.tapestry5.hibernate.HibernateEntityPackageManager;
-import org.apache.tapestry5.http.services.Request;
-import org.apache.tapestry5.http.services.RequestFilter;
-import org.apache.tapestry5.http.services.RequestHandler;
-import org.apache.tapestry5.http.services.Response;
+import org.apache.tapestry5.hibernate.HibernateTransactionAdvisor;
+import org.apache.tapestry5.http.services.RequestGlobals;
+import org.apache.tapestry5.ioc.MethodAdviceReceiver;
 import org.apache.tapestry5.ioc.ServiceBinder;
 import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Decorate;
 import org.apache.tapestry5.ioc.annotations.ImportModule;
-import org.apache.tapestry5.ioc.annotations.Local;
-import org.apache.tapestry5.ioc.services.ApplicationDefaults;
-import org.apache.tapestry5.ioc.services.SymbolProvider;
+import org.apache.tapestry5.ioc.annotations.Match;
+import org.apache.tapestry5.ioc.services.ThreadLocale;
 import org.apache.tapestry5.modules.Bootstrap4Module;
+import org.apache.tapestry5.services.ApplicationStateContribution;
+import org.apache.tapestry5.services.ApplicationStateCreator;
 import org.apache.tapestry5.services.ApplicationStateManager;
 import org.apache.tapestry5.services.ComponentRequestFilter;
 import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.PersistentLocale;
+import org.hibernate.Session;
 import org.slf4j.Logger;
 
+import info.ajanovski.eprms.model.entities.Person;
+import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.util.ModelConstants;
+import info.ajanovski.eprms.mq.MessagingService;
 import info.ajanovski.eprms.tap.data.GenericDao;
 import info.ajanovski.eprms.tap.data.PersonDao;
@@ -50,9 +59,12 @@
 import info.ajanovski.eprms.tap.data.ResourceDao;
 import info.ajanovski.eprms.tap.util.AppConfig;
+import info.ajanovski.eprms.tap.util.UserInfo;
+import info.ajanovski.eprms.tap.util.UserInfo.UserRole;
 
 @ImportModule(Bootstrap4Module.class)
 public class AppModule {
+
 	public static void bind(ServiceBinder binder) {
-		binder.bind(AccessController.class).withId("AccessController");
+		binder.bind(AccessControllerRequestFilter.class);
 		binder.bind(GenericDao.class);
 		binder.bind(GenericService.class);
@@ -63,8 +75,10 @@
 		binder.bind(ResourceManager.class);
 		binder.bind(ResourceDao.class);
+		binder.bind(MessagingService.class);
+		binder.bind(TranslationService.class);
 	}
 
 	public static void contributeFactoryDefaults(MappedConfiguration<String, Object> configuration) {
-		configuration.override(SymbolConstants.APPLICATION_VERSION, "0.0.1-SNAPSHOT");
+		configuration.override(SymbolConstants.APPLICATION_VERSION, "0.0.4-SNAPSHOT");
 		configuration.override(SymbolConstants.PRODUCTION_MODE, false);
 	}
@@ -76,9 +90,8 @@
 		configuration.add(SymbolConstants.ENABLE_HTML5_SUPPORT, true);
 		configuration.add(SymbolConstants.COMPRESS_WHITESPACE, false);
-	}
-
-	@Contribute(SymbolProvider.class)
-	@ApplicationDefaults
-	public static void setupEnvironment(MappedConfiguration<String, Object> configuration) {
+		configuration.add(SymbolConstants.CHARSET, "UTF-8");
+
+		configuration.add("tapestry.hibernate.early-startup", true);
+
 		configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery");
 	}
@@ -89,32 +102,109 @@
 	}
 
-	public RequestFilter buildTimingFilter(final Logger log) {
-		return new RequestFilter() {
-			public boolean service(Request request, Response response, RequestHandler handler) throws IOException {
-				long startTime = System.currentTimeMillis();
+	@Match({ "*Service", "*Dao", "*Manager" })
+	public static void adviseEnableTransactions(HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver) {
+		advisor.addTransactionCommitAdvice(receiver);
+	}
+
+	@Decorate(serviceInterface = ThreadLocale.class)
+	public ThreadLocale decorateThreadLocale(final ThreadLocale threadLocale, final PersistentLocale persistentLocale) {
+		return new ThreadLocale() {
+			@Override
+			public void setLocale(Locale locale) {
+				threadLocale.setLocale(locale);
+			}
+
+			@Override
+			public Locale getLocale() {
+				if (!persistentLocale.isSet()) {
+					setLocale(new Locale("en"));
+					persistentLocale.set(new Locale("en"));
+				}
+				return threadLocale.getLocale();
+			}
+
+		};
+	}
+
+	public static final void contributeComponentRequestHandler(
+			OrderedConfiguration<ComponentRequestFilter> configuration,
+			ComponentRequestFilter accessControllerRequestFilter, ApplicationStateManager asm,
+			ComponentSource componentSource) {
+		configuration.add("AccessControllerRequestFilter", accessControllerRequestFilter, "before:*");
+	}
+
+	public void contributeApplicationStateManager(
+			MappedConfiguration<Class, ApplicationStateContribution> configuration, Session session,
+			PersonManager personManager, RequestGlobals requestGlobals, Logger logger) {
+		ApplicationStateCreator<UserInfo> userInfoCreator = new ApplicationStateCreator<UserInfo>() {
+			public UserInfo create() {
+				logger.debug("userInfoCreator.create entered");
+
+				UserInfo userInfo = new UserInfo();
+				userInfo.setUserRoles(null);
+				userInfo.setPersonId(null);
+				userInfo.setUserName(null);
+
 				try {
-					return handler.service(request, response);
-				} finally {
-					long elapsed = System.currentTimeMillis() - startTime;
-					log.debug("Request time: {} ms", elapsed);
+					String userName = requestGlobals.getHTTPServletRequest().getRemoteUser();
+					userInfo.setUserName(userName);
+					logger.info("Login by user: " + userName);
+
+					Person loggedInPerson = (Person) session.getSession()
+							.createQuery("from Person p where userName=:userName").setParameter("userName", userName)
+							.getSingleResult();
+
+					if (loggedInPerson == null) {
+						userInfo.setUserRoles(null);
+						userInfo.setPersonId(null);
+					} else {
+						logger.debug("Login personId: {}", loggedInPerson.getPersonId());
+
+						List<UserInfo.UserRole> userRoles = new ArrayList<UserRole>();
+
+						for (PersonRole pr : personManager.getPersonRolesForPerson(loggedInPerson.getPersonId())) {
+							if (pr.getRole().getName().equals(ModelConstants.RoleAdministrator)) {
+								userRoles.add(UserRole.ADMINISTRATOR);
+							} else if (pr.getRole().getName().equals(ModelConstants.RoleInstructor)) {
+								userRoles.add(UserRole.INSTRUCTOR);
+							} else if (pr.getRole().getName().equals(ModelConstants.RoleStudent)) {
+								userRoles.add(UserRole.STUDENT);
+							}
+						}
+
+						if (userRoles.size() == 0) {
+							logger.debug("Login user role is set to NONE");
+							userRoles.add(UserRole.NONE);
+						}
+
+						logger.debug("Login user has {} roles", userRoles.size());
+
+						userInfo.setUserName(userName);
+						userInfo.setPersonId(loggedInPerson.getPersonId());
+						userInfo.setUserRoles(userRoles);
+						logger.debug("userInfo is now initialized");
+
+					}
+
+					return userInfo;
+
+				} catch (Exception e) {
+					if (userInfo.getUserName() != null) {
+						logger.error("userName {} is not found", userInfo.getUserName());
+					} else {
+						logger.error("userName is empty");
+					}
+					// throw new NoSuchUserException();
+					return userInfo;
 				}
 			}
 		};
+		configuration.add(UserInfo.class, new ApplicationStateContribution("session", userInfoCreator));
 	}
 
 	public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration) {
 		configuration.add("fontsource-fira-sans", "META-INF/resources/webjars/fontsource-fira-sans/3.0.5");
-		configuration.add("tango-icon-theme", "org/freedesktop/tango");
-	}
-
-	@Contribute(RequestHandler.class)
-	public void addTimingFilter(OrderedConfiguration<RequestFilter> configuration, @Local RequestFilter filter) {
-		configuration.add("Timing", filter);
-	}
-
-	public static final void contributeComponentRequestHandler(
-			OrderedConfiguration<ComponentRequestFilter> configuration, ComponentRequestFilter accessController,
-			ApplicationStateManager asm, ComponentSource componentSource) {
-		configuration.add("AccessController", accessController, "before:*");
+		configuration.add("ck", "META-INF/modules/vendor");
+		// configuration.add("tango-icon-theme", "org/freedesktop/tango");
 	}
 
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManager.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManager.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManager.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -25,9 +25,10 @@
 import info.ajanovski.eprms.model.entities.Person;
 import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.entities.Role;
 
 public interface PersonManager {
 
 	public List<Person> getAllPersons();
-	
+
 	public Person getPersonByUsername(String username);
 
@@ -40,3 +41,5 @@
 	public List<PersonRole> getPersonRolesForPerson(long personId);
 
+	public List<Role> getRolesForPerson(long personId);
+
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManagerImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManagerImpl.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/PersonManagerImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -27,46 +27,52 @@
 import info.ajanovski.eprms.model.entities.Person;
 import info.ajanovski.eprms.model.entities.PersonRole;
+import info.ajanovski.eprms.model.entities.Role;
 import info.ajanovski.eprms.tap.data.PersonDao;
 
 public class PersonManagerImpl implements PersonManager {
 
-        @Inject
-        private GenericService genericService;
+	@Inject
+	private GenericService genericService;
 
-        @Inject
-        private PersonDao personDao;
+	@Inject
+	private PersonDao personDao;
 
-        @Override
-        public List<Person> getAllPersons() {
-                return this.personDao.getAllPersons();
-        }
+	@Override
+	public List<Person> getAllPersons() {
+		return this.personDao.getAllPersons();
+	}
 
-        @Override
-        public Person getPersonByUsername(String username) {
-                return this.personDao.getPersonByUsername(username);
-        }
+	@Override
+	public Person getPersonByUsername(String username) {
+		return this.personDao.getPersonByUsername(username);
+	}
 
-        public Person getPersonById(long personId) {
-                return genericService.getByPK(Person.class, personId);
-        }
+	public Person getPersonById(long personId) {
+		return genericService.getByPK(Person.class, personId);
+	}
 
-        @Override
-        public List<Person> getPersonByFilter(String filter) {
-                return personDao.getPersonByFilter(filter);
-        }
+	@Override
+	public List<Person> getPersonByFilter(String filter) {
+		return personDao.getPersonByFilter(filter);
+	}
 
-        public List<PersonRole> getPersonRolesForPerson(long personId) {
-                return personDao.getPersonRolesForPerson(personId);
-        }
+	public List<PersonRole> getPersonRolesForPerson(long personId) {
+		return personDao.getPersonRolesForPerson(personId);
+	}
 
-        @Override
-        public String getPersonFullName(Person person) {
-                return personDao.getPersonFullName(person);
-        }
+	@Override
+	public String getPersonFullName(Person person) {
+		return personDao.getPersonFullName(person);
+	}
 
-        @Override
-        public String getPersonFullNameWithId(Person person) {
-                return personDao.getPersonFullNameWithId(person);
-        }
+	@Override
+	public String getPersonFullNameWithId(Person person) {
+		return personDao.getPersonFullNameWithId(person);
+	}
+
+	@Override
+	public List<Role> getRolesForPerson(long personId) {
+		return personDao.getRolesForPerson(personId);
+	}
 
 }
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationService.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationService.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationService.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,7 @@
+package info.ajanovski.eprms.tap.services;
+
+public interface TranslationService {
+
+	public String getTranslation(String className, String AttributeCode, long originalObjectId, String locale);
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationServiceImpl.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationServiceImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/services/TranslationServiceImpl.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,33 @@
+package info.ajanovski.eprms.tap.services;
+
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+
+import info.ajanovski.eprms.model.entities.Translation;
+
+public class TranslationServiceImpl implements TranslationService {
+
+	@Inject
+	private Session session;
+
+	@Inject
+	private GenericService genericService;
+
+	@Override
+	public String getTranslation(String className, String attributeCode, long originalObjectId, String locale) {
+		try {
+			Criteria crit = session.createCriteria(Translation.class)
+					.add(Restrictions.and(Restrictions.eq("className", className),
+							Restrictions.eq("attributeCode", attributeCode), Restrictions.eq("locale", locale),
+							Restrictions.eq("originalObjectId", originalObjectId)))
+					.setReadOnly(true);
+
+			return ((Translation) crit.uniqueResult()).getTranslatedText();
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+}
Index: eprms-tap/src/main/java/info/ajanovski/eprms/tap/util/UserInfo.java
===================================================================
--- eprms-tap/src/main/java/info/ajanovski/eprms/tap/util/UserInfo.java	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/java/info/ajanovski/eprms/tap/util/UserInfo.java	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -21,18 +21,8 @@
 package info.ajanovski.eprms.tap.util;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.tapestry5.http.services.RequestGlobals;
-import org.apache.tapestry5.ioc.annotations.Inject;
-import org.slf4j.Logger;
-
-import info.ajanovski.eprms.model.entities.Person;
-import info.ajanovski.eprms.model.entities.PersonRole;
-import info.ajanovski.eprms.model.util.ModelConstants;
-import info.ajanovski.eprms.tap.services.PersonManager;
-
 public class UserInfo {
-	enum UserRole {
+	public enum UserRole {
 		NONE, STUDENT, INSTRUCTOR, ADMINISTRATOR
 	};
@@ -42,55 +32,10 @@
 	private List<UserRole> userRoles;
 
-	private PersonManager pm;
-	private Logger logger;
-
-	public UserInfo(@Inject RequestGlobals requestGlobals, @Inject Logger logger, @Inject PersonManager pm)
-			throws Exception {
-		this.pm = pm;
-		this.logger = logger;
-
-		if (requestGlobals != null) {
-			if (requestGlobals.getHTTPServletRequest().getRemoteUser() != null) {
-				this.userName = requestGlobals.getHTTPServletRequest().getRemoteUser();
-				this.setupUser();
-			} else {
-				this.userName = null;
-			}
-		} else {
-			this.userName = null;
-		}
+	public String getUserName() {
+		return userName;
 	}
 
-	private void setupUser() throws Exception {
-		if (userName != null) {
-			logger.info("Logged in user: {}", userName);
-			userRoles = new ArrayList<UserRole>();
-			Person p = pm.getPersonByUsername(userName);
-			if (p == null) {
-				personId = null;
-				userRoles.clear();
-			} else {
-				this.personId = Long.valueOf(p.getPersonId());
-				if (personId != null) {
-					for (PersonRole pr : pm.getPersonRolesForPerson(personId)) {
-						if (pr.getRole().getName().equals(ModelConstants.RoleAdministrator)) {
-							userRoles.add(UserRole.ADMINISTRATOR);
-						} else if (pr.getRole().getName().equals(ModelConstants.RoleInstructor)) {
-							userRoles.add(UserRole.INSTRUCTOR);
-						} else if (pr.getRole().getName().equals(ModelConstants.RoleStudent)) {
-							userRoles.add(UserRole.STUDENT);
-						}
-					}
-					if (userRoles.size() == 0) {
-						userRoles.add(UserRole.NONE);
-					}
-				}
-			}
-		}
-
-	}
-
-	public String getUserName() {
-		return userName;
+	public void setUserName(String userName) {
+		this.userName = userName;
 	}
 
@@ -99,19 +44,51 @@
 	}
 
+	public void setPersonId(Long personId) {
+		this.personId = personId;
+	}
+
+	public List<UserRole> getUserRoles() {
+		return userRoles;
+	}
+
+	public void setUserRoles(List<UserRole> userRoles) {
+		this.userRoles = userRoles;
+	}
+
 	public boolean isNone() {
-		return userRoles.contains(UserRole.NONE);
+		if (userRoles != null) {
+			return userRoles.contains(UserRole.NONE);
+		} else {
+			return false;
+		}
 	}
 
 	public boolean isStudent() {
-		return userRoles.contains(UserRole.STUDENT);
+		if (userRoles != null) {
+			return userRoles.contains(UserRole.STUDENT);
+		} else {
+			return false;
+		}
+	}
+
+	public boolean isInstructor() {
+		if (userRoles != null) {
+			return userRoles.contains(UserRole.INSTRUCTOR);
+		} else {
+			return false;
+		}
 	}
 
 	public boolean isAdministrator() {
-		return userRoles.contains(UserRole.ADMINISTRATOR);
+		if (userRoles != null) {
+			return userRoles.contains(UserRole.ADMINISTRATOR);
+		} else {
+			return false;
+		}
 	}
 
 	public void impersonate(String inUsername) throws Exception {
 		this.userName = inUsername;
-		this.setupUser();
+//		this.setupUser();
 	}
 
Index: eprms-tap/src/main/resources/AppConfig.properties
===================================================================
--- eprms-tap/src/main/resources/AppConfig.properties	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/AppConfig.properties	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -31,2 +31,4 @@
 
 tapestry.hmac-passphrase=@tapestry.hmac-passphrase@
+
+MQHost=@MQHost@
Index: eprms-tap/src/main/resources/META-INF/assets/site-overrides.css
===================================================================
--- eprms-tap/src/main/resources/META-INF/assets/site-overrides.css	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/META-INF/assets/site-overrides.css	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -79,2 +79,6 @@
 	stroke-linejoin: round;
 }
+
+nav.navbar {
+	background-color: #050D58 !important;
+}
Index: eprms-tap/src/main/resources/META-INF/assets/webeditor-custom.css
===================================================================
--- eprms-tap/src/main/resources/META-INF/assets/webeditor-custom.css	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/META-INF/assets/webeditor-custom.css	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,23 @@
+@charset "UTF-8";
+
+p.comment {
+	background: #ffff80;
+}
+
+.inlinecomment {
+	background: #ffffa0;
+	margin-left:  2rem;
+	border-left:  1px solid black;
+	padding-left: 0.5rem;
+}
+
+.resultschema {
+	background: #d0d0ff;
+	margin-left:  0.5em;
+	margin-right: 0.5em;
+}
+
+div.box {
+	padding: 0.5em;
+	background: #e0e0e0;
+}
Index: eprms-tap/src/main/resources/META-INF/modules/ModalBox.js
===================================================================
--- eprms-tap/src/main/resources/META-INF/modules/ModalBox.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/META-INF/modules/ModalBox.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,24 @@
+define(["jquery", "bootstrap/modal"], function($) {
+
+	var activate = function(modalId, options) {
+		console.log("MODAL ACTIVATE");
+		$('#' + modalId).modal(options);
+	}
+
+	var hide = function(modalId) {
+		console.log("MODAL HIDE");
+		var $modal = $('#' + modalId);
+		if ($modal.length > 0) {
+			$modal.modal('hide');
+		} else {
+			$('body').removeClass('modal-open');
+			$('.modal-backdrop').remove();
+		}
+	}
+
+	return {
+		activate: activate,
+		hide: hide
+	}
+
+});
Index: eprms-tap/src/main/resources/META-INF/modules/webeditor-config-admin.js
===================================================================
--- eprms-tap/src/main/resources/META-INF/modules/webeditor-config-admin.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/META-INF/modules/webeditor-config-admin.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the dbLearnStar system (hereinafter: dbLearn*).
+ *     
+ * dbLearn* is free software: you can redistribute it and/or modify it under the 
+ * terms of the GNU General Public License as published by the Free Software 
+ * Foundation, either version 3 of the License, or (at your option) any later 
+ * version.
+ *     
+ * dbLearn* 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 General Public License for more 
+ * details.
+ *     
+ * You should have received a copy of the GNU General Public License along 
+ * with dbLearn*.  If not, see <https://www.gnu.org/licenses/>.
+ * 
+ ******************************************************************************/
+
+requirejs.config({
+	shim: {
+		'ckeditor-jquery': ['jquery', 'ckeditor-core']
+	},
+	paths: {
+		'ckeditor-core': '../webjars/ckeditor/4.16.1/standard/ckeditor',
+		'ckeditor-jquery': '../webjars/ckeditor/4.16.1/standard/adapters/jquery'
+	}
+});
+
+define(["jquery", "ckeditor-jquery"], function($) {
+	init = function(spec) {
+		$('#' + spec.id).ckeditor(function() {
+		},
+			{
+				specialChars: ['σ', 'θ', 'π', '⨯', '⋈', 'ρ', '÷', '&cup;', '&cap;',
+					'←', '→', '∨', '∧', '¬', '∀', '∃', '∄', '∈', '∉', '⊂', '⊃',
+					'⊆', '⊇', '≤', '≠', '≥'],
+				toolbarGroups: [
+					{ "name": "basicstyles", "groups": ["basicstyles"] },
+					{ "name": "paragraph", "groups": ["list"] },
+					{ "name": "insert", "groups": ["insert"] },
+					{ "name": "styles", "groups": ["styles"] },
+					{ "name": "document", "groups": ["mode"] }
+				],
+				stylesSet: [
+					{
+						name: 'Box',
+						element: 'div',
+						attributes: { 'class': 'box' }
+					}, {
+						name: 'Comment',
+						element: 'p',
+						attributes: { 'class': 'comment' }
+					}, {
+						name: 'InlineComment',
+						element: 'span',
+						attributes: { 'class': 'inlinecomment' }
+					}, {
+						name: 'ResultsSchema',
+						element: 'span',
+						attributes: { 'class': 'resultschema' }
+					}
+				],
+				removeButtons: 'Anchor,Strike,blockquote',
+				contentsCss: [spec.csspath],
+				baseFloatZIndex: 40000
+			});
+	};
+	return init;
+}); 
Index: eprms-tap/src/main/resources/META-INF/modules/webeditor-config.js
===================================================================
--- eprms-tap/src/main/resources/META-INF/modules/webeditor-config.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/META-INF/modules/webeditor-config.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Vangel V. Ajanovski
+ *     
+ * This file is part of the dbLearnStar system (hereinafter: dbLearn*).
+ *     
+ * dbLearn* is free software: you can redistribute it and/or modify it under the 
+ * terms of the GNU General Public License as published by the Free Software 
+ * Foundation, either version 3 of the License, or (at your option) any later 
+ * version.
+ *     
+ * dbLearn* 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 General Public License for more 
+ * details.
+ *     
+ * You should have received a copy of the GNU General Public License along 
+ * with dbLearn*.  If not, see <https://www.gnu.org/licenses/>.
+ * 
+ ******************************************************************************/
+
+requirejs.config({
+	shim: {
+		'ckeditor-jquery': ['jquery', 'ckeditor-core']
+	},
+	paths: {
+		'ckeditor-core': '../webjars/ckeditor/4.16.1/standard/ckeditor',
+		'ckeditor-jquery': '../webjars/ckeditor/4.16.1/standard/adapters/jquery'
+	}
+});
+
+define(["jquery", "ckeditor-jquery"], function($) {
+	init = function(spec) {
+		$('#' + spec.id).ckeditor(function() {
+		},
+			{
+				specialChars: ['σ', 'θ', 'π', '⨯', '⋈', 'ρ', '÷', '&cup;', '&cap;',
+					'←', '→', '∨', '∧', '¬', '∀', '∃', '∄', '∈', '∉', '⊂', '⊃',
+					'⊆', '⊇', '≤', '≠', '≥'],
+				toolbarGroups: [
+					{ "name": "basicstyles", "groups": ["basicstyles"] },
+					{ "name": "paragraph", "groups": ["list"] },
+					{ "name": "insert", "groups": ["insert"] },
+					{ "name": "styles", "groups": ["styles"] },
+					{ "name": "document", "groups": ["mode"] }
+				],
+				stylesSet: [
+					{
+						name: 'Box',
+						element: 'div',
+						attributes: { 'class': 'box' }
+					}
+				],
+				removeButtons: 'Anchor,Strike,blockquote',
+				contentsCss: [spec.csspath],
+				baseFloatZIndex: 40000
+			});
+	};
+	return init;
+}); 
Index: eprms-tap/src/main/resources/META-INF/modules/zoneUpdateEffect.js
===================================================================
--- eprms-tap/src/main/resources/META-INF/modules/zoneUpdateEffect.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/META-INF/modules/zoneUpdateEffect.js	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,14 @@
+define([ "jquery", "t5/core/dom", "t5/core/events" ], function($, dom, events) {
+
+	$('*[data-container-type="zone"]').on(events.zone.didUpdate, function() {
+		$(this).css("animation", "0.3s linear slidein");
+	});
+
+	$('*[data-container-type="zone"]').on("animationend", function() {
+		$(this).css("animation", "none");
+		$(this).offsetHeight;
+		$(this).css("animation", "null");
+	});
+
+	//return null;
+});
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/Layout.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/Layout.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/Layout.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -18,7 +18,6 @@
 
 <body style="padding-top: 4.5em;">
-	<nav class="navbar navbar-dark navbar-expand-lg bg-dark fixed-top"
-		style="background-color: #03030f;">
-		<a class="navbar-brand" t:type="pagelink" t:page="index">${message:app-title-short}</a>
+	<nav class="navbar navbar-dark navbar-expand-lg fixed-top">
+		<a class="navbar-brand" t:type="pagelink" t:page="user/MyProfile">${message:app-title-short}</a>
 		<button class="navbar-toggler" type="button" data-toggle="collapse"
 			data-target="#mainMenu" aria-controls="mainMenu"
@@ -28,5 +27,5 @@
 
 		<div class="collapse navbar-collapse" id="mainMenu">
-			<ul class="navbar-nav mr-auto">
+			<ul class="navbar-nav mr-auto" t:type="if" t:test="userInfo">
 				<li t:type="loop" t:source="studentPageNames" t:value="pageName"
 					class="nav-item"><a class="nav-link ${classForPageName}"
@@ -47,8 +46,10 @@
 
 			<ul class="navbar-nav navbar-right">
+
 				<li class="nav-item"><a class="nav-link" href=""
-					t:type="actionlink" t:id="localeToggle">${message:lang-label}
-						${displayLanguage}</a></li>
-				<li class="nav-item dropdown"><a
+					t:type="actionlink" t:id="localeToggle">${message:lang-label} <span
+						class="btn btn-primary pl-1 pr-1 pt-0 pb-0">${displayLanguage}</span></a></li>
+
+				<li class="nav-item dropdown" t:type="if" t:test="userInfo"><a
 					class="nav-link dropdown-toggle" href="#" id="mainMenuUserProfile"
 					role="button" data-toggle="dropdown" aria-haspopup="true"
@@ -57,5 +58,5 @@
 					<div class="dropdown-menu" aria-labelledby="mainMenuUserProfile">
 						<t:if t:test="userInfo">
-							<a href="" t:type="pagelink" t:page="logout"
+							<a href="" t:type="pagelink" t:page="user/Logout"
 								class="dropdown-item"><img t:type="SVGIcon" t:path="log-out" />
 								${message:Logout-label}</a>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/ModalBox.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/ModalBox.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/ModalBox.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,17 @@
+<!-- Based on http://readyareyou.blogspot.com.au/2012/11/tapestry5-bootstrap-modal-dialog.html . -->
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+<t:content>
+	<div class="modal fade" id="${clientId}" tabindex="-1" role="dialog"
+		aria-labelledby="myModalLabel" aria-hidden="true">
+		<div class="modal-dialog modal-xl" role="document">
+			<div class="modal-content">
+				<div class="modal-body">
+					<button type="button" class="close" data-dismiss="modal"
+						aria-hidden="true">&times;</button>
+					<t:body />
+				</div>
+			</div>
+		</div>
+	</div>
+</t:content>
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/PublicLayout.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/PublicLayout.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/PublicLayout.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+<head>
+<meta charset="utf-8" />
+
+<title>${title}</title>
+
+<meta name="viewport"
+	content="width=device-width, initial-scale=1, shrink-to-fit=no" />
+<meta name="description" content="${message:system-description}" />
+<meta name="author" content="${message:main-developer-name}" />
+<link rel="shortcut icon" href="${asset:context:/favicon.ico}" />
+<meta http-equiv="Expires" content="Mon, 26 Jul 1997 05:00:00 GMT" />
+<meta http-equiv="Pragma" content="no-cache" />
+<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+</head>
+
+<body style="padding-top: 4.5em;">
+	<nav class="navbar navbar-dark navbar-expand-lg bg-dark fixed-top"
+		style="background-color: #03030f;">
+		<a class="navbar-brand" t:type="pagelink" t:page="index">${message:app-title-short}</a>
+		<button class="navbar-toggler" type="button" data-toggle="collapse"
+			data-target="#mainMenu" aria-controls="mainMenu"
+			aria-expanded="false" aria-label="Toggle navigation">
+			<span class="navbar-toggler-icon"></span>
+		</button>
+
+		<div class="collapse navbar-collapse" id="mainMenu">
+			<ul class="navbar-nav mr-auto">
+				<li t:type="loop" t:source="publicPageNames" t:value="pageName"
+					class="nav-item"><a class="nav-link ${classForPageName}"
+					t:type="pagelink" t:page="prop:pageName">${pageNameTitle}</a></li>
+			</ul>
+
+			<ul class="navbar-nav navbar-right">
+
+				<li class="nav-item"><a class="nav-link" href=""
+					t:type="actionlink" t:id="localeToggle">${message:lang-label}
+						${displayLanguage}</a></li>
+
+				<li class="nav-item"><a class="nav-link" href="/user/Login">${message:Login-label}</a></li>
+			</ul>
+		</div>
+	</nav>
+
+	<div class="container-fluid">
+		<div class="row">
+			<div class="col-12">
+				<t:alerts />
+			</div>
+		</div>
+
+		<!-- content -->
+		<t:body />
+		<!-- /content -->
+
+		<hr />
+		<footer>
+			<p>
+				Copyright &copy;${message:copyrightYear} <a
+					href="https://ajanovski.info">${message:copyrightHolder}</a>
+			</p>
+		</footer>
+	</div>
+</body>
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/TeamMembersGrid.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/TeamMembersGrid.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/components/TeamMembersGrid.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -2,5 +2,5 @@
 	xmlns:p="tapestry:parameter">
 
-<h5 class="card-title">${message:Team-label}: ${team.name}</h5>
+<h5 class="card-title">${message:Team-label}:${team.name}</h5>
 
 <table t:type="grid" class="table table-sm" t:source="teamMembers"
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Error404.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Error404.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Error404.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -1,3 +1,3 @@
-<html t:type="layout" title="Error404 Page Not Found | epm"
+<html t:type="PublicLayout" title="Error404 Page Not Found | epm"
 	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
 	xmlns:p="tapestry:parameter">
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index.properties
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index.properties	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,3 +1,0 @@
-greeting-title=Welcome
-greeting=The EPRMS - Educational Project and Resources Management System is a management information system covering student projects, source repositories and other related resources. This is an open-source system, initially developed as a demonstrational web application for a course on Internet Technologies. 
-greeting-url=https://github.com/ajanovski/eprms
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -1,3 +1,3 @@
-<html t:type="layout" title="${message:app-title-short}"
+<html t:type="Layout" title="${message:app-title-short}"
 	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
 
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index_mk.properties
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Index_mk.properties	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,2 +1,0 @@
-greeting-title=\u0414\u043E\u0431\u0440\u043E\u0434\u043E\u0458\u0434\u043E\u0432\u0442\u0435
-greeting=\u0415\u041F\u0420\u041C\u0421 - \u0415\u0434\u0443\u043A\u0430\u0442\u0438\u0432\u0435\u043D \u041F\u0440\u043E\u0435\u043A\u0442\u0435\u043D \u041C\u0435\u043D\u0430\u045F\u043C\u0435\u043D\u0442 \u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0441\u043A\u0438 \u0441\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u043C\u0435\u043D\u0430\u045F\u0438\u0440\u0430\u045A\u0435 \u043D\u0430 \u0441\u0442\u0443\u0434\u0435\u043D\u0442\u0441\u043A\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0438, \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0443\u043C\u0438 \u043D\u0430 \u0438\u0437\u0432\u043E\u0440\u0435\u043D \u043A\u043E\u0434 \u0438 \u0434\u0440\u0443\u0433\u0438 \u043F\u043E\u0432\u0440\u0437\u0430\u043D\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0438 \u0441\u043E \u043F\u0440\u043E\u0446\u0435\u0441\u043E\u0442 \u043D\u0430 \u0440\u0430\u0437\u0432\u043E\u0458 \u043D\u0430 \u0441\u0442\u0443\u0434\u0435\u043D\u0442\u0441\u043A\u0438\u0442\u0435 \u043F\u0440\u043E\u0435\u043A\u0442\u0438. \u041E\u0432\u0430 \u0435 \u0441\u0438\u0441\u0442\u0435\u043C \u0441\u043E \u043E\u0442\u0432\u043E\u0440\u0435\u043D \u043A\u043E\u0434, \u0438\u043D\u0438\u0446\u0438\u0458\u0430\u043B\u043D\u043E \u0440\u0430\u0437\u0432\u0438\u0435\u043D \u043A\u0430\u043A\u043E \u043F\u0440\u0438\u043C\u0435\u0440 \u0432\u0435\u0431 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u043F\u043E\u043A\u0440\u0438\u0435\u043D\u0430 \u0432\u043E \u043D\u0430\u0441\u0442\u0430\u0432\u0430\u0442\u0430 \u043D\u0430 \u043F\u0440\u0435\u0434\u043C\u0435\u0442\u043E\u0442 \u0418\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u0422\u0435\u0445\u043D\u043E\u043B\u043E\u0433\u0438\u0438 \u043D\u0430 \u0424\u0418\u041D\u041A\u0418. 
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Logout.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/Logout.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,34 +1,0 @@
-<html t:type="layout" title="sqlLearning ${message:logout-page}"
-	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
-	xmlns:p="tapestry:parameter">
-<head>
-<title>${message:logout-page}</title>
-</head>
-<body>
-	<h1>${message:logout-page}</h1>
-	<h2>
-		<span class="fas fa-check-square"></span> Апликациска одјава
-	</h2>
-	<p>Одјавени сте од оваа апликација. Сите ваши сесиски податоци се
-		избришани од серверот. Можете да продолжите со користење на останатите
-		сервиси.</p>
-	<h2>
-		<span class="fas fa-remove"></span> CAS ${message:logout-page}
-	</h2>
-	<p>
-		<b>Имајте предвид дека CAS системот служи за да ја задржи вашата
-			најава сѐ додека имате потреба од користење на различните факултетски
-			сервиси. Одјавата од оваа апликација, не ве одјави од CAS системот.
-			Така со влез во било кој факултетски сервис автоматски ќе бидете
-			најавени во истиот.</b>
-	</p>
-	<p>
-		Доколку сакате ЦЕЛОСНО да се одјавите од CAS системот и од сите
-		факултетски сервиси кои го користат кликнете на копчето: <br /> <a
-			href="${casServer}?service=${logoutRedirectToServer}"
-			class="btn btn-primary">Целосна одјава од CAS</a> <br /> На крај,
-		препорачано е да го затворите вашиот интернет прелистувач, сите негови
-		прозорци и сите негови таб листови.
-	</p>
-</body>
-</html>
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyDatabases.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyDatabases.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,47 +1,0 @@
-<html t:type="layout" title="Index | epm"
-	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
-
-<h1>${message:MyDatabases-pagelink}</h1>
-
-<div class="card mb-3" t:type="loop" t:source="projectDatabases"
-	t:value="database">
-	<div class="card-body">
-		<div class="card-title">
-			<h2>Project: ${database.project.title}</h2>
-			<h3>Database: ${database.name}</h3>
-		</div>
-		<p>Please use the following parameters to connect to this database</p>
-		<table class="table table-sm">
-			<tr class="table-primary">
-				<td>SSH tunnel server:</td>
-				<td>${database.tunnelServer}</td>
-			</tr>
-			<tr class="table-primary">
-				<td>SSH tunnel user:</td>
-				<td>${database.tunnelUser}</td>
-			</tr>
-			<tr class="table-primary">
-				<td>SSH tunnel password:</td>
-				<td>${database.tunnelPassword}</td>
-			</tr>
-			<tr class="table-secondary">
-				<td>Database Server:</td>
-				<td>${database.server}</td>
-			</tr>
-			<tr class="table-secondary">
-				<td>Database Name:</td>
-				<td>${database.name}</td>
-			</tr>
-			<tr class="table-secondary">
-				<td>Database User:</td>
-				<td>${database.owner}</td>
-			</tr>
-			<tr class="table-secondary">
-				<td>Database Password:</td>
-				<td>${database.password}</td>
-			</tr>
-		</table>
-	</div>
-</div>
-
-</html>
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyProjectReports.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyProjectReports.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,44 +1,0 @@
-<html t:type="layout" title="Index | epm"
-	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
-
-<style>
-.projectcard:nth-child(odd){
-	background: #6aa;
-}
-.projectcard:nth-child(even){
-	background: #aa6;
-	
-}
-</style>
-
-<h1>${message:myprojectreports-pagelink}</h1>
-
-<div class="card mb-4 projectcard" t:type="loop" t:source="myProjects"
-	t:value="project">
-	<div class="card-header">
-		<h2>Project: ${project.title}</h2>
-	</div>
-	<div class="card-body">
-		<div class="card mb-3 p-3" t:type="loop" t:source="project.activities"
-			t:value="activity">
-			<h3>${message:activity-label}:${activity.title}</h3>
-			<div class="card mb-3 p-3" t:type="loop"
-				t:source="activity.workReports" t:value="workReport">
-				<h4>${message:report-label}:${workReport.title}</h4>
-				<p>${message:description-label}:${workReport.description}</p>
-				<p>${message:percentReported-label}:
-					${workReport.percentReported}</p>
-				<div class="card mb-3 p-3 bg-info text-white" t:type="loop"
-					t:source="workReport.workEvaluations" t:value="workEvaluation">
-					<p>${message:evaluation-label}:${workEvaluation.title}</p>
-					<p>${message:description-label}:${workEvaluation.description}</p>
-					<p>${message:percentEvaluated-label}:
-						${workEvaluation.percentEvaluated}</p>
-					<p>${message:points-label}:${workEvaluation.points}</p>
-				</div>
-			</div>
-		</div>
-	</div>
-</div>
-
-</html>
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyRepositories.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyRepositories.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,18 +1,0 @@
-<html t:type="layout" title="Index | epm"
-	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
-
-<h1>${message:MyRepositories-pagelink}</h1>
-
-<h2>${message:Personal-label}</h2>
-<table class="table table-sm" t:type="grid" t:source="personalRepositories"
-	t:exclude="repositoryId"></table>
-
-<h2>${message:project-label}</h2>
-<table class="table table-sm" t:type="grid" t:source="projectRepositories"
-	t:exclude="repositoryId"></table>
-
-<h2>${message:team-label}</h2>
-<table class="table table-sm" t:type="grid" t:source="teamRepositories"
-	t:exclude="repositoryId"></table>
-
-</html>
Index: rms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyRepositoryAuth.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/MyRepositoryAuth.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ 	(revision )
@@ -1,23 +1,0 @@
-<html t:type="layout" title="Index | epm"
-	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
-
-<h1>Repository Authentication</h1>
-
-<p>Please enter your new password for repository authentication.</p>
-
-<form t:type="form" t:id="AuthForm">
-
-	<div class="form-group">
-		<t:label t:for="password" />
-		<t:passwordfield t:id="password" />
-	</div>
-
-	<div class="form-group">
-		<t:label t:for="confirmPassword" />
-		<t:passwordfield t:id="confirmPassword" />
-	</div>
-
-	<t:submit t:value="OK" />
-
-</form>
-</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivities.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivities.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivities.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -3,9 +3,9 @@
 	xmlns:p="tapestry:parameter">
 
-<a t:type="backlink" t:page="admin/manageprojects" />
+<a t:type="backlink" t:page="admin/manageprojects"></a>
 
 <h1>${message:admin/ProjectActivities-pagelink}</h1>
 
-<h2>Project: ${selectedProject.title}</h2>
+<h2>Project: ${selectedProject?.title}</h2>
 
 <div t:type="if" t:test="newActivity">
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageActivityTypes.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,40 @@
+<html t:type="layout" title="message:admin/ProjectActivities-pagelink"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
+	xmlns:p="tapestry:parameter">
+
+<h1>${message:admin/ManageActivityTypes-pagelink}</h1>
+
+<p>
+	<span t:type="unless" t:test="newActivityType"><a
+		class="btn btn-primary" t:type="actionlink" t:id="newActivityType"><img
+			t:type="SVGIcon" t:path="plus-square" /> ${message:New-label}
+			${message:ActivityType-label}</a></span>
+</p>
+
+<div class="card" t:type="if" t:test="newActivityType">
+	<div class="card-body">
+		<form t:type="beaneditform" id="newActivityTypeForm"
+			t:id="newActivityTypeForm" t:object="newActivityType"
+			t:exclude="activityTypeId" t:add="superActivityType"
+			t:submitLabel="OK" t:cancel="true">
+			<p:superActivityType>
+				<div class="form-group">
+					<label t:type="label" t:for="superActivityType"></label> <select
+						t:id="superActivityType" t:type="select" t:model="listTypes"
+						t:value="newActivityType.superActivityType"></select>
+				</div>
+			</p:superActivityType>
+		</form>
+	</div>
+</div>
+
+<div t:type="zone" id="zoneActivityTypes" t:id="zoneActivityTypes">
+	<p class="m-0" style="margin-left:${hierarchicalDepth}em !important;" t:type="loop"
+		t:source="allActivityTypes" t:value="activityType">
+		${activityType.title} <a href="" t:type="ActionLink"
+			t:id="EditActivityType" id="EditActivityType"
+			t:context="activityType"><img t:type="SVGIcon" t:path="edit" /></a>
+	</p>
+</div>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageDatabases.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageDatabases.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageDatabases.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -31,10 +31,10 @@
 			t:row="database">
 			<p:databaseIdCell>
-				<a t:type="actionlink" t:id="edit" t:context="database"
-					class="btn btn-sm btn-secondary" t:mixins="confirm"><img t:type="SVGIcon"
-						t:path="edit" /> ${message:edit-label}</a>
-				<a t:type="actionlink" t:id="delete" t:context="database"
-					class="btn btn-sm btn-danger" t:mixins="confirm"><img t:type="SVGIcon"
-						t:path="trash" /> ${message:remove-label}</a>
+				<a href="" t:type="actionlink" t:id="edit" t:context="database"
+					class="btn btn-sm btn-secondary" t:mixins="confirm"><img
+					t:type="SVGIcon" t:path="edit" /> ${message:edit-label}</a>
+				<a href="" t:type="actionlink" t:id="delete" t:context="database"
+					class="btn btn-sm btn-danger" t:mixins="confirm"><img
+					t:type="SVGIcon" t:path="trash" /> ${message:remove-label}</a>
 			</p:databaseIdCell>
 		</table>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManagePersons.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManagePersons.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManagePersons.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,54 @@
+<html t:type="layout" title="message:admin/ManageTeams-pagelink"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
+	xmlns:p="tapestry:parameter">
+
+<h1>${message:admin/ManagePersons-pagelink}</h1>
+
+<p>
+	<span t:type="unless" t:test="personListToImport">
+		<a href="" t:type="actionlink" t:id="ImportPersons"
+			class="btn btn-sm btn-primary"><img t:type="SVGIcon"
+			t:path="upload" /> ${message:import-label}</a>
+	</span>
+
+	<span t:type="unless" t:test="personToEdit">
+		<a href="" t:type="actionlink" t:id="NewPerson" t:context="person"
+			class="btn btn-sm btn-primary"><img t:type="SVGIcon" t:path="plus-square" />
+			${message:New-label}</a>
+	</span>
+</p>
+
+<div t:type="if" t:test="personListToImport"
+	class="card bg-light p-3 mb-3">
+	<form t:type="form" t:id="frmImport">
+		<div class="form-group">
+			<label t:type="label" t:for="personListToImport"></label><input
+				t:id="personListToImport" t:type="textarea"
+				t:object="personListToImport" />
+		</div>
+		<input t:type="submit" t:value="OK" />
+	</form>
+	<p class="bg-warning p-1 mt-3">${errors}</p>
+</div>
+
+<div t:type="if" t:test="personToEdit" class="card bg-light p-3 mb-3">
+	<form t:type="beaneditform" t:id="frmNewPerson" t:object="personToEdit"
+		t:exclude="personId" t:value="OK" t:cancel="true"></form>
+</div>
+
+<table class="table table-sm" t:type="grid" t:source="allPersons"
+	t:row="person" t:exclude="personId,authString" t:add="actions">
+	<p:actionsCell>
+		<a href="" t:type="actionlink" t:id="EditPerson" t:context="person"
+			class="btn btn-sm btn-primary"><img t:type="SVGIcon"
+			t:path="edit" /> ${message:edit-label}</a>
+		<a href="" t:type="actionlink" t:id="TogglePersonStatus"
+			t:context="person" class="btn btn-sm btn-secondary"><img
+			t:type="SVGIcon" t:path="slash" /> ${message:toggle-status-label}</a>
+		<a href="" t:type="actionlink" t:id="DeletePerson" t:context="person"
+			class="btn btn-sm btn-secondary"><img t:type="SVGIcon"
+			t:path="trash" /> ${message:remove-label}</a>
+	</p:actionsCell>
+</table>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageProjects.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageProjects.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ManageProjects.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -41,7 +41,15 @@
 							<label t:type="label" t:for="inCourses"></label>
 							<div t:type="palette" t:id="inCourses" t:encoder="courseEncoder"
-								t:model="coursesModel" t:size="4"></div>
+								t:model="coursesModel" t:selected="inCourses" t:size="4"></div>
 						</div>
 					</p:courses>
+					<p:description>
+						<div class="form-group">
+							<label t:type="label" t:for="description"></label>
+							<textarea t:id="description" t:type="textarea"
+								t:value="newProject.description" t:mixins="webeditor"
+								t:WebEditor.areaType="" />
+						</div>
+					</p:description>
 				</form>
 			</div>
@@ -123,10 +131,13 @@
 				</span>
 			</p>
-			<h3>${project.title}</h3>
+
+			<h3>${project.title}
+				<small class="text-muted">Status: ${project.status}</small>
+			</h3>
 			<p t:type="if" t:test="projectCourses">
-				<button class="btn btn-sm" t:type="loop" t:source="projectCourses"
-					t:value="course">${course.title}</button>
+				<span t:type="loop" t:source="projectCourses" t:value="course">${courseTitle}</span>
 			</p>
 		</div>
+
 		<div class="card-body">
 			<div class="row">
@@ -164,5 +175,16 @@
 								class="btn btn-sm btn-secondary "><img t:type="SVGIcon"
 								t:path="user-plus" /> ${message:add-label}
-								${message:TeamMember-label}</a>
+								${message:TeamMember-label}</a> <a t:type="actionlink"
+								t:context="responsibility.team" t:id="editTeam" role="button"
+								class="btn btn-sm btn-primary "><img t:type="SVGIcon"
+								t:path="edit" /> ${message:edit-label}
+								${message:team-label}</a>
+							<t:unless t:test="responsibility.team.teamMembers">
+								<a t:type="actionlink" t:context="responsibility"
+									t:id="deleteResponsibility" role="button"
+									class="btn btn-danger btn-sm "><img t:type="SVGIcon"
+									t:path="user-minus" /> ${message:remove-label}
+									${message:team-label}</a>
+							</t:unless>
 						</p>
 					</div>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.tml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/OverallCourseReport.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -2,60 +2,95 @@
 	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
 	xmlns:p="tapestry:parameter">
+<style>
+.CREATED {
+	background-color: #ffc0c0ff !important;
+}
+</style>
+
 
 <h1>${message:admin/OverallCourseReport-pagelink}</h1>
 
-<div class="card">
-	<div class="card-body">
-		<form t:type="form" id="selectProject" class="form-inline">
-			<div class="form-group">
-				<label t:type="label" t:for="selectCourse"></label><select
-					t:id="selectCourse" t:type="select" t:model="coursesModel"
-					t:value="selectedCourse" onchange="this.form.submit(); "></select>
-			</div>
-			<t:submit t:value="OK" />
-		</form>
+<form t:type="form" id="selectProject" class="form-inline col-12 mb-3">
+	<div class="form-group">
+		<label t:type="label" t:for="selectCourse"></label><select
+			t:id="selectCourse" t:type="select" t:model="coursesModel"
+			t:value="selectedCourse" onchange="this.form.submit(); "></select>
+	</div>
+	<t:submit t:value="OK" />
+</form>
+
+
+<div t:type="zone" t:id="zNewWorkReportModal" id="zNewWorkReportModal">
+	<div t:type="if" t:test="newWorkReport">
+		<t:ModalBox t:id="newWorkReportModal">
+			<h2>${message:Report-label}</h2>
+			<form t:id="frmAddWorkReport" t:type="beaneditform"
+				t:object="newWorkReport" t:exclude="workReportId"></form>
+		</t:ModalBox>
 	</div>
 </div>
 
-
-
-<div t:type="if" t:test="newWorkReport">
-	<form t:id="frmAddWorkReport" t:type="beaneditform"
-		t:object="newWorkReport" t:exclude="workReportId"></form>
-</div>
-
-<div t:type="if" t:test="newWorkEvaluation">
-	<form t:id="frmAddWorkEvaluation" t:type="beaneditform"
-		t:object="newWorkEvaluation" t:exclude="workEvaluationId"></form>
-</div>
-
-<div class="d-flex flex-row mb-1" t:type="loop" t:source="allProjects"
-	t:value="project">
-	<div class="col-2 bg-dark text-light">${project.title}<br />
-		${projectTotal}
-	</div>
-	<div class="col-2 bg-light" t:type="loop" t:source="project.activities"
-		t:value="activity">${activity.title}
-		<div class="card p-1 font-small" t:type="loop"
-			t:source="activity.workReports" t:value="workReport">
-			<small>${workReport.title} ${workReport.description}</small>
-			<div class="card p-1 font-small bg-info text-light" t:type="loop"
-				t:source="workReport.workEvaluations" t:value="workEvaluation">
-				<small>${workEvaluation.title} ${workEvaluation.description}
-					${workEvaluation.points}<a href="" t:type="actionlink"
-					t:id="editWorkEvaluation" t:context="workEvaluation"><img
-						t:type="svgicon" t:path="edit" /></a>
-				</small>
-			</div>
-			<a href="" t:type="actionlink" t:id="addWorkEvaluation"
-				t:context="workReport"><img t:type="svgicon"
-				t:path="check-square" /></a>
-		</div>
-		<p>
-			<a href="" t:type="actionlink" t:id="addWorkReport"
-				t:context="activity"><img t:type="svgicon" t:path="file-plus" /></a>
-		</p>
+<div t:type="zone" t:id="zNewWorkEvaluationModal"
+	id="zNewWorkEvaluationModal">
+	<div t:type="if" t:test="newWorkEvaluation">
+		<t:ModalBox t:id="newWorkEvaluationModal">
+			<h2>${message:Evaluation-label}</h2>
+			<form t:id="frmAddWorkEvaluation" t:type="beaneditform"
+				t:object="newWorkEvaluation" t:exclude="workEvaluationId">
+				<p:description>
+					<textarea t:type="textarea" t:value="newWorkEvaluation.description"
+						t:mixins="webeditor" t:WebEditor.areaType="" />
+				</p:description>
+			</form>
+		</t:ModalBox>
 	</div>
 </div>
 
+<div t:type="if" t:test="selectedCourse">
+	<div class="d-flex flex-row mb-1">
+		<div class="col-2 p-1 bg-dark text-light">
+			<h3>${message:Project-label}</h3>
+		</div>
+		<div class="col-2 p-1 bg-light" t:type="loop"
+			t:source="selectedCourse.courseActivityTypes"
+			t:value="courseActivityType">
+			<small>${courseActivityType.activityType.title}</small>
+		</div>
+	</div>
+	<div class="d-flex flex-row mb-1" t:type="loop" t:source="allProjects"
+		t:value="project">
+		<div class="col-2 p-1 bg-dark text-light">
+			<p>${project.title}</p>
+			<p>${projectTotal}</p>
+		</div>
+		<div class="col-2 p-1 bg-light" t:type="loop"
+			t:source="selectedCourse.courseActivityTypes"
+			t:value="courseActivityType">
+			<div class="card p-1 font-small" t:type="loop"
+				t:source="activity?.workReports" t:value="workReport">
+				<small>${workReport.title}<br />${workReport.description}</small>
+				<div
+					class="card p-1 font-small bg-info text-light ${workEvaluation.status}"
+					t:type="loop" t:source="workReport.workEvaluations"
+					t:value="workEvaluation">
+					<small>${workEvaluation.title}<br /> <t:outputRaw
+							t:value="workEvaluation.description" /> ${workEvaluation.points}<a
+						href="" t:type="actionlink" t:id="editWorkEvaluation"
+						t:context="workEvaluation"><img t:type="svgicon" t:path="edit" /></a><a
+						href="" t:type="actionlink" t:id="toggleWorkEvaluationStatus"
+						t:context="workEvaluation"><img t:type="svgicon"
+							t:path="toggle-left" /></a>
+					</small>
+				</div>
+				<a href="" t:type="actionlink" t:id="addWorkEvaluation"
+					t:context="workReport"><img t:type="svgicon"
+					t:path="check-square" /></a>
+			</div>
+			<p>
+				<a href="" t:type="actionlink" t:id="addWorkReport"
+					t:context="activity"><img t:type="svgicon" t:path="file-plus" /></a>
+			</p>
+		</div>
+	</div>
+</div>
 </html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/admin/ProjectAutomation.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,22 @@
+<html t:type="layout" title="message:admin/ProjectAutomation-pagelink"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
+	xmlns:p="tapestry:parameter">
+
+<h1>${message:admin/ProjectAutomation-pagelink}</h1>
+
+<ul>
+	<li t:type="loop" t:source="projects" t:value="project">
+		# ${project.title}
+		<ul t:type="if" t:test="project.responsibilities">
+			<li t:type="loop" t:source="project.responsibilities"
+				t:value="responsibility">../create_trac_repo_with_db.sh
+				${responsibility?.team.name} <span t:type="loop"
+				t:source="responsibility?.team?.teamMembers" t:value="member">&nbsp;${member.person.userName}</span>
+			</li>
+		</ul>
+	</li>
+</ul>
+
+<p><a href="" t:type="actionlink" t:id="activateAllListed">Activate all listed</a></p>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Login.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Login.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Login.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,26 @@
+<html t:type="Layout" title="${message:app-title-short}"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+
+<div class="jumbotron text-center hoverable p-4">
+
+	<div class="row">
+
+		<div class="col-md-3 offset-md-1 mx-3 my-3">
+			<div class="view overlay">
+				<img src="${asset:context:images/logo.png}" class="img-fluid"
+					alt="${message:greeting}" /> <a>
+					<div class="mask rgba-white-slight"></div>
+				</a>
+			</div>
+		</div>
+
+		<div class="col-md-8 text-md-left ml-3 mt-3">
+			<h4 class="h4 mb-4">${message:greeting-title} ${userInfo?.userName}</h4>
+			<p class="font-weight-normal">${message:greeting}</p>
+			<a class="btn btn-success" href="${message:greeting-url}">${message:greeting-url}</a>
+		</div>
+
+	</div>
+
+</div>
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Logout.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Logout.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/Logout.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,25 @@
+<html t:type="layout" title="message:app-title-short"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
+	xmlns:p="tapestry:parameter">
+<head>
+<title>${message:logout-page}</title>
+</head>
+<body>
+	<h1>${message:logout-page}</h1>
+
+	<h2>${message:application-logout}</h2>
+
+	<p>${message:logout-info-application}</p>
+
+	<h2>${message:logout-page}</h2>
+	<p>
+		<b>${message:logout-info-total}</b>
+	</p>
+	<p>
+		${message:logout-desc-total}<br /> <a href="${casLogoutLink}"
+			class="btn btn-primary">${message:logout-desc-total-title}</a> <br />
+		${message:logout-desc-total-cont}
+	</p>
+
+</body>
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyDatabases.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyDatabases.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyDatabases.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,55 @@
+<html t:type="layout" title="Index | epm"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+
+<h1>${message:user/MyDatabases-pagelink}</h1>
+
+<div class="card mb-3" t:type="loop" t:source="projectDatabases"
+	t:value="database">
+	<div class="card-body">
+		<div class="card-title">
+			<h2>Project: ${database.project.title}</h2>
+			<h3>Database: ${database.name}</h3>
+		</div>
+                <p>The professor recommends using the DBEAVER software (opensource and free), that he can support via a ready-m
+ade package (tested at the premises of the Faculty, available for Windows and Linux). You need to download the 7Z package, unpa
+ck it to a folder of your choice and start the script for starting DBEAVER, otherwise it will not work correctly. The package i
+ncludes an example connection configuration. The packages are available here: <a href="https://bazi.finki.ukim.mk/materijali/So
+ftware/">https://bazi.finki.ukim.mk/materijali/Software/</a></p>                                                               
+                <p>Note that the server will block your IP address immediately if you attempt a connection before setting up th
+e correct connection parameters. So, before attempting a connection make sure that you have setup SSH tunnel parameters (in the
+ respective configuration section) and database connection parameters (in the respective configuration section) in DBEAVER acco
+rding to the information below. Detailed instructions are included as a PDF file in the package.</p>                           
+		<table class="table table-sm">
+			<tr class="table-primary">
+				<td>SSH tunnel server:</td>
+				<td>${database.tunnelServer}</td>
+			</tr>
+			<tr class="table-primary">
+				<td>SSH tunnel user:</td>
+				<td>${database.tunnelUser}</td>
+			</tr>
+			<tr class="table-primary">
+				<td>SSH tunnel password:</td>
+				<td>${database.tunnelPassword}</td>
+			</tr>
+			<tr class="table-secondary">
+				<td>Database Server:</td>
+				<td>${database.server}</td>
+			</tr>
+			<tr class="table-secondary">
+				<td>Database Name:</td>
+				<td>${database.name}</td>
+			</tr>
+			<tr class="table-secondary">
+				<td>Database User:</td>
+				<td>${database.owner}</td>
+			</tr>
+			<tr class="table-secondary">
+				<td>Database Password:</td>
+				<td>${database.password}</td>
+			</tr>
+		</table>
+	</div>
+</div>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProfile.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProfile.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProfile.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,35 @@
+<html t:type="Layout" title="${message:app-title-short}"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+
+<div class="row">
+
+	<div class="col-md-4">
+		<img src="${asset:context:images/logo.png}" class="col-8 mb-3"
+			alt="${message:greeting}" /> <a>
+			<div class="mask rgba-white-slight"></div>
+		</a>
+		<p class="font-weight-normal">${message:greeting}</p>
+		<a href="${message:greeting-url}">${message:greeting-url}</a>
+	</div>
+
+	<div class="col-md-8">
+		<div class="card bg-light p-3">
+			<div t:type="unless" t:test="editPerson">
+				<h4 class="h4 mb-4">${message:greeting-title}
+					${userInfo?.userName}</h4>
+				<div t:type="beandisplay" t:object="person"
+					t:exclude="personId,authString"></div>
+				<a href="" t:type="actionlink" t:id="EditProfile"
+					class="btn btn-primary">${message:edit-label}</a>
+			</div>
+			<div t:type="if" t:test="editPerson">
+				<h4 class="h4 mb-4">${message:Edit-label}:${userInfo?.userName}</h4>
+				<div t:type="beaneditform" t:id="frmEditPerson"
+					t:object="editPerson" t:exclude="personId,userName,authString"></div>
+			</div>
+		</div>
+	</div>
+
+</div>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProjectReports.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProjectReports.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyProjectReports.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,97 @@
+<html t:type="layout" title="Index | epm"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
+	xmlns:p="tapestry:parameter">
+
+<style>
+.bg-project:nth-child(even) {
+	background: #e0ffff;
+}
+
+.bg-project:nth-child(odd) {
+	background: #80ffff;
+}
+</style>
+
+<div t:type="zone" t:id="zModal" id="zModal">
+	<t:if t:test="newWorkReport">
+		<t:ModalBox t:id="assessmentModal">
+			<h3>${message:Report-label}</h3>
+			<form t:id="frmNewWorkReport" t:type="BeanEditForm"
+				t:object="newWorkReport" t:exclude="workReportId,submissionDate"
+				t:value="OK" t:cancel="true">
+				<p:description>
+					<div class="form-group">
+						<label t:type="label" t:for="description"></label>
+						<textarea t:id="description" t:type="textarea"
+							t:value="newWorkReport.description" t:mixins="webeditor"
+							t:WebEditor.areaType="" />
+					</div>
+				</p:description>
+			</form>
+		</t:ModalBox>
+	</t:if>
+</div>
+
+<h1>${message:user/MyProjectReports-pagelink}</h1>
+
+<div class="card mb-4 bg-project" t:type="loop" t:source="myProjects"
+	t:value="project">
+	<div class="card-header">
+		<h2>${project.title}
+			<a class="btn btn-default" data-toggle="collapse"
+				href="#collapse${project.projectId}" role="button"
+				aria-expanded="false" aria-controls="collapse${project.projectId}">
+				<svg t:type="svgicon" t:path="list" />
+			</a>
+		</h2>
+	</div>
+
+	<div class="card-body collapse" id="collapse${project.projectId}">
+		<div class="card mb-3 p-4" t:type="loop" t:source="projectActivities"
+			t:value="activity">
+			<h3>${activity.title}</h3>
+			<div class="card mb-3 p-3 bg-light" t:type="loop"
+				t:source="activity.workReports" t:value="workReport">
+				<div class="d-flex">
+					<div class="mr-auto p-2">
+						<h4>${message:report-label}</h4>
+					</div>
+					<div class="p-2">
+						<div t:type="unless" t:test="workReport.workEvaluations">
+							<a href="" class="btn btn-secondary" t:id="EditWorkReport"
+								t:type="actionlink" t:context="workReport"><svg
+									t:type="svgicon" t:path="edit" data-toggle="modal"
+									data-target="#newWorkReportModal" /> ${message:edit-label}</a> <a
+								href="" class="btn btn-danger" t:id="DeleteWorkReport"
+								t:type="actionlink" t:mixins="Confirm" t:context="workReport"><svg
+									t:type="svgicon" t:path="trash" /> ${message:remove-label}</a>
+						</div>
+					</div>
+				</div>
+				<div t:type="beandisplay" t:object="workReport"
+					t:exclude="workReportId" t:add="person">
+					<p:person>${workReport?.person?.lastName}</p:person>
+				</div>
+				<div class="card mb-3 p-3 bg-info text-white" t:type="loop"
+					t:source="workReport.workEvaluations" t:value="workEvaluation">
+					<h5>${message:evaluation-label}</h5>
+					<div t:type="if" t:test="evaluationPublished">
+						<div t:type="beandisplay" t:object="workEvaluation"
+							t:exclude="workEvaluationId,status">
+							<p:description>
+								<t:outputRaw t:value="workEvaluation.description" />
+							</p:description>
+						</div>
+						<p:else>${message:in-progress-label}</p:else>
+					</div>
+				</div>
+			</div>
+			<p>
+				<a href="" t:id="AddReport" t:type="actionlink" t:context="activity"
+					class="btn btn-small btn-primary"><svg t:type="svgicon"
+						t:path="plus" /> ${message:add-label} ${message:report-label}</a>
+			</p>
+		</div>
+	</div>
+</div>
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositories.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositories.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositories.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,18 @@
+<html t:type="layout" title="Index | epm"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+
+<h1>${message:user/MyRepositories-pagelink}</h1>
+
+<h2>${message:Personal-label}</h2>
+<table class="table table-sm" t:type="grid" t:source="personalRepositories"
+	t:exclude="repositoryId"></table>
+
+<h2>${message:project-label}</h2>
+<table class="table table-sm" t:type="grid" t:source="projectRepositories"
+	t:exclude="repositoryId"></table>
+
+<h2>${message:team-label}</h2>
+<table class="table table-sm" t:type="grid" t:source="teamRepositories"
+	t:exclude="repositoryId"></table>
+
+</html>
Index: eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.tml
===================================================================
--- eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
+++ eprms-tap/src/main/resources/info/ajanovski/eprms/tap/pages/user/MyRepositoryAuth.tml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -0,0 +1,23 @@
+<html t:type="layout" title="Index | epm"
+	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+
+<h1>Repository Authentication</h1>
+
+<p>Please enter your new password for repository authentication.</p>
+
+<form t:type="form" t:id="AuthForm">
+
+	<div class="form-group">
+		<t:label t:for="password" />
+		<t:passwordfield t:id="password" />
+	</div>
+
+	<div class="form-group">
+		<t:label t:for="confirmPassword" />
+		<t:passwordfield t:id="confirmPassword" />
+	</div>
+
+	<t:submit t:value="OK" />
+
+</form>
+</html>
Index: eprms-tap/src/main/resources/log4j2.yml
===================================================================
--- eprms-tap/src/main/resources/log4j2.yml	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/resources/log4j2.yml	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -59,2 +59,11 @@
         name: info.ajanovski.eprms.tap
         level: info
+
+      -
+        name: org.springframework
+        level: info
+
+      -
+        name: org.hibernate
+        level: info
+
Index: eprms-tap/src/main/webapp/WEB-INF/app.properties
===================================================================
--- eprms-tap/src/main/webapp/WEB-INF/app.properties	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/webapp/WEB-INF/app.properties	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -1,50 +1,63 @@
-# This is where global application properties go.
-# You can also have individual message catalogs for each page and each
-# component that override these defaults.
-# The name of this file is based on the <filter-name> element in web.
-
-index-pagelink=Home
-myprojectreports-pagelink=My Project Reports
-myrepositories-pagelink=My Repositories
-myrepositoryauth-pagelink=Repository Auth
-mydatabases-pagelink=My Databases
-admin/ManageTeams-pagelink=Teams
+in-progress-label=In progress ...
+Activities-label=Activities
+ActivityId-label=Activity Id
+Activity-label=Activity
+ActivityType-label=Activity Type
+add-label=Add
+admin-label=Admin
+admin/ManageActivityTypes-pagelink=Manage Activity Types
+admin/ManageDatabases-pagelink=Manage Databases
+admin/ManagePersons-pagelink=Manage Persons
 admin/ManageProjects-pagelink=Projects
 admin/ManageRepositories-pagelink=Manage Repositories
-admin/ManageDatabases-pagelink=Manage Databases
+admin/ManageTeams-pagelink=Teams
+admin/OverallCourseReport-pagelink=Overall Course Report
 admin/ProjectActivities-pagelink=Manage Project Activities
-admin/OverallCourseReport-pagelink=Overall Course Report
-
-admin-label=Admin
+admin/ProjectAutomation-pagelink=Automatation of Projects
+application-logout=Application Logout
 app-title-short=EPRMS
-activity-label=Activity
+back-label=Back
+copy-label=Copy
+copyrightHolder=Vangel V. Ajanovski
+copyrightYear=2021
+database-label=Database
+description-label=Description
+edit-label=Edit
+evaluation-label=Evaluation
+greeting=The EPRMS - Educational Project and Resources Management System is a management information system covering student projects, source repositories and other related resources. This is an open-source system, initially developed as a demonstrational web application for a course on Internet Technologies. 
+greeting-title=Welcome
+greeting-url=https://github.com/ajanovski/eprms
+import-label=Import
+Index-pagelink=Home
 lang-label=Language
+Login-label=Login
+logout-desc-total-cont=\u041D\u0430 \u043A\u0440\u0430\u0458, \u043F\u0440\u0435\u043F\u043E\u0440\u0430\u0447\u0430\u043D\u043E \u0435 \u0434\u0430 \u0433\u043E \u0437\u0430\u0442\u0432\u043E\u0440\u0438\u0442\u0435 \u0432\u0430\u0448\u0438\u043E\u0442 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u043F\u0440\u0435\u043B\u0438\u0441\u0442\u0443\u0432\u0430\u0447, \u0441\u0438\u0442\u0435 \u043D\u0435\u0433\u043E\u0432\u0438 \u043F\u0440\u043E\u0437\u043E\u0440\u0446\u0438 \u0438 \u0441\u0438\u0442\u0435 \u043D\u0435\u0433\u043E\u0432\u0438 \u0442\u0430\u0431 \u043B\u0438\u0441\u0442\u043E\u0432\u0438.
+logout-desc-total-title=\u0426\u0435\u043B\u043E\u0441\u043D\u0430 \u043E\u0434\u0458\u0430\u0432\u0430 \u043E\u0434 CAS
+logout-desc-total=\u0414\u043E\u043A\u043E\u043B\u043A\u0443 \u0441\u0430\u043A\u0430\u0442\u0435 \u0426\u0415\u041B\u041E\u0421\u041D\u041E \u0434\u0430 \u0441\u0435 \u043E\u0434\u0458\u0430\u0432\u0438\u0442\u0435 \u043E\u0434 CAS \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u0442 \u0438 \u043E\u0434 \u0441\u0438\u0442\u0435 \u0444\u0430\u043A\u0443\u043B\u0442\u0435\u0442\u0441\u043A\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0438 \u043A\u043E\u0438 \u0433\u043E \u043A\u043E\u0440\u0438\u0441\u0442\u0430\u0442 \u043A\u043B\u0438\u043A\u043D\u0435\u0442\u0435 \u043D\u0430 \u043A\u043E\u043F\u0447\u0435\u0442\u043E:
+logout-info-application=\u041E\u0434\u0458\u0430\u0432\u0435\u043D\u0438 \u0441\u0442\u0435 \u043E\u0434 \u043E\u0432\u0430\u0430 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430. \u0421\u0438\u0442\u0435 \u0432\u0430\u0448\u0438 \u0441\u0435\u0441\u0438\u0441\u043A\u0438 \u043F\u043E\u0434\u0430\u0442\u043E\u0446\u0438 \u0441\u0435 \u0438\u0437\u0431\u0440\u0438\u0448\u0430\u043D\u0438 \u043E\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0442. \u041C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u0435 \u0441\u043E \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045A\u0435 \u043D\u0430 \u043E\u0441\u0442\u0430\u043D\u0430\u0442\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0438.
+logout-info-total=\u0418\u043C\u0430\u0458\u0442\u0435 \u043F\u0440\u0435\u0434\u0432\u0438\u0434 \u0434\u0435\u043A\u0430 CAS \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u0442 \u0441\u043B\u0443\u0436\u0438 \u0437\u0430 \u0434\u0430 \u0458\u0430 \u0437\u0430\u0434\u0440\u0436\u0438 \u0432\u0430\u0448\u0430\u0442\u0430 \u043D\u0430\u0458\u0430\u0432\u0430 \u0441\u0450 \u0434\u043E\u0434\u0435\u043A\u0430 \u0438\u043C\u0430\u0442\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043E\u0434 \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045A\u0435 \u043D\u0430 \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u0438\u0442\u0435 \u0444\u0430\u043A\u0443\u043B\u0442\u0435\u0442\u0441\u043A\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0438. \u041E\u0434\u0458\u0430\u0432\u0430\u0442\u0430 \u043E\u0434 \u043E\u0432\u0430\u0430 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430, \u043D\u0435 \u0432\u0435 \u043E\u0434\u0458\u0430\u0432\u0438 \u043E\u0434 CAS \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u0442. \u0422\u0430\u043A\u0430 \u0441\u043E \u0432\u043B\u0435\u0437 \u0432\u043E \u0431\u0438\u043B\u043E \u043A\u043E\u0458 \u0444\u0430\u043A\u0443\u043B\u0442\u0435\u0442\u0441\u043A\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u045C\u0435 \u0431\u0438\u0434\u0435\u0442\u0435 \u043D\u0430\u0458\u0430\u0432\u0435\u043D\u0438 \u0432\u043E \u0438\u0441\u0442\u0438\u043E\u0442.
+Logout-label=Logout
+Logout-label=Logout
+logout-page=CAS Logout
+logout-page=Logout
+newActivity-label=New Activity
+new-label=Create
+paste-label=Paste
+percentEvaluated-label=Evaluated % of total work in this activity
+percentReported-label=Reporting % of total work in this activity that has been completed
+personal-label=Personal
+points-label=Points
+project-label=Project
+remove-label=Remove
+report-label=Report
+repositories-label=Repositories
+repository-label=Repository
+reset-label=Reset
 team-label=Team
 teammember-label=Team member
-project-label=Project
-repository-label=Repository
-database-label=Database
-new-label=Create
-add-label=Add
-remove-label=Remove
-personal-label=Personal
-repositories-label=Repositories
-edit-label=Edit
-newActivity-label=New Activity
-activities-label=Activities
-copy-label=Copy
-paste-label=Paste
-reset-label=Reset
-report-label=Report
-description-label=Description
-percentReported-label=Reported % of total work in this activity
-evaluation-label=Evaluation
-percentEvaluated-label=Evaluated % of total work in this activity
-points-label=Points
-
-Logout-label=Logout
-logout-page=Logout
-
-copyrightYear=2021
-copyrightHolder=Vangel V. Ajanovski
-back-label=Back
+toggle-status-label=Toggle status
+user/MyDatabases-pagelink=My Databases
+user/MyProfile-pagelink=My Profile
+user/MyProjectReports-pagelink=My Project Reports
+user/MyRepositories-pagelink=My Repositories
+user/MyRepositoryauth-pagelink=Repository Auth
Index: eprms-tap/src/main/webapp/WEB-INF/app_mk.properties
===================================================================
--- eprms-tap/src/main/webapp/WEB-INF/app_mk.properties	(revision 5f7f096ff5c2155f33ce1048e3cafde589db7acf)
+++ eprms-tap/src/main/webapp/WEB-INF/app_mk.properties	(revision 7769f78aae132efd0c95cac4858305cf4f3bbde3)
@@ -1,60 +1,72 @@
-# This is where global application properties go.
-# You can also have individual message catalogs for each page and each
-# component that override these defaults.
-# The name of this file is based on the <filter-name> element in web.
-
-index-pagelink=\u041F\u043E\u0447\u0435\u0442\u043D\u0430
-myprojectreports-pagelink=\u041C\u043E\u0438 \u0418\u0437\u0432\u0435\u0448\u0442\u0430\u0438
-
-myrepositories-pagelink=\u041C\u043E\u0438 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0443\u043C\u0438
-myrepositoryauth-pagelink=\u0410\u0432\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u0437\u0430 \u0440\u0435\u043F\u043E
-mydatabases-pagelink=\u041C\u043E\u0438 \u0431\u0430\u0437\u0438 \u043D\u0430 \u043F\u043E\u0434\u0430\u0442\u043E\u0446\u0438
-admin/ManageTeams-pagelink=\u0423\u043F\u0440\u0430\u0432\u0443\u0432\u0430\u045A\u0435 \u0441\u043E \u0422\u0438\u043C\u043E\u0432\u0438
-admin/ManageProjects-pagelink=\u0423\u043F\u0440\u0430\u0432\u0443\u0432\u0430\u045A\u0435 \u0441\u043E \u041F\u0440\u043E\u0435\u043A\u0442\u0438
-admin/ManageRepositories-pagelink=\u0423\u043F\u0440\u0430\u0432\u0443\u0432\u0430\u045A\u0435 \u0441\u043E \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0443\u043C\u0438
-admin/ManageDatabases-pagelink=\u0423\u043F\u0440\u0430\u0432\u0443\u0432\u0430\u045A\u0435 \u0441\u043E \u0431\u0430\u0437\u0438 \u043D\u0430 \u043F\u043E\u0434\u0430\u0442\u043E\u0446\u0438
-admin/ProjectActivities-pagelink=\u0423\u043F\u0440\u0430\u0432\u0443\u0432\u0430\u045A\u0435 \u0441\u043E \u043F\u0440\u043E\u0435\u043A\u0442\u043D\u0438 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u0438
-admin/OverallCourseReport-pagelink=\u0418\u0437\u0432\u0435\u0448\u0442\u0430\u0458
-admin-label=\u0410\u0434\u043C\u0438\u043D
-app-title=\u0415\u041F\u041C
+in-progress-label=Во тек ...
+Activities-label=Активности
+ActivityId-label=Активност Ид.
+activity-label=Активност
+ActivityType-label=Тип на Активност
+add-label=Додади
+admin-label=Админ
+admin/ManageActivityTypes-pagelink=Управување со типови активности
+admin/ManageDatabases-pagelink=Управување со бази на податоци
+admin/ManagePersons-pagelink=Управување со лица
+admin/ManageProjects-pagelink=Управување со проекти
+admin/ManageRepositories-pagelink=Управување со репозиториуми
+admin/ManageTeams-pagelink=Управување со тимови
+admin/OverallCourseReport-pagelink=Преглед на извештаи на курс
+admin/ProjectActivities-pagelink=Управување со проектни активности
+admin/ProjectAutomation-pagelink=Автоматизација на проекти
+application-logout=Апликациска одјава
+app-title=ЕПРМС
+back-label=назад
+copy-label=Копирај
+copyrightHolder=Вангел В. Ајановски
+copyrightYear=2021
+database-label=База на податоци
+description-label=Опис
+description-label=Опис
+edit-label=Измени
+evaluation-label=Евалуација
+firstName-label=Име
+greeting-title=Добродојдовте
+greeting-url=https://github.com/ajanovski/eprms
+greeting=ЕПРМС - Едукативниот Проектен и Ресурсен Менаџмент Систем е информациски систем за менаџирање на студентски проекти, репозиториуми на изворен код и други поврзани ресурси со процесот на развој на студентските проекти. Ова е систем со отворен код, иницијално развиен како пример веб апликација покриена во наставата на предметот Интернет Технологии на ФИНКИ. 
+import-label=Увоз
+index-pagelink=Почетна
 lang-label=Language
-team-label=\u0422\u0438\u043C
-activity-label=\u0410\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
-
-teammember-label=\u0427\u043B\u0435\u043D \u043D\u0430 \u0442\u0438\u043C\u043E\u0442
-project-label=\u041F\u0440\u043E\u0435\u043A\u0442
-repository-label=\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0443\u043C
-database-label=\u0411\u0430\u0437\u0430 \u043D\u0430 \u043F\u043E\u0434\u0430\u0442\u043E\u0446\u0438
-new-label=\u041A\u0440\u0435\u0438\u0440\u0430\u0458
-add-label=\u0414\u043E\u0434\u0430\u0434\u0438
-remove-label=\u041E\u0442\u0441\u0442\u0440\u0430\u043D\u0438
-personal-label=\u041B\u0438\u0447\u043D\u0438
-repositories-label=\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0443\u043C\u0438
-edit-label=\u0418\u0437\u043C\u0435\u043D\u0438
-newActivity-label=\u041D\u043E\u0432\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
-activityId-label=\u0411\u0440. \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
-title-label=\u041D\u0430\u0437\u0438\u0432
-description-label=\u041E\u043F\u0438\u0441
-selectActivityType-label=\u0418\u0437\u0431\u0435\u0440\u0438 \u0442\u0438\u043F \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
-activities-label=\u0410\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u0438
-copy-label=\u041A\u043E\u043F\u0438\u0440\u0430\u0458
-reset-label=\u0420\u0435\u0441\u0435\u0442
-report-label=\u0418\u0437\u0432\u0435\u0448\u0442\u0430\u0458
-description-label=\u041E\u043F\u0438\u0441
-percentReported-label=\u0418\u0437\u0432\u0435\u0441\u0442\u0443\u0432\u0430\u043C\u0435 \u0434\u0435\u043A\u0430 \u0441\u0435 \u0438\u0437\u0440\u0430\u0431\u043E\u0442\u0435\u043D\u0438 % \u043E\u0434 \u0432\u043A\u0443\u043F\u043D\u0430\u0442\u0430 \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0430 \u043E\u0432\u0430\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
-evaluation-label=\u0415\u0432\u0430\u043B\u0443\u0430\u0446\u0438\u0458\u0430
-percentEvaluated-label=\u0415\u0432\u0430\u043B\u0443\u0438\u0440\u0430\u043D\u043E \u0435 \u0434\u0435\u043A\u0430 \u0441\u0435 \u0438\u0437\u0440\u0430\u0431\u043E\u0442\u0435\u043D\u0438 % \u043E\u0434 \u0432\u043A\u0443\u043F\u043D\u0430\u0442\u0430 \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0430 \u043E\u0432\u0430\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442
+lastName-label=Презиме
+Login-label=Најава
+logout-desc-total-cont=На крај, препорачано е да го затворите вашиот интернет прелистувач, сите негови прозорци и сите негови таб листови.
+logout-desc-total-title=Целосна одјава од CAS
+logout-desc-total=Доколку сакате ЦЕЛОСНО да се одјавите од CAS системот и од сите факултетски сервиси кои го користат кликнете на копчето:
+logout-info-application=Одјавени сте од оваа апликација. Сите ваши сесиски податоци се избришани од серверот. Можете да продолжите со користење на останатите сервиси.
+logout-info-total=Имајте предвид дека CAS системот служи за да ја задржи вашата најава сѐ додека имате потреба од користење на различните факултетски сервиси. Одјавата од оваа апликација, не ве одјави од CAS системот. Така со влез во било кој факултетски сервис автоматски ќе бидете најавени во истиот.
+Logout-label=Одјава
+logout-page=CAS Logout
+mydatabases-pagelink=Мои бази на податоци
+myprojectreports-pagelink=Мои Извештаи
+myrepositories-pagelink=Мои репозиториуми
+myrepositoryauth-pagelink=Автентикација за репо
+newActivity-label=Нова активност
+new-label=Креирај
+percentEvaluated-label=Евалуирано е дека се изработени % од вкупната работа на оваа активност
+percentReported-label=Известуваме % од вкупната  работа во оваа задача кој е завршен
+personal-label=Лични
 points-label=Points
-
-Logout-label=\u041E\u0434\u0458\u0430\u0432\u0430
-logout-page=\u041E\u0434\u0458\u0430\u0432\u0430
-
-copyrightYear=2021
-copyrightHolder=\u0412\u0430\u043D\u0433\u0435\u043B \u0412. \u0410\u0458\u0430\u043D\u043E\u0432\u0441\u043A\u0438
-
-positionNumber-label=\u041F\u043E\u0437\u0438\u0446\u0438\u0458\u0430 \u0431\u0440\u043E\u0458
-lastName-label=\u041F\u0440\u0435\u0437\u0438\u043C\u0435
-firstName-label=\u0418\u043C\u0435
-userName-label=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435
-role-label=\u0423\u043B\u043E\u0433\u0430
-back-label=\u043D\u0430\u0437\u0430\u0434
+positionNumber-label=Позиција број
+project-label=Проект
+remove-label=Отстрани
+report-label=Извештај
+repositories-label=Репозиториуми
+repository-label=Репозиториум
+reset-label=Ресет
+role-label=Улога
+selectActivityType-label=Избери тип активност
+team-label=Тим
+teammember-label=Член на тимот
+title-label=Назив
+toggle-status-label=Промени статус
+userName-label=Корисничко име
+user/MyDatabases-pagelink=Мои бази
+user/MyProfile-pagelink=Мој профил
+user/MyProjectReports-pagelink=Мои извештаи
+user/MyRepositories-pagelink=Мои репозиториуми
+user/MyRepositoryauth-pagelink=Најава на репозиториуми
