diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
index fa4dfd6180952501ceae7373d90053b8f1d5e1d5..2c861be83bc1779340ffa0d1b8177e1ff8cc4b40 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
@@ -230,6 +230,11 @@ public interface FlexiTableElement extends FormItem {
 	 */
 	public void selectAll();
 	
+	/**
+	 * Select all rows visible on the current page.
+	 */
+	public void selectPage();
+	
 	/**
 	 * Remove all multi selected index.
 	 */
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractFlexiTableRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractFlexiTableRenderer.java
index dc310a1dcf1ed9ffd22970a8eb0bda3b1c0b530c..b65247113ba09602e9ca8dabd2548bfa21653113 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractFlexiTableRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractFlexiTableRenderer.java
@@ -405,11 +405,22 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
 			sb.append("<div class='o_table_footer'><div class='o_table_checkall input-sm'>");
 
 			if(ftE.isSelectAllEnable()) {
+				FlexiTableDataModel<?> dataModel = ftE.getTableDataModel();
+				int numOfRows = dataModel.getRowCount();
+				
 				sb.append("<a id='")
 				  .append(dispatchId).append("_sa' href=\"javascript:o_table_toggleCheck('").append(formName).append("', true);")
 				  .append(FormJSHelper.getXHRFnCallFor(ftE.getRootForm(), dispatchId, 1, true, true, true,
 						  new NameValuePair("select", "checkall")))
-				  .append("\"><i class='o_icon o_icon-lg o_icon_check_on'> </i> <span>").append(translator.translate("form.checkall"))
+				  .append("\"><i class='o_icon o_icon-lg o_icon_check_on'> </i> <span>")
+				  .append(translator.translate("form.checkall.numbered", new String[] { Integer.toString(numOfRows) }))
+				  .append("</span></a>");
+				
+				sb.append("<a id='")
+				  .append(dispatchId).append("_sa' href=\"javascript:o_table_toggleCheck('").append(formName).append("', true);")
+				  .append(FormJSHelper.getXHRFnCallFor(ftE.getRootForm(), dispatchId, 1, true, true, true,
+						  new NameValuePair("select", "checkpage")))
+				  .append("\"><i class='o_icon o_icon-lg o_icon_check_on'> </i> <span>").append(translator.translate("form.checkpage"))
 				  .append("</span></a>");
 	
 				sb.append("<a id='")
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
index d6fad8e3d64685762740498a1426cb1cff648bb3..3e3819ce9123fd00275eaebb9568ab7343d3b4e9 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
@@ -163,7 +163,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		for(int i=dataModel.getTableColumnModel().getColumnCount(); i-->0; ) {
 			FlexiColumnModel col = dataModel.getTableColumnModel().getColumnModel(i);
 			if(col.isDefaultVisible()) {
-				enabledColumnIndex.add(new Integer(col.getColumnIndex()));
+				enabledColumnIndex.add(Integer.valueOf(col.getColumnIndex()));
 			}
 		}
 
@@ -923,6 +923,8 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 			doExport(ureq);
 		} else if(dispatchuri != null && select != null && select.equals("checkall")) {
 			selectAll();
+		} else if(dispatchuri != null && select != null && select.equals("checkpage")) {
+			selectPage();
 		} else if(dispatchuri != null && select != null && select.equals("uncheckall")) {
 			doUnSelectAll();
 		} else if(customButton != null
@@ -998,7 +1000,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		} else if(searchFieldEl.getComponent() == source) {
 			if(event instanceof AutoCompleteEvent) {
 				AutoCompleteEvent ace = (AutoCompleteEvent)event;
-				doSearch(ureq, FlexiTableSearchEvent.QUICK_SEARCH_KEY_SELECTION, ace.getKey(), null);
+				doSearch(ureq, FlexiTableReduceEvent.QUICK_SEARCH_KEY_SELECTION, ace.getKey(), null);
 			}
 		}
 	}
@@ -1081,7 +1083,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		for(int i=dataModel.getRowCount(); i-->0; ) {
 			Object obj = dataModel.getObject(i);
 			if(obj != null && selectedObjects.contains(obj)) {
-				multiSelectedIndex.put(new Integer(i), obj);
+				multiSelectedIndex.put(Integer.valueOf(i), obj);
 			}
 		}
 		
@@ -1184,7 +1186,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		}
 		component.setDirty(true);
 		
-		getRootForm().fireFormEvent(ureq, new FlexiTableFilterEvent(FlexiTableFilterEvent.FILTER, this,
+		getRootForm().fireFormEvent(ureq, new FlexiTableFilterEvent(FlexiTableReduceEvent.FILTER, this,
 				getQuickSearchString(), getSelectedFilters(), getSelectedExtendedFilters(), null, FormEvent.ONCLICK));
 	}
 	
@@ -1213,7 +1215,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 			}
 		}
 
-		getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(FlexiTableSearchEvent.EXTENDED_FILTER, this,
+		getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(FlexiTableReduceEvent.EXTENDED_FILTER, this,
 				getSearchText(), getSelectedFilters(), getSelectedExtendedFilters(), getConditionalQueries(), FormEvent.ONCLICK));
 	}
 	
@@ -1512,7 +1514,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 			search = searchFieldEl.getValue();
 		}
 		List<String> condQueries = extendedSearchCtrl.getConditionalQueries();
-		doSearch(ureq, FlexiTableSearchEvent.SEARCH, search, condQueries);
+		doSearch(ureq, FlexiTableReduceEvent.SEARCH, search, condQueries);
 	}
 	
 	protected void evalSearchRequest(UserRequest ureq) {
@@ -1528,9 +1530,9 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		String search = searchFieldEl.getValue();
 
 		if(key != null) {
-			doSearch(ureq, FlexiTableSearchEvent.QUICK_SEARCH_KEY_SELECTION, key, null);
+			doSearch(ureq, FlexiTableReduceEvent.QUICK_SEARCH_KEY_SELECTION, key, null);
 		} else if(StringHelper.containsNonWhitespace(search)) {
-			doSearch(ureq, FlexiTableSearchEvent.QUICK_SEARCH, search, null);
+			doSearch(ureq, FlexiTableReduceEvent.QUICK_SEARCH, search, null);
 		} else {
 			resetSearch(ureq);
 		}
@@ -1559,7 +1561,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		}
 		if(StringHelper.containsNonWhitespace(search)) {
 			searchFieldEl.setValue(search);
-			doSearch(ureq, FlexiTableSearchEvent.QUICK_SEARCH, search, null);
+			doSearch(ureq, FlexiTableReduceEvent.QUICK_SEARCH, search, null);
 		}
 	}
 	
@@ -1574,11 +1576,30 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		int numOfRows = getRowCount();
 		for(int i=0; i<numOfRows;i++) {
 			Object objectRow = dataModel.getObject(i);
-			multiSelectedIndex.put(new Integer(i), objectRow);
+			multiSelectedIndex.put(Integer.valueOf(i), objectRow);
 		}
 		allSelectedNeedLoadOfWholeModel = true;
 	}
 	
+	@Override
+	public void selectPage() {
+		if(multiSelectedIndex != null) {
+			multiSelectedIndex.clear();
+		} else {
+			multiSelectedIndex = new HashMap<>();
+		}
+		
+		int firstRow = getFirstRow();
+		int maxRows = getMaxRows();
+		int rows = dataModel.getRowCount();
+		int lastRow = Math.min(rows, firstRow + maxRows);
+		for (int i = firstRow; i < lastRow; i++) {
+			Object objectRow = dataModel.getObject(i);
+			multiSelectedIndex.put(Integer.valueOf(i), objectRow);
+		}
+		allSelectedNeedLoadOfWholeModel = false;
+	}
+	
 	protected void doUnSelectAll() {
 		if(multiSelectedIndex != null) {
 			multiSelectedIndex.clear();
@@ -1668,7 +1689,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 
 	@Override
 	public boolean isMultiSelectedIndex(int index) {
-		return multiSelectedIndex != null && multiSelectedIndex.containsKey(new Integer(index));
+		return multiSelectedIndex != null && multiSelectedIndex.containsKey(Integer.valueOf(index));
 	}
 	
 	protected void toogleSelectIndex(String selection) {
@@ -1685,7 +1706,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		}
 		
 		try {
-			Integer row = new Integer(rowStr);
+			Integer row = Integer.valueOf(rowStr);
 			if(multiSelectedIndex.containsKey(row)) {
 				if(multiSelectedIndex.remove(row) != null && allSelectedNeedLoadOfWholeModel) {
 					allSelectedNeedLoadOfWholeModel = false;
@@ -1703,12 +1724,12 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		if(multiSelectedIndex == null) {
 			multiSelectedIndex = new HashMap<>();
 		}
-		//selection format row_{formDispId}-{index}
+		// selection format row_{formDispId}-{index}
 		if(selections != null && selections.length > 0) {
 			int firstIndex = getPageSize() * getPage();
 			int lastResult = firstIndex + getPageSize() -1;
 			for(int i=firstIndex; i<lastResult; i++) {
-				multiSelectedIndex.remove(new Integer(i));
+				multiSelectedIndex.remove(Integer.valueOf(i));
 			}
 
 			for(String selection:selections) {	
@@ -1717,7 +1738,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 					String rowStr = selection.substring(index+1);
 					int row = Integer.parseInt(rowStr);
 					Object objectRow = dataModel.getObject(row);
-					multiSelectedIndex.put(new Integer(row), objectRow);
+					multiSelectedIndex.put(Integer.valueOf(row), objectRow);
 				}
 			}
 		}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_de.properties
index 9fd2ddba78e45034a3b0ea54da2c337e629d4885..88bcb8bda50509d6252556d0a6a445081e96a906 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_de.properties
@@ -2,4 +2,6 @@
 page.size.a=Zeige {0} bis {1} von {2} Zeilen.
 page.size.b=Eintr\u00E4ge pro Seite
 show.all=Alle
-remove.filters=Filter entfernen
\ No newline at end of file
+remove.filters=Filter entfernen
+form.checkall.numbered=Alle {0} Zeilen ausw\u00E4hlen
+form.checkpage=Alle Zeilen der Seite ausw\u00E4hlen
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_en.properties
index 006a8c0051895681015b31be27b822e83b4d1313..a3062842fa1801a01fb1cebcf6fa6c95d7fac7e0 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_en.properties
@@ -2,4 +2,6 @@
 page.size.a=Show {0} to {1} of {2} rows.
 page.size.b=Entries per page
 show.all=All
-remove.filters=Remove filters
\ No newline at end of file
+remove.filters=Remove filters
+form.checkall.numbered=Select all {0} rows
+form.checkpage=Select page's rows
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_fr.properties
index efeb7e90534bc12aef7f1f3ff480e23e6a98fc80..f6771ff811217194c2f1d9a28424b1b8eb782b54 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/_i18n/LocalStrings_fr.properties
@@ -3,3 +3,5 @@ page.size.a=Montre {0} \u00E0 {1} de {2} lignes.
 page.size.b=Entr\u00E9es par page
 remove.filters=Enlever les filtres
 show.all=Toutes
+form.checkall.numbered=S\u00E9lectionner toutes les {0} lignes
+form.checkpage=S\u00E9lectionner la page
diff --git a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java
index 768c7fc55b50f2fa8bd068152341c66ce50dd15f..c4742d70ff27b154ec143a8ca1384072be9cdb37 100644
--- a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java
+++ b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java
@@ -168,10 +168,12 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf {
 	private VFSStatus deleteBasefile() {
 		VFSStatus status = VFSConstants.NO;
 		try {
-			Files.delete(getBasefile().toPath());
+			if(!Files.deleteIfExists(getBasefile().toPath())) {
+				log.debug("Cannot delete base file because it doesn't exist: {}", this);
+			}
 			status = VFSConstants.YES;
 		} catch(IOException e) {
-			log.error("Cannot delete base file: " + this, e);
+			log.error("Cannot delete base file: {}", this, e);
 		}
 		return status;
 	}
diff --git a/src/main/java/org/olat/core/util/xml/XStreamHelper.java b/src/main/java/org/olat/core/util/xml/XStreamHelper.java
index 5efa6c9d26a9992052de3b03ebc453a6a49485f2..446bc767942469d0dd6a0ae4c64ff15e5b8738a7 100644
--- a/src/main/java/org/olat/core/util/xml/XStreamHelper.java
+++ b/src/main/java/org/olat/core/util/xml/XStreamHelper.java
@@ -178,8 +178,7 @@ public class XStreamHelper {
 	 */
 	public static Object xstreamClone(Object in) {
 		String data = unconfiguredXStream.toXML(in);
-		Object out = unconfiguredXStream.fromXML(data);
-		return out;
+		return unconfiguredXStream.fromXML(data);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java
index 2c749c57f57e623a127a5d49d44ccf21c3dfdb15..5d9a17177256ccbb8b8ba8e17cdd4920f21547e5 100644
--- a/src/main/java/org/olat/course/CourseFactory.java
+++ b/src/main/java/org/olat/course/CourseFactory.java
@@ -552,11 +552,11 @@ public class CourseFactory {
 		CourseConfigManager courseConfigMgr = CoreSpringFactory.getImpl(CourseConfigManager.class);
 		courseConfigMgr.deleteConfigOf(newCourse);
 
-		// Unzip course strucure in new course
+		// Unzip course structure in new course
 		LocalFolderImpl courseBaseContainer = newCourse.getCourseBaseContainer();
 		File fCanonicalCourseBasePath = courseBaseContainer.getBasefile();
 		if (ZipUtil.unzip(zipFile, fCanonicalCourseBasePath)) {
-			// Load course strucure now
+			// Load course structure now
 			try {
 				newCourse.load();
 				CourseConfig cc = courseConfigMgr.loadConfigFor(newCourse);
diff --git a/src/main/java/org/olat/fileresource/types/FileResource.java b/src/main/java/org/olat/fileresource/types/FileResource.java
index c7dd66add0fc226ac72e47d4518e0c1955f815b2..dcd6535fb42fa74b883ceb1e9bb2a6776368af95 100644
--- a/src/main/java/org/olat/fileresource/types/FileResource.java
+++ b/src/main/java/org/olat/fileresource/types/FileResource.java
@@ -69,12 +69,12 @@ public class FileResource implements OLATResourceable {
 	
 	public FileResource() {
 		typeName = GENERIC_TYPE_NAME;
-		typeId = new Long(CodeHelper.getForeverUniqueID());
+		typeId = Long.valueOf(CodeHelper.getForeverUniqueID());
 	}
 	
 	public FileResource(String typeName) {
 		this.typeName = typeName;
-		typeId = new Long(CodeHelper.getForeverUniqueID());
+		typeId = Long.valueOf(CodeHelper.getForeverUniqueID());
 	}
 
 	/**
diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
index a4bcc8571e862fbda217ee9c88339ef88ce0a3ec..ff15ce66fba072e8e44564e7bd31d2c44342694e 100644
--- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java
+++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
@@ -66,6 +66,9 @@ public interface CurriculumService {
 	public Curriculum getCurriculum(CurriculumRef ref);
 	
 	public Curriculum updateCurriculum(Curriculum curriculum);
+
+	public void deleteCurriculum(CurriculumRef curriculum);
+	
 	
 	public List<Curriculum> getCurriculums(Collection<? extends CurriculumRef> refs);
 	
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
index 75960f18f010bac9acb6f1f017d9391f27bc472f..e308f50cfc3d49dbe6cd12739942fdede8ddd8fa 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
@@ -27,6 +27,7 @@ import java.util.stream.Collectors;
 
 import javax.persistence.TypedQuery;
 
+import org.olat.basesecurity.Group;
 import org.olat.basesecurity.GroupRoles;
 import org.olat.basesecurity.IdentityRef;
 import org.olat.basesecurity.OrganisationRoles;
@@ -342,6 +343,13 @@ public class CurriculumDAO {
 		return dbInstance.getCurrentEntityManager().merge(curriculum);
 	}
 	
+	public void delete(CurriculumImpl curriculum) {
+		Group group = curriculum.getGroup();
+		groupDao.removeMemberships(group);
+		dbInstance.getCurrentEntityManager().remove(curriculum);
+		groupDao.removeGroup(group);
+	}
+	
 	public List<Identity> getMembersIdentity(CurriculumRef curriculum, String role) {
 		StringBuilder sb = new StringBuilder(256);
 		sb.append("select ident from curriculum cur")
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumImportHandler.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumImportHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc26693615b9a69ee58b3ece8c91fc1f028b2120
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumImportHandler.java
@@ -0,0 +1,227 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.manager;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.logging.log4j.Logger;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
+import org.olat.core.id.Organisation;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.PathUtils;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.WebappHelper;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.fileresource.types.ResourceEvaluation;
+import org.olat.modules.curriculum.Curriculum;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementImpl;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs;
+import org.olat.modules.curriculum.model.CurriculumImpl;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryStatusEnum;
+import org.olat.repository.handlers.RepositoryHandler;
+import org.olat.repository.handlers.RepositoryHandlerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ * Initial date: 19 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class CurriculumImportHandler {
+	
+	private static final Logger log = Tracing.createLoggerFor(CurriculumImportHandler.class);
+	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
+	private RepositoryHandlerFactory repositoryHandlerFactory;
+	
+	public String getCurriculumName(File archive) {
+		try (FileSystem fileSystem=FileSystems.newFileSystem(archive.toPath(), null)) {
+			Path curriculumXml = fileSystem.getPath("/curriculum.xml");
+			Curriculum curriculum = CurriculumXStream.curriculumFromPath(curriculumXml);
+			if(curriculum != null) {
+				return curriculum.getDisplayName();
+			}
+		} catch (Exception e) {
+			log.error("", e);
+		}
+		return null;
+	}
+
+	public boolean importCurriculum(File archive, String curriculumName, Organisation organisation, Identity author, Locale locale) {
+		try (FileSystem fileSystem=FileSystems.newFileSystem(archive.toPath(), null)) {
+			Path curriculumXml = fileSystem.getPath("/curriculum.xml");
+			Curriculum curriculum = CurriculumXStream.curriculumFromPath(curriculumXml);
+			if(curriculum == null) {
+				return false;
+			}
+			if(StringHelper.containsNonWhitespace(curriculumName)) {
+				curriculum.setDisplayName(curriculumName);
+			}
+			Map<Long,CurriculumElement> archiveKeyToCurriculumElements = new HashMap<>();
+			importCurriculumStructure(curriculum, organisation, archiveKeyToCurriculumElements);
+			
+			Path curriculumEntriesXml = fileSystem.getPath("/curriculum_entries.xml");
+			CurriculumElementToRepositoryEntryRefs entryRefs = CurriculumXStream.entryRefsFromPath(curriculumEntriesXml);
+			if(entryRefs != null) {
+				importEntries(entryRefs, archiveKeyToCurriculumElements, organisation, fileSystem, author, locale);
+			}
+			return true;
+		} catch (Exception e) {
+			log.error("", e);
+			return false;
+		}
+	}
+	
+	private void importEntries(CurriculumElementToRepositoryEntryRefs entryRefs,
+			Map<Long,CurriculumElement> archiveKeyToCurriculumElements, Organisation organisation,
+			FileSystem fileSystem, Identity author, Locale locale) throws IOException {
+		List<CurriculumElementToRepositoryEntryRef> entriesRefs = entryRefs.getEntryRefs();
+		Map<Long,RepositoryEntry> archivedRepositoryEntryKeys = new HashMap<>();
+		
+		for(CurriculumElementToRepositoryEntryRef entryRef:entriesRefs) {
+			CurriculumElement element = archiveKeyToCurriculumElements.get(entryRef.getCurriculumElementKey());
+			if(element == null) {
+				continue;
+			}
+			
+			RepositoryEntry entry;
+			if(archivedRepositoryEntryKeys.containsKey(entryRef.getRepositoryEntryKey())) {
+				entry = archivedRepositoryEntryKeys.get(entryRef.getRepositoryEntryKey());
+			} else {
+				entry = importRepositoryEntry(entryRef, organisation, fileSystem, author, locale);
+			}
+			if(entry != null) {
+				curriculumService.addRepositoryEntry(element, entry, false);
+			}
+			archivedRepositoryEntryKeys.put(entryRef.getRepositoryEntryKey(), entry);
+		}
+	}
+	
+	private RepositoryEntry importRepositoryEntry(CurriculumElementToRepositoryEntryRef archivedRef, Organisation organisation,
+			FileSystem fileSystem, Identity author, Locale locale) throws IOException {
+		String zipName = "repo_" + archivedRef.getRepositoryEntryKey() + ".zip";
+		Path curriculumXml = fileSystem.getPath("/" + zipName);
+		
+		RepositoryEntry importedEntry = null;
+		if(Files.exists(curriculumXml)) {
+			File tmpArchive = new File(WebappHelper.getTmpDir(), UUID.randomUUID() + zipName);
+			tmpArchive.mkdirs();
+			PathUtils.copyFileToDir(curriculumXml, tmpArchive.getParentFile(), tmpArchive.getName());
+
+			for(String type:repositoryHandlerFactory.getSupportedTypes()) {
+				RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(type);
+				ResourceEvaluation eval = handler.acceptImport(tmpArchive, tmpArchive.getName());
+				if(eval != null && eval.isValid()) {
+					importedEntry = handler.importResource(author, archivedRef.getRepositoryEntryInitialAuthor(),
+							archivedRef.getRepositoryEntryDisplayname(), archivedRef.getRepositoryEntryDescription(),
+							true, organisation, locale, tmpArchive, zipName);
+					dbInstance.commit();
+					if("CourseModule".equals(importedEntry.getOlatResource().getResourceableTypeName())) {
+						ICourse course = CourseFactory.loadCourse(importedEntry);
+						CourseFactory.publishCourse(course, RepositoryEntryStatusEnum.preparation, false, false, author, locale);
+					}
+				}
+			}
+			
+			if(!Files.deleteIfExists(tmpArchive.toPath())) {
+				log.warn("Cannot delete {}", tmpArchive.getAbsolutePath());
+			}
+			dbInstance.commitAndCloseSession();
+		}
+		return importedEntry;
+	}
+
+	private void importCurriculumStructure(Curriculum archiveCurriculum, Organisation organisation, Map<Long,CurriculumElement> archiveKeyToCurriculumElements) {
+		Curriculum curriculum = curriculumService
+				.createCurriculum(archiveCurriculum.getIdentifier(), archiveCurriculum.getDisplayName(), archiveCurriculum.getDescription(), organisation);
+		curriculum.setDegree(archiveCurriculum.getDegree());
+		curriculum.setStatus(archiveCurriculum.getStatus());
+		curriculum = curriculumService.updateCurriculum(curriculum);
+		
+		List<CurriculumElementType> elementTypes = curriculumService.getCurriculumElementTypes();
+		for(CurriculumElement rootElement:((CurriculumImpl)archiveCurriculum).getRootElements()) {
+			importCurriculumElements(curriculum, rootElement, null, elementTypes, archiveKeyToCurriculumElements);
+		}
+	}
+
+	private void importCurriculumElements(Curriculum curriculum, CurriculumElement archivedElement,
+			CurriculumElement parentElement, List<CurriculumElementType> elementTypes, Map<Long,CurriculumElement> archiveKeyToCurriculumElements) {
+		if(archivedElement == null) return;
+		
+		CurriculumElementType elementType = findType(archivedElement.getType(), elementTypes);
+		
+		CurriculumElement element = curriculumService.createCurriculumElement(archivedElement.getIdentifier(), archivedElement.getDisplayName(), archivedElement.getElementStatus(),
+				archivedElement.getBeginDate(), archivedElement.getEndDate(), parentElement, elementType,
+				archivedElement.getCalendars(), archivedElement.getLectures(), curriculum);
+		element.setElementStatus(archivedElement.getElementStatus());
+		
+		archiveKeyToCurriculumElements.put(archivedElement.getKey(), element);
+		
+		for(CurriculumElement childElement:((CurriculumElementImpl)archivedElement).getChildren()) {
+			importCurriculumElements(curriculum, childElement, element, elementTypes, archiveKeyToCurriculumElements);
+		}
+	}
+	
+	private CurriculumElementType findType(CurriculumElementType archivedType, List<CurriculumElementType> elementTypes) {
+		if(archivedType == null || elementTypes.isEmpty()) return null;
+		
+		for(CurriculumElementType elementType:elementTypes) {
+			if(elementType.getIdentifier() != null && elementType.getIdentifier().equals(archivedType.getIdentifier())) {
+				return elementType;
+			}
+		}
+		
+		for(CurriculumElementType elementType:elementTypes) {
+			if(elementType.getDisplayName() != null && elementType.getDisplayName().equals(archivedType.getDisplayName())) {
+				return elementType;
+			}
+		}
+		
+		CurriculumElementType newElementType = curriculumService.createCurriculumElementType(archivedType.getIdentifier(),
+				archivedType.getDisplayName(), archivedType.getDescription(), archivedType.getExternalId());
+		elementTypes.add(newElementType);
+		dbInstance.commit();
+		return newElementType;
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
index 97969f7a7cb8d3a39a22be69fcb053edc2e1c997..af7adb3108d3ac91cad6a006df9026abc27a0a4f 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
@@ -72,6 +72,7 @@ import org.olat.modules.curriculum.model.CurriculumElementRepositoryEntryViews;
 import org.olat.modules.curriculum.model.CurriculumElementSearchInfos;
 import org.olat.modules.curriculum.model.CurriculumElementSearchParams;
 import org.olat.modules.curriculum.model.CurriculumElementWebDAVInfos;
+import org.olat.modules.curriculum.model.CurriculumImpl;
 import org.olat.modules.curriculum.model.CurriculumInfos;
 import org.olat.modules.curriculum.model.CurriculumMember;
 import org.olat.modules.curriculum.model.CurriculumRefImpl;
@@ -141,6 +142,18 @@ public class CurriculumServiceImpl implements CurriculumService, OrganisationDat
 		return curriculumDao.update(curriculum);
 	}
 	
+	@Override
+	public void deleteCurriculum(CurriculumRef curriculumRef) {
+		CurriculumImpl curriculum = (CurriculumImpl)getCurriculum(curriculumRef);
+		for(CurriculumElement rootElement:curriculum.getRootElements()) {
+			deleteCurriculumElement(rootElement);
+		}
+		dbInstance.commit();
+		curriculum = (CurriculumImpl)getCurriculum(curriculumRef);
+		curriculumDao.delete(curriculum);
+		dbInstance.commit();
+	}
+
 	@Override
 	public List<Curriculum> getCurriculums(Collection<? extends CurriculumRef> refs) {
 		return curriculumDao.loadByKeys(refs);
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumXStream.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumXStream.java
new file mode 100644
index 0000000000000000000000000000000000000000..30401379ad8b63a4e62271ee2fe7d62e26e23034
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumXStream.java
@@ -0,0 +1,128 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.manager;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.logging.log4j.Logger;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.io.ShieldOutputStream;
+import org.olat.core.util.xml.XStreamHelper;
+import org.olat.modules.curriculum.Curriculum;
+import org.olat.modules.curriculum.CurriculumCalendars;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumElementToTaxonomyLevel;
+import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumElementTypeManagedFlag;
+import org.olat.modules.curriculum.CurriculumLectures;
+import org.olat.modules.curriculum.model.CurriculumElementImpl;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs;
+import org.olat.modules.curriculum.model.CurriculumElementToTaxonomyLevelImpl;
+import org.olat.modules.curriculum.model.CurriculumElementTypeImpl;
+import org.olat.modules.curriculum.model.CurriculumImpl;
+import org.olat.modules.portfolio.handler.BinderXStream;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.security.ExplicitTypePermission;
+
+/**
+ * 
+ * Initial date: 17 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CurriculumXStream {
+	
+	private static final Logger log = Tracing.createLoggerFor(BinderXStream.class);
+	private static final XStream xstream = XStreamHelper.createXStreamInstanceForDBObjects();
+	
+	static {
+		XStream.setupDefaultSecurity(xstream);
+		Class<?>[] types = new Class[] {
+				Curriculum.class, CurriculumImpl.class, CurriculumElement.class, CurriculumElementImpl.class,
+				CurriculumElementType.class, CurriculumElementTypeImpl.class,
+				CurriculumElementTypeManagedFlag.class, CurriculumLectures.class, CurriculumCalendars.class,
+				CurriculumElementToTaxonomyLevel.class, CurriculumElementToTaxonomyLevelImpl.class,
+				CurriculumElementToRepositoryEntryRef.class, CurriculumElementToRepositoryEntryRefs.class,
+				Hashtable.class, HashMap.class
+		};
+		xstream.addPermission(new ExplicitTypePermission(types));
+
+		xstream.omitField(CurriculumImpl.class, "group");
+		xstream.omitField(CurriculumImpl.class, "organisation");
+		xstream.omitField(CurriculumElementImpl.class, "group");
+		xstream.omitField(CurriculumElementImpl.class, "curriculumParent");
+		xstream.omitField(CurriculumElementImpl.class, "taxonomyLevels");
+	}
+	
+	public static final Curriculum curriculumFromPath(Path path)
+	throws IOException {
+		try(InputStream inStream = Files.newInputStream(path)) {
+			return (Curriculum)xstream.fromXML(inStream);
+		} catch (Exception e) {
+			log.error("Cannot import this map: {}", path, e);
+			return null;
+		}
+	}
+	
+	public static final CurriculumElementToRepositoryEntryRefs entryRefsFromPath(Path path)
+	throws IOException {
+		try(InputStream inStream = Files.newInputStream(path)) {
+			return (CurriculumElementToRepositoryEntryRefs)xstream.fromXML(inStream);
+		} catch (Exception e) {
+			log.error("Cannot import this map: {}", path, e);
+			return null;
+		}
+	}
+	
+	public static final Curriculum fromXml(String xml) {
+		return (Curriculum)xstream.fromXML(xml);
+	}
+	
+	public static final String toXml(Curriculum curriculum) {
+		return xstream.toXML(curriculum);
+	}
+	
+	public static final void toStream(Curriculum curriculum, ZipOutputStream zout)
+	throws IOException {
+		try(OutputStream out=new ShieldOutputStream(zout)) {
+			xstream.toXML(curriculum, out);
+		} catch (Exception e) {
+			log.error("Cannot export this curriculum: {}", curriculum, e);
+		}
+	}
+	
+	public static final void toStream(CurriculumElementToRepositoryEntryRefs entryRefs, ZipOutputStream zout)
+	throws IOException {
+		try(OutputStream out=new ShieldOutputStream(zout)) {
+			xstream.toXML(entryRefs, out);
+		} catch (Exception e) {
+			log.error("Cannot export these entries references: {}", entryRefs, e);
+		}
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/manager/ExportCurriculumMediaResource.java b/src/main/java/org/olat/modules/curriculum/manager/ExportCurriculumMediaResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..403a7b8fccd5996378cd6e4eb11ff3ba69d0f088
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/manager/ExportCurriculumMediaResource.java
@@ -0,0 +1,236 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.manager;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.logging.log4j.Logger;
+import org.hibernate.Hibernate;
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.gui.media.MediaResource;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.FileUtils;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.io.HttpServletResponseOutputStream;
+import org.olat.core.util.io.ShieldOutputStream;
+import org.olat.modules.curriculum.Curriculum;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementImpl;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs;
+import org.olat.modules.curriculum.model.CurriculumImpl;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.handlers.RepositoryHandler;
+import org.olat.repository.handlers.RepositoryHandlerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 17 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ExportCurriculumMediaResource implements MediaResource {
+	private static final Logger log = Tracing.createLoggerFor(ExportCurriculumMediaResource.class);
+	
+	private final Curriculum curriculum;
+	
+	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
+	private RepositoryHandlerFactory handlerFactory;
+	
+	public ExportCurriculumMediaResource(Curriculum curriculum) {
+		CoreSpringFactory.autowireObject(this);
+		this.curriculum = curriculum;
+	}
+	
+	@Override
+	public long getCacheControlDuration() {
+		return 0;
+	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
+	
+	@Override
+	public String getContentType() {
+		return "application/zip";
+	}
+
+	@Override
+	public Long getSize() {
+		return null;
+	}
+
+	@Override
+	public InputStream getInputStream() {
+		return null;
+	}
+
+	@Override
+	public Long getLastModified() {
+		return null;
+	}
+
+	@Override
+	public void release() {
+		//
+	}
+	
+	@Override
+	public void prepare(HttpServletResponse hres) {
+		try {
+			hres.setCharacterEncoding("UTF-8");
+		} catch (Exception e) {
+			log.error("", e);
+		}
+		
+		try(ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) {
+			Curriculum loadedCurriculum = curriculumService.getCurriculum(curriculum);
+			unproxy(loadedCurriculum);
+			String label = loadedCurriculum.getDisplayName();
+			String secureLabel = StringHelper.transformDisplayNameToFileSystemName(label);
+
+			String file = secureLabel + ".zip";
+			hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + StringHelper.urlEncodeUTF8(file));			
+			hres.setHeader("Content-Description", StringHelper.urlEncodeUTF8(label));
+
+			zout.setLevel(9);
+			
+			// curriculum structure
+			zout.putNextEntry(new ZipEntry("curriculum.xml"));
+			CurriculumXStream.toStream(loadedCurriculum, zout);
+			zout.closeEntry();
+			
+			// curriculum element to repository entry
+			List<ExportRepositoryEntry> collectedEntries = new ArrayList<>();
+			for(CurriculumElement element:((CurriculumImpl)loadedCurriculum).getRootElements()) {
+				collectEntries(element, collectedEntries);
+			}
+			CurriculumElementToRepositoryEntryRefs entryRefs = new CurriculumElementToRepositoryEntryRefs(new ArrayList<>());
+			for(ExportRepositoryEntry collectedEntry:collectedEntries) {
+				entryRefs.getEntryRefs().add(new CurriculumElementToRepositoryEntryRef(collectedEntry.getEntry(),
+						collectedEntry.getCurriculumElement().getKey()));
+			}
+			zout.putNextEntry(new ZipEntry("curriculum_entries.xml"));
+			CurriculumXStream.toStream(entryRefs, zout);
+			zout.closeEntry();
+			
+			// export repository entries
+			Set<Long> duplicates = new HashSet<>();
+			for(ExportRepositoryEntry exportedEntry:collectedEntries) {
+				if(!duplicates.contains(exportedEntry.getEntry().getKey())) {
+					exportEntries(exportedEntry, zout);
+					duplicates.add(exportedEntry.getEntry().getKey());
+				}
+			}
+		} catch (Exception e) {
+			log.error("", e);
+		}
+	}
+	
+	private void exportEntries(ExportRepositoryEntry exportedEntry, ZipOutputStream zout)
+	throws IOException {
+		RepositoryEntry entry = exportedEntry.getEntry();
+		OLATResourceable ores = entry.getOlatResource();
+		RepositoryHandler handler = handlerFactory.getRepositoryHandler(entry);
+		
+		MediaResource mr = handler.getAsMediaResource(ores);
+		zout.putNextEntry(new ZipEntry("repo_" + entry.getKey() + ".zip"));
+
+		try(OutputStream out=new ShieldOutputStream(zout);
+				InputStream in = mr.getInputStream()) {
+			if(in == null) {
+				HttpServletResponseOutputStream response = new HttpServletResponseOutputStream(out);
+				mr.prepare(response);
+			} else {
+				FileUtils.copy(in, out);
+			}
+		} catch(Exception e) {
+			log.error("", e);
+		}
+		zout.closeEntry();
+	}
+	
+	private void collectEntries(CurriculumElement curriculumElement, List<ExportRepositoryEntry> collectedEntries) {
+		if(curriculumElement == null) return;
+		
+		List<RepositoryEntry> entries = curriculumService.getRepositoryEntries(curriculumElement);
+		for(RepositoryEntry entry:entries) {
+			collectedEntries.add(new ExportRepositoryEntry(entry, curriculumElement));
+		}
+
+		for(CurriculumElement element:((CurriculumElementImpl)curriculumElement).getChildren()) {
+			collectEntries(element, collectedEntries);
+		}
+	}
+	
+	private void unproxy(Curriculum loadedCurriculum) {
+		loadedCurriculum.getOrganisation();
+		for(CurriculumElement element:((CurriculumImpl)loadedCurriculum).getRootElements()) {
+			unproxy(element);
+		}
+	}
+	
+	private void unproxy(CurriculumElement curriculumElement) {
+		if(curriculumElement == null) return;
+		
+		curriculumElement.getCurriculum();
+		curriculumElement.setType(Hibernate.unproxy(curriculumElement.getType(), CurriculumElementType.class));
+		for(CurriculumElement element:((CurriculumElementImpl)curriculumElement).getChildren()) {
+			unproxy(element);
+		}
+	}
+	
+	private static class ExportRepositoryEntry {
+		
+		private final RepositoryEntry entry;
+		private final CurriculumElement curriculumElement;
+		
+		public ExportRepositoryEntry(RepositoryEntry entry, CurriculumElement curriculumElement) {
+			this.entry = entry;
+			this.curriculumElement = curriculumElement;
+		}
+		
+		public RepositoryEntry getEntry() {
+			return entry;
+		}
+		
+		public CurriculumElement getCurriculumElement() {
+			return curriculumElement;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRef.java b/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRef.java
new file mode 100644
index 0000000000000000000000000000000000000000..edcc28f6d31d9f7063b0054201f5105e0974bcc6
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRef.java
@@ -0,0 +1,91 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.model;
+
+import org.olat.repository.RepositoryEntry;
+
+/**
+ * This is only used for import/export operations
+ * 
+ * Initial date: 19 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CurriculumElementToRepositoryEntryRef {
+	
+	private Long repositoryEntryKey;
+	private String repositoryEntryDisplayname;
+	private String repositoryEntryDescription;
+	private String repositoryEntryInitialAuthor;
+	
+	private Long curriculumElementKey;
+	
+	public CurriculumElementToRepositoryEntryRef() {
+		//
+	}
+	
+	public CurriculumElementToRepositoryEntryRef(RepositoryEntry repositoryEntry, Long curriculumElementKey) {
+		repositoryEntryKey = repositoryEntry.getKey();
+		repositoryEntryDisplayname = repositoryEntry.getDisplayname();
+		repositoryEntryDescription = repositoryEntry.getDescription();
+		repositoryEntryInitialAuthor = repositoryEntry.getInitialAuthor();
+		this.curriculumElementKey = curriculumElementKey;
+	}
+	
+	public Long getRepositoryEntryKey() {
+		return repositoryEntryKey;
+	}
+	
+	public void setRepositoryEntryKey(Long repositoryEntryKey) {
+		this.repositoryEntryKey = repositoryEntryKey;
+	}
+	
+	public String getRepositoryEntryDisplayname() {
+		return repositoryEntryDisplayname;
+	}
+
+	public void setRepositoryEntryDisplayname(String repositoryEntryDisplayname) {
+		this.repositoryEntryDisplayname = repositoryEntryDisplayname;
+	}
+
+	public String getRepositoryEntryDescription() {
+		return repositoryEntryDescription;
+	}
+
+	public void setRepositoryEntryDescription(String repositoryEntryDescription) {
+		this.repositoryEntryDescription = repositoryEntryDescription;
+	}
+
+	public String getRepositoryEntryInitialAuthor() {
+		return repositoryEntryInitialAuthor;
+	}
+
+	public void setRepositoryEntryInitialAuthor(String repositoryEntryInitialAuthor) {
+		this.repositoryEntryInitialAuthor = repositoryEntryInitialAuthor;
+	}
+
+	public Long getCurriculumElementKey() {
+		return curriculumElementKey;
+	}
+	
+	public void setCurriculumElementKey(Long curriculumElementKey) {
+		this.curriculumElementKey = curriculumElementKey;
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRefs.java b/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRefs.java
new file mode 100644
index 0000000000000000000000000000000000000000..472d35cbae702de6ef1f42c93c9fb4da612f1480
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/model/CurriculumElementToRepositoryEntryRefs.java
@@ -0,0 +1,50 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.model;
+
+import java.util.List;
+
+/**
+ * This is only used for import/export operations
+ * 
+ * Initial date: 19 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CurriculumElementToRepositoryEntryRefs {
+	
+	private List<CurriculumElementToRepositoryEntryRef> entryRefs;
+	
+	public CurriculumElementToRepositoryEntryRefs() {
+		//
+	}
+	
+	public CurriculumElementToRepositoryEntryRefs(List<CurriculumElementToRepositoryEntryRef> entryRefs) {
+		this.entryRefs = entryRefs;
+	}
+
+	public List<CurriculumElementToRepositoryEntryRef> getEntryRefs() {
+		return entryRefs;
+	}
+
+	public void setEntryRefs(List<CurriculumElementToRepositoryEntryRef> entryRefs) {
+		this.entryRefs = entryRefs;
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java
new file mode 100644
index 0000000000000000000000000000000000000000..cebd73160932f3d426890b027230d13d1099e24f
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java
@@ -0,0 +1,127 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
+import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.util.StringHelper;
+import org.olat.modules.curriculum.CurriculumService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 19 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ConfirmCurriculumDeleteController extends FormBasicController {
+
+	private static final String[] onKeys = new String[]{ "on" };
+	
+	private FormLink deleteButton;
+	private MultipleSelectionElement acknowledgeEl;
+	
+	private final CurriculumRow rowToDelete;
+	
+	@Autowired
+	private CurriculumService curriculumService;
+	
+	public ConfirmCurriculumDeleteController(UserRequest ureq, WindowControl wControl, CurriculumRow rowToDelete) {
+		super(ureq, wControl, "confirm_delete_curriculum");
+		this.rowToDelete = rowToDelete;
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		if(formLayout instanceof FormLayoutContainer) {
+			String[] args = new String[] {
+				StringHelper.escapeHtml(rowToDelete.getDisplayName()),
+				Long.toString(rowToDelete.getNumOfElements())
+			};
+			String msg = translate("confirmation.delete.curriculum", args);
+			((FormLayoutContainer)formLayout).contextPut("msg", msg);
+		}
+		
+		FormLayoutContainer layoutCont = FormLayoutContainer.createDefaultFormLayout("confirm", getTranslator());
+		formLayout.add("confirm", layoutCont);
+		layoutCont.setRootForm(mainForm);
+		
+		uifactory.addStaticTextElement("curriculum.displayName", "curriculum.displayName",
+				StringHelper.escapeHtml(rowToDelete.getDisplayName()), layoutCont);
+		
+		String[] onValues = new String[]{ translate("delete.curriculum.acknowledge") };
+		acknowledgeEl = uifactory.addCheckboxesHorizontal("acknowledge", "confirmation", layoutCont, onKeys, onValues);
+		
+		FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
+		layoutCont.add(buttonsCont);
+		uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl());
+		deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+	
+	@Override
+	protected boolean validateFormLogic(UserRequest ureq) {
+		boolean allOk = super.validateFormLogic(ureq);
+		
+		acknowledgeEl.clearError();
+		if(!acknowledgeEl.isAtLeastSelected(1)) {
+			acknowledgeEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		}
+		
+		return allOk;
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void formCancelled(UserRequest ureq) {
+		fireEvent(ureq, Event.CANCELLED_EVENT);
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(deleteButton == source) {
+			if(validateFormLogic(ureq)) {
+				curriculumService.deleteCurriculum(rowToDelete);
+				fireEvent(ureq, Event.DONE_EVENT);
+			}
+		}
+		super.formInnerEvent(ureq, source, event);
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementCalendarController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementCalendarController.java
index a19f90041c140f4627d3a1b57fefd162a3c32c88..efb5d4f8a9090e142cf30a6f10e955ac28491f36 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementCalendarController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementCalendarController.java
@@ -27,6 +27,7 @@ import java.util.List;
 
 import org.olat.commons.calendar.CalendarManager;
 import org.olat.commons.calendar.model.CalendarUserConfiguration;
+import org.olat.commons.calendar.ui.CalendarController;
 import org.olat.commons.calendar.ui.WeeklyCalendarController;
 import org.olat.commons.calendar.ui.components.KalendarRenderWrapper;
 import org.olat.commons.calendar.ui.events.CalendarGUIModifiedEvent;
@@ -84,7 +85,7 @@ public class CurriculumElementCalendarController extends BasicController impleme
 		calendars = loadCalendars(ureq, entries);
 
 		callerOres = OresHelper.createOLATResourceableInstance(CurriculumElement.class, element.getKey());
-		calendarController = new WeeklyCalendarController(ureq, wControl, calendars, WeeklyCalendarController.CALLER_CURRICULUM,
+		calendarController = new WeeklyCalendarController(ureq, wControl, calendars, CalendarController.CALLER_CURRICULUM,
 				callerOres, false);
 		calendarController.setDifferentiateManagedEvent(CourseCalendars.needToDifferentiateManagedEvents(calendars));
 		listenTo(calendarController);
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
index db23654fe2614debf178f65241ec7af5babcbc91..de294f91f37e493db768d6212da09b67985b72b5 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
@@ -54,9 +54,11 @@ import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
+import org.olat.core.gui.media.MediaResource;
 import org.olat.core.id.Roles;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.modules.curriculum.Curriculum;
 import org.olat.modules.curriculum.CurriculumElementMembership;
@@ -65,6 +67,7 @@ import org.olat.modules.curriculum.CurriculumManagedFlag;
 import org.olat.modules.curriculum.CurriculumSecurityCallback;
 import org.olat.modules.curriculum.CurriculumSecurityCallbackFactory;
 import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.manager.ExportCurriculumMediaResource;
 import org.olat.modules.curriculum.model.CurriculumElementRefImpl;
 import org.olat.modules.curriculum.model.CurriculumInfos;
 import org.olat.modules.curriculum.model.CurriculumSearchParameters;
@@ -81,6 +84,7 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	
 	private FlexiTableElement tableEl;
 	private Link newCurriculumButton;
+	private Link importCurriculumButton;
 	private CurriculumManagerDataModel tableModel;
 	private final TooledStackedPanel toolbarPanel;
 	
@@ -88,7 +92,9 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	private CloseableModalController cmc;
 	private CurriculumComposerController composerCtrl;
 	private EditCurriculumController newCurriculumCtrl;
+	private ImportCurriculumController importCurriculumCtrl;
 	private EditCurriculumOverviewController editCurriculumCtrl;
+	private ConfirmCurriculumDeleteController deleteCurriculumCtrl;
 	private CloseableCalloutWindowController toolsCalloutCtrl;
 	
 	private int counter = 0;
@@ -113,6 +119,10 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	@Override
 	public void initTools() {
 		if(secCallback.canNewCurriculum()) {
+			importCurriculumButton = LinkFactory.createToolLink("import.curriculum", translate("import.curriculum"), this, "o_icon_import");
+			importCurriculumButton.setElementCssClass("o_sel_import_curriculum");
+			toolbarPanel.addTool(importCurriculumButton, Align.left);
+			
 			newCurriculumButton = LinkFactory.createToolLink("add.curriculum", translate("add.curriculum"), this, "o_icon_add");
 			newCurriculumButton.setElementCssClass("o_sel_add_curriculum");
 			toolbarPanel.addTool(newCurriculumButton, Align.left);
@@ -246,7 +256,8 @@ public class CurriculumListManagerController extends FormBasicController impleme
 			}
 			cmc.deactivate();
 			cleanUp();
-		} else if(editCurriculumCtrl == source) {
+		} else if(editCurriculumCtrl == source || importCurriculumCtrl == source
+				|| deleteCurriculumCtrl == source) {
 			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
 				loadModel(tableEl.getQuickSearchString(), false);
 			}
@@ -259,8 +270,12 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	}
 	
 	private void cleanUp() {
+		removeAsListenerAndDispose(importCurriculumCtrl);
+		removeAsListenerAndDispose(deleteCurriculumCtrl);
 		removeAsListenerAndDispose(newCurriculumCtrl);
 		removeAsListenerAndDispose(cmc);
+		importCurriculumCtrl = null;
+		deleteCurriculumCtrl = null;
 		newCurriculumCtrl = null;
 		cmc = null;
 	}
@@ -269,6 +284,8 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	public void event(UserRequest ureq, Component source, Event event) {
 		if(newCurriculumButton == source) {
 			doNewCurriculum(ureq);
+		} else if(importCurriculumButton == source) {
+			doImportCurriculum(ureq);
 		} else if(toolbarPanel == source) {
 			if(event instanceof PopEvent) {
 				PopEvent pe = (PopEvent)event;
@@ -311,6 +328,17 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		loadModel(event.getSearch(), true);
 	}
 	
+	private void doImportCurriculum(UserRequest ureq) {
+		if(importCurriculumCtrl != null) return;
+
+		importCurriculumCtrl = new ImportCurriculumController(ureq, getWindowControl());
+		listenTo(importCurriculumCtrl);
+		
+		cmc = new CloseableModalController(getWindowControl(), "close", importCurriculumCtrl.getInitialComponent(), true, translate("import.curriculum"));
+		listenTo(cmc);
+		cmc.activate();
+	}
+	
 	private void doNewCurriculum(UserRequest ureq) {
 		if(newCurriculumCtrl != null) return;
 
@@ -335,6 +363,29 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		}
 	}
 	
+	private void doDeleteCurriculum(UserRequest ureq, CurriculumRow row) {
+		removeAsListenerAndDispose(deleteCurriculumCtrl);
+		
+		Curriculum curriculum = curriculumService.getCurriculum(row);
+		if(curriculum == null) {
+			showWarning("warning.curriculum.deleted");
+		} else {
+			deleteCurriculumCtrl = new ConfirmCurriculumDeleteController(ureq, getWindowControl(), row);
+			listenTo(deleteCurriculumCtrl);
+			
+			String title = translate("delete.curriculum.title", new String[] { StringHelper.escapeHtml(row.getDisplayName()) });
+			cmc = new CloseableModalController(getWindowControl(), "close", deleteCurriculumCtrl.getInitialComponent(), true, title);
+			listenTo(cmc);
+			cmc.activate();
+		}
+	}
+	
+	private void doExportCurriculum(UserRequest ureq, CurriculumRow row) {
+		Curriculum curriculum = curriculumService.getCurriculum(row);
+		MediaResource mr = new ExportCurriculumMediaResource(curriculum);
+		ureq.getDispatchResult().setResultingMediaResource(mr);
+	}
+	
 	private void doSelectCurriculum(UserRequest ureq, CurriculumRow row, List<ContextEntry> entries) {
 		Curriculum curriculum = curriculumService.getCurriculum(row);
 		if(curriculum == null) {
@@ -378,6 +429,7 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		
 		private Link editLink;
 		private Link deleteLink;
+		private Link exportLink;
 		private final VelocityContainer mainVC;
 
 		private CurriculumRow row;
@@ -392,6 +444,8 @@ public class CurriculumListManagerController extends FormBasicController impleme
 			
 			//edit
 			editLink = addLink("edit", "o_icon_edit", links);
+			exportLink = addLink("export", "o_icon_export", links);
+			
 			if(!CurriculumManagedFlag.isManaged(curriculum, CurriculumManagedFlag.delete)) {
 				links.add("-");
 				deleteLink = addLink("delete", "o_icon_delete_item", links);
@@ -421,7 +475,10 @@ public class CurriculumListManagerController extends FormBasicController impleme
 				doEditCurriculum(ureq, row);
 			} else if(deleteLink == source) {
 				close();
-				showWarning("Not implemented");
+				doDeleteCurriculum(ureq, row);
+			} else if(exportLink == source) {
+				close();
+				doExportCurriculum(ureq, row);
 			}
 		}
 		
diff --git a/src/main/java/org/olat/modules/curriculum/ui/ImportCurriculumController.java b/src/main/java/org/olat/modules/curriculum/ui/ImportCurriculumController.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4427e957160764966320e0c06502c2c3fc9619f
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/ImportCurriculumController.java
@@ -0,0 +1,167 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.ui;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.olat.basesecurity.OrganisationModule;
+import org.olat.basesecurity.OrganisationRoles;
+import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.model.OrganisationRefImpl;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FileElement;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
+import org.olat.core.gui.components.form.flexible.elements.TextElement;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.id.Organisation;
+import org.olat.core.id.Roles;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.UserSession;
+import org.olat.modules.curriculum.manager.CurriculumImportHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 17 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ImportCurriculumController extends FormBasicController {
+	
+	private FileElement uploadFileEl;
+	private TextElement displayNameEl;
+	private SingleSelection organisationEl;
+	
+	@Autowired
+	private OrganisationModule organisationModule;
+	@Autowired
+	private OrganisationService organisationService;
+	@Autowired
+	private CurriculumImportHandler curriculumImportHandler;
+	
+	public ImportCurriculumController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl);
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		uploadFileEl = uifactory.addFileElement(getWindowControl(), "curriculum.file", formLayout);
+		uploadFileEl.limitToMimeType(Collections.singleton("application/zip"), "error.mimetype", new String[]{ "ZIP" });
+		uploadFileEl.setMandatory(true);
+		uploadFileEl.addActionListener(FormEvent.ONCHANGE);
+		
+		displayNameEl = uifactory.addTextElement("curriculum.displayName", 255, "", formLayout);
+		displayNameEl.setMandatory(true);
+		
+		initFormOrganisations(formLayout, ureq.getUserSession());
+		
+		FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
+		formLayout.add(buttonsCont);
+		uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl());
+		uifactory.addFormSubmitButton("import.curriculum", buttonsCont);
+	}
+	
+	private void initFormOrganisations(FormItemContainer formLayout, UserSession usess) {
+		Roles roles = usess.getRoles();
+		List<Organisation> organisations = organisationService.getOrganisations(getIdentity(), roles,
+				OrganisationRoles.administrator, OrganisationRoles.curriculummanager);
+		
+		List<String> keyList = new ArrayList<>();
+		List<String> valueList = new ArrayList<>();
+		for(Organisation organisation:organisations) {
+			keyList.add(organisation.getKey().toString());
+			valueList.add(organisation.getDisplayName());
+		}
+
+		organisationEl = uifactory.addDropdownSingleselect("curriculum.organisation", formLayout,
+				keyList.toArray(new String[keyList.size()]), valueList.toArray(new String[valueList.size()]));
+		organisationEl.setVisible(organisationModule.isEnabled());
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected boolean validateFormLogic(UserRequest ureq) {
+		boolean allOk = super.validateFormLogic(ureq);
+		
+		displayNameEl.clearError();
+		if(!StringHelper.containsNonWhitespace(displayNameEl.getValue())) {
+			displayNameEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		}
+		
+		uploadFileEl.clearError();
+		if(uploadFileEl.getUploadFile() == null) {
+			uploadFileEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		} else {
+			validateFormItem(uploadFileEl);
+		}
+		
+		return allOk;
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(uploadFileEl == source) {
+			if(!StringHelper.containsNonWhitespace(displayNameEl.getValue())
+					&& uploadFileEl.getUploadFile() != null) {
+				String name = curriculumImportHandler.getCurriculumName(uploadFileEl.getUploadFile());
+				displayNameEl.setValue(name);
+			}
+		}
+		super.formInnerEvent(ureq, source, event);
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		File archive = uploadFileEl.getUploadFile();
+		
+		Organisation organisation;
+		if(organisationEl.isOneSelected()) {
+			Long organisationKey = Long.valueOf(organisationEl.getSelectedKey());
+			organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey));
+		} else {
+			organisation = organisationService.getDefaultOrganisation();
+		}
+		String curriculumName = displayNameEl.getValue();
+		curriculumImportHandler.importCurriculum(archive, curriculumName, organisation, getIdentity(), getLocale());
+		fireEvent(ureq, Event.DONE_EVENT);
+	}
+
+	@Override
+	protected void formCancelled(UserRequest ureq) {
+		fireEvent(ureq, Event.CANCELLED_EVENT);
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html
new file mode 100644
index 0000000000000000000000000000000000000000..2e8fdedae59c72e0d7bd0d26b46e251667162464
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html
@@ -0,0 +1,4 @@
+<div class="o_error">
+	<p><i class="o_icon o_icon-lg o_icon_important"> </i> $msg</p>
+</div>
+$r.render("confirm")
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
index 440d5cca7eb2f520c11ae7bc9703e9766922721f..c0b4bf630247d5d65d22af09f23c54e21c1a3cf4 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
@@ -16,9 +16,11 @@ confirm.remove.member.title=Mitglieder entfernen
 confirm.remove.member.text=Wollen Sie wirklich diese Mitglieder entfernen?
 confirm.remove.resource.title=Lernresourcen entfernen
 confirm.remove.resource.text=Wollen Sie wirklich diese Lernresourcen entfernen?
+confirmation=Best\u00E4tigung
 confirmation.delete.type=Wollen Sie wirklich den Typ "{0}" l\u00F6schen?
 confirmation.delete.type.title=Typ "{0}" l\u00F6schen
 confirmation.delete.element=Wollen Sie wirklich dieses Curriculum Element "{0}" l\u00F6schen?
+confirmation.delete.curriculum=Wollen Sie wirklich dieses Curriculum "{0}" l\u00F6schen? Er enth\u00E4lt <strong>{1} Elementen</strong>.
 confirmation.delete.element.title=Curriculum Element "{0}" l\u00F6schen
 copy.element=Element kopieren
 copy.element.title=Element "{0}" kopieren
@@ -48,10 +50,13 @@ curriculum.external.id=Externe ID
 curriculum.identifier=Bezeichnung
 curriculum.in.my.courses.enabled=Curriculum in "Meine Kurse"
 curriculum.inactive.explain=Sie haben kein aktives Curriculum Element mit einem publizierten Kurs in diesem Curriculum.
+curriculum.file=Datei
 curriculum.key=ID
 curriculum.metadata=Metadaten
 curriculum.organisation=Organisation
 curriculum.search=Suchen
+delete.curriculum.acknowledge=Ich verstehe, dass das Curriculum und alle seine Elementen werden definitive gel\u00F6scht.
+delete.curriculum.title=Curriculum "{0}" l\u00F6schen
 details=Infoseite
 details.copy=Kopieren
 details.delete=L\u00F6schen
@@ -61,6 +66,7 @@ error.target.no.insertion.point=Sie m\u00FCssen eine Position w\u00E4hlen.
 filter.active=$\:status.active
 filter.deleted=$\:status.deleted
 filter.inactive=$\:status.inactive
+import.curriculum=Curriculum importieren
 import.member=$org.olat.group.ui.main\:import.member
 info.copy.element.type.sucessfull=Der Typ "{0}" wurde erfolgreich kopiert.
 override.member=Externe Verwaltung \u00FCbergehen
diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties
index d66b8c97e91abd392485ff27896ce584ccce3457..543913620d4204e31101e8ac7e4741ebb6104927 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties
@@ -16,6 +16,8 @@ confirm.remove.member.text=Do you really want to remove this member(s)?
 confirm.remove.member.title=Remove member
 confirm.remove.resource.text=Do you really want to remove this learn resource(s)?
 confirm.remove.resource.title=Remove learn resources
+confirmation=Confirmation
+confirmation.delete.curriculum=Do you really want to delete this curriculum "{0}"? It contains <strong>{1} elements</strong>.
 confirmation.delete.element=Do you really want to delete this curriculum element "{0}"?
 confirmation.delete.element.title=Delete curriculum element "{0}"
 confirmation.delete.type=Do you really want to delete this type "{0}"?
@@ -48,10 +50,13 @@ curriculum.external.id=External ID
 curriculum.identifier=Identifier
 curriculum.in.my.courses.enabled=Curriculum in "My courses"
 curriculum.inactive.explain=You don't have an active curriculum element in this curriculum with a published course.
+curriculum.file=File
 curriculum.key=ID
 curriculum.metadata=Metadata
 curriculum.organisation=Organisation
 curriculum.search=Search
+delete.binder.acknowledge=I understand that the curriculum and all its elements will be definitely deleted.
+delete.curriculum.title=Delete curriculum "{0}"
 details=Info page
 details.copy=Copy
 details.delete=Delete
@@ -61,6 +66,7 @@ error.target.no.insertion.point=You must choose a position.
 filter.active=$\:status.active
 filter.deleted=$\:status.deleted
 filter.inactive=$\:status.inactive
+import.curriculum=Import curriculum
 import.member=$org.olat.group.ui.main\:import.member
 info.copy.element.type.sucessfull=The type "{0}" was successfully copied.
 lectures=Absences
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
index 7bf718c0d54838ab25238ba25e1befbf13c0d925..f40e2186857e11f0cd63634537438f950860ecc9 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
@@ -144,7 +144,7 @@ delete.assignment.in.use.confirm.descr=$\:delete.assignment.confirm.descr <div c
 delete.assignment.template.confirm.descr=Do you really want to delete this template "{0}"?
 delete.assignment.template.confirm.title=Delete template
 delete.binder=Delete binder
-delete.binder.acknowledge=I understand that the binder and all its entries will be definetly deleted.
+delete.binder.acknowledge=I understand that the binder and all its entries will be definitely deleted.
 delete.binder.acknowledge.2=I understand that the binder cannot be restored again.
 delete.binder.success=Binder is successfully deleted.
 delete.binder.warning=Do you really want to delete the binder "{0}"? It contains <strong>{1}</strong> sections, <strong>{2}</strong> entries and <strong>{3}</strong> comments.
diff --git a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyController.java b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyController.java
index 8decbac7f4802adfe5563b855c5194c5c01ae74b..725a1e55b8eb1fc6ce6e6184c26afe5043a87679 100644
--- a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyController.java
+++ b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyController.java
@@ -63,6 +63,8 @@ public class EditTaxonomyController extends FormBasicController {
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		formLayout.setElementCssClass("o_sel_taxonomy_form");
+		
 		if(taxonomy != null) {
 			String key = taxonomy.getKey().toString();
 			uifactory.addStaticTextElement("taxonomy.key", key, formLayout);
@@ -98,7 +100,7 @@ public class EditTaxonomyController extends FormBasicController {
 
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
+		boolean allOk = super.validateFormLogic(ureq);
 		
 		displayNameEl.clearError();
 		if(!StringHelper.containsNonWhitespace(displayNameEl.getValue())) {
@@ -112,7 +114,7 @@ public class EditTaxonomyController extends FormBasicController {
 			allOk &= false;
 		}
 		
-		return allOk & super.validateFormLogic(ureq);
+		return allOk;
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
index 7f550ac2565f86f451a718590f08756c90c51ec4..1812a960e8dcf5a92c2cf0ec614de57cbbfbc0d2 100644
--- a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
+++ b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
@@ -271,14 +271,14 @@ public class EditTaxonomyLevelController extends FormBasicController {
 		
 		String selectedTypeKey = taxonomyLevelTypeEl.getSelectedKey();
 		if(StringHelper.containsNonWhitespace(selectedTypeKey)) {
-			TaxonomyLevelTypeRef typeRef = new TaxonomyLevelTypeRefImpl(new Long(selectedTypeKey));
+			TaxonomyLevelTypeRef typeRef = new TaxonomyLevelTypeRefImpl(Long.valueOf(selectedTypeKey));
 			TaxonomyLevelType type = taxonomyService.getTaxonomyLevelType(typeRef);
 			level.setType(type);
 		} else {
 			level.setType(null);
 		}
 		if(StringHelper.isLong(sortOrderEl.getValue())) {
-			level.setSortOrder(new Integer(sortOrderEl.getValue()));
+			level.setSortOrder(Integer.valueOf(sortOrderEl.getValue()));
 		} else {
 			level.setSortOrder(null);
 		}
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
index 3ffa9de9215415cec130a721950217eeece549fe..640b2d205fa5d8b8a12036b1048d19b6ef62e3a7 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
@@ -643,7 +643,7 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 		}
 	}
 	
-	protected void processPopEvent(@SuppressWarnings("unused") UserRequest ureq, PopEvent pop) {
+	protected void processPopEvent(UserRequest ureq, PopEvent pop) {
 		if(pop.getController() == settingsCtrl && settingsChanged) {
 			RepositoryEntry entry = repositoryService.loadByKey(getRepositoryEntry().getKey());
 			refreshRepositoryEntry(entry);
@@ -676,8 +676,6 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 				doClose(ureq);
 			} else if(event instanceof ReloadSettingsEvent) {
 				processReloadSettingsEvent((ReloadSettingsEvent)event);
-			} else if(event instanceof ReloadSettingsEvent) {
-				processReloadSettingsEvent((ReloadSettingsEvent)event);
 			} else if (event == RepositoryEntryLifeCycleChangeController.closedEvent
 					|| event == RepositoryEntryLifeCycleChangeController.unclosedEvent) {
 				processClosedUnclosedEvent(ureq);
diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
index a2623d33301f9f0b44bc64b24af6176c896ba1a2..8165e395e9876d7eb47d0dead9d038ff8051cc61 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
@@ -1066,7 +1066,7 @@ public class AuthorListController extends FormBasicController implements Activat
 		boolean isAlreadyLocked = typeToDownload.isLocked(ores);
 		try {			
 		  lockResult = typeToDownload.acquireLock(ores, ureq.getIdentity());
-		  if(lockResult == null || (lockResult !=null && lockResult.isSuccess() && !isAlreadyLocked)) {
+		  if(lockResult == null || (lockResult.isSuccess() && !isAlreadyLocked)) {
 		    MediaResource mr = typeToDownload.getAsMediaResource(ores);
 		    if(mr!=null) {
 		      repositoryService.incrementDownloadCounter(entry);
diff --git a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
index 1dc9f8761bd953f25b4e6daddc205a247574a9cc..ca624a1f8dedec6a140c6652adc6145989f57a81 100644
--- a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
+++ b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
@@ -320,7 +320,7 @@ public class ImportRepositoryEntryController extends FormBasicController {
 
 		String displayName = "";
 		boolean references = false;
-		if (handlers != null && handlers.size() > 0) { // add image and typename code
+		if (handlers != null && !handlers.isEmpty()) { // add image and typename code
 			ResourceHandler handler = handlers.get(0);
 			displayName = handler.getEval().getDisplayname();
 			references = handler.getEval().isReferences();
@@ -358,7 +358,7 @@ public class ImportRepositoryEntryController extends FormBasicController {
 		if(references) {
 			referencesEl.select(refKeys[0], true);
 		}
-		importButton.setEnabled(handlers.size() > 0);
+		importButton.setEnabled(!handlers.isEmpty());
 	}
 	
 	private class ResourceHandler {
diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumXStreamTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumXStreamTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1720acbce94f4505fefe945aceeb64e95e5987d6
--- /dev/null
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumXStreamTest.java
@@ -0,0 +1,84 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.manager;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.core.commons.persistence.DB;
+import org.olat.modules.curriculum.Curriculum;
+import org.olat.modules.curriculum.CurriculumCalendars;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumElementStatus;
+import org.olat.modules.curriculum.CurriculumLectures;
+import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 17 juil. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CurriculumXStreamTest extends OlatTestCase {
+
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private CurriculumService curriculumService;
+	
+	@Test
+	public void toStream() {
+		Curriculum curriculum = curriculumService.createCurriculum("CUR-XSTREAM-1", "My Curriculum 1", "Short desc.", null);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-1", "1. Element",  CurriculumElementStatus.active,
+				new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum);
+		dbInstance.commitAndCloseSession();
+
+		Curriculum loadedCurriculum = curriculumService.getCurriculum(curriculum);
+		String xml = CurriculumXStream.toXml(loadedCurriculum);
+		Assert.assertTrue(xml.contains(curriculum.getDisplayName()));
+		Assert.assertTrue(xml.contains(element.getDisplayName()));
+		
+		Curriculum streamedCurriculum = CurriculumXStream.fromXml(xml);
+		Assert.assertNotNull(streamedCurriculum);
+		Assert.assertEquals(loadedCurriculum.getKey(), streamedCurriculum.getKey());
+	}
+	
+	@Test
+	public void curriculumFromXml_version14x() throws Exception {
+		URL input = CurriculumXStreamTest.class.getResource("curriculum.xml");
+		File inputFile = new File(input.getFile());
+		Curriculum export = CurriculumXStream.curriculumFromPath(inputFile.toPath());
+		Assert.assertNotNull(export);
+	}
+	
+	@Test
+	public void entriesFromXml_version14x() throws Exception {
+		URL input = CurriculumXStreamTest.class.getResource("curriculum_entries.xml");
+		File inputFile = new File(input.getFile());
+		CurriculumElementToRepositoryEntryRefs export = CurriculumXStream.entryRefsFromPath(inputFile.toPath());
+		Assert.assertNotNull(export);
+	}
+}
diff --git a/src/test/java/org/olat/modules/curriculum/manager/curriculum.xml b/src/test/java/org/olat/modules/curriculum/manager/curriculum.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a747d3d67d367438bbf42a263c595ba2f0daf57f
--- /dev/null
+++ b/src/test/java/org/olat/modules/curriculum/manager/curriculum.xml
@@ -0,0 +1,328 @@
+<org.olat.modules.curriculum.model.CurriculumImpl>
+  <key>1</key>
+  <creationDate class="sql-timestamp">2018-07-13 14:04:18.723</creationDate>
+  <lastModified class="sql-timestamp">2018-07-13 14:04:18.723</lastModified>
+  <identifier>Physik</identifier>
+  <displayName>Physik</displayName>
+  <description></description>
+  <rootElements>
+    <org.olat.modules.curriculum.model.CurriculumElementImpl>
+      <key>1</key>
+      <creationDate class="sql-timestamp">2018-07-13 14:04:36.1</creationDate>
+      <lastModified class="sql-timestamp">2018-10-22 12:38:22.917</lastModified>
+      <posCurriculum>0</posCurriculum>
+      <identifier>Astrophysik</identifier>
+      <displayName>Astrophysik</displayName>
+      <description></description>
+      <calendarsEnabledString>disabled</calendarsEnabledString>
+      <status>active</status>
+      <materializedPathKeys>/1/</materializedPathKeys>
+      <children>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>8</key>
+          <creationDate class="sql-timestamp">2018-07-18 16:33:55.543</creationDate>
+          <lastModified class="sql-timestamp">2019-02-19 10:39:31.199</lastModified>
+          <pos>0</pos>
+          <identifier>Solar system</identifier>
+          <displayName>Solar system</displayName>
+          <description></description>
+          <calendarsEnabledString>disabled</calendarsEnabledString>
+          <lecturesEnabledString>enabled</lecturesEnabledString>
+          <status>active</status>
+          <beginDate class="sql-timestamp">2019-02-11 23:00:00</beginDate>
+          <endDate class="sql-timestamp">2019-02-27 23:00:00</endDate>
+          <materializedPathKeys>/1/8/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>10</key>
+              <creationDate class="sql-timestamp">2018-07-18 16:34:29.45</creationDate>
+              <lastModified class="sql-timestamp">2018-10-22 12:37:33.456</lastModified>
+              <pos>0</pos>
+              <identifier>Saturn</identifier>
+              <displayName>Saturn</displayName>
+              <description></description>
+              <calendarsEnabledString>enabled</calendarsEnabledString>
+              <status>active</status>
+              <materializedPathKeys>/1/8/10/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+              <type class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl">
+                <key>4</key>
+                <creationDate class="sql-timestamp">2018-10-22 12:35:23.921</creationDate>
+                <lastModified class="sql-timestamp">2018-10-22 12:35:23.923</lastModified>
+                <identifier>Seminar</identifier>
+                <displayName>Seminar</displayName>
+                <description></description>
+                <cssClass></cssClass>
+                <calendarsEnabledString>enabled</calendarsEnabledString>
+                <allowedSubTypes>
+                  <isTempSession>false</isTempSession>
+                  <initialized>false</initialized>
+                  <owner class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl" reference="../.."/>
+                  <cachedSize>-1</cachedSize>
+                  <role>org.olat.modules.curriculum.model.CurriculumElementTypeImpl.allowedSubTypes</role>
+                  <key class="long">4</key>
+                  <dirty>false</dirty>
+                  <elementRemoved>false</elementRemoved>
+                  <allowLoadOutsideTransaction>false</allowLoadOutsideTransaction>
+                </allowedSubTypes>
+              </type>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>11</key>
+              <creationDate class="sql-timestamp">2018-07-18 16:34:42.244</creationDate>
+              <lastModified class="sql-timestamp">2018-10-11 08:20:32.406</lastModified>
+              <pos>1</pos>
+              <identifier>Jupiter</identifier>
+              <displayName>Jupiter</displayName>
+              <description></description>
+              <calendarsEnabledString>disabled</calendarsEnabledString>
+              <status>active</status>
+              <beginDate class="sql-timestamp">2018-10-05 22:00:00</beginDate>
+              <endDate class="sql-timestamp">2018-10-26 22:00:00</endDate>
+              <materializedPathKeys>/1/8/11/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+          </children>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+          <type class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl">
+            <key>2</key>
+            <creationDate class="sql-timestamp">2018-10-22 12:34:59.867</creationDate>
+            <lastModified class="sql-timestamp">2019-02-13 14:08:32.946</lastModified>
+            <identifier>Semester</identifier>
+            <displayName>Semester</displayName>
+            <description></description>
+            <cssClass></cssClass>
+            <calendarsEnabledString>enabled</calendarsEnabledString>
+            <lecturesEnabledString>enabled</lecturesEnabledString>
+            <allowedSubTypes>
+              <isTempSession>false</isTempSession>
+              <initialized>false</initialized>
+              <owner class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl" reference="../.."/>
+              <cachedSize>-1</cachedSize>
+              <role>org.olat.modules.curriculum.model.CurriculumElementTypeImpl.allowedSubTypes</role>
+              <key class="long">2</key>
+              <dirty>false</dirty>
+              <elementRemoved>false</elementRemoved>
+              <allowLoadOutsideTransaction>false</allowLoadOutsideTransaction>
+            </allowedSubTypes>
+          </type>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>9</key>
+          <creationDate class="sql-timestamp">2018-07-18 16:34:14.697</creationDate>
+          <lastModified class="sql-timestamp">2018-10-15 14:27:47.814</lastModified>
+          <pos>1</pos>
+          <identifier>Galaxy</identifier>
+          <displayName>Galaxy</displayName>
+          <description></description>
+          <calendarsEnabledString>disabled</calendarsEnabledString>
+          <status>active</status>
+          <beginDate class="sql-timestamp">2018-09-30 22:00:00</beginDate>
+          <endDate class="sql-timestamp">2018-10-02 22:00:00</endDate>
+          <materializedPathKeys>/1/9/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children/>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+      </children>
+      <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../.."/>
+      <type class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl">
+        <key>1</key>
+        <creationDate class="sql-timestamp">2018-10-05 07:18:24.409</creationDate>
+        <lastModified class="sql-timestamp">2018-10-22 12:35:04.245</lastModified>
+        <identifier>Bildungsgang</identifier>
+        <displayName>Bildungsgang</displayName>
+        <description></description>
+        <cssClass></cssClass>
+        <calendarsEnabledString>enabled</calendarsEnabledString>
+        <allowedSubTypes>
+          <isTempSession>false</isTempSession>
+          <initialized>false</initialized>
+          <owner class="org.olat.modules.curriculum.model.CurriculumElementTypeImpl" reference="../.."/>
+          <cachedSize>-1</cachedSize>
+          <role>org.olat.modules.curriculum.model.CurriculumElementTypeImpl.allowedSubTypes</role>
+          <key class="long">1</key>
+          <dirty>false</dirty>
+          <elementRemoved>false</elementRemoved>
+          <allowLoadOutsideTransaction>false</allowLoadOutsideTransaction>
+        </allowedSubTypes>
+      </type>
+    </org.olat.modules.curriculum.model.CurriculumElementImpl>
+    <org.olat.modules.curriculum.model.CurriculumElementImpl>
+      <key>2</key>
+      <creationDate class="sql-timestamp">2018-07-18 16:31:54.842</creationDate>
+      <lastModified class="sql-timestamp">2018-10-16 12:57:04.003</lastModified>
+      <posCurriculum>1</posCurriculum>
+      <identifier>Quantum Physik</identifier>
+      <displayName>Quantum Physik</displayName>
+      <description></description>
+      <calendarsEnabledString>enabled</calendarsEnabledString>
+      <status>active</status>
+      <materializedPathKeys>/2/</materializedPathKeys>
+      <children>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>25</key>
+          <creationDate class="sql-timestamp">2018-10-16 12:57:29.674</creationDate>
+          <lastModified class="sql-timestamp">2018-10-16 13:01:11.316</lastModified>
+          <pos>0</pos>
+          <identifier>Chromodynamique quantique</identifier>
+          <displayName>Chromodynamique quantique</displayName>
+          <description></description>
+          <calendarsEnabledString>enabled</calendarsEnabledString>
+          <status>active</status>
+          <materializedPathKeys>/2/25/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>27</key>
+              <creationDate class="sql-timestamp">2018-10-16 13:00:48.07</creationDate>
+              <lastModified class="sql-timestamp">2019-02-19 10:57:29.496</lastModified>
+              <pos>0</pos>
+              <identifier>Chromodynamique quantique aspects pratiques</identifier>
+              <displayName>Chromodynamique quantique aspects pratiques</displayName>
+              <description></description>
+              <calendarsEnabledString>disabled</calendarsEnabledString>
+              <lecturesEnabledString>enabled</lecturesEnabledString>
+              <status>active</status>
+              <materializedPathKeys>/2/25/27/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>28</key>
+              <creationDate class="sql-timestamp">2018-10-16 13:01:04.464</creationDate>
+              <lastModified class="sql-timestamp">2018-10-16 13:01:04.464</lastModified>
+              <pos>1</pos>
+              <identifier>Chromodynamique quantique théorie math.</identifier>
+              <displayName>Chromodynamique quantique théorie math.</displayName>
+              <calendarsEnabledString>disabled</calendarsEnabledString>
+              <status>active</status>
+              <materializedPathKeys>/2/25/28/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+          </children>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>26</key>
+          <creationDate class="sql-timestamp">2018-10-16 12:58:20.489</creationDate>
+          <lastModified class="sql-timestamp">2018-10-16 12:58:20.489</lastModified>
+          <pos>1</pos>
+          <identifier>Mécanique quantique relativiste</identifier>
+          <displayName>Mécanique quantique relativiste</displayName>
+          <calendarsEnabledString>disabled</calendarsEnabledString>
+          <status>active</status>
+          <materializedPathKeys>/2/26/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children/>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+      </children>
+      <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../.."/>
+    </org.olat.modules.curriculum.model.CurriculumElementImpl>
+    <org.olat.modules.curriculum.model.CurriculumElementImpl>
+      <key>3</key>
+      <creationDate class="sql-timestamp">2018-07-18 16:32:22.429</creationDate>
+      <lastModified class="sql-timestamp">2018-07-18 16:32:22.429</lastModified>
+      <posCurriculum>2</posCurriculum>
+      <identifier>Math</identifier>
+      <displayName>Math</displayName>
+      <status>active</status>
+      <materializedPathKeys>/3/</materializedPathKeys>
+      <children>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>4</key>
+          <creationDate class="sql-timestamp">2018-07-18 16:32:39.837</creationDate>
+          <lastModified class="sql-timestamp">2018-07-18 16:32:39.837</lastModified>
+          <pos>0</pos>
+          <identifier>Topology</identifier>
+          <displayName>Topology</displayName>
+          <status>active</status>
+          <materializedPathKeys>/3/4/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children/>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+        <org.olat.modules.curriculum.model.CurriculumElementImpl>
+          <key>5</key>
+          <creationDate class="sql-timestamp">2018-07-18 16:32:59.384</creationDate>
+          <lastModified class="sql-timestamp">2018-07-18 16:32:59.384</lastModified>
+          <pos>1</pos>
+          <identifier>Numerische Simulation</identifier>
+          <displayName>Numerische Simulation</displayName>
+          <status>inactive</status>
+          <materializedPathKeys>/3/5/</materializedPathKeys>
+          <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+          <children>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>6</key>
+              <creationDate class="sql-timestamp">2018-07-18 16:33:16.646</creationDate>
+              <lastModified class="sql-timestamp">2018-07-18 16:33:16.646</lastModified>
+              <pos>0</pos>
+              <identifier>R Software</identifier>
+              <displayName>R Software</displayName>
+              <status>active</status>
+              <materializedPathKeys>/3/5/6/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+            <org.olat.modules.curriculum.model.CurriculumElementImpl>
+              <key>7</key>
+              <creationDate class="sql-timestamp">2018-07-18 16:33:39.025</creationDate>
+              <lastModified class="sql-timestamp">2018-10-15 14:27:58.13</lastModified>
+              <pos>1</pos>
+              <identifier>Fortran</identifier>
+              <displayName>Fortran</displayName>
+              <description></description>
+              <calendarsEnabledString>disabled</calendarsEnabledString>
+              <status>active</status>
+              <beginDate class="sql-timestamp">2018-09-30 22:00:00</beginDate>
+              <endDate class="sql-timestamp">2018-10-02 22:00:00</endDate>
+              <materializedPathKeys>/3/5/7/</materializedPathKeys>
+              <parent class="org.olat.modules.curriculum.model.CurriculumElementImpl" reference="../../.."/>
+              <children/>
+              <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../../../.."/>
+            </org.olat.modules.curriculum.model.CurriculumElementImpl>
+          </children>
+          <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../../../.."/>
+        </org.olat.modules.curriculum.model.CurriculumElementImpl>
+      </children>
+      <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../.."/>
+    </org.olat.modules.curriculum.model.CurriculumElementImpl>
+    <org.olat.modules.curriculum.model.CurriculumElementImpl>
+      <key>17</key>
+      <creationDate class="sql-timestamp">2018-07-26 16:46:33.362</creationDate>
+      <lastModified class="sql-timestamp">2018-07-26 16:58:46.45</lastModified>
+      <pos>0</pos>
+      <posCurriculum>3</posCurriculum>
+      <identifier>To delete 5</identifier>
+      <displayName>To delete 5</displayName>
+      <status>deleted</status>
+      <materializedPathKeys>/17/</materializedPathKeys>
+      <children/>
+      <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../.."/>
+    </org.olat.modules.curriculum.model.CurriculumElementImpl>
+    <org.olat.modules.curriculum.model.CurriculumElementImpl>
+      <key>20</key>
+      <creationDate class="sql-timestamp">2018-07-26 19:32:10.768</creationDate>
+      <lastModified class="sql-timestamp">2018-07-26 19:36:07.528</lastModified>
+      <pos>0</pos>
+      <posCurriculum>4</posCurriculum>
+      <identifier>To delete 8</identifier>
+      <displayName>To delete 8</displayName>
+      <status>deleted</status>
+      <materializedPathKeys>/20/</materializedPathKeys>
+      <children/>
+      <curriculum class="org.olat.modules.curriculum.model.CurriculumImpl" reference="../../.."/>
+    </org.olat.modules.curriculum.model.CurriculumElementImpl>
+  </rootElements>
+</org.olat.modules.curriculum.model.CurriculumImpl>
\ No newline at end of file
diff --git a/src/test/java/org/olat/modules/curriculum/manager/curriculum_entries.xml b/src/test/java/org/olat/modules/curriculum/manager/curriculum_entries.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e6a05aff603e11aa9fe83a7e0bdaddeabc0a01d5
--- /dev/null
+++ b/src/test/java/org/olat/modules/curriculum/manager/curriculum_entries.xml
@@ -0,0 +1,95 @@
+<org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs>
+  <entryRefs>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>319913984</repositoryEntryKey>
+      <repositoryEntryDisplayname>4 Generate courses</repositoryEntryDisplayname>
+      <repositoryEntryDescription>Training&lt;br /&gt;</repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>1</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1201504256</repositoryEntryKey>
+      <repositoryEntryDisplayname>Assessment docs</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>1</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1408073728</repositoryEntryKey>
+      <repositoryEntryDisplayname>Curriculum course</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>1</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1529020417</repositoryEntryKey>
+      <repositoryEntryDisplayname>Refactoring 3 (book)</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>1</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>321880064</repositoryEntryKey>
+      <repositoryEntryDisplayname>Course with members list</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>10</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>819789824</repositoryEntryKey>
+      <repositoryEntryDisplayname>Lectures</repositoryEntryDisplayname>
+      <repositoryEntryDescription>&lt;p&gt;Bla bla&lt;/p&gt;</repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>10</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1495105536</repositoryEntryKey>
+      <repositoryEntryDisplayname>Curriculum calendar</repositoryEntryDisplayname>
+      <repositoryEntryDescription>&lt;p&gt;This is a course in a curriculum with calender&lt;/p&gt;</repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>10</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1496940544</repositoryEntryKey>
+      <repositoryEntryDisplayname>Course curriculum Reï</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>rei</repositoryEntryInitialAuthor>
+      <curriculumElementKey>10</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1603698688</repositoryEntryKey>
+      <repositoryEntryDisplayname>Optional Tasks</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>10</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1495105536</repositoryEntryKey>
+      <repositoryEntryDisplayname>Curriculum calendar</repositoryEntryDisplayname>
+      <repositoryEntryDescription>&lt;p&gt;This is a course in a curriculum with calender&lt;/p&gt;</repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>27</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>1495105536</repositoryEntryKey>
+      <repositoryEntryDisplayname>Curriculum calendar</repositoryEntryDisplayname>
+      <repositoryEntryDescription>&lt;p&gt;This is a course in a curriculum with calender&lt;/p&gt;</repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>26</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>330956800</repositoryEntryKey>
+      <repositoryEntryDisplayname>Assessment mode</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>4</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+    <org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+      <repositoryEntryKey>977698816</repositoryEntryKey>
+      <repositoryEntryDisplayname>Participants folders</repositoryEntryDisplayname>
+      <repositoryEntryDescription></repositoryEntryDescription>
+      <repositoryEntryInitialAuthor>kanu</repositoryEntryInitialAuthor>
+      <curriculumElementKey>4</curriculumElementKey>
+    </org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRef>
+  </entryRefs>
+</org.olat.modules.curriculum.model.CurriculumElementToRepositoryEntryRefs>
\ No newline at end of file
diff --git a/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java b/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java
index 3def4cd2ca5af86e21893446edcf5afd93ed3bd7..92c8f3ee8f5bf61cb92b9abe6e05e5b032314781 100644
--- a/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java
+++ b/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java
@@ -2503,6 +2503,7 @@ public class ImsQTI21EditorTest extends Deployments {
 		// make the test
 		QTI21Page
 			.getQTI21Page(participantBrowser)
+			.assertOnAssessmentItem()
 			.answerMatchDropSourceToTarget("Einstein", "Physicist")
 			.answerMatchDropSourceToTarget("Planck", "Physicist")
 			.answerMatchDropSourceToTarget("Euler", "Mathematician")
@@ -2694,6 +2695,7 @@ public class ImsQTI21EditorTest extends Deployments {
 		// make the test
 		QTI21Page
 			.getQTI21Page(participantBrowser)
+			.assertOnAssessmentItem()
 			.saveAnswer()
 			.assertFeedback("Correct feedback")
 			.nextAnswer()
diff --git a/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java b/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java
index 75cbefc3e76f1093d72052084cb155d8a0f65c37..e633ce745064452dd438392e95298c19daf92183 100644
--- a/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java
+++ b/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java
@@ -666,8 +666,8 @@ public class ImsQTI21InteractionsTest extends Deployments {
 			.clickToolbarRootCrumb();
 		
 		QTI21Page qtiPage = QTI21Page
-				.getQTI21Page(browser)
-				.assertOnAssessmentItem();
+			.getQTI21Page(browser)
+			.assertOnAssessmentItem();
 		qtiPage
 			.settings()
 			.options()
@@ -715,8 +715,8 @@ public class ImsQTI21InteractionsTest extends Deployments {
 			.clickToolbarRootCrumb();
 		
 		QTI21Page qtiPage = QTI21Page
-				.getQTI21Page(browser)
-				.assertOnAssessmentItem();
+			.getQTI21Page(browser)
+			.assertOnAssessmentItem();
 		qtiPage
 			.settings()
 			.options()
@@ -764,8 +764,8 @@ public class ImsQTI21InteractionsTest extends Deployments {
 			.clickToolbarRootCrumb();
 		
 		QTI21Page qtiPage = QTI21Page
-				.getQTI21Page(browser)
-				.assertOnAssessmentItem();
+			.getQTI21Page(browser)
+			.assertOnAssessmentItem();
 		qtiPage
 			.settings()
 			.options()
diff --git a/src/test/java/org/olat/selenium/ImsQTI21Test.java b/src/test/java/org/olat/selenium/ImsQTI21Test.java
index 9f3d03563ff3e349258737478f523dbedce29428..1c5213922b1df74bdd419078b0892de5a844614c 100644
--- a/src/test/java/org/olat/selenium/ImsQTI21Test.java
+++ b/src/test/java/org/olat/selenium/ImsQTI21Test.java
@@ -189,12 +189,12 @@ public class ImsQTI21Test extends Deployments {
 		NavigationPage navBar = NavigationPage.load(browser);
 		navBar
 			.openAuthoringEnvironment()
-			.uploadResource(qtiTestTitle, qtiTestFile);
+			.uploadResource(qtiTestTitle, qtiTestFile)
+			.clickToolbarRootCrumb();
 		
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
-			.clickToolbarBack()
 			.settings()
 			.options()
 			.showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions())
@@ -244,12 +244,12 @@ public class ImsQTI21Test extends Deployments {
 		NavigationPage navBar = NavigationPage.load(browser);
 		navBar
 			.openAuthoringEnvironment()
-			.uploadResource(qtiTestTitle, qtiTestFile);
+			.uploadResource(qtiTestTitle, qtiTestFile)
+			.clickToolbarRootCrumb();
 		
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
-			.clickToolbarBack()
 			.settings()
 			.options()
 			.showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions())
@@ -603,6 +603,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.answerSingleChoiceWithParagraph("Right")
 			.saveAnswer()
@@ -691,6 +692,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.answerSingleChoiceWithParagraph("Right")
 			.saveAnswer()
@@ -788,6 +790,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.answerSingleChoiceWithParagraph("Correct")
 			.saveAnswer()
@@ -806,6 +809,7 @@ public class ImsQTI21Test extends Deployments {
 		qtiPage = QTI21Page
 				.getQTI21Page(browser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.assertOnAssessmentItem("Kprim")
 			.answerCorrectKPrim("True", "Right")
@@ -921,6 +925,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(participantBrowser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.assertOnAssessmentItem()
 			.answerSingleChoiceWithParagraph("Correct response")
@@ -1042,6 +1047,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 				.getQTI21Page(participantBrowser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.assertOnAssessmentItem()
 			.answerSingleChoiceWithParagraph("Correct answer")
@@ -1182,6 +1188,7 @@ public class ImsQTI21Test extends Deployments {
 		QTI21Page qtiPage = QTI21Page
 			.getQTI21Page(browser);
 		qtiPage
+			.assertOnStart()
 			.start()
 			.answerSingleChoiceWithParagraph("Right")
 			.saveAnswer()
diff --git a/src/test/java/org/olat/selenium/QuestionPoolTest.java b/src/test/java/org/olat/selenium/QuestionPoolTest.java
index c319dae75196febeabc287fe69200f7336d99d07..7308baef78400d9252ffa3d8fd286cbb8d00c08f 100644
--- a/src/test/java/org/olat/selenium/QuestionPoolTest.java
+++ b/src/test/java/org/olat/selenium/QuestionPoolTest.java
@@ -120,6 +120,7 @@ public class QuestionPoolTest extends Deployments {
 		administration
 			.openTaxonomy()
 			.selectTaxonomy("QPOOL")
+			.assertOnMetadata()
 			.selectTaxonomyTree()
 			.atLeastOneLevel("at-least-one", "At least one")
 			.selectTaxonomyLevel("at-least-one")
diff --git a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
index d3ef98e91cec85322d5e1d53e2aef77b9a8ff70e..05a615b6572fc7bf87683b0ee6f2eca24c7a743b 100644
--- a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
+++ b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
@@ -201,8 +201,20 @@ public class CourseEditorPageFragment {
 		
 		By nodeBy = By.xpath("//div[@id='o_course_editor_choose_nodetype']//a[contains(@class,'o_sel_course_editor_node-" + nodeAlias + "')]");
 		OOGraphene.moveAndClick(nodeBy, browser);
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialogDisappears(browser);
+		return assertOnNodeTitle();
+	}
+	
+	/**
+	 * Wait until the short title and description field are
+	 * there.
+	 * 
+	 * @return Itself
+	 */
+	public CourseEditorPageFragment assertOnNodeTitle() {
+		By shortTitleBy = By.className("o_sel_node_editor_shorttitle");
+		OOGraphene.waitElement(shortTitleBy, browser);
+		OOGraphene.waitTinymce(browser);
 		return this;
 	}
 	
@@ -214,8 +226,9 @@ public class CourseEditorPageFragment {
 	 * @return Itself
 	 */
 	public CourseEditorPageFragment nodeTitle(String title) {
+		assertOnNodeTitle();
+
 		By shortTitleBy = By.cssSelector("div.o_sel_node_editor_shorttitle input[type='text']");
-		OOGraphene.waitElement(shortTitleBy, browser);
 		WebElement shortTitleEl = browser.findElement(shortTitleBy);
 		shortTitleEl.clear();
 		shortTitleEl.sendKeys(title);
diff --git a/src/test/java/org/olat/selenium/page/course/RemindersPage.java b/src/test/java/org/olat/selenium/page/course/RemindersPage.java
index 0a1a98588e5731efaedb1d0dd536787282b3ac9a..977bcc4e1f646b6332e27bba953bdccdaa9124fb 100644
--- a/src/test/java/org/olat/selenium/page/course/RemindersPage.java
+++ b/src/test/java/org/olat/selenium/page/course/RemindersPage.java
@@ -71,9 +71,8 @@ public class RemindersPage {
 	 */
 	public RemindersPage openActionMenu(String title) {
 		By rowBy = By.xpath("//fieldset[contains(@class,'o_sel_course_reminder_list')]//table//tr[//td//a[contains(text(), '" + title + "')]]//td//a[contains(@class,'o_sel_course_reminder_tools')]");
-		List<WebElement> reminderListEls = browser.findElements(rowBy);
-		Assert.assertEquals(1, reminderListEls.size());
-		reminderListEls.get(0).click();
+		OOGraphene.waitElement(rowBy, browser);
+		browser.findElement(rowBy).click();
 		OOGraphene.waitBusy(browser);
 		return this;
 	}
diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
index d31a89fda3aa44c8f998cb62b65cd2a2d1518cdf..04d8a29654a75f2de9331e3f2f65a65b51069ead 100644
--- a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
+++ b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
@@ -50,6 +50,13 @@ public class QTI21Page {
 		this.browser = browser;
 	}
 	
+	/**
+	 * Get only the page. You need to assert on start or assessment item
+	 * to make it reliable.
+	 * 
+	 * @param browser The browser
+	 * @return The QTI 2.1 page
+	 */
 	public static QTI21Page getQTI21Page(WebDriver browser) {
 		By mainBy = By.id("o_main_wrapper");
 		OOGraphene.waitElement(mainBy, browser);
@@ -64,8 +71,8 @@ public class QTI21Page {
 	
 	public QTI21Page start() {
 		By startBy = By.cssSelector("a.o_sel_start_qti21assessment");
-		WebElement startButton = browser.findElement(startBy);
-		startButton.click();
+		OOGraphene.waitElement(startBy, browser);
+		browser.findElement(startBy).click();
 		OOGraphene.waitBusy(browser);
 		By mainBy = By.cssSelector("div.qtiworks.o_assessmenttest");
 		OOGraphene.waitElement(mainBy, browser);
@@ -82,6 +89,7 @@ public class QTI21Page {
 	
 	public QTI21Page startTestPart() {
 		By startBy = By.xpath("//button[contains(@onclick,'advanceTestPart')]");
+		OOGraphene.waitElement(startBy, browser);
 		browser.findElement(startBy).click();
 		OOGraphene.waitBusy(browser);
 		By menuBy = By.id("o_qti_menu");
@@ -960,6 +968,8 @@ public class QTI21Page {
 	}
 	
 	public QTI21SettingsPage settings() {
+		By toolsLinkBy = By.cssSelector("ul.o_tools li.o_tool_dropdown a.o_sel_repository_tools");
+		OOGraphene.waitElement(toolsLinkBy, browser);
 		if(!browser.findElement(toolsMenu).isDisplayed()) {
 			openToolsMenu();
 		}
diff --git a/src/test/java/org/olat/selenium/page/repository/RepositorySettingsPage.java b/src/test/java/org/olat/selenium/page/repository/RepositorySettingsPage.java
index d1c0e2b64c599f8c74785b3f52bc006b5b886734..d81d78c30f884934c44f7683a09afa6e7351bf4a 100644
--- a/src/test/java/org/olat/selenium/page/repository/RepositorySettingsPage.java
+++ b/src/test/java/org/olat/selenium/page/repository/RepositorySettingsPage.java
@@ -40,6 +40,7 @@ public class RepositorySettingsPage {
 	public RepositoryEditDescriptionPage assertOnInfos() {
 		By infosBy = By.cssSelector("fieldset.o_sel_edit_repositoryentry");
 		OOGraphene.waitElement(infosBy, browser);
+		OOGraphene.waitTinymce(browser);
 		return new RepositoryEditDescriptionPage(browser);
 	}
 	
diff --git a/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyAdminPage.java b/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyAdminPage.java
index c1988376ec1fae35f32d63555914d497067287f0..3f34285b5011a1e9f87c0575558141bb296d841e 100644
--- a/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyAdminPage.java
+++ b/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyAdminPage.java
@@ -45,7 +45,6 @@ public class TaxonomyAdminPage {
 	
 	public TaxonomyPage selectTaxonomy(String identifier) {
 		OOGraphene.scrollTop(browser);//scroll top if the settings were set
-		OOGraphene.waitingALittleBit();
 		
 		By selectBy = By.xpath("//div[@class='o_taxonomy_row'][div/div/h4/small[text()[contains(.,'" + identifier + "')]]]/div/div[@class='panel-body']/div[@class='pull-right']/a");
 		OOGraphene.waitElement(selectBy, browser);
diff --git a/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyPage.java b/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyPage.java
index e941f3f36c1ca00944edbbfa538efee60d79d56c..bd0371e2999820f572d8f92096c1546fe122b650 100644
--- a/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyPage.java
+++ b/src/test/java/org/olat/selenium/page/taxonomy/TaxonomyPage.java
@@ -37,6 +37,18 @@ public class TaxonomyPage {
 		this.browser = browser;
 	}
 	
+	/**
+	 * Assert on the edit page of the taxonomy.
+	 * 
+	 * @return Itsefl
+	 */
+	public TaxonomyPage assertOnMetadata() {
+		By selectLevelsBy = By.cssSelector(".o_sel_taxonomy_form");
+		OOGraphene.waitElement(selectLevelsBy, browser);
+		OOGraphene.waitTinymce(browser);
+		return this;
+	}
+	
 	/**
 	 * Select the tab to manage the taxonomy levels.
 	 *