diff --git a/NOTICE.TXT b/NOTICE.TXT
index 979fc0ee23b367a9daa5b49ee1e8c90124f7060b..bd10b3b1ee93edbbd1353c44276bea7a97a692a2 100644
--- a/NOTICE.TXT
+++ b/NOTICE.TXT
@@ -140,6 +140,8 @@ This product uses software based on the BSD License
 * Antlr (BSD license) [http://www.antlr.org]
 * PostgreSQL JDBC Driver(BSD License) [http://jdbc.postgresql.org]
 * d3js (BSD License) [http://d3js.org]
+* qtiworks (BSD License) [https://github.com/davemckain/qtiworks][https://webapps.ph.ed.ac.uk/qtiworks/public/]
+* snuggletex (BSD License) [https://sourceforge.net/projects/snuggletex/]
 
 -----------------------------------------------------------------------
 This product uses software based on the Common Public License Version
@@ -156,6 +158,11 @@ This product uses software based on the Lesser General Public License (LGPL)
 * JAMWiki (GNU Lesser General Public License) [http://jamwiki.org/wiki/en]
 * XOM (GNU Lesser General Public License) [http://www.xom.nu]
 * TinyMCE WYSIWYG HTML editor (LGPL) [http://tinymce.moxiecode.com]
+* asciimath-parser (LGPL 3.0) [https://github.com/davemckain/asciimath-parser]
+
+-----------------------------------------------------------------------
+This product uses software based on the Mozilla Public License
+* saxon (Mozilla Public License Version 2.0) [http://www.saxonica.com]
 
 -----------------------------------------------------------------------
 This product uses software in the public domain
diff --git a/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java
index 0c99e15b13ada46d01f7d543278d8526e8fa258c..dced06eca948647bc55491dd814f608986eb031a 100644
--- a/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java
+++ b/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java
@@ -255,8 +255,8 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
 		sf.append("select avg(aentry.score) as scoreAverage, ")
 		  .append(" sum(case when aentry.passed=true then 1 else 0 end) as numOfPassed,")
 		  .append(" sum(case when aentry.passed=false then 1 else 0 end) as numOfFailed,")
-		  .append(" sum(case when (aentry.status is null or not(aentry.status='").append(AssessmentEntryStatus.notStarted.name()).append("') or aentry.passed is null) then 1 else 0 end) as numOfNotAttempted,")
-		  .append(" sum(aentry.key) as numOfStatements,")
+		  //.append(" sum(case when (aentry.status is null or not(aentry.status='").append(AssessmentEntryStatus.notStarted.name()).append("') or aentry.passed is null) then 1 else 0 end) as numOfNotAttempted,")
+		  //.append(" sum(aentry.key) as numOfStatements,")
 		  .append(" v.key as repoKey")
 		  .append(" from assessmententry aentry ")
 		  .append(" inner join aentry.repositoryEntry v ")
@@ -308,12 +308,10 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
 			Double averageScore = (Double)result[0];
 			Long numOfPassed = (Long)result[1];
 			Long numOfFailed = (Long)result[2];
-			Long numOfNotAttempted = (Long)result[3];
 			
 			entry.setAverageScore(averageScore);
 			entry.setCountPassed(numOfPassed == null ? 0 : numOfPassed.intValue());
 			entry.setCountFailed(numOfFailed == null ? 0 : numOfFailed.intValue());
-			entry.setCountNotAttempted(numOfNotAttempted == null ? 0 : numOfNotAttempted.intValue());
 		}
 		return entry;
 	}
@@ -338,7 +336,8 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
 		if(params.getBusinessGroupKeys() != null && params.getBusinessGroupKeys().size() > 0) {
 			sb.append(" ident.key in (select participant.identity.key from repoentrytogroup as rel, businessgroup bgi, bgroupmember as participant")
 	          .append("    where rel.entry.key=:repoEntryKey and rel.group=bgi.baseGroup and rel.group=participant.group and bgi.key in (:businessGroupKeys) ")
-	          .append("  )");
+			  .append("    and participant.role='").append(GroupRoles.participant.name()).append("'")
+			  .append("  )");
 		} else if(params.isAdmin()) {
 			sb.append(" (ident.key in (select participant.identity.key from repoentrytogroup as rel, bgroupmember as participant")
 	          .append("    where rel.entry.key=:repoEntryKey and rel.group=participant.group")
@@ -366,7 +365,7 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
 		TypedQuery<T> query = dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), classResult)
 				.setParameter("repoEntryKey", params.getEntry().getKey());
-		if(!params.isAdmin()) {
+		if(!params.isAdmin() && (params.getBusinessGroupKeys() == null || params.getBusinessGroupKeys().isEmpty())) {
 			query.setParameter("identityKey", coach.getKey());
 		}
 		if(identityKey != null) {
diff --git a/src/main/java/org/olat/course/assessment/model/AssessmentStatistics.java b/src/main/java/org/olat/course/assessment/model/AssessmentStatistics.java
index 9fb7a7436b8cc6614b33ae9553f90ca7faebbb31..983fce2e49e073a8b1fc7802f8109a75f4668b79 100644
--- a/src/main/java/org/olat/course/assessment/model/AssessmentStatistics.java
+++ b/src/main/java/org/olat/course/assessment/model/AssessmentStatistics.java
@@ -29,7 +29,6 @@ public class AssessmentStatistics {
 
 	private int countPassed;
 	private int countFailed;
-	private int countNotAttempted;
 	private Double averageScore;
 	
 	public int getCountPassed() {
@@ -48,14 +47,6 @@ public class AssessmentStatistics {
 		this.countFailed = countFailed;
 	}
 	
-	public int getCountNotAttempted() {
-		return countNotAttempted;
-	}
-	
-	public void setCountNotAttempted(int countNotAttempted) {
-		this.countNotAttempted = countNotAttempted;
-	}
-	
 	public Double getAverageScore() {
 		return averageScore;
 	}
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
index fdb7b9fce14a1411792a78be4a377b7243cebca2..da0b1a09aa1dd0ea164766239c5f1ee04e18ad8b 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
@@ -117,7 +117,7 @@ public class AssessmentItemFactory {
 		//the single choice interaction
 		ItemBody itemBody = appendDefaultItemBody(assessmentItem);
 		ChoiceInteraction choiceInteraction = appendChoiceInteraction(itemBody, responseDeclarationId, 1, true);
-		appendSimpleChoice(choiceInteraction, "New answer", "sc");
+		appendSimpleChoice(choiceInteraction, "New answer", correctResponseId);
 
 		//response processing
 		ResponseProcessing responseProcessing = createResponseProcessing(assessmentItem, responseDeclarationId);
@@ -513,6 +513,15 @@ public class AssessmentItemFactory {
 		return newChoice;
 	}
 	
+	public static SimpleChoice appendSimpleChoice(ChoiceInteraction choiceInteraction, String text, Identifier identifier) {
+		SimpleChoice newChoice = new SimpleChoice(choiceInteraction);
+		newChoice.setIdentifier(identifier);
+		P firstChoiceText = AssessmentItemFactory.getParagraph(newChoice, text);
+		newChoice.getFlowStatics().add(firstChoiceText);
+		choiceInteraction.getNodeGroups().getSimpleChoiceGroup().getSimpleChoices().add(newChoice);
+		return newChoice;
+	}
+	
 	private static void appendIdentifierValue(CorrectResponse correctResponse, Identifier correctResponseId) {
 		FieldValue fieldValue = new FieldValue(correctResponse);
 		IdentifierValue identifierValue = new IdentifierValue(correctResponseId);
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/interactions/SingleChoiceAssessmentItemBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/interactions/SingleChoiceAssessmentItemBuilder.java
index 6a0bad49adcd6613e329922437a3ed8d17870a26..181e51a75425cbde973bea9e0dcf9d1542baccc3 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/interactions/SingleChoiceAssessmentItemBuilder.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/interactions/SingleChoiceAssessmentItemBuilder.java
@@ -100,7 +100,7 @@ public class SingleChoiceAssessmentItemBuilder extends SimpleChoiceAssessmentIte
 		ItemBody itemBody = appendDefaultItemBody(assessmentItem);
 		ChoiceInteraction choiceInteraction = appendChoiceInteraction(itemBody, responseDeclarationId, 1, true);
 		
-		appendSimpleChoice(choiceInteraction, "New answer", "sc");
+		appendSimpleChoice(choiceInteraction, "New answer", correctResponseId);
 
 		//response processing
 		ResponseProcessing responseProcessing = createResponseProcessing(assessmentItem, responseDeclarationId);
diff --git a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
index 915b2481e11f9f8a58eb1141e9653cbd1206aae5..282f98945f08fc70231d78f24a23158c1eadf30c 100644
--- a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
+++ b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
@@ -60,6 +60,10 @@ public interface AssessmentEntry {
 	
 	public void setAssessmentStatus(AssessmentEntryStatus assessmentStatus);
 
+	/**
+	 * Used by Onyx
+	 * @return 
+	 */
 	public Boolean getFullyAssessed();
 
 	public void setFullyAssessed(Boolean fullyAssessed);
@@ -76,16 +80,28 @@ public interface AssessmentEntry {
 
 	public void setCoachComment(String coachComment);
 
+	/**
+	 * @return The course or learn resource where the user is assessed.
+	 */
 	public RepositoryEntry getRepositoryEntry();
 	
 	public String getSubIdent();
 	
 	/**
-	 * 
-	 * @return
+	 * @return The reference to the test
 	 */
 	public RepositoryEntry getReferenceEntry();
+	
+	/**
+	 * @return The unique identifier for anonymous user (guest)
+	 */
+	public String getAnonymousIdentifier();
 
+	/**
+	 * If the anonymous identifier is set, this method return null, must return null.
+	 * 
+	 * @return The assessed identity
+	 */
 	public Identity getIdentity();
 
 }
diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
index c452200935bafbf6ec63b9ec95c531c4bc41ee38..12796aba0362329ac18044e722e8877f5a2a1f36 100644
--- a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
+++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
@@ -49,7 +49,7 @@ public class AssessmentEntryDAO {
 	@Autowired
 	private DB dbInstance;
 	
-	public AssessmentEntry createCourseNodeAssessment(Identity assessedIdentity, String anonymousIdentifier,
+	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
 			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry) {
 		
 		AssessmentEntryImpl data = new AssessmentEntryImpl();
@@ -64,7 +64,7 @@ public class AssessmentEntryDAO {
 		return data;
 	}
 	
-	public AssessmentEntry createCourseNodeAssessment(Identity assessedIdentity, String anonymousIdentifier,
+	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
 			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry,
 			Float score, Boolean passed) {
 		
@@ -212,6 +212,14 @@ public class AssessmentEntryDAO {
 		return dbInstance.getCurrentEntityManager().merge(nodeAssessment);
 	}
 	
+	/**
+	 * Load all assessment entries for the specific assessed repository entry with
+	 * the specific sub identifier (it is mandatory).
+	 * 
+	 * @param entry The entry (mandatory)
+	 * @param subIdent The subIdent (mandatory)
+	 * @return A list of assessment entries
+	 */
 	public List<AssessmentEntry> loadAssessmentEntryBySubIdent(RepositoryEntryRef entry, String subIdent) {
 		return dbInstance.getCurrentEntityManager()
 				.createNamedQuery("loadAssessmentEntryByRepositoryEntryAndSubIdent", AssessmentEntry.class)
@@ -229,6 +237,14 @@ public class AssessmentEntryDAO {
 				.getResultList();
 	}
 
+	/**
+	 * Load all the assessment entries for a specific user and a specific assessed repository entry
+	 * (typically a course).
+	 * 
+	 * @param assessedIdentity The assessed user
+	 * @param entry The assessed course / repository entry
+	 * @return A list of assessment entries
+	 */
 	public List<AssessmentEntry> loadAssessmentEntriesByAssessedIdentity(Identity assessedIdentity, RepositoryEntry entry) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select data from assessmententry data where data.repositoryEntry.key=:repositoryEntryKey and data.identity.key=:identityKey");
@@ -239,7 +255,16 @@ public class AssessmentEntryDAO {
 				.getResultList();
 	}
 
-	public List<AssessmentEntry> loadAssessmentEntryByBusinessGroup(Group assessedGroup, RepositoryEntry entry, String subIdent) {
+	/**
+	 * Load all the assessment entry of the specific group. But aware that the query exclude the default group
+	 * of the repository entry! The query doesn't check the member ship but only the relation to the course.
+	 * 
+	 * @param assessedGroup The group (mandatory)
+	 * @param entry The repository entry (mandatory)
+	 * @param subIdent The sub identifier (mandatory)
+	 * @return A list of assessment entries
+	 */
+	public List<AssessmentEntry> loadAssessmentEntryByGroup(Group assessedGroup, RepositoryEntry entry, String subIdent) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select data from assessmententry data")
 		  .append(" inner join data.repositoryEntry v")
diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
index 32b7521949848aa171551947d54d5d7454d17e7c..90b7ca288b9313b9e219c11e04ef6042278afc31 100644
--- a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
+++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
@@ -50,7 +50,7 @@ public class AssessmentServiceImpl implements AssessmentService {
 	@Override
 	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
 			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed) {
-		return assessmentEntryDao.createCourseNodeAssessment(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry, score, passed);
+		return assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry, score, passed);
 	}
 
 	@Override
@@ -59,7 +59,7 @@ public class AssessmentServiceImpl implements AssessmentService {
 		
 		AssessmentEntry assessmentEntry = assessmentEntryDao.loadAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent);
 		if(assessmentEntry == null) {
-			assessmentEntry = assessmentEntryDao.createCourseNodeAssessment(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry);
+			assessmentEntry = assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry);
 			dbInstance.commit();
 		}
 		return assessmentEntry;
@@ -102,7 +102,7 @@ public class AssessmentServiceImpl implements AssessmentService {
 
 	@Override
 	public List<AssessmentEntry> loadAssessmentEntries(BusinessGroup assessedGroup, RepositoryEntry entry, String subIdent) {
-		return assessmentEntryDao.loadAssessmentEntryByBusinessGroup(assessedGroup.getBaseGroup(), entry, subIdent);
+		return assessmentEntryDao.loadAssessmentEntryByGroup(assessedGroup.getBaseGroup(), entry, subIdent);
 	}
 
 	@Override
diff --git a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
index 1e714feec2863f2580f90269be7d4289f33e1aba..c205043a6173e298a1f8f0b15460818d6a6b146a 100644
--- a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
+++ b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
@@ -19,14 +19,30 @@
  */
 package org.olat.course.assessment.manager;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
 import org.junit.Assert;
 import org.junit.Test;
+import org.olat.basesecurity.GroupRoles;
+import org.olat.basesecurity.IdentityShort;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentToolManager;
+import org.olat.course.assessment.model.AssessedBusinessGroup;
+import org.olat.course.assessment.model.AssessmentStatistics;
+import org.olat.course.assessment.model.SearchAssessedIdentityParams;
+import org.olat.group.BusinessGroup;
+import org.olat.group.manager.BusinessGroupDAO;
+import org.olat.group.manager.BusinessGroupRelationDAO;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.manager.AssessmentEntryDAO;
+import org.olat.modules.assessment.model.AssessmentEntryStatus;
+import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
 import org.olat.repository.RepositoryEntry;
+import org.olat.restapi.repository.course.CoursesWebService;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,22 +59,102 @@ public class AssessmentToolManagerTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
-	private AssessmentEntryDAO courseNodeAssessmentDao;
+	private BusinessGroupDAO businessGroupDao;
+	@Autowired
+	private AssessmentEntryDAO assessmentEntryDao;
 	@Autowired
 	private AssessmentToolManager assessmentToolManager;
+	@Autowired
+	private BusinessGroupRelationDAO businessGroupRelationDao;
 	
 	@Test
-	public void getAssessedIdentities() {
-		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-1");
-		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
-		String subIdent = "39486543874";
+	public void assessmentTool_coach() {
+		//course
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-author-1");
+		ICourse course = CoursesWebService.createEmptyCourse(author, "course-assessment-tool", "course long name", null);
+		
+		//members as participant and coach
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-1");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-2");
+		Identity assessedIdentity3 = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-3");
+		Identity assessedIdentity4 = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-4");
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("ast-coach-1");
 
-		AssessmentEntry nodeAssessment = courseNodeAssessmentDao
-				.createCourseNodeAssessment(assessedIdentity, null, entry, subIdent, entry);
-		Assert.assertNotNull(nodeAssessment);
+		RepositoryEntry entry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		
+		BusinessGroup group1 = businessGroupDao.createAndPersist(null, "assessment-tool-bg-1", "assessment-tool-bg-1-desc", -1, -1, false, false, false, false, false);
+		businessGroupRelationDao.addRelationToResource(group1, entry);
+		BusinessGroup group2 = businessGroupDao.createAndPersist(null, "assessment-tool-bg-2", "assessment-tool-bg-2-desc", -1, -1, false, false, false, false, false);
+		businessGroupRelationDao.addRelationToResource(group2, entry);
+		
+		businessGroupRelationDao.addRole(assessedIdentity1, group1, GroupRoles.participant.name());
+		businessGroupRelationDao.addRole(assessedIdentity2, group1, GroupRoles.participant.name());
+		businessGroupRelationDao.addRole(assessedIdentity3, group2, GroupRoles.participant.name());
+		businessGroupRelationDao.addRole(coach, group1, GroupRoles.coach.name());
+		dbInstance.commitAndCloseSession();
+		
+		// some datas
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 5.0f, Boolean.TRUE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 8.0f, Boolean.TRUE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 9.0f, Boolean.TRUE);
+		assessmentEntryDao.createAssessmentEntry(null, UUID.randomUUID().toString(), entry, subIdent, refEntry);
 		dbInstance.commitAndCloseSession();
 		
+		// coach of group 1 with id 1 and id2
+		List<BusinessGroup> coachedGroups = Collections.singletonList(group1);
+		AssessmentToolSecurityCallback assessmentCallback = new AssessmentToolSecurityCallback(false, false, false, true, coachedGroups);
+		SearchAssessedIdentityParams params = new SearchAssessedIdentityParams(entry, subIdent, refEntry, assessmentCallback);
+
+		// statistics
+		AssessmentStatistics statistics = assessmentToolManager.getStatistics(coach, params);
+		Assert.assertEquals(4.0d, statistics.getAverageScore().doubleValue(), 0.0001);
+		Assert.assertEquals(1, statistics.getCountFailed());
+		Assert.assertEquals(1, statistics.getCountPassed());
+
+		//check assessed identities list
+		List<Identity> assessedIdentities = assessmentToolManager.getAssessedIdentities(coach, params);
+		Assert.assertNotNull(assessedIdentities);
+		Assert.assertEquals(2, assessedIdentities.size());
+		
+		//number of assessed identities
+		int numOfAssessedIdentities = assessmentToolManager.getNumberOfAssessedIdentities(coach, params);
+		Assert.assertEquals(2, numOfAssessedIdentities);
+
+		List<IdentityShort> assessedShortIdentities = assessmentToolManager.getShortAssessedIdentities(coach, params, 120);
+		Assert.assertNotNull(assessedShortIdentities);
+		Assert.assertEquals(2, assessedShortIdentities.size());
+		
+		List<AssessmentEntry> assessmentEntries = assessmentToolManager.getAssessmentEntries(coach, params, AssessmentEntryStatus.notStarted);
+		Assert.assertNotNull(assessmentEntries);
+		Assert.assertEquals(0, assessmentEntries.size());
+		
+		// separate check with more options in the search parameters
+		// add by group key 
+		params.setBusinessGroupKeys(Collections.singletonList(group1.getKey()));
+		
+		// assessed groups
+		List<AssessedBusinessGroup> assessedGroups = assessmentToolManager.getBusinessGroupStatistics(coach, params);
+		Assert.assertNotNull(assessedGroups);
+		Assert.assertEquals(1, assessedGroups.size());
+
+		//check assessed identities list
+		List<Identity> assessedIdentitiesAlt = assessmentToolManager.getAssessedIdentities(coach, params);
+		Assert.assertNotNull(assessedIdentitiesAlt);
+		Assert.assertEquals(2, assessedIdentitiesAlt.size());
+		
+		//number of assessed identities
+		int numOfAssessedIdentitiesAlt = assessmentToolManager.getNumberOfAssessedIdentities(coach, params);
+		Assert.assertEquals(2, numOfAssessedIdentitiesAlt);
 
+		List<IdentityShort> assessedShortIdentitiesAlt = assessmentToolManager.getShortAssessedIdentities(coach, params, 120);
+		Assert.assertNotNull(assessedShortIdentitiesAlt);
+		Assert.assertEquals(2, assessedShortIdentitiesAlt.size());
 		
+		List<AssessmentEntry> assessmentEntriesAlt = assessmentToolManager.getAssessmentEntries(coach, params, AssessmentEntryStatus.notStarted);
+		Assert.assertNotNull(assessmentEntriesAlt);
+		Assert.assertEquals(0, assessmentEntriesAlt.size());
 	}
 }
diff --git a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
index 240fe466f55ac0c28c7c6ff4e2e5e70bab0d1240..ad56342537640e1a0f63b134aaba3f04e65cf852 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
@@ -28,11 +28,14 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 import org.olat.basesecurity.BaseSecurity;
@@ -46,7 +49,10 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
 import org.olat.core.id.User;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.mail.ContactList;
+import org.olat.core.util.mail.MailModule;
 import org.olat.core.util.mail.MailPackage;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupModule;
@@ -72,6 +78,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class BusinessGroupServiceTest extends OlatTestCase {
 	
+	private static final OLog log = Tracing.createLoggerFor(BusinessGroupServiceTest.class);
 	private static boolean initialize = false;
 	
 	@Autowired
@@ -92,6 +99,8 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 	private BusinessGroupModule businessGroupModule;
 	@Autowired
 	private BusinessGroupService businessGroupService;
+	@Autowired
+	private MailModule mailModule;
 	
 	// Identities for tests
 	private static Identity id1 = null;
@@ -1114,9 +1123,6 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 		Assert.assertFalse(optionToLeaveLearnersGroup.isAllowToLeave());
 	}
 	
-	/**
-	 * 
-	 */
 	@Test
 	public void allowToLeavingBusinessGroup_withCourse() {
 		//authors group
@@ -1145,4 +1151,100 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 			Assert.assertTrue(roles.isOLATAdmin());
 		}
 	}
+	
+	@Ignore @Test
+	public void parallelRemoveParticipants() {
+		mailModule.setInterSystem(true);
+		businessGroupModule.setMandatoryEnrolmentEmailForUsers("true");
+		
+		Identity admin = JunitTestHelper.createAndPersistIdentityAsRndUser("remove-p1-1");
+		
+		int NUM_OF_THREADS = 20;
+		int NUM_OF_GROUPS = 50;
+		int NUM_OF_PARTICIPANTS = 10;
+		
+		//create the members
+		List<Identity> members = new ArrayList<>();
+		for(int i=0; i<NUM_OF_PARTICIPANTS; i++) {
+			Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("remove-p1-1");
+			for(int j=0;j<20;j++) {
+				members.add(participant);
+			}
+		}
+		dbInstance.commitAndCloseSession();
+		
+		//prepare the business groups
+		final CountDownLatch finishCount = new CountDownLatch(NUM_OF_THREADS);
+		List<RemoveParticipantsThread> threads = new ArrayList<>(NUM_OF_THREADS);
+		for(int i=0; i<NUM_OF_THREADS; i++) {
+			List<BusinessGroup> groups = new ArrayList<>();
+			for(int j=0;j<NUM_OF_GROUPS;j++) {
+				BusinessGroup group = businessGroupService.createBusinessGroup(admin, "move-bg-5", "move-desc", 0, 1, true, true, null);
+				for(Identity identity:members) {
+					businessGroupRelationDao.addRole(identity, group, GroupRoles.participant.name());
+				}
+				dbInstance.commitAndCloseSession();
+			}
+			threads.add(new RemoveParticipantsThread(groups, members, admin, finishCount));
+		}		
+		
+		// remove the participants
+		for(RemoveParticipantsThread thread:threads) {
+			thread.start();
+		}
+		
+		// sleep until threads should have terminated/excepted
+		try {
+			finishCount.await(120, TimeUnit.SECONDS);
+		} catch (InterruptedException e) {
+			log.error("", e);
+			Assert.fail();
+		}
+
+		for(RemoveParticipantsThread thread:threads) {
+			assertTrue("Subscriber does not exists", thread.isOk());
+		}	
+		
+
+		businessGroupModule.setMandatoryEnrolmentEmailForUsers("false");
+	}
+	
+	private class RemoveParticipantsThread extends Thread {
+
+		private boolean ok = false;
+		private Identity uIdentity;
+		private List<Identity> members;
+		private List<BusinessGroup> businessGroups;
+
+		private final List<Exception> exceptionHolder = new ArrayList<>();
+		private final CountDownLatch countDown;
+
+		public RemoveParticipantsThread(List<BusinessGroup> businessGroups, List<Identity> members, Identity uIdentity, CountDownLatch countDown) {
+			this.members = members;
+			this.uIdentity = uIdentity;
+			this.businessGroups = businessGroups;
+			this.countDown = countDown;
+		}
+		
+		public boolean isOk() {
+			return ok;
+		}
+		
+		@Override
+		public void run() {
+			try {
+				Thread.sleep(10);
+				for(BusinessGroup businessGroup:businessGroups) {
+					businessGroupService.removeParticipants(uIdentity, members, businessGroup, null);
+				}
+				ok = true;
+			} catch (Exception ex) {
+				exceptionHolder.add(ex);// no exception should happen
+				ex.printStackTrace();
+			} finally {
+				countDown.countDown();
+				dbInstance.commitAndCloseSession();
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
index c4cbc9218ca27629b11db47a264e3e1816229156..8991294167eb91179ade25c31d292d9534c8545b 100644
--- a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
+++ b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
@@ -19,14 +19,18 @@
  */
 package org.olat.modules.assessment.manager;
 
+import java.util.List;
 import java.util.UUID;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.olat.basesecurity.GroupRoles;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.group.BusinessGroup;
+import org.olat.group.manager.BusinessGroupDAO;
+import org.olat.group.manager.BusinessGroupRelationDAO;
 import org.olat.modules.assessment.AssessmentEntry;
-import org.olat.modules.assessment.manager.AssessmentEntryDAO;
 import org.olat.repository.RepositoryEntry;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -44,16 +48,20 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
-	private AssessmentEntryDAO courseNodeAssessmentDao;
+	private BusinessGroupDAO businessGroupDao;
+	@Autowired
+	private AssessmentEntryDAO assessmentEntryDao;
+	@Autowired
+	private BusinessGroupRelationDAO businessGroupRelationDao;
 	
 	@Test
-	public void createCourseNodeAssessment() {
+	public void createAssessmentEntry() {
 		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-1");
 		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
 		String subIdent = "39485349759";
 
-		AssessmentEntry nodeAssessment = courseNodeAssessmentDao
-				.createCourseNodeAssessment(assessedIdentity, null, entry, subIdent, entry);
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, entry);
 		Assert.assertNotNull(nodeAssessment);
 		dbInstance.commitAndCloseSession();
 		
@@ -66,16 +74,37 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		Assert.assertEquals(subIdent, nodeAssessment.getSubIdent());
 	}
 	
+	@Test
+	public void createAssessmentEntry_anonymous() {
+		String anonymousIdentifier = UUID.randomUUID().toString();
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = "39485349759";
+		
+
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(null, anonymousIdentifier, entry, subIdent, entry);
+		Assert.assertNotNull(nodeAssessment);
+		dbInstance.commitAndCloseSession();
+		
+		//check values
+		Assert.assertNotNull(nodeAssessment.getKey());
+		Assert.assertNotNull(nodeAssessment.getCreationDate());
+		Assert.assertNotNull(nodeAssessment.getLastModified());
+		Assert.assertEquals(anonymousIdentifier, nodeAssessment.getAnonymousIdentifier());
+		Assert.assertEquals(entry, nodeAssessment.getRepositoryEntry());
+		Assert.assertEquals(subIdent, nodeAssessment.getSubIdent());
+	}
+	
 	@Test
 	public void loadCourseNodeAssessmentById() {
 		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-2");
 		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
 		String subIdent = UUID.randomUUID().toString();
-		AssessmentEntry nodeAssessment = courseNodeAssessmentDao
-				.createCourseNodeAssessment(assessedIdentity, null, entry, subIdent, entry);
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, entry);
 		dbInstance.commitAndCloseSession();
 		
-		AssessmentEntry reloadedAssessment = courseNodeAssessmentDao.loadAssessmentEntryById(nodeAssessment.getKey());
+		AssessmentEntry reloadedAssessment = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment.getKey());
 		Assert.assertEquals(nodeAssessment.getKey(), reloadedAssessment.getKey());
 		Assert.assertEquals(nodeAssessment, reloadedAssessment);
 		Assert.assertEquals(assessedIdentity, reloadedAssessment.getIdentity());
@@ -84,15 +113,15 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 	}
 	
 	@Test
-	public void loadCourseNodeAssessment() {
+	public void loadAssessmentEntry() {
 		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-3");
 		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
 		String subIdent = UUID.randomUUID().toString();
-		AssessmentEntry nodeAssessment = courseNodeAssessmentDao
-				.createCourseNodeAssessment(assessedIdentity, null, entry, subIdent, entry);
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, entry);
 		dbInstance.commitAndCloseSession();
 		
-		AssessmentEntry reloadedAssessment = courseNodeAssessmentDao
+		AssessmentEntry reloadedAssessment = assessmentEntryDao
 				.loadAssessmentEntry(assessedIdentity, null, entry, subIdent);
 		Assert.assertEquals(nodeAssessment.getKey(), reloadedAssessment.getKey());
 		Assert.assertEquals(nodeAssessment, reloadedAssessment);
@@ -100,5 +129,297 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		Assert.assertEquals(entry, reloadedAssessment.getRepositoryEntry());
 		Assert.assertEquals(subIdent, reloadedAssessment.getSubIdent());
 	}
+	
+	@Test
+	public void loadAssessmentEntry_anonymous() {
+		String anonymousIdentifier = UUID.randomUUID().toString();
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(null, anonymousIdentifier, entry, subIdent, entry);
+		dbInstance.commitAndCloseSession();
+		
+		AssessmentEntry reloadedAssessment = assessmentEntryDao
+				.loadAssessmentEntry(null, anonymousIdentifier, entry, subIdent);
+		Assert.assertEquals(nodeAssessment.getKey(), reloadedAssessment.getKey());
+		Assert.assertEquals(nodeAssessment, reloadedAssessment);
+		Assert.assertEquals(anonymousIdentifier, reloadedAssessment.getAnonymousIdentifier());
+		Assert.assertEquals(entry, reloadedAssessment.getRepositoryEntry());
+		Assert.assertEquals(subIdent, reloadedAssessment.getSubIdent());
+	}
+	
+	@Test
+	public void loadAssessmentEntry_withSoftkey() {
+		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-4");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, entry);
+		dbInstance.commitAndCloseSession();
+		
+		AssessmentEntry reloadedAssessment = assessmentEntryDao
+				.loadAssessmentEntry(assessedIdentity, entry, subIdent, entry.getSoftkey());
+		Assert.assertEquals(nodeAssessment.getKey(), reloadedAssessment.getKey());
+		Assert.assertEquals(nodeAssessment, reloadedAssessment);
+		Assert.assertEquals(assessedIdentity, reloadedAssessment.getIdentity());
+		Assert.assertEquals(entry, reloadedAssessment.getRepositoryEntry());
+		Assert.assertEquals(subIdent, reloadedAssessment.getSubIdent());
+	}
+	
+	@Test
+	public void loadAssessmentEntry_specificTest() {
+		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-5");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessmentRef = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry);
+		dbInstance.commitAndCloseSession();
+		
+		AssessmentEntry reloadedAssessmentRef = assessmentEntryDao
+				.loadAssessmentEntry(assessedIdentity, entry, subIdent, refEntry);
+		Assert.assertEquals(nodeAssessmentRef.getKey(), reloadedAssessmentRef.getKey());
+		Assert.assertEquals(nodeAssessmentRef, reloadedAssessmentRef);
+		Assert.assertEquals(assessedIdentity, reloadedAssessmentRef.getIdentity());
+		Assert.assertEquals(entry, reloadedAssessmentRef.getRepositoryEntry());
+		Assert.assertEquals(subIdent, reloadedAssessmentRef.getSubIdent());
+	}
+	
+	@Test
+	public void resetAssessmentEntry() {
+		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-6");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessmentRef = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE);
+		dbInstance.commitAndCloseSession();
+		
+		AssessmentEntry resetedAssessmentRef = assessmentEntryDao
+				.resetAssessmentEntry(nodeAssessmentRef);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertEquals(nodeAssessmentRef, resetedAssessmentRef);
+		Assert.assertEquals(assessedIdentity, resetedAssessmentRef.getIdentity());
+		Assert.assertNull(resetedAssessmentRef.getScore());
+		Assert.assertNull(resetedAssessmentRef.getPassed());
+		Assert.assertEquals(new Integer(0), resetedAssessmentRef.getAttempts());
+		Assert.assertNull(resetedAssessmentRef.getCompletion());
+		
+		// double check by reloading the entry
+		AssessmentEntry reloadedAssessmentRef = assessmentEntryDao
+				.loadAssessmentEntryById(resetedAssessmentRef.getKey());
+		dbInstance.commitAndCloseSession();
 
-}
+		Assert.assertEquals(nodeAssessmentRef, reloadedAssessmentRef);
+		Assert.assertNull(reloadedAssessmentRef.getScore());
+		Assert.assertNull(reloadedAssessmentRef.getPassed());
+		Assert.assertEquals(new Integer(0), reloadedAssessmentRef.getAttempts());
+		Assert.assertNull(reloadedAssessmentRef.getCompletion());
+	}
+	
+	@Test
+	public void loadAssessmentEntries_subIdent() {
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-7");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-8");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+		
+		// load with our subIdent above
+		List<AssessmentEntry> assessmentEntries = assessmentEntryDao
+				.loadAssessmentEntryBySubIdent(entry, subIdent);
+		Assert.assertNotNull(assessmentEntries);
+		Assert.assertEquals(2, assessmentEntries.size());
+		Assert.assertTrue(assessmentEntries.contains(nodeAssessmentId1));
+		Assert.assertTrue(assessmentEntries.contains(nodeAssessmentId2));
+		Assert.assertFalse(assessmentEntries.contains(nodeAssessmentId3));
+		Assert.assertFalse(assessmentEntries.contains(nodeAssessmentId4));
+	}
+	
+	@Test
+	public void getAllIdentitiesWithAssessmentData() {
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-9");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-10");
+		Identity assessedIdentity3 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-11");
+		Identity assessedIdentity4 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-12");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		String subIdent = UUID.randomUUID().toString();
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+
+		// id 1,2,3 are in the entry, but 4 is in an other entry and must not appears in the list
+		List<Identity> assessedIdentities = assessmentEntryDao.getAllIdentitiesWithAssessmentData(entry);
+		Assert.assertNotNull(assessedIdentities);
+		Assert.assertEquals(3, assessedIdentities.size());
+		Assert.assertTrue(assessedIdentities.contains(assessedIdentity1));
+		Assert.assertTrue(assessedIdentities.contains(assessedIdentity2));
+		Assert.assertTrue(assessedIdentities.contains(assessedIdentity3));
+		Assert.assertFalse(assessedIdentities.contains(assessedIdentity4));
+	}
+	
+	@Test
+	public void loadAssessmentEntriesByAssessedIdentity() {
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-13");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-14");
+		Identity assessedIdentity3 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-15");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+		
+		// load for identity 1
+		List<AssessmentEntry> assessmentEntriesId1 = assessmentEntryDao
+				.loadAssessmentEntriesByAssessedIdentity(assessedIdentity1, entry);
+		Assert.assertNotNull(assessmentEntriesId1);
+		Assert.assertEquals(1, assessmentEntriesId1.size());
+		Assert.assertTrue(assessmentEntriesId1.contains(nodeAssessmentId1));
+		Assert.assertFalse(assessmentEntriesId1.contains(nodeAssessmentId2));
+		Assert.assertFalse(assessmentEntriesId1.contains(nodeAssessmentId3));
+		Assert.assertFalse(assessmentEntriesId1.contains(nodeAssessmentId4));
+		
+		//load for identity 2
+		List<AssessmentEntry> assessmentEntriesId2 = assessmentEntryDao
+				.loadAssessmentEntriesByAssessedIdentity(assessedIdentity2, entry);
+		Assert.assertNotNull(assessmentEntriesId2);
+		Assert.assertEquals(2, assessmentEntriesId2.size());
+		Assert.assertFalse(assessmentEntriesId2.contains(nodeAssessmentId1));
+		Assert.assertTrue(assessmentEntriesId2.contains(nodeAssessmentId2));
+		Assert.assertTrue(assessmentEntriesId2.contains(nodeAssessmentId3));
+		Assert.assertFalse(assessmentEntriesId2.contains(nodeAssessmentId4));
+		
+		//load for identity 3
+		List<AssessmentEntry> assessmentEntriesId3 = assessmentEntryDao
+				.loadAssessmentEntriesByAssessedIdentity(assessedIdentity3, entry);
+		Assert.assertNotNull(assessmentEntriesId3);
+		Assert.assertEquals(0, assessmentEntriesId3.size());
+	}
+	
+	@Test
+	public void loadAssessmentEntryByGroup() {
+		// a simulated course with 2 groups
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-16");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-17");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		BusinessGroup group1 = businessGroupDao.createAndPersist(null, "assessment-bg-1", "assessment-bg-1-desc", -1, -1, false, false, false, false, false);
+		businessGroupRelationDao.addRelationToResource(group1, entry);
+		BusinessGroup group2 = businessGroupDao.createAndPersist(null, "assessment-bg-2", "assessment-bg-2-desc", -1, -1, false, false, false, false, false);
+		businessGroupRelationDao.addRelationToResource(group2, entry);
+		
+		businessGroupRelationDao.addRole(assessedIdentity1, group1, GroupRoles.participant.name());
+		businessGroupRelationDao.addRole(assessedIdentity2, group1, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		// some assessment entries
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+		
+		//load the assessment entries of entry
+		List<AssessmentEntry> assessmentEntries = assessmentEntryDao.loadAssessmentEntryByGroup(group1.getBaseGroup(), entry, subIdent);
+		
+		Assert.assertNotNull(assessmentEntries);
+		Assert.assertEquals(2, assessmentEntries.size());
+		Assert.assertTrue(assessmentEntries.contains(nodeAssessmentId1));
+		Assert.assertTrue(assessmentEntries.contains(nodeAssessmentId2));
+		Assert.assertFalse(assessmentEntries.contains(nodeAssessmentId3));
+		Assert.assertFalse(assessmentEntries.contains(nodeAssessmentId4));
+	}
+	
+	@Test
+	public void deleteEntryForReferenceEntry() {
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-18");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-19");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessment1 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		AssessmentEntry nodeAssessment2 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessment3 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessment4 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+		
+		// delete by reference
+		assessmentEntryDao.deleteEntryForReferenceEntry(refEntry);
+		dbInstance.commitAndCloseSession();
+
+		//check
+		AssessmentEntry deletedAssessmentEntry1 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment1.getKey());
+		Assert.assertNull(deletedAssessmentEntry1);
+		AssessmentEntry deletedAssessmentEntry2 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment2.getKey());
+		Assert.assertNull(deletedAssessmentEntry2);
+		AssessmentEntry deletedAssessmentEntry3 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment3.getKey());
+		Assert.assertNotNull(deletedAssessmentEntry3);
+		AssessmentEntry deletedAssessmentEntry4 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment4.getKey());
+		Assert.assertNull(deletedAssessmentEntry4);
+	}
+	
+	@Test
+	public void deleteEntryForRepositoryEntry() {
+		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-20");
+		Identity assessedIdentity2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-21");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessment1 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
+		AssessmentEntry nodeAssessment2 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessment3 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+		AssessmentEntry nodeAssessment4 = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		dbInstance.commitAndCloseSession();
+		
+		// delete by reference
+		assessmentEntryDao.deleteEntryForRepositoryEntry(entry);
+		dbInstance.commitAndCloseSession();
+
+		//check
+		AssessmentEntry deletedAssessmentEntry1 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment1.getKey());
+		Assert.assertNull(deletedAssessmentEntry1);
+		AssessmentEntry deletedAssessmentEntry2 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment2.getKey());
+		Assert.assertNull(deletedAssessmentEntry2);
+		AssessmentEntry deletedAssessmentEntry3 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment3.getKey());
+		Assert.assertNull(deletedAssessmentEntry3);
+		AssessmentEntry deletedAssessmentEntry4 = assessmentEntryDao.loadAssessmentEntryById(nodeAssessment4.getKey());
+		Assert.assertNotNull(deletedAssessmentEntry4);
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/modules/portfolio/manager/CategoryDAOTest.java b/src/test/java/org/olat/modules/portfolio/manager/CategoryDAOTest.java
index d29e377bcb2122120c13caa1c12558fe2c2729e9..d345757754624c209472cc85d753799069d95fb6 100644
--- a/src/test/java/org/olat/modules/portfolio/manager/CategoryDAOTest.java
+++ b/src/test/java/org/olat/modules/portfolio/manager/CategoryDAOTest.java
@@ -19,15 +19,26 @@
  */
 package org.olat.modules.portfolio.manager;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
 import org.junit.Assert;
 import org.junit.Test;
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.resource.OresHelper;
+import org.olat.modules.portfolio.Binder;
 import org.olat.modules.portfolio.Category;
+import org.olat.modules.portfolio.CategoryToElement;
+import org.olat.modules.portfolio.Media;
+import org.olat.modules.portfolio.Page;
+import org.olat.modules.portfolio.PortfolioService;
+import org.olat.modules.portfolio.Section;
+import org.olat.modules.portfolio.model.CategoryLight;
+import org.olat.modules.portfolio.model.CategoryStatistics;
+import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -42,7 +53,16 @@ public class CategoryDAOTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private PageDAO pageDao;
+	@Autowired
+	private BinderDAO binderDao;
+	@Autowired
+	private MediaDAO mediaDao;
+	@Autowired
 	private CategoryDAO categoryDao;
+	@Autowired
+	private PortfolioService portfolioService;
+	
 	
 	@Test
 	public void createCategory() {
@@ -71,5 +91,115 @@ public class CategoryDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, categories.size());
 		Assert.assertEquals(category, categories.get(0));
 	}
+	
+	@Test
+	public void getMediaCategories() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-media-1");
+		Media media = mediaDao.createMedia("Media to categorize", "Media category", "Media content", "text", "[Media:0]", null, 10, id);
+		dbInstance.commit();
+
+		Category category = categoryDao.createAndPersistCategory("Cool");
+		OLATResourceable ores = OresHelper.createOLATResourceableInstance(Media.class, media.getKey());
+		categoryDao.appendRelation(ores, category);
+		dbInstance.commitAndCloseSession();
+		
+		// load medias
+		List<CategoryLight> categories = categoryDao.getMediaCategories(id);
+		Assert.assertNotNull(categories);
+		Assert.assertEquals(1, categories.size());
+		Assert.assertEquals(category.getName(), categories.get(0).getCategory());
+	}
+	
+	@Test
+	public void getMediaCategoriesStatistics() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-media-1");
+		Media media = mediaDao.createMedia("Media to categorize", "Media category", "Media content", "text", "[Media:0]", null, 10, id);
+		dbInstance.commit();
+
+		Category category = categoryDao.createAndPersistCategory("Cool");
+		OLATResourceable ores = OresHelper.createOLATResourceableInstance(Media.class, media.getKey());
+		categoryDao.appendRelation(ores, category);
+		dbInstance.commitAndCloseSession();
+		
+		// load medias
+		List<CategoryStatistics> catStatistics = categoryDao.getMediaCategoriesStatistics(id);
+		Assert.assertNotNull(catStatistics);
+		Assert.assertEquals(1, catStatistics.size());
+		Assert.assertEquals(category.getName(), catStatistics.get(0).getName());
+		Assert.assertTrue(1 <= catStatistics.get(0).getCount());
+	}
+	
+	@Test
+	public void getCategorizedOwnedPages() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-1");
+		Binder binder = portfolioService.createNewBinder("Binder p2", "A binder with 2 page", null, author);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page1 = pageDao.createAndPersist("Jules Verne", "Cing semaine en ballon", null, null, reloadedSection, null);
+		Page page2 = pageDao.createAndPersist("J. Verne", "Une ville flottante", null, null, reloadedSection, null);
+		Page page3 = pageDao.createAndPersist("Verne", "Les Tribulations d'un Chinois en Chine", null, null, reloadedSection, null);
+		dbInstance.commitAndCloseSession();
+		
+		List<String> categories1 = new ArrayList<>();
+		categories1.add("Jules");
+		categories1.add("Verne");
+		categories1.add("Aventure");
+		categories1.add("Voyage");
+		portfolioService.updateCategories(page1, categories1);
+		
+		List<String> categories2 = new ArrayList<>();
+		categories2.add("Jules");
+		categories2.add("Verne");
+		categories2.add("Anticipation");
+		categories2.add("Technologie");
+		portfolioService.updateCategories(page2, categories2);
+		
+		List<String> categories3 = new ArrayList<>();
+		categories3.add("Jules");
+		categories3.add("Verne");
+		categories3.add("Aventure");
+		categories3.add("Chine");
+		portfolioService.updateCategories(page3, categories3);
+		dbInstance.commitAndCloseSession();
+		
+		List<CategoryToElement> categories = categoryDao.getCategorizedOwnedPages(author);
+		Assert.assertNotNull(categories);
+		Assert.assertEquals(12, categories.size());
+	}
+	
+	@Test
+	public void getCategorizedSectionsAndPages() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-1");
+		Binder binder = portfolioService.createNewBinder("Binder about Verne", "A binder with a single page", null, author);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page = pageDao.createAndPersist("Jules Verne", "Deux ans de vacances", null, null, reloadedSection, null);
+		dbInstance.commitAndCloseSession();
+		
+		List<String> categoriesSection = new ArrayList<>();
+		categoriesSection.add("Jules");
+		categoriesSection.add("Verne");
+		portfolioService.updateCategories(section, categoriesSection);
+		
+		List<String> categoriesPage = new ArrayList<>();
+		categoriesPage.add("Aventure");
+		categoriesPage.add("Vacances");
+		portfolioService.updateCategories(page, categoriesPage);
+		dbInstance.commitAndCloseSession();
+
+		//load by section
+		List<CategoryToElement> categories = categoryDao.getCategorizedSectionAndPages(section);
+		Assert.assertNotNull(categories);
+		Assert.assertEquals(4, categories.size());
+		
+		//load by binder
+		List<CategoryToElement> categoriesByBinder = categoryDao.getCategorizedSectionsAndPages(binder);
+		Assert.assertNotNull(categoriesByBinder);
+		Assert.assertEquals(4, categoriesByBinder.size());
+	}
 
 }
diff --git a/src/test/java/org/olat/modules/portfolio/manager/MediaDAOTest.java b/src/test/java/org/olat/modules/portfolio/manager/MediaDAOTest.java
index 07c7b46edcd97f74918d06c20706bb6bcbe34173..18eec5bb65a1d7f9a23adffeee22f23dd27db50b 100644
--- a/src/test/java/org/olat/modules/portfolio/manager/MediaDAOTest.java
+++ b/src/test/java/org/olat/modules/portfolio/manager/MediaDAOTest.java
@@ -19,11 +19,22 @@
  */
 package org.olat.modules.portfolio.manager;
 
+import java.util.List;
+
 import org.junit.Assert;
 import org.junit.Test;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.modules.portfolio.Binder;
+import org.olat.modules.portfolio.BinderLight;
 import org.olat.modules.portfolio.Media;
+import org.olat.modules.portfolio.MediaLight;
+import org.olat.modules.portfolio.Page;
+import org.olat.modules.portfolio.PageBody;
+import org.olat.modules.portfolio.PortfolioService;
+import org.olat.modules.portfolio.Section;
+import org.olat.modules.portfolio.handler.TextHandler;
+import org.olat.modules.portfolio.model.MediaPart;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,6 +51,12 @@ public class MediaDAOTest extends OlatTestCase {
 	private DB dbInstance;
 	@Autowired
 	private MediaDAO mediaDao;
+	@Autowired
+	private PageDAO pageDao;
+	@Autowired
+	private BinderDAO binderDao;
+	@Autowired
+	private PortfolioService portfolioService;
 	
 	@Test
 	public void createMedia() {
@@ -62,5 +79,61 @@ public class MediaDAOTest extends OlatTestCase {
 		Assert.assertEquals("[Media:0]", reloadedMedia.getBusinessPath());
 		Assert.assertEquals(id, reloadedMedia.getAuthor());
 	}
+	
+	@Test
+	public void searchByAuthor() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-media-2");
+		Media media1 = mediaDao.createMedia("Media 1", "The media theory", "Media theory is very important subject", "Forum", "[Media:0]", null, 10, author);
+		Media media2 = mediaDao.createMedia("Media 2", "Java", "One of the most widespread programming language", "Forum", "[Media:0]", null, 10, author);
+		Media media3 = mediaDao.createMedia("Media 3", "Europe", "Un continent", "Forum", "[Media:0]", null, 10, author);
+		dbInstance.commit();
+		
+		//not owned
+		Identity someoneElse = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-media-2");
+		Media mediaAlt = mediaDao.createMedia("Media 3", "Europe", "Un continent", "Forum", "[Media:0]", null, 10, someoneElse);
+		dbInstance.commit();
+		
+		// search owned medias
+		List<MediaLight> ownedMedias = mediaDao.searchByAuthor(author, null, null);
+		Assert.assertNotNull(ownedMedias);
+		Assert.assertEquals(3, ownedMedias.size());
+		Assert.assertTrue(ownedMedias.contains(media1));
+		Assert.assertTrue(ownedMedias.contains(media2));
+		Assert.assertTrue(ownedMedias.contains(media3));
+		Assert.assertFalse(ownedMedias.contains(mediaAlt));
+		
+		// search medias
+		List<MediaLight> searchMedias = mediaDao.searchByAuthor(author, "Europe", null);
+		Assert.assertNotNull(searchMedias);
+		Assert.assertEquals(1, searchMedias.size());
+		Assert.assertFalse(searchMedias.contains(media1));
+		Assert.assertFalse(searchMedias.contains(media2));
+		Assert.assertTrue(searchMedias.contains(media3));
+		Assert.assertFalse(searchMedias.contains(mediaAlt));
+	}
+	
+	@Test
+	public void usedInBinders() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-media-2");
+		Binder binder = portfolioService.createNewBinder("Binder p2", "A binder with 2 page", null, author);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+		
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page = pageDao.createAndPersist("Page 1", "A page with content.", null, null, reloadedSection, null);
+		Media media = mediaDao.createMedia("Media", "Binder", "Une citation sur les classeurs", TextHandler.TEXT_MEDIA, "[Media:0]", null, 10, author);
+		dbInstance.commitAndCloseSession();
 
-}
+		MediaPart mediaPart = new MediaPart();
+		mediaPart.setMedia(media);
+		PageBody reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, mediaPart);
+		dbInstance.commitAndCloseSession();
+		
+		//reload
+		List<BinderLight> binders = mediaDao.usedInBinders(media);
+		Assert.assertNotNull(binders);
+		Assert.assertEquals(1, binders.size());
+		Assert.assertTrue(binders.get(0).getKey().equals(binder.getKey()));
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/modules/portfolio/manager/PageDAOTest.java b/src/test/java/org/olat/modules/portfolio/manager/PageDAOTest.java
index c46b12ba098cb6e1725918045ddf9f8dd73430ce..b69e6cf57ba1a45559b7a0ea0f37666c33b4bd98 100644
--- a/src/test/java/org/olat/modules/portfolio/manager/PageDAOTest.java
+++ b/src/test/java/org/olat/modules/portfolio/manager/PageDAOTest.java
@@ -24,12 +24,19 @@ import java.util.List;
 import org.junit.Assert;
 import org.junit.Test;
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
+import org.olat.modules.portfolio.Binder;
 import org.olat.modules.portfolio.Page;
 import org.olat.modules.portfolio.PageBody;
 import org.olat.modules.portfolio.PagePart;
+import org.olat.modules.portfolio.PortfolioRoles;
+import org.olat.modules.portfolio.PortfolioService;
 import org.olat.modules.portfolio.Section;
 import org.olat.modules.portfolio.model.BinderImpl;
 import org.olat.modules.portfolio.model.HTMLPart;
+import org.olat.modules.portfolio.model.SpacerPart;
+import org.olat.modules.portfolio.model.TitlePart;
+import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -47,6 +54,8 @@ public class PageDAOTest extends OlatTestCase {
 	private PageDAO pageDao;
 	@Autowired
 	private BinderDAO binderDao;
+	@Autowired
+	private PortfolioService portfolioService;
 	
 	
 	@Test
@@ -112,7 +121,236 @@ public class PageDAOTest extends OlatTestCase {
 		Assert.assertNotNull(onlyParts);
 		Assert.assertEquals(1, onlyParts.size());
 		Assert.assertEquals(htmlPart, onlyParts.get(0));
+	}
+	
+	@Test
+	public void getPages_binder() {
+		BinderImpl binder = binderDao.createAndPersist("Binder p2", "A binder with 2 page", null, null);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+		
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page1 = pageDao.createAndPersist("Page 1", "A page with content.", null, null, reloadedSection, null);
+		Page page2 = pageDao.createAndPersist("Page 2", "A page with content.", null, null, reloadedSection, null);
+		Page page3 = pageDao.createAndPersist("Juno", "Juno is a spacecraft.", null, null, reloadedSection, null);
+		dbInstance.commitAndCloseSession();
+
+		//reload
+		List<Page> sectionPages = pageDao.getPages(binder, null);
+		Assert.assertNotNull(sectionPages);
+		Assert.assertEquals(3, sectionPages.size());
+		Assert.assertTrue(sectionPages.contains(page1));
+		Assert.assertTrue(sectionPages.contains(page2));
+		Assert.assertTrue(sectionPages.contains(page3));
+		
+		//reload
+		List<Page> searchedPages = pageDao.getPages(binder, "juno");
+		Assert.assertNotNull(searchedPages);
+		Assert.assertEquals(1, searchedPages.size());
+		Assert.assertFalse(searchedPages.contains(page1));
+		Assert.assertFalse(searchedPages.contains(page2));
+		Assert.assertTrue(searchedPages.contains(page3));
+	}
+	
+	@Test
+	public void getPages_section() {
+		BinderImpl binder = binderDao.createAndPersist("Binder p2", "A binder with 2 page", null, null);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+		
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page1 = pageDao.createAndPersist("Page 1", "A page with content.", null, null, reloadedSection, null);
+		Page page2 = pageDao.createAndPersist("Page 2", "A page with content.", null, null, reloadedSection, null);
+		Page page3 = pageDao.createAndPersist("Page 3", "A page with the demonstration of Hawking about black hole'evaporation.", null, null, reloadedSection, null);
+		dbInstance.commitAndCloseSession();
+
+		//reload
+		List<Page> sectionPages = pageDao.getPages(reloadedSection, null);
+		Assert.assertNotNull(sectionPages);
+		Assert.assertEquals(3, sectionPages.size());
+		Assert.assertTrue(sectionPages.contains(page1));
+		Assert.assertTrue(sectionPages.contains(page2));
+		Assert.assertTrue(sectionPages.contains(page3));
+		
+		//reload
+		List<Page> searchedPages = pageDao.getPages(reloadedSection, "Hawking");
+		Assert.assertNotNull(searchedPages);
+		Assert.assertEquals(1, searchedPages.size());
+		Assert.assertFalse(searchedPages.contains(page1));
+		Assert.assertFalse(searchedPages.contains(page2));
+		Assert.assertTrue(searchedPages.contains(page3));
+	}
+	
+	@Test
+	public void getOwnedPages() {
+		//an owned binder
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-1");
+		Binder binder = portfolioService.createNewBinder("Binder p2", "A binder with 2 page", null, author);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page1 = pageDao.createAndPersist("Page 1", "A page with content.", null, null, reloadedSection, null);
+		Page page2 = pageDao.createAndPersist("Page 2", "A page with content.", null, null, reloadedSection, null);
+		Page page3 = pageDao.createAndPersist("Anime", "Princess Mononoke is the second most famous anime of Miazaki.", null, null, reloadedSection, null);
+		dbInstance.commitAndCloseSession();
+		
+		//a not owned binder
+		BinderImpl binderAlt = binderDao.createAndPersist("Not my binder", "A binder that I don't own", null, null);
+		Section sectionAlt = binderDao.createSection("Section", "First section", null, null, binderAlt);
+		dbInstance.commitAndCloseSession();
+		
+		Section reloadedSectionAlt = binderDao.loadSectionByKey(sectionAlt.getKey());
+		Page pageAlt = pageDao.createAndPersist("Page alt", "A page with alternative content.", null, null, reloadedSectionAlt, null);
+		dbInstance.commitAndCloseSession();
+
+		//reload
+		List<Page> sectionPages = pageDao.getOwnedPages(author, null);
+		Assert.assertNotNull(sectionPages);
+		Assert.assertEquals(3, sectionPages.size());
+		Assert.assertTrue(sectionPages.contains(page1));
+		Assert.assertTrue(sectionPages.contains(page2));
+		Assert.assertTrue(sectionPages.contains(page3));
+		Assert.assertFalse(sectionPages.contains(pageAlt));
+		
+		//reload
+		List<Page> searchedPages = pageDao.getOwnedPages(author, "Miazaki");
+		Assert.assertNotNull(searchedPages);
+		Assert.assertEquals(1, searchedPages.size());
+		Assert.assertFalse(searchedPages.contains(page1));
+		Assert.assertFalse(searchedPages.contains(page2));
+		Assert.assertTrue(searchedPages.contains(page3));
+		Assert.assertFalse(sectionPages.contains(pageAlt));
+	}
+	
+	@Test
+	public void getMembers() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-1");
+		//an owned binder
+		Page page = portfolioService.appendNewPage(author, "Page 3", "A page with content.", null, null, null);
+		dbInstance.commitAndCloseSession();
+
+		//reload
+		List<Identity> owners = pageDao.getMembers(page, PortfolioRoles.owner.name());
+		Assert.assertNotNull(owners);
+		Assert.assertEquals(1, owners.size());
+		Assert.assertEquals(author, owners.get(0));
+	}
+	
+	@Test
+	public void getLastPage() {
+		//an owned binder
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("pf-1");
+		Binder binder = portfolioService.createNewBinder("Binder p2", "A binder with 2 page", null, author);
+		Section section = binderDao.createSection("Section", "First section", null, null, binder);
+		dbInstance.commitAndCloseSession();
+
+		Section reloadedSection = binderDao.loadSectionByKey(section.getKey());
+		Page page1 = pageDao.createAndPersist("Page 1", "A page with content.", null, null, reloadedSection, null);
+		sleep(1500);
+		Page page2 = pageDao.createAndPersist("Page 2", "A page with content.", null, null, reloadedSection, null);
+		sleep(1500);
+		Page page3 = portfolioService.appendNewPage(author, "Page 3", "A page with content.", null, null, null);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(page1);
+		
+		//reload
+		Page lastBinderPage = pageDao.getLastPage(author, true);
+		Assert.assertNotNull(lastBinderPage);
+		Assert.assertEquals(page2, lastBinderPage);
+		
+		//reload
+		Page lastFloatingPage = pageDao.getLastPage(author, false);
+		Assert.assertNotNull(lastFloatingPage);
+		Assert.assertEquals(page3, lastFloatingPage);
+	}
+	
+	@Test
+	public void persistPart() {
+		Page page = pageDao.createAndPersist("Page 1", "A page with content.", null, null, null, null);
+		dbInstance.commitAndCloseSession();
+		
+		HTMLPart htmlPart = new HTMLPart();
+		PageBody reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, htmlPart);
+		dbInstance.commitAndCloseSession();
+		
+		TitlePart titlePart = new TitlePart();
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, titlePart, 0);
+		dbInstance.commitAndCloseSession();
+		
+		//reload
+		List<PagePart> reloadedPageParts = pageDao.getParts(reloadedBody);
+		Assert.assertNotNull(reloadedPageParts);
+		Assert.assertEquals(2, reloadedPageParts.size());
+		Assert.assertEquals(titlePart, reloadedPageParts.get(0));
+		Assert.assertEquals(htmlPart, reloadedPageParts.get(1));
+	}
+	
+	@Test
+	public void moveParts() {
+		Page page = pageDao.createAndPersist("Page 1", "A page with content.", null, null, null, null);
+		dbInstance.commitAndCloseSession();
+		
+		HTMLPart htmlPart = new HTMLPart();
+		PageBody reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, htmlPart);
+		dbInstance.commitAndCloseSession();
+		
+		TitlePart titlePart = new TitlePart();
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, titlePart, 0);
+		dbInstance.commitAndCloseSession();
+		
+		SpacerPart spacePart = new SpacerPart();
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.persistPart(reloadedBody, spacePart, 0);
+		dbInstance.commitAndCloseSession();
+		
+		//check the order
+		List<PagePart> reloadedPageParts = pageDao.getParts(reloadedBody);
+		Assert.assertNotNull(reloadedPageParts);
+		Assert.assertEquals(3, reloadedPageParts.size());
+		Assert.assertEquals(spacePart, reloadedPageParts.get(0));
+		Assert.assertEquals(titlePart, reloadedPageParts.get(1));
+		Assert.assertEquals(htmlPart, reloadedPageParts.get(2));
+		
+		//move title part up
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.moveUpPart(reloadedBody, titlePart);
+		dbInstance.commitAndCloseSession();
+		
+		List<PagePart> moveUpPageParts = pageDao.getParts(reloadedBody);
+		Assert.assertNotNull(moveUpPageParts);
+		Assert.assertEquals(3, moveUpPageParts.size());
+		Assert.assertEquals(titlePart, moveUpPageParts.get(0));
+		Assert.assertEquals(spacePart, moveUpPageParts.get(1));
+		Assert.assertEquals(htmlPart, moveUpPageParts.get(2));
+		
+		//move space part down
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.moveDownPart(reloadedBody, spacePart);
+		dbInstance.commitAndCloseSession();
+		
+		List<PagePart> moveDownPageParts = pageDao.getParts(reloadedBody);
+		Assert.assertNotNull(moveDownPageParts);
+		Assert.assertEquals(3, moveDownPageParts.size());
+		Assert.assertEquals(titlePart, moveDownPageParts.get(0));
+		Assert.assertEquals(htmlPart, moveDownPageParts.get(1));
+		Assert.assertEquals(spacePart, moveDownPageParts.get(2));
+
+		//not useful move space part down
+		reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey());
+		pageDao.moveDownPart(reloadedBody, spacePart);
+		dbInstance.commitAndCloseSession();
 		
+		List<PagePart> moveDownPageParts2 = pageDao.getParts(reloadedBody);
+		Assert.assertNotNull(moveDownPageParts2);
+		Assert.assertEquals(3, moveDownPageParts2.size());
+		Assert.assertEquals(titlePart, moveDownPageParts2.get(0));
+		Assert.assertEquals(htmlPart, moveDownPageParts2.get(1));
+		Assert.assertEquals(spacePart, moveDownPageParts2.get(2));
 	}
 
 }