diff --git a/src/main/java/org/olat/repository/CatalogEntry.java b/src/main/java/org/olat/repository/CatalogEntry.java
index c4c8ce21c83ce283bb759f662e310aad9f0abac0..0760c0c9e4ab55607b6784bf2de9ca0589316d8d 100644
--- a/src/main/java/org/olat/repository/CatalogEntry.java
+++ b/src/main/java/org/olat/repository/CatalogEntry.java
@@ -169,10 +169,24 @@ public interface CatalogEntry extends CatalogEntryRef, CreateInfo, Persistable,
 	/**
 	 * get position of entry
 	 * 
-	 * @return
+	 * @return Integer
 	 */
 	public Integer getPosition();
 	
+	/**
+	 * get short title
+	 * 
+	 * @return String
+	 */
+	public String getShortTitle();
+	
+	/**
+	 * set short title
+	 * 
+	 * @param shortTitle
+	 */
+	public void setShortTitle(String shortTitle);
+	
 	
 	public enum OrderBy {
 		name,
diff --git a/src/main/java/org/olat/repository/RepositoryModule.java b/src/main/java/org/olat/repository/RepositoryModule.java
index 6cffc38f960262d5cf24d6309e24df5278dc0d83..f40ed446bdd3a6d0de7483fddee7caa44af88bb7 100644
--- a/src/main/java/org/olat/repository/RepositoryModule.java
+++ b/src/main/java/org/olat/repository/RepositoryModule.java
@@ -19,11 +19,11 @@
  */
 package org.olat.repository;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.NewControllerFactory;
 import org.olat.core.configuration.AbstractSpringModule;
 import org.olat.core.id.Roles;
 import org.olat.core.id.context.SiteContextEntryControllerCreator;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.coordinate.CoordinatorManager;
@@ -55,6 +55,7 @@ public class RepositoryModule extends AbstractSpringModule {
 	private static final String CATALOG_SITE_ENABLED = "site.catalog.enable";
 	private static final String CATALOG_ENABLED = "catalog.enable";
 	private static final String CATALOG_BROWSING_ENABLED = "catalog.brwosing.enable";
+	private static final String CATALOG_ADD_AT_LAST = "catalog.add.last";
 	private static final String MYCOURSES_SEARCH_ENABLED = "mycourses.search.enabled";
 	private static final String MYCOURSES_ALL_RESOURCES_ENABLED = "mycourses.all.resources.enabled";
 	
@@ -75,6 +76,8 @@ public class RepositoryModule extends AbstractSpringModule {
 	private boolean catalogEnabled;
 	@Value("${repo.catalog.browsing.enable}")
 	private boolean catalogBrowsingEnabled;
+	@Value("${catalog.add.last:true}")
+	private boolean catalogAddLast;
 	
 	@Value("${repo.managed}")
 	private boolean managedRepositoryEntries;
@@ -208,6 +211,11 @@ public class RepositoryModule extends AbstractSpringModule {
 		if(StringHelper.containsNonWhitespace(taxonomyTreeKeyObj)) {
 			taxonomyTreeKey = taxonomyTreeKeyObj;
 		}
+		
+		String catalogAddLastObj = getStringPropertyValue(CATALOG_ADD_AT_LAST, true);
+		if(StringHelper.containsNonWhitespace(taxonomyTreeKeyObj)) {
+			catalogAddLast = "true".equals(catalogAddLastObj);
+		}
 	}
 
 	/**
@@ -270,6 +278,15 @@ public class RepositoryModule extends AbstractSpringModule {
 		catalogBrowsingEnabled = enabled;
 		setStringProperty(CATALOG_BROWSING_ENABLED, Boolean.toString(enabled), true);
 	}
+	
+	public boolean isCatalogAddAtLast() {
+		return catalogAddLast;
+	}
+	
+	public void setCatalogAddAtLast(boolean addAtLast) {
+		catalogAddLast = addAtLast;
+		setStringProperty(CATALOG_ADD_AT_LAST, Boolean.toString(addAtLast), true);
+	}
 
 	public boolean isMyCoursesSearchEnabled() {
 		return myCoursesSearchEnabled;
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
index 02fff67d7e549c3daa2c621c7b1ad238f0e35a26..7a255f8e03b0a677dd1dd9b8e07db44474b8d4a0 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
@@ -459,7 +459,7 @@ orderby.author=Dozent
 orderby.automatic=Automatisch
 orderby.creationDate=Erstellungsdatum
 orderby.completion=$org.olat.modules.assessment.ui\:learning.progress
-orderby.custom=Vorsortiert
+orderby.custom=Geordnet
 orderby.favorit=Favorit
 orderby.lastModified=Zuletzt ge\u00E4ndert
 orderby.lastVisited=Zuletzt besucht
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
index a568be07f410012c2437b1b1ce78dfda8d15c48d..94eec8732324abf7fe1356101dc9a540b1a60935 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
@@ -459,7 +459,7 @@ orderby.author=Author
 orderby.automatic=Automatic
 orderby.completion=$org.olat.modules.assessment.ui\:learning.progress
 orderby.creationDate=Creation date
-orderby.custom=Presorted
+orderby.custom=Arranged
 orderby.favorit=Favourite
 orderby.lastModified=Last modified
 orderby.lastVisited=Last visited
diff --git a/src/main/java/org/olat/repository/manager/CatalogManager.java b/src/main/java/org/olat/repository/manager/CatalogManager.java
index 21f191ce40c3ed74f2f43ed0d70ee4cb8c62f2da..8182259f533f1a6481ee78d894c01eab7d1ff0be 100644
--- a/src/main/java/org/olat/repository/manager/CatalogManager.java
+++ b/src/main/java/org/olat/repository/manager/CatalogManager.java
@@ -66,6 +66,8 @@ import org.olat.repository.CatalogEntryRef;
 import org.olat.repository.RepositoryDeletionModule;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
+import org.olat.repository.RepositoryEntryStatusEnum;
+import org.olat.repository.RepositoryModule;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.controllers.EntryChangedEvent;
 import org.olat.repository.controllers.EntryChangedEvent.Change;
@@ -114,6 +116,8 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	@Autowired
 	private SecurityGroupDAO securityGroupDao;
 	@Autowired
+	private RepositoryModule repositoryModule;
+	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
 	private OrganisationService organisationService;
@@ -306,9 +310,17 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	
 	public void deleteCatalogEntry(RepositoryEntryRef entry, CatalogEntry parent) {
 		CatalogEntry ce = getCatalogEntryBy(entry, parent);
+		parent = loadCatalogEntry(parent);
+		
 		if(ce != null) {
 			SecurityGroup owner = ce.getOwnerGroup();
+			List<CatalogEntry> catalogEntries = parent.getChildren();
+			
+			catalogEntries.remove(ce);
+			updateCatalogEntry(parent);
+			
 			dbInstance.getCurrentEntityManager().remove(ce);
+			
 			if (owner != null) {
 				log.debug("deleteCatalogEntry case_1: delete owner-group={}", owner);
 				securityGroupDao.deleteSecurityGroup(owner);
@@ -324,14 +336,22 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	 * @param ce
 	 */
 	public void deleteCatalogEntry(CatalogEntry ce) {
-		final boolean debug = log.isDebugEnabled();
-		if(debug) log.debug("deleteCatalogEntry start... ce={}", ce);
+		log.debug("deleteCatalogEntry start... ce={}", ce);
+		
+		//reload the detached catalog entry, delete it and then the owner group
+		ce = getCatalogEntryByKey(ce.getKey());
 		
 		if (ce.getType() == CatalogEntry.TYPE_LEAF) {
-			//reload the detached catalog entry, delete it and then the owner group
-			ce = getCatalogEntryByKey(ce.getKey());
 			if(ce != null) {
 				SecurityGroup owner = ce.getOwnerGroup();
+				
+				if (ce.getParent() != null) {
+					CatalogEntry parent = ce.getParent();
+					List<CatalogEntry> catalogEntries = parent.getChildren();
+					catalogEntries.remove(ce);
+					updateCatalogEntry(parent);
+				}
+				
 				dbInstance.getCurrentEntityManager().remove(ce);
 				if (owner != null) {
 					log.debug("deleteCatalogEntry case_1: delete owner-group={}", owner);
@@ -340,15 +360,23 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 			}
 		} else {
 			List<SecurityGroup> secGroupsToBeDeleted = new ArrayList<>();
+			
 			deleteCatalogSubtree(ce,secGroupsToBeDeleted);
 			// after deleting all entries, delete all secGroups corresponding
 			for (Iterator<SecurityGroup> iter = secGroupsToBeDeleted.iterator(); iter.hasNext();) {
 				SecurityGroup grp = iter.next();
-				if(debug) log.debug("deleteCatalogEntry case_2: delete groups of deleteCatalogSubtree grp={}", grp);
+				log.debug("deleteCatalogEntry case_2: delete groups of deleteCatalogSubtree grp={}", grp);
 				securityGroupDao.deleteSecurityGroup(grp);
 			}
+			
+			if (ce.getParent() != null) {
+				CatalogEntry parent = ce.getParent();
+				List<CatalogEntry> catalogEntries = parent.getChildren();
+				catalogEntries.remove(ce);
+				updateCatalogEntry(parent);
+			}
 		}
-		if(debug) log.debug("deleteCatalogEntry END");
+		log.debug("deleteCatalogEntry END");
 	}
 
 	/**
@@ -550,20 +578,92 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	 * @param newEntry
 	 */
 	public void addCatalogEntry(CatalogEntry parent, CatalogEntry newEntry) {
-		parent = getCatalogEntryByKey(parent.getKey());
+		parent = loadCatalogEntry(parent);
 		
 		boolean debug = log.isDebugEnabled();
 		if(debug) log.debug("addCatalogEntry parent={}", parent);
 		if(debug) log.debug("addCatalogEntry newEntry={}", newEntry);
 		if(debug) log.debug("addCatalogEntry newEntry.getOwnerGroup()={}", newEntry.getOwnerGroup());
 		
-		List<CatalogEntry> catEntries = parent.getChildren();
 		newEntry.setParent(parent);
 		saveCatalogEntry(newEntry);
-		catEntries.add(newEntry);
-		updateCatalogEntry(parent);
+		
+		addToChildren(parent, newEntry);
+		
 		dbInstance.commitAndCloseSession();
 	}
+	
+	private void addToChildren(CatalogEntry parentEntry, CatalogEntry newEntry) {
+		parentEntry = loadCatalogEntry(parentEntry);
+		newEntry = loadCatalogEntry(newEntry);
+		List<CatalogEntry> catEntries = parentEntry.getChildren();
+		int index = 0;
+		boolean added = false;
+		String closed = RepositoryEntryStatusEnum.closed.name();
+		RepositoryEntry repoEntry = newEntry.getRepositoryEntry();
+		
+		if(catEntries.isEmpty()) {
+			catEntries.add(newEntry);
+			return;
+		}
+
+		cleanNullEntries(catEntries);
+		
+		for (CatalogEntry catalogEntry : catEntries) {
+			// Add entries
+			if (catalogEntry.getType() == CatalogEntry.TYPE_LEAF && newEntry.getType() == CatalogEntry.TYPE_LEAF) {
+				if (repositoryModule.isCatalogAddAtLast()) {
+					// Closed entry to the end
+					if (repoEntry.getStatus().equals(closed)) {
+						catEntries.add(newEntry);
+						added = true;
+						break;
+					} 
+					// Not closed entry to the end of not closed entries
+					else if (catalogEntry.getRepositoryEntry().getStatus().equals(closed)) {
+						catEntries.add(index, newEntry);
+						added = true;
+						break;
+					}
+				} else {
+					// Closed entry to the beginning of closed
+					if (repoEntry.getStatus().equals(closed) && catalogEntry.getRepositoryEntry().getStatus().equals(closed)) {
+						catEntries.add(index, newEntry);
+						added = true;
+						break;
+					} 
+					// Not closed entry to the beginning of not closed entries
+					else if (!repoEntry.getStatus().equals(closed) && !catalogEntry.getRepositoryEntry().getStatus().equals(closed)) {
+						catEntries.add(index, newEntry);
+						added = true;
+						break;
+					}
+				}
+			} 
+			// Add categories
+			else if (newEntry.getType() == CatalogEntry.TYPE_NODE) {
+				if (repositoryModule.isCatalogAddAtLast()) {
+					if (catalogEntry.getType() == CatalogEntry.TYPE_LEAF) {
+						catEntries.add(index, newEntry);
+						added = true; 
+						break;
+					}
+				} else {
+					catEntries.add(0, newEntry);
+					added = true;
+					break;
+				}
+			}
+			index++;
+		}
+		
+		// If not added already, add it to the bottom of the list
+		if (!added) {
+			catEntries.add(newEntry);
+		}
+
+		updateCatalogEntry(parentEntry);
+	}
 
 	/**
 	 * Find all CatalogEntries which can act as catalog roots. Frankly speaking
@@ -617,38 +717,12 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	
 	public CatalogEntry addCatalogCategory(CatalogEntry ce, CatalogEntry parentCe) {
 		if(parentCe != null) {
-			parentCe = loadCatalogEntry(parentCe.getKey());
+			parentCe = loadCatalogEntry(parentCe);
 		}
 		ce.setParent(parentCe);
 		saveCatalogEntry(ce);	
-
-		if (parentCe != null) {
-			List<CatalogEntry> catEntries = parentCe.getChildren();
-			if(catEntries.isEmpty()) {
-				catEntries.add(ce);
-			} else {
-				cleanNullEntries(catEntries);
-				
-				boolean added = false;
-				List<CatalogEntry> catalogEntries = new ArrayList<>(catEntries);
-				for (CatalogEntry catalogEntry : catalogEntries) {
-					if (catalogEntry.getType() == ce.getType()) {
-						catEntries.add(catEntries.indexOf(catalogEntry), ce);
-						added = true;
-						break;
-					}
-				}
-				
-				if(!added) {
-					if(ce.getType() == CatalogEntry.TYPE_NODE) {
-						catEntries.add(0, ce);
-					} else {
-						catEntries.add(ce);
-					}
-				}
-				updateCatalogEntry(parentCe);
-			}
-		}
+		
+		addToChildren(parentCe, ce);
 		
 		dbInstance.commitAndCloseSession();
 		return ce;
@@ -671,7 +745,8 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 	public boolean moveCatalogEntry(CatalogEntry toBeMovedEntry, CatalogEntry newParentEntry) {
 		// reload current item to prevent stale object modification
 		toBeMovedEntry = loadCatalogEntry(toBeMovedEntry);
-		newParentEntry = loadCatalogEntry(newParentEntry);		
+		newParentEntry = loadCatalogEntry(newParentEntry);	
+		
 		// check that the new parent is not a leaf
 		if (newParentEntry.getType() == CatalogEntry.TYPE_LEAF) return false;
 		// check that the new parent is not a child of the to be moved entry
@@ -683,9 +758,26 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 			}
 			tempEntry = tempEntry.getParent();
 		}
+		// Check that the new parent doesn't contain the entry already and remove it from its list
+		List<CatalogEntry> newParentChildren = newParentEntry.getChildren();
+		for (CatalogEntry newParentChild : newParentChildren) {
+			if (newParentChild.getType() == CatalogEntry.TYPE_LEAF && newParentChild.getRepositoryEntry().equals(toBeMovedEntry.getRepositoryEntry())) {
+				// Entry is already existing
+				return false;
+			}
+		}
+		// Get the old parent and remove it from its list
+		CatalogEntry oldParentEntry;
+		if (toBeMovedEntry.getParent() != null) {
+			oldParentEntry = toBeMovedEntry.getParent();
+			List<CatalogEntry> oldChildren = oldParentEntry.getChildren();
+			oldChildren.remove(toBeMovedEntry);
+			updateCatalogEntry(oldParentEntry);
+		}
 		// set new parent and save
 		toBeMovedEntry.setParent(newParentEntry);
 		updateCatalogEntry(toBeMovedEntry);
+		addToChildren(newParentEntry, toBeMovedEntry);
 		dbInstance.commitAndCloseSession();
 		return true;
 	}
@@ -871,4 +963,26 @@ public class CatalogManager implements UserDataDeletable, InitializingBean {
 		
 		return 1;
 	}
+	
+	public int setPosition(Long childEntryKey, int position) {
+		CatalogEntry childEntry = getCatalogEntryByKey(childEntryKey);
+		CatalogEntry parentEntry = childEntry.getParent();
+		List<CatalogEntry> children = parentEntry.getChildren();
+		
+		if (position >= 0 && position < children.size()) {
+			children.remove(children.indexOf(childEntry));
+			children.add(position, childEntry);
+			
+			updateCatalogEntry(parentEntry);		
+			dbInstance.commitAndCloseSession();
+			
+			return 0;
+		} else if (position < 0) {
+			return 1;
+		} else if (position >= children.size()) {
+			return 2;
+		} else {
+			return -1;
+		}
+	}
 }
diff --git a/src/main/java/org/olat/repository/model/CatalogEntryImpl.java b/src/main/java/org/olat/repository/model/CatalogEntryImpl.java
index 7ed96fb7c0c9cecf5ceaaa6ae172e6a10b6c489b..a3f07ebcfa5a3e5ff97b52c98a9e7be492c6a212 100644
--- a/src/main/java/org/olat/repository/model/CatalogEntryImpl.java
+++ b/src/main/java/org/olat/repository/model/CatalogEntryImpl.java
@@ -31,6 +31,7 @@ import java.util.List;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
@@ -85,9 +86,12 @@ public class CatalogEntryImpl implements CatalogEntry {
 	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
 	private Date creationDate;
 	
-	@Column(name = "name", unique = false, nullable = false, length = 100)
+	@Column(name = "name", unique = false, nullable = false)
 	private String name;
 	
+	@Column(name = "short_title", unique = false, nullable = true)
+	private String shortTitle;
+	
 	@Column(name = "style", unique = false, nullable = true)
 	private String styleString;
 	
@@ -105,7 +109,7 @@ public class CatalogEntryImpl implements CatalogEntry {
 	@JoinColumn(name = "parent_id", nullable = true, insertable = true, updatable = true)
 	private CatalogEntry parent;
 	
-	@OneToMany(targetEntity = CatalogEntryImpl.class, mappedBy = "parent")
+	@OneToMany(targetEntity = CatalogEntryImpl.class, mappedBy = "parent", fetch = FetchType.LAZY)
 	@OrderColumn(name = "order_index")
 	private List<CatalogEntry> children;
 
@@ -139,13 +143,23 @@ public class CatalogEntryImpl implements CatalogEntry {
 	public String getName() {
 		return name;
 	}
-
+	
 	@Override
 	public void setName(String name) {
 		if (name.length() > 100)
 			throw new AssertException("CatalogEntry: Name is limited to 100 characters.");
 		this.name = name;
 	}
+	
+	@Override 
+	public String getShortTitle() {
+		return shortTitle;
+	}
+	
+	@Override 
+	public void setShortTitle(String shortTitle) {
+		this.shortTitle = shortTitle;
+	}
 
 	public String getStyleString() {
 		return styleString;
diff --git a/src/main/java/org/olat/repository/ui/admin/CatalogAdminController.java b/src/main/java/org/olat/repository/ui/admin/CatalogAdminController.java
index e2c7d1ecdef5688ee5060bc135a92979862f4a3e..5b422a058069105adaaeb6522aff5b4e1285072f 100644
--- a/src/main/java/org/olat/repository/ui/admin/CatalogAdminController.java
+++ b/src/main/java/org/olat/repository/ui/admin/CatalogAdminController.java
@@ -23,6 +23,7 @@ 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.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 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.control.Controller;
@@ -40,7 +41,11 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class CatalogAdminController extends FormBasicController {
 
-	private MultipleSelectionElement enableEl, enableBrowsingEl, siteEl;
+	private MultipleSelectionElement enableEl;
+	private MultipleSelectionElement enableBrowsingEl;
+	private MultipleSelectionElement siteEl;
+	private SingleSelection addEntryPosEl;
+	
 	
 	@Autowired
 	private RepositoryModule repositoryModule;
@@ -73,6 +78,18 @@ public class CatalogAdminController extends FormBasicController {
 		siteEl.select("xx", repositoryModule.isCatalogSiteEnabled());
 		siteEl.setEnabled(enabled);
 		siteEl.addActionListener(FormEvent.ONCLICK);
+		
+		String[] addEntryKeys = {AddEntryPosition.top.name(), AddEntryPosition.bottom.name()};
+		String[] addEntryValues = {translate("catalog.addposition." + AddEntryPosition.top.name()), translate("catalog.addposition." + AddEntryPosition.bottom.name())};
+		
+		addEntryPosEl = uifactory.addDropdownSingleselect("catalog.addposition", "catalog.addposition", formLayout, addEntryKeys, addEntryValues);
+		if (repositoryModule.isCatalogAddAtLast()) {
+			addEntryPosEl.select(AddEntryPosition.bottom.name(), true);
+		} else {
+			addEntryPosEl.select(AddEntryPosition.top.name(), true);
+		}
+		addEntryPosEl.setEnabled(enabled);
+		addEntryPosEl.addActionListener(FormEvent.ONCHANGE);
 	}
 
 	@Override
@@ -87,10 +104,17 @@ public class CatalogAdminController extends FormBasicController {
 			repositoryModule.setCatalogEnabled(enabled);
 			siteEl.setEnabled(enabled);
 			enableBrowsingEl.setEnabled(enabled);
+			addEntryPosEl.setEnabled(enabled);
 		} else if(source == siteEl) {
 			repositoryModule.setCatalogSiteEnabled(siteEl.isSelected(0));
 		} else if(source == enableBrowsingEl) {
 			repositoryModule.setCatalogBrowsingEnabled(enableBrowsingEl.isSelected(0));
+		} else if (source == addEntryPosEl) {
+			if (addEntryPosEl.getSelectedKey().equals(AddEntryPosition.bottom.name())) {
+				repositoryModule.setCatalogAddAtLast(true);
+			} else {
+				repositoryModule.setCatalogAddAtLast(false);
+			}
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -99,4 +123,9 @@ public class CatalogAdminController extends FormBasicController {
 	protected void formOK(UserRequest ureq) {
 		//
 	}
+	
+	private enum AddEntryPosition {
+		top,
+		bottom;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_de.properties
index a60ad8bccd3d16c54e1fc3f47a62e6e428a7c074..306dd7abc5fe4e5694e46b59cbc0653cab55657e 100644
--- a/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_de.properties
@@ -2,6 +2,9 @@
 admin.catalog.settings=Katalog settings
 admin.menu.title=Katalog
 admin.menu.title.alt=Katalog
+catalog.addposition=Neue Eintr\u00e4ge hinzuf\u00fcgen
+catalog.addposition.bottom=Am Ende
+catalog.addposition.top=Am Anfang
 catalog.browsing=Katalog in "Kurse"
 catalog.enable=Katalog einschalten
 catalog.site=Katalog in eigener Site
diff --git a/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_en.properties
index d97343f5bbbb46352016641fc0fa90987cfc2f11..e05ce14753398b136cbfeacc75d874ecdba88dc4 100644
--- a/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/repository/ui/admin/_i18n/LocalStrings_en.properties
@@ -2,6 +2,9 @@
 admin.catalog.settings=Catalog settings
 admin.menu.title=Catalog
 admin.menu.title.alt=Catalog
+catalog.addposition=Add new entries
+catalog.addposition.bottom=At the end
+catalog.addposition.top=At the beginning
 catalog.enable=Enable catalog
 catalog.browsing=Catalog in "Courses"
 catalog.site=Catalog in its own site
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryEditController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryEditController.java
index afbb5166d81669943120bfa6a6a5678308c0c9d1..c321ec0eda830896577d5d1d2bd45ec5640019ee 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryEditController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryEditController.java
@@ -118,13 +118,12 @@ public class CatalogEntryEditController extends FormBasicController {
 		nameEl.setMandatory(true);
 		nameEl.setNotEmptyCheck("form.legende.mandatory");
 		
-		/*
-		String shortTitle = catalogEntry == null ? "" : catalogEntry.get() != null ? catalogEntry.getDescription() : "";
+		String shortTitle = catalogEntry == null ? "" : catalogEntry.getShortTitle() != null ? catalogEntry.getShortTitle() : "";
 		shortTitleEl = uifactory.addTextElement("shortTitle", "entry.shorttitle", 255, shortTitle, formLayout);
 		shortTitleEl.setElementCssClass("o_sel_cat_short_title");
 		shortTitleEl.setMandatory(true);
 		shortTitleEl.setNotEmptyCheck("form.legende.mandatory");
-		*/
+		shortTitleEl.setHelpText(translate("catalog.popup.edit.shorttitle.desc"));
 		
 		String desc = catalogEntry == null ? "" : catalogEntry.getDescription();
 		descriptionEl = uifactory.addRichTextElementForStringDataMinimalistic("description", "entry.description", desc, 10, -1, formLayout, getWindowControl());
@@ -179,16 +178,8 @@ public class CatalogEntryEditController extends FormBasicController {
 	protected boolean validateFormLogic(UserRequest ureq) {
 		boolean allOk = super.validateFormLogic(ureq);
 		
-		nameEl.clearError();
-		if(StringHelper.containsNonWhitespace(nameEl.getValue())) {
-			if(nameEl.getValue().length() > 99) {
-				nameEl.setErrorKey("input.toolong", new String[]{ "100" });
-				allOk &= false;
-			}
-		} else {
-			nameEl.setErrorKey("form.legende.mandatory", null);
-			allOk &= false;
-		}
+		allOk &= validateTextInput(nameEl, 100);
+		allOk &= validateTextInput(shortTitleEl, 16);
 		
 		styleEl.clearError();
 		if(!styleEl.isOneSelected()) {
@@ -198,6 +189,21 @@ public class CatalogEntryEditController extends FormBasicController {
 
 		return allOk;
 	}
+	
+	private boolean validateTextInput(TextElement textElement, int lenght) {		
+		textElement.clearError();
+		if(StringHelper.containsNonWhitespace(nameEl.getValue())) {
+			if(textElement.getValue().length() > lenght) {
+				textElement.setErrorKey("input.toolong", new String[]{ String.valueOf(lenght) });
+				return false;
+			}
+		} else {
+			textElement.setErrorKey("form.legende.mandatory", null);
+			return false;
+		}
+		
+		return true;
+	}
 
 	@Override
 	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
@@ -235,6 +241,7 @@ public class CatalogEntryEditController extends FormBasicController {
 			catalogEntry.setStyle(null);
 		}
 		catalogEntry.setDescription(descriptionEl.getValue());
+		catalogEntry.setShortTitle(shortTitleEl.getValue());
 		
 		if(catalogEntry.getKey() == null) {
 			//a new one
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryPositionDialogController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryPositionDialogController.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd4a62c41ee508c70332783d57cf30998d046291
--- /dev/null
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryPositionDialogController.java
@@ -0,0 +1,147 @@
+/**
+ * OLAT - Online Learning and Training<br>
+ * http://www.olat.org
+ * <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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <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>
+ * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
+ * University of Zurich, Switzerland.
+ * <hr>
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * This file has been modified by the OpenOLAT community. Changes are licensed
+ * under the Apache 2.0 license as the original file.
+ */
+package org.olat.repository.ui.catalog;
+
+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.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.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.Util;
+import org.olat.repository.CatalogEntry;
+import org.olat.repository.manager.CatalogManager;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/* 
+ * Date: 24 Feb 2020<br>
+ * @author Alexander Boeckle
+ */
+public class CatalogEntryPositionDialogController extends FormBasicController {
+	Long catalogEntryKey;
+	int position;
+	int smallest;
+	int biggest;
+
+	CatalogEntry catalogEntry;
+
+	@Autowired
+	CatalogManager catalogManager;
+	
+	FormLink smallestFormLink;
+	FormLink smallerFormLink;
+	FormLink biggestFormLink;
+	FormLink biggerFormLink;
+	TextElement positionTextElement;
+
+	public CatalogEntryPositionDialogController(UserRequest ureq, WindowControl wControl, Long catalogEntryKey, int smallest, int biggest) {
+		super(ureq, wControl, "catPosition", Util.createPackageTranslator(CatalogNodeManagerController.class, ureq.getLocale()));
+		
+		catalogEntry = catalogManager.getCatalogEntryByKey(catalogEntryKey);
+		this.biggest = biggest + 1;
+		this.smallest = smallest + 1;
+		this.catalogEntryKey = catalogEntryKey;
+		this.position = catalogEntry.getPosition() + 1;
+
+		initForm(ureq);
+	}
+	
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {	
+		flc.contextPut("catalog_entry_name", catalogEntry.getName());
+		
+		smallestFormLink = uifactory.addFormLink("catalog.popup.position.smallest", formLayout, Link.BUTTON);
+		smallerFormLink = uifactory.addFormLink("catalog.popup.position.smaller", formLayout, Link.BUTTON);
+		positionTextElement = uifactory.addTextElement("catalog.popup.position.set", 5, String.valueOf(position), formLayout);
+		positionTextElement.setDisplaySize(4);
+		positionTextElement.setMandatory(true);
+		positionTextElement.setElementCssClass("o_centered_form");
+		biggerFormLink = uifactory.addFormLink("catalog.popup.position.bigger", formLayout, Link.BUTTON);
+		biggestFormLink = uifactory.addFormLink("catalog.popup.position.biggest", formLayout, Link.BUTTON);
+		
+		FormLayoutContainer filterButtonLayout = FormLayoutContainer.createButtonLayout("save", getTranslator());
+		filterButtonLayout.setRootForm(mainForm);
+		formLayout.add(filterButtonLayout);
+		
+		uifactory.addFormSubmitButton("catalog.popup.position.save", filterButtonLayout);
+	}
+	
+	@Override
+	protected boolean validateFormLogic(UserRequest ureq) {
+		boolean allOk = super.validateFormLogic(ureq);
+		try {
+			position = Integer.parseInt(positionTextElement.getValue());
+			
+			if (position < smallest || position > biggest) {
+				positionTextElement.setErrorKey("catalog.popup.position.error.number", new String[]{String.valueOf(smallest), String.valueOf(biggest)});
+				allOk&=false;
+			} 
+		} catch (Exception e) {
+			positionTextElement.setErrorKey("catalog.popup.position.error.number.format", null);
+			allOk&=false;
+		}
+	
+		return allOk;
+	}
+	
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if (source == smallerFormLink && position > smallest) {
+			position -= 1;
+			positionTextElement.setValue(String.valueOf(position));
+		} else if (source == smallestFormLink) {
+			position = smallest + 1;
+			positionTextElement.setValue(String.valueOf(smallest));
+		} else if (source == biggerFormLink && position < biggest) {
+			position += 1;
+			positionTextElement.setValue(String.valueOf(position));
+		} else if (source == biggestFormLink) {
+			position = biggest + 1;
+			positionTextElement.setValue(String.valueOf(biggest));
+		}
+	}
+	
+	@Override
+	protected void formOK(UserRequest ureq) {
+		catalogManager.setPosition(catalogEntryKey, position - 1);
+		fireEvent(ureq, Event.DONE_EVENT);
+	}
+	
+	@Override
+	protected void formCancelled(UserRequest ureq) {
+		fireEvent(ureq, Event.CANCELLED_EVENT);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+}
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRow.java b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRow.java
index 254f5ca60a73680a511bd288596d3461d1290643..59926fb2ba36ca1cd609db3dc051dc7d960c199d 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRow.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRow.java
@@ -22,6 +22,7 @@ package org.olat.repository.ui.catalog;
 import java.util.Date;
 import java.util.List;
 
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.resource.OresHelper;
@@ -44,7 +45,7 @@ public class CatalogEntryRow implements RepositoryEntryRef, RepositoryEntryLight
 
 	private Long key;
 	private Long catEntryKey;
-	private int position;
+	private Integer position;
 	private String name;
 	private String authors;
 	private String shortenedDescription;
@@ -66,6 +67,8 @@ public class CatalogEntryRow implements RepositoryEntryRef, RepositoryEntryLight
 	private Date lifecycleStart;
 	private Date lifecycleEnd;
 	
+	private FormLink positionLink;
+	
 	private List<PriceMethod> accessTypes;
 
 	private OLATResourceable olatResource;
@@ -103,7 +106,7 @@ public class CatalogEntryRow implements RepositoryEntryRef, RepositoryEntryLight
 	public CatalogEntryRow(RepositoryEntry view, CatalogEntry cat) {
 		this(view);
 		
-		position = cat.getPosition() == null ? 0 : cat.getPosition().intValue();
+		position = cat.getPosition() == null ? 0 : cat.getPosition();
 		catEntryKey = cat.getKey();
 	}
 		
@@ -186,7 +189,7 @@ public class CatalogEntryRow implements RepositoryEntryRef, RepositoryEntryLight
 		return lifecycleEnd;
 	}
 	
-	public int getPosition() {
+	public Integer getPosition() {
 		return position;
 	}
 	
@@ -222,4 +225,12 @@ public class CatalogEntryRow implements RepositoryEntryRef, RepositoryEntryLight
 	public String getAuthors() {
 		return authors;
 	}
+	
+	public FormLink getPositionLink() {
+		return positionLink;
+	}
+	
+	public void setPositionLink(FormLink positionLink) {
+		this.positionLink = positionLink;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRowModel.java b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRowModel.java
index 16011ea7ad636c3fc9f8a5e6be2290063cbd93b7..11b711c28df8549d9469dec367392fac292fca67 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRowModel.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogEntryRowModel.java
@@ -76,7 +76,7 @@ public class CatalogEntryRowModel extends DefaultFlexiTableDataModel<CatalogEntr
 			case detailsSupported: return item;
 			case move: return item;
 			case delete: return item;
-			case position: return item.getPosition();
+			case position: return item.getPositionLink();
 		}
 		return null;
 	}
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogManagerController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogManagerController.java
index 5b5a7865508a9f487dec661f2d14e2cebfefc1d7..fd3a5c8b08a1d8f356c6a65ab58bcea06f7f0ea0 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogManagerController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogManagerController.java
@@ -63,9 +63,10 @@ public class CatalogManagerController extends BasicController implements Activat
 
 		List<CatalogEntry> rootNodes = catalogManager.getRootCatalogEntries();
 		if(rootNodes.size() == 1) {
-			catalogCtrl = new CatalogNodeManagerController(ureq, getWindowControl(), getWindowControl(), rootNodes.get(0), toolbarPanel, false);
+			CatalogEntry root = rootNodes.get(0);
+			catalogCtrl = new CatalogNodeManagerController(ureq, getWindowControl(), getWindowControl(), root, toolbarPanel, false);
 			listenTo(catalogCtrl);
-			toolbarPanel.pushController("Catalog", catalogCtrl);
+			toolbarPanel.pushController(root.getShortTitle(), catalogCtrl);
 			catalogCtrl.initToolbar();
 		}
 	}
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeController.java
index d52e9e7cfd4f24dacec37813d79dbaea310829b6..ada3d9e5274c0f6dc653ca0e0e4235292c004451 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeController.java
@@ -97,7 +97,8 @@ public class CatalogNodeController extends BasicController implements Activateab
 		} else {
 			mainVC.contextPut("listStyle", Style.tiles.name());
 		}
-		mainVC.contextPut("catalogEntryName", catalogEntry.getName());
+		mainVC.contextPut("catalogEntryTitle", catalogEntry.getName());
+		mainVC.contextPut("catalogEntryShortTitle", catalogEntry.getShortTitle());
 		int level  = 0;
 		CatalogEntry parent = catalogEntry.getParent();
 		while (parent != null) {
@@ -114,7 +115,7 @@ public class CatalogNodeController extends BasicController implements Activateab
 			mainVC.contextPut("catThumbnail", image.getName());
 		}
 		
-		List<CatalogEntry> childCe = catalogEntry.getChildren();
+		List<CatalogEntry> childCe = catalogManager.getChildrenOf(catalogEntry);
 		List<String> subCategories = new ArrayList<>();
 		int count = 0;
 		for (CatalogEntry entry : childCe) {
@@ -129,13 +130,22 @@ public class CatalogNodeController extends BasicController implements Activateab
 				mainVC.contextPut("k" + cmpId, entry.getKey());
 				
 				String title = StringHelper.escapeHtml(entry.getName());
+				String shortTitle; 
+				if (entry.getShortTitle() == null) {
+					shortTitle = StringHelper.escapeHtml(entry.getName());
+				} else {
+					shortTitle = StringHelper.escapeHtml(entry.getShortTitle());
+				}
+				
 				Link link = LinkFactory.createCustomLink(cmpId, "select_node", cmpId, Link.LINK + Link.NONTRANSLATED, mainVC, this);
 				link.setCustomDisplayText(title);
 				link.setIconLeftCSS("o_icon o_icon_catalog_sub");
 				link.setUserObject(entry.getKey());
 				subCategories.add(Integer.toString(count));
 				String titleId = "title_" + count;
+				String shortTitleId = "short_title_" + count;
 				mainVC.contextPut(titleId, title);
+				mainVC.contextPut(shortTitleId, shortTitle);
 			}
 		}
 		mainVC.contextPut("subCategories", subCategories);
@@ -146,7 +156,7 @@ public class CatalogNodeController extends BasicController implements Activateab
 		searchParams.setParentEntry(catalogEntry);
 		searchParams.setClosed(Boolean.FALSE);
 		
-		entryListController = new RepositoryEntryListController(ureq, wControl, searchParams, true, false, "catalog", stackPanel);
+		entryListController = new RepositoryEntryListController(ureq, wControl, searchParams, true, false, false, "catalog", stackPanel);
 		if(!entryListController.isEmpty() || searchParams.getFilters() != null) {
 			mainVC.put("entries", entryListController.getInitialComponent());
 		}
@@ -157,7 +167,8 @@ public class CatalogNodeController extends BasicController implements Activateab
 				= new SearchMyRepositoryEntryViewParams(getIdentity(), ureq.getUserSession().getRoles());
 		searchClosedParams.setParentEntry(catalogEntry);
 		searchClosedParams.setClosed(Boolean.TRUE);
-		closedEntryListController = new RepositoryEntryListController(ureq, wControl, searchClosedParams, true, false, "catalog-closed", stackPanel);
+		
+		closedEntryListController = new RepositoryEntryListController(ureq, wControl, searchClosedParams, true, false, false, "catalog-closed", stackPanel);
 		if(!closedEntryListController.isEmpty() || searchClosedParams.getFilters() != null) {
 			mainVC.put("closedEntries", closedEntryListController.getInitialComponent());
 		}
@@ -206,7 +217,7 @@ public class CatalogNodeController extends BasicController implements Activateab
 			
 			childNodeController = new CatalogNodeController(ureq, bwControl, rootwControl, entry, stackPanel, wrapInMainPanel);
 			listenTo(childNodeController);
-			stackPanel.pushController(entry.getName(), childNodeController);
+			stackPanel.pushController(entry.getShortTitle(), childNodeController);
 			
 			addToHistory(ureq, childNodeController);
 		}
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
index 84f5163423126968e03db7b681e76f7cb67b57f6..9bf5331e622cff5841178d3541f6e279c59530c1 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogNodeManagerController.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.olat.NewControllerFactory;
 import org.olat.admin.securitygroup.gui.GroupController;
@@ -37,6 +38,7 @@ import org.olat.core.gui.components.Component;
 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.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 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.elements.table.BooleanCellRenderer;
@@ -51,11 +53,14 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlex
 import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer;
 import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.components.stack.PopEvent;
 import org.olat.core.gui.components.stack.TooledStackedPanel;
 import org.olat.core.gui.components.stack.TooledStackedPanel.Align;
 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.gui.control.generic.closablewrapper.CalloutSettings;
+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.control.generic.modal.DialogBoxController;
@@ -121,13 +126,17 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	public static final OLATResourceable lockRes = OresHelper.createOLATResourceableType("CatalogNodeManagerController");
 	
 	private final TooledStackedPanel toolbarPanel;
+	private final AtomicInteger counter = new AtomicInteger();
 	
 	private GroupController groupCtrl;
 	private CloseableModalController cmc;
 	private ContactFormController contactCtrl;
 	private RepositorySearchController entrySearchCtrl;
+	private CatalogEntryPositionDialogController positionCtrl;
+	private CloseableCalloutWindowController positionCalloutCtrl;
 
 	private CatalogNodeManagerController childNodeCtrl;
+	private CatalogNodeManagerController positionMoveCtrl;
 	private CatalogEntryMoveController categoryMoveCtrl;
 	private CatalogEntryMoveController entryResourceMoveCtrl;
 	private CatalogEntryEditController addEntryCtrl, editEntryCtrl;
@@ -159,6 +168,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	
 	private static final String CMD_UP = "leaf_up";
 	private static final String CMD_DOWN = "leaf_down";
+	private static final String CMD_SET_POSITION = "set_position";
 	
 	private LockResult catModificationLock;
 	private final MapperKey mapperThumbnailKey;
@@ -206,6 +216,42 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		isOrdering = false;
 		flc.contextPut("isOrdering", isOrdering);
 		
+		this.toolbarPanel.addListener(this);
+		
+		if(isAdministrator) {
+			isLocalTreeAdmin = false;
+		} else {
+			isLocalTreeAdmin = localTreeAdmin || catalogManager.isOwner(catalogEntry, getIdentity());
+		}
+
+		initForm(ureq);
+		
+		loadEntryInfos();
+		loadNodesChildren();
+		loadResources(ureq);
+		//catch the events from the velocity template
+		flc.getFormItemComponent().addListener(this);
+	}
+	
+	public CatalogNodeManagerController(UserRequest ureq, WindowControl wControl, WindowControl rootwControl,
+			CatalogEntry catalogEntry, TooledStackedPanel stackPanel, boolean localTreeAdmin, boolean isOrdering) {
+		super(ureq, wControl, "node");
+		setTranslator(Util.createPackageTranslator(RepositoryService.class, ureq.getLocale(), getTranslator()));
+		
+		this.toolbarPanel = stackPanel;
+		this.catalogEntry = catalogEntry;
+		this.rootwControl = rootwControl;
+		mapperThumbnailKey = mapperService.register(null, "catalogentryImage", new CatalogEntryImageMapper());
+		
+		Roles roles = ureq.getUserSession().getRoles();
+		isAuthor = roles.isAuthor();
+		isGuest = roles.isGuestOnly();
+		isAdministrator = roles.isAdministrator() || roles.isLearnResourceManager();
+		this.isOrdering = isOrdering;
+		flc.contextPut("isOrdering", isOrdering);
+		
+		this.toolbarPanel.addListener(this);
+		
 		if(isAdministrator) {
 			isLocalTreeAdmin = false;
 		} else {
@@ -244,11 +290,11 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		
 		leafColumns = new ArrayList<>();
 		
-		FlexiTableColumnModel entriesColumnsModel = getCatalogFlexiTableColumnModel("opened-", true);
+		FlexiTableColumnModel entriesColumnsModel = getCatalogFlexiTableColumnModel("opened-", !isOrdering);
 		entriesModel = new CatalogEntryRowModel(entriesColumnsModel);
 		entriesEl = uifactory.addTableElement(getWindowControl(), "entries", entriesModel, getTranslator(), formLayout);
 		
-		FlexiTableColumnModel closedEntriesColumnsModel = getCatalogFlexiTableColumnModel("closed-", true);
+		FlexiTableColumnModel closedEntriesColumnsModel = getCatalogFlexiTableColumnModel("closed-", !isOrdering);
 		closedEntriesModel = new CatalogEntryRowModel(closedEntriesColumnsModel);
 		closedEntriesEl = uifactory.addTableElement(getWindowControl(), "closedEntries", closedEntriesModel, getTranslator(), formLayout);
 		
@@ -262,25 +308,29 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		DefaultFlexiColumnModel columnModel;
 		
-		leafUpColumnModel = new DefaultFlexiColumnModel(false, Cols.up.i18nKey(), Cols.up.ordinal(), CMD_UP, false, null);
-		leafUpColumnModel.setCellRenderer(new BooleanCellRenderer(
-				new StaticFlexiCellRenderer("", CMD_UP, "o_icon o_icon-lg o_icon_move_up"),
-				null));
-		leafUpColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_up");
-		leafUpColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);
-		columnsModel.addFlexiColumnModel(leafUpColumnModel);
-		
-		leafDownColumnModel = new DefaultFlexiColumnModel(false, Cols.down.i18nKey(), Cols.down.ordinal(), CMD_DOWN, false, null);
-		leafDownColumnModel.setCellRenderer(new BooleanCellRenderer(
-				new StaticFlexiCellRenderer("", CMD_DOWN, "o_icon o_icon-lg o_icon_move_down"),
-				null));
-		leafDownColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_down");
-		leafDownColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);	
-		columnsModel.addFlexiColumnModel(leafDownColumnModel);
-		
-		leafPositionColumnModel = new DefaultFlexiColumnModel(false, Cols.position.i18nKey(), Cols.position.ordinal(), sortEnabled, Cols.position.name());
-		columnsModel.addFlexiColumnModel(leafPositionColumnModel);
-		leafColumns.add(leafPositionColumnModel);
+		if (!sortEnabled) {
+			leafUpColumnModel = new DefaultFlexiColumnModel(true, Cols.up.i18nKey(), Cols.up.ordinal(), CMD_UP, false, null);
+			leafUpColumnModel.setCellRenderer(new BooleanCellRenderer(
+					new StaticFlexiCellRenderer("", CMD_UP, "o_icon o_icon-lg o_icon_move_up"),
+					null));
+			leafUpColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_up");
+			leafUpColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);
+			leafUpColumnModel.setAlwaysVisible(true);
+			columnsModel.addFlexiColumnModel(leafUpColumnModel);
+			
+			leafDownColumnModel = new DefaultFlexiColumnModel(true, Cols.down.i18nKey(), Cols.down.ordinal(), CMD_DOWN, false, null);
+			leafDownColumnModel.setCellRenderer(new BooleanCellRenderer(
+					new StaticFlexiCellRenderer("", CMD_DOWN, "o_icon o_icon-lg o_icon_move_down"),
+					null));
+			leafDownColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_down");
+			leafDownColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);	
+			leafDownColumnModel.setAlwaysVisible(true);
+			columnsModel.addFlexiColumnModel(leafDownColumnModel);
+
+			
+			leafPositionColumnModel = new DefaultFlexiColumnModel(true, Cols.position.i18nKey(), Cols.position.ordinal(), false, null);
+			columnsModel.addFlexiColumnModel(leafPositionColumnModel);
+		}
 		
 		columnModel = new DefaultFlexiColumnModel(false, Cols.key.i18nKey(), Cols.key.ordinal(), sortEnabled, OrderBy.key.name());
 		leafColumns.add(columnModel);
@@ -349,10 +399,13 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		leafColumns.add(columnModel);
 		columnsModel.addFlexiColumnModel(columnModel);
 		
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.delete.i18nKey(), translate(Cols.delete.i18nKey()), cmdPrefix + "delete"));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.move.i18nKey(), translate(Cols.move.i18nKey()), cmdPrefix + "move"));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.detailsSupported.i18nKey(), Cols.detailsSupported.ordinal(), cmdPrefix + "details",
-				new StaticFlexiCellRenderer("", cmdPrefix + "details", "o_icon o_icon-lg o_icon_details", translate("details"))));
+		if (!isOrdering) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.delete.i18nKey(), translate(Cols.delete.i18nKey()), cmdPrefix + "delete"));
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.move.i18nKey(), translate(Cols.move.i18nKey()), cmdPrefix + "move"));
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.detailsSupported.i18nKey(), Cols.detailsSupported.ordinal(), cmdPrefix + "details",
+					new StaticFlexiCellRenderer("", cmdPrefix + "details", "o_icon o_icon-lg o_icon_details", translate("details"))));
+		}
+		
 		return columnsModel;
 	}
 	
@@ -360,23 +413,24 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		//add the table
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		
-		nodeUpColumnModel = new DefaultFlexiColumnModel(false, NodeCols.up.i18nKey(), NodeCols.up.ordinal(), CMD_UP, false, null);
+		nodeUpColumnModel = new DefaultFlexiColumnModel(true, NodeCols.up.i18nKey(), NodeCols.up.ordinal(), CMD_UP, false, null);
 		nodeUpColumnModel.setCellRenderer(new BooleanCellRenderer(
 				new StaticFlexiCellRenderer("", CMD_UP, "o_icon o_icon_fw o_icon-lg o_icon_move_up"),
 				null));
 		nodeUpColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_up");
 		nodeUpColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);
+		nodeUpColumnModel.setAlwaysVisible(true);
 
 		
-		nodeDownColumnModel = new DefaultFlexiColumnModel(false, NodeCols.down.i18nKey(), NodeCols.down.ordinal(), CMD_DOWN, false, null);
+		nodeDownColumnModel = new DefaultFlexiColumnModel(true, NodeCols.down.i18nKey(), NodeCols.down.ordinal(), CMD_DOWN, false, null);
 		nodeDownColumnModel.setCellRenderer(new BooleanCellRenderer(
 				new StaticFlexiCellRenderer("", CMD_DOWN, "o_icon o_icon_fw o_icon-lg o_icon_move_down"),
 				null));
 		nodeDownColumnModel.setIconHeader("o_icon o_icon_fw o_icon-lg o_icon_move_down");
 		nodeDownColumnModel.setAlignment(FlexiColumnModel.ALIGNMENT_ICON);
+		nodeDownColumnModel.setAlwaysVisible(true);
 		
 		nodePositionColumnModel = new DefaultFlexiColumnModel(true, NodeCols.position.i18nKey(), NodeCols.position.ordinal(), false, null);
-
 		
 		columnsModel.addFlexiColumnModel(nodeUpColumnModel);
 		columnsModel.addFlexiColumnModel(nodeDownColumnModel);
@@ -388,7 +442,9 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	} 
 
 	private void loadEntryInfos() {
-		flc.contextPut("catalogEntryName", catalogEntry.getName());
+		catalogEntry = catalogManager.loadCatalogEntry(catalogEntry);
+		flc.contextPut("catalogEntryTitle", catalogEntry.getName());
+		flc.contextPut("catalogEntryShortTitle", catalogEntry.getShortTitle());
 		if(StringHelper.containsNonWhitespace(catalogEntry.getDescription())) {
 			flc.contextPut("catalogEntryDesc", catalogEntry.getDescription());
 		}
@@ -404,7 +460,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	}
 
 	private void loadResources(UserRequest ureq) {
-		catalogEntry = catalogManager.getCatalogEntryByKey(catalogEntry.getKey());
+		catalogEntry = catalogManager.loadCatalogEntry(catalogEntry);
 		List<CatalogEntry> detachedChildren = catalogManager.getChildrenOf(catalogEntry);
 		
 		SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters(getIdentity(), ureq.getUserSession().getRoles());
@@ -455,14 +511,22 @@ public class CatalogNodeManagerController extends FormBasicController implements
 			}
 			
 			if(entry.getEntryStatus() == RepositoryEntryStatusEnum.closed) {
+				FormLink positionLink = uifactory.addFormLink("position_" + counter.incrementAndGet(), "positionClosedEntries", String.valueOf(row.getPosition() + 1), null, null, Link.NONTRANSLATED);
+				positionLink.setUserObject(row);
+				row.setPositionLink(positionLink);
+				
 				closedItems.add(row);
 			} else {
+				FormLink positionLink = uifactory.addFormLink("position_" + counter.incrementAndGet(), "positionEntries", String.valueOf(row.getPosition() + 1), null, null, Link.NONTRANSLATED);
+				positionLink.setUserObject(row);
+				row.setPositionLink(positionLink);
+				
 				items.add(row);
 			}
 		}
 		
 		Comparator<CatalogEntryRow> comparator = (row1, row2) -> {
-			return ((Integer)row1.getPosition()).compareTo(row2.getPosition());
+			return row1.getPosition().compareTo(row2.getPosition());
 		};
 
 		Collections.sort(items, comparator);
@@ -475,16 +539,25 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		closedEntriesModel.setObjects(closedItems);
 		closedEntriesEl.reset(true, true, true);
 		closedEntriesEl.setVisible(closedEntriesModel.getRowCount() > 0);
+		
+		flc.setDirty(true);
 	}
 	
 	protected void loadNodesChildren() {
+		catalogEntry = catalogManager.loadCatalogEntry(catalogEntry);
 		List<CatalogEntry> catalogChildren = catalogManager.getChildrenOf(catalogEntry);
 		List<String> subCategories = new ArrayList<>();
 		List<NodeEntryRow> nodeEntries = new ArrayList<>();
 		int count = 0;
 		for (CatalogEntry entry : catalogChildren) {
 			if(entry != null && entry.getType() == CatalogEntry.TYPE_NODE) {
-				nodeEntries.add(new NodeEntryRow(entry));
+				NodeEntryRow row = new NodeEntryRow(entry);
+				
+				FormLink positionLink = uifactory.addFormLink("position_" + counter.incrementAndGet(), "positionNodes", String.valueOf(row.getPosition() + 1), null, null, Link.NONTRANSLATED);
+				positionLink.setUserObject(row);
+				row.setPositionLink(positionLink);
+				
+				nodeEntries.add(row);
 
 				String cmpId = "cat_" + (++count);
 
@@ -496,13 +569,21 @@ public class CatalogNodeManagerController extends FormBasicController implements
 				flc.contextPut("k" + cmpId, entry.getKey());
 
 				String title = StringHelper.escapeHtml(entry.getName());
+				String shortTitle; 
+				if (entry.getShortTitle() == null) {
+					shortTitle = StringHelper.escapeHtml(entry.getName());
+				} else {
+					shortTitle = StringHelper.escapeHtml(entry.getShortTitle());
+				}
 				Link link = LinkFactory.createCustomLink(cmpId, "select_node", cmpId, Link.LINK + Link.NONTRANSLATED, flc.getFormItemComponent(), this);
 				link.setIconLeftCSS("o_icon o_icon_catalog_sub");
 				link.setCustomDisplayText(title);
 				link.setUserObject(entry.getKey());
 				subCategories.add(Integer.toString(count));
 				String titleId = "title_" + count;
+				String shortTitleId = "short_title_" + count;
 				flc.contextPut(titleId, title);
+				flc.contextPut(shortTitleId, shortTitle);
 			}
 		}
 		flc.contextPut("subCategories", subCategories);
@@ -516,6 +597,8 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		nodeEntriesModel.setObjects(nodeEntries);
 		nodeEntriesEl.reset(true, true, true);
 		nodeEntriesEl.setVisible(nodeEntriesModel.getRowCount() > 0);
+		
+		flc.setDirty(true);
 	}
 	
 	protected void initToolbar() {
@@ -525,55 +608,89 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	
 		if (canAdministrateCategory || canAddLinks) {
 			if (canAdministrateCategory) {
-				orderLink = LinkFactory.createToolLink("order", translate("tools.order.catalog"), this, "o_icon_order");
-				orderLink.setElementCssClass("o_sel_catalog_order_category");
-				toolbarPanel.addTool(orderLink, Align.right);
+				if (orderLink == null) {
+					orderLink = LinkFactory.createToolLink("order", translate("tools.order.catalog"), this, "o_icon_order");
+					orderLink.setElementCssClass("o_sel_catalog_order_category");
+					toolbarPanel.addTool(orderLink, Align.right);
+				} else {
+					orderLink.setVisible(true);
+				}
 			}
 			if (canAdministrateCategory) {
-				editLink = LinkFactory.createToolLink("edit", translate("tools.edit.catalog.category"), this, "o_icon_edit");
-				editLink.setElementCssClass("o_sel_catalog_edit_category");
-				toolbarPanel.addTool(editLink, Align.left);
+				if (editLink == null) {
+					editLink = LinkFactory.createToolLink("edit", translate("tools.edit.catalog.category"), this, "o_icon_edit");
+					editLink.setElementCssClass("o_sel_catalog_edit_category");
+					toolbarPanel.addTool(editLink, Align.left);
+				} else {
+					editLink.setVisible(true);
+				}
 			}
 			if (canAdministrateCategory) {
-				nominateLink = LinkFactory.createToolLink("nominate", translate("tools.edit.catalog.category.ownergroup"), this, "o_icon_user");
-				nominateLink.setElementCssClass("o_sel_catalog_category_owner");
-				toolbarPanel.addTool(nominateLink, Align.right); 
+				if (nominateLink == null) {
+					nominateLink = LinkFactory.createToolLink("nominate", translate("tools.edit.catalog.category.ownergroup"), this, "o_icon_user");
+					nominateLink.setElementCssClass("o_sel_catalog_category_owner");
+					toolbarPanel.addTool(nominateLink, Align.right); 
+				} else {
+					nominateLink.setVisible(true);
+				}
 			}
 			if (canAddLinks) {
-				contactLink = LinkFactory.createToolLink("contact", translate("tools.new.catalog.categoryrequest"), this, "o_icon_mail");
-				contactLink.setElementCssClass("o_sel_catalog_contact_owner");
-				toolbarPanel.addTool(contactLink, Align.right);
+				if (contactLink == null) {
+					contactLink = LinkFactory.createToolLink("contact", translate("tools.new.catalog.categoryrequest"), this, "o_icon_mail");
+					contactLink.setElementCssClass("o_sel_catalog_contact_owner");
+					toolbarPanel.addTool(contactLink, Align.right);
+				} else {
+					nominateLink.setVisible(true);
+				}
 			}
 			if (canAdministrateCategory && catalogEntry.getParent() != null) {
 				// delete root? very dangerous, disabled!
-				deleteLink = LinkFactory.createToolLink("delete", translate("tools.delete.catalog.entry"), this, "o_icon_delete");
-				deleteLink.setElementCssClass("o_sel_catalog_delete_category");
-				toolbarPanel.addTool(deleteLink, Align.left);
+				if (deleteLink == null) {
+					deleteLink = LinkFactory.createToolLink("delete", translate("tools.delete.catalog.entry"), this, "o_icon_delete");
+					deleteLink.setElementCssClass("o_sel_catalog_delete_category");
+					toolbarPanel.addTool(deleteLink, Align.left);
+				} else {
+					deleteLink.setVisible(true);
+				}
 			}
 			if (canAdministrateCategory && catalogEntry.getParent() != null) {
-				moveLink = LinkFactory.createToolLink("move", translate("tools.move.catalog.entry"), this, "o_icon_move");
-				moveLink.setElementCssClass("o_sel_catalog_move_category");
-				toolbarPanel.addTool(moveLink, Align.left);
+				if (moveLink == null) {
+					moveLink = LinkFactory.createToolLink("move", translate("tools.move.catalog.entry"), this, "o_icon_move");
+					moveLink.setElementCssClass("o_sel_catalog_move_category");
+					toolbarPanel.addTool(moveLink, Align.left);
+				} else {
+					moveLink.setVisible(true);
+				}
 			}
 		}
 
 		if(isAdministrator || isLocalTreeAdmin || isAuthor) {
 			if (canAddSubCategories) {
-				addCategoryLink = LinkFactory.createToolLink("addResource", translate("tools.add.catalog.category"), this, "o_icon_catalog_sub");
-				addCategoryLink.setElementCssClass("o_sel_catalog_add_category");
-				toolbarPanel.addTool(addCategoryLink, Align.left);
+				if (addCategoryLink == null) {
+					addCategoryLink = LinkFactory.createToolLink("addResource", translate("tools.add.catalog.category"), this, "o_icon_catalog_sub");
+					addCategoryLink.setElementCssClass("o_sel_catalog_add_category");
+					toolbarPanel.addTool(addCategoryLink, Align.left);
+				} else {
+					addCategoryLink.setVisible(true);
+				}
+				
 			}
 			if (canAddLinks) {
-				addResourceLink = LinkFactory.createToolLink("addResource", translate("tools.add.catalog.link"), this, "o_icon_add");
-				addResourceLink.setElementCssClass("o_sel_catalog_add_link_to_resource");
-				toolbarPanel.addTool(addResourceLink, Align.left);
+				if (addResourceLink == null) {
+					addResourceLink = LinkFactory.createToolLink("addResource", translate("tools.add.catalog.link"), this, "o_icon_add");
+					addResourceLink.setElementCssClass("o_sel_catalog_add_link_to_resource");
+					toolbarPanel.addTool(addResourceLink, Align.left);
+				} else {
+					addResourceLink.setVisible(true);
+				}
 			}
 		}	
 	}
 	
 	@Override
 	protected void doDispose() {
-		//
+		this.toolbarPanel.removeListener(this);	
+		releaseLock();
 	}
 	
 	@Override
@@ -645,7 +762,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 					doMoveCatalogEntry(row.getCatEntryKey(), cmd, ureq);
 				} else if (cmd.equals(CMD_UP)) {
 					doMoveCatalogEntry(row.getCatEntryKey(), cmd, ureq);
-				}
+				} 
 			}
 		} else if(closedEntriesEl == source) {
 			if(event instanceof SelectionEvent) {
@@ -664,7 +781,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 					doMoveCatalogEntry(row.getCatEntryKey(), cmd, ureq);
 				} else if (cmd.equals(CMD_UP)) {
 					doMoveCatalogEntry(row.getCatEntryKey(), cmd, ureq);
-				}
+				} 
 			}
 		} else if (nodeEntriesEl == source) {		
 			if (event instanceof SelectionEvent) {
@@ -675,8 +792,31 @@ public class CatalogNodeManagerController extends FormBasicController implements
 					doMoveCatalogEntry(row.getKey(), cmd, ureq);
 				} else if (cmd.equals(CMD_UP)) {
 					doMoveCatalogEntry(row.getKey(), cmd, ureq);
-				}
+				} 
 			}
+		} else if(source instanceof FormLink) {
+			FormLink link = (FormLink) source;
+
+			if("positionNodes".equals(link.getCmd())) {
+				int size = nodeEntriesModel.getObjects().size();
+				int smallest = nodeEntriesModel.getObject(0).getPosition();
+				int biggest = nodeEntriesModel.getObject(size - 1).getPosition();
+				
+				doOpenPositionDialog(ureq, link, smallest, biggest);
+			} else if("positionEntries".equals(link.getCmd())) {
+				int size = entriesModel.getObjects().size();
+				int smallest = entriesModel.getObject(0).getPosition();
+				int biggest = entriesModel.getObject(size - 1).getPosition();
+				
+				doOpenPositionDialog(ureq, link, smallest, biggest);
+			} else if("positionClosedEntries".equals(link.getCmd())) {
+				int size = closedEntriesModel.getObjects().size();
+				int smallest = closedEntriesModel.getObject(0).getPosition();
+				int biggest = closedEntriesModel.getObject(size - 1).getPosition();
+				
+				doOpenPositionDialog(ureq, link, smallest, biggest);
+			}
+
 		}
 		
 		super.formInnerEvent(ureq, source, event);
@@ -718,6 +858,13 @@ public class CatalogNodeManagerController extends FormBasicController implements
 					logWarn("Not a valid long: " + node, e);
 				}
 			}
+		} else if (toolbarPanel == source) {
+			if (event instanceof PopEvent) {
+				loadNodesChildren();
+				loadResources(ureq);
+				loadEntryInfos();
+			}
+			
 		}
 		super.event(ureq, source, event);
 	}
@@ -738,6 +885,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 			}
 			cmc.deactivate();
 			cleanUp();
+			toolbarPanel.changeDisplayname(catalogEntry.getShortTitle());
 			fireEvent(ureq, Event.CHANGED_EVENT);
 		} else if(categoryMoveCtrl == source) {
 			cmc.deactivate();
@@ -773,6 +921,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 			}
 		} else if(childNodeCtrl == source) {
 			if(event == Event.BACK_EVENT) {
+				toolbarPanel.popController(childNodeCtrl);
 				toolbarPanel.popUpToController(this);
 				removeAsListenerAndDispose(childNodeCtrl);
 				childNodeCtrl = null;
@@ -801,27 +950,37 @@ public class CatalogNodeManagerController extends FormBasicController implements
 				CatalogEntryRow row = (CatalogEntryRow)dialogDeleteLink.getUserObject();
 				catalogManager.deleteCatalogEntry(row, catalogEntry);
 				loadResources(ureq);
+//				toolbarPanel.popController(this);
+				fireEvent(ureq, Event.BACK_EVENT);
 			}
 		} else if(entryResourceMoveCtrl == source) {
+			CatalogEntry moveMe = entryResourceMoveCtrl.getMoveMe();
 			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
-				CatalogEntry moveMe = entryResourceMoveCtrl.getMoveMe();
 				showInfo("tools.move.catalog.entry.success", moveMe.getName());
 				loadResources(ureq);
+			} else if (event == Event.FAILED_EVENT) {
+				showError("tools.move.catalog.entry.success", moveMe.getName());
 			}
 			cmc.deactivate();
 			cleanUp();
+		} else if (positionCtrl == source) {
+			if (event == Event.DONE_EVENT) {
+				loadNodesChildren();
+				loadResources(ureq);
+			}
+			positionCalloutCtrl.deactivate();
+			cleanUp();
+			fireEvent(ureq, Event.CHANGED_EVENT);
 		} else if(cmc == source) {
+			loadNodesChildren();
+			loadResources(ureq);
 			cleanUp();
 		}
 		super.event(ureq, source, event);
 	}
 	
 	private void cleanUp() {
-		//remove the lock, always
-		if (catModificationLock != null && catModificationLock.isSuccess()) {
-			CoordinatorManager.getInstance().getCoordinator().getLocker().releaseLock(catModificationLock);
-			catModificationLock = null;
-		}
+		releaseLock();
 		
 		removeAsListenerAndDispose(cmc);
 		removeAsListenerAndDispose(groupCtrl);
@@ -829,12 +988,27 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		removeAsListenerAndDispose(addEntryCtrl);
 		removeAsListenerAndDispose(editEntryCtrl);
 		removeAsListenerAndDispose(entrySearchCtrl);
+		removeAsListenerAndDispose(positionCtrl);
+		removeAsListenerAndDispose(positionCalloutCtrl);
+		removeAsListenerAndDispose(positionMoveCtrl);
+		
 		cmc = null;
 		groupCtrl = null;
 		contactCtrl = null;
 		addEntryCtrl = null;
 		editEntryCtrl = null;
 		entrySearchCtrl = null;
+		positionCtrl = null;
+		positionCalloutCtrl = null;
+		positionMoveCtrl = null;
+	}
+	
+	private void releaseLock() {
+		//remove the lock, always
+		if (catModificationLock != null && catModificationLock.isSuccess()) {
+			CoordinatorManager.getInstance().getCoordinator().getLocker().releaseLock(catModificationLock);
+			catModificationLock = null;
+		}
 	}
 
 	private CatalogNodeManagerController selectCatalogEntry(UserRequest ureq, CatalogEntry entry) {
@@ -847,7 +1021,7 @@ public class CatalogNodeManagerController extends FormBasicController implements
 			
 			childNodeCtrl = new CatalogNodeManagerController(ureq, bwControl, rootwControl, entry, toolbarPanel, isLocalTreeAdmin);
 			listenTo(childNodeCtrl);
-			toolbarPanel.pushController(entry.getName(), childNodeCtrl);
+			toolbarPanel.pushController(entry.getShortTitle(), childNodeCtrl);
 			childNodeCtrl.initToolbar();
 			
 			addToHistory(ureq, childNodeCtrl);
@@ -856,57 +1030,27 @@ public class CatalogNodeManagerController extends FormBasicController implements
 	}
 	
 	private void doActivateOrdering(UserRequest ureq) {
-		initForm(ureq);
-		
-		loadEntryInfos();
-		loadNodesChildren();
-		loadResources(ureq);
-		
-		if (isOrdering) {
-			entriesEl.setColumnModelVisible(leafUpColumnModel, false);
-			entriesEl.setColumnModelVisible(leafDownColumnModel, false);
-			entriesEl.setColumnModelVisible(leafPositionColumnModel, false);
-			
-			closedEntriesEl.setColumnModelVisible(leafUpColumnModel, false);
-			closedEntriesEl.setColumnModelVisible(leafDownColumnModel, false);
-			closedEntriesEl.setColumnModelVisible(leafPositionColumnModel, false);
-			
-			entriesEl.reset();
-			closedEntriesEl.reset();
+		catModificationLock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockRes, getIdentity(), LOCK_TOKEN);
+		if (catModificationLock.isSuccess() && !isOrdering) {	
+			boolean activateOrdering = false;
+			activateOrdering |= nodeEntriesModel.getObjects().size() > 1;
+			activateOrdering |= entriesModel.getObjects().size() > 1;
+			activateOrdering |= closedEntriesModel.getObjects().size() > 1;
 			
-			for (DefaultFlexiColumnModel columnModel : leafColumns) {
-				columnModel.setSortable(true);
+			if (activateOrdering) {
+				positionMoveCtrl = new CatalogNodeManagerController(ureq, getWindowControl(), rootwControl, catalogEntry, toolbarPanel, isLocalTreeAdmin, true);
+				listenTo(positionMoveCtrl);
+				
+				cmc = new CloseableModalController(getWindowControl(), "close", positionMoveCtrl.getInitialComponent(), true, translate("tools.order.catalog"));
+				listenTo(cmc);
+				cmc.activate();	
+			} else {
+				showWarning("catalog.position.deactivated");
 			}
-			
-//			for (int i =entriesModel.getColumnCount(); i) {
-//				entriesModel.getTableColumnModel().getColumnModel(i).setSortable(false);
-//			}
-			
-			nodeEntriesEl.setColumnModelVisible(nodeUpColumnModel, false);
-			nodeEntriesEl.setColumnModelVisible(nodeDownColumnModel, false);
-			nodeEntriesEl.reset();
 		} else {
-			entriesEl.setColumnModelVisible(leafUpColumnModel, true);
-			entriesEl.setColumnModelVisible(leafDownColumnModel, true); 
-			entriesEl.setColumnModelVisible(leafPositionColumnModel, true);
-			
-			closedEntriesEl.setColumnModelVisible(leafUpColumnModel, true);
-			closedEntriesEl.setColumnModelVisible(leafDownColumnModel, true);
-			closedEntriesEl.setColumnModelVisible(leafPositionColumnModel, true);
-			
-			entriesEl.reset();
-			closedEntriesEl.reset();
-			
-			for (DefaultFlexiColumnModel columnModel : leafColumns) {
-				columnModel.setSortable(false);
-			}
-			
-			nodeEntriesEl.setColumnModelVisible(nodeUpColumnModel, true);
-			nodeEntriesEl.setColumnModelVisible(nodeDownColumnModel, true);
-			nodeEntriesEl.reset();
+			String ownerName = userManager.getUserDisplayName(catModificationLock.getOwner());
+			showError("catalog.locked.by", ownerName);
 		}
-		isOrdering = !isOrdering;
-		flc.contextPut("isOrdering", isOrdering);
 	}
 	
 	private void doMoveCatalogEntry(Long key, String command, UserRequest ureq) {
@@ -918,25 +1062,63 @@ public class CatalogNodeManagerController extends FormBasicController implements
 		loadResources(ureq);
 	}
 	
+	private void doOpenPositionDialog(UserRequest ureq, FormLink link, int smallest, int biggest) {
+		removeAsListenerAndDispose(positionCalloutCtrl);
+		removeAsListenerAndDispose(positionCtrl);
+		
+		catModificationLock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockRes, getIdentity(), LOCK_TOKEN);
+		if (catModificationLock.isSuccess()) {
+			Object rowObject = link.getUserObject();
+			
+			
+			if (rowObject instanceof NodeEntryRow) {
+				NodeEntryRow row = (NodeEntryRow) rowObject;
+				positionCtrl = new CatalogEntryPositionDialogController(ureq, getWindowControl(), row.getKey(), smallest, biggest);
+			} else if (rowObject instanceof CatalogEntryRow) {
+				CatalogEntryRow row = (CatalogEntryRow) rowObject;
+				positionCtrl = new CatalogEntryPositionDialogController(ureq, getWindowControl(), row.getCatEntryKey(), smallest, biggest);
+			} else {
+				return;
+			}
+			
+			listenTo(positionCtrl);
+			
+			CalloutSettings settings = new CalloutSettings(true);
+			positionCalloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(),positionCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, "", settings);
+			listenTo(positionCalloutCtrl);
+			positionCalloutCtrl.activate();
+			
+		} else {
+			String ownerName = userManager.getUserDisplayName(catModificationLock.getOwner());
+			showError("catalog.locked.by", ownerName);
+		}
+	}
+	
 	private void doAddResource(UserRequest ureq) {
 		removeAsListenerAndDispose(entrySearchCtrl);
 		removeAsListenerAndDispose(cmc);
-		
-		entrySearchCtrl = new RepositorySearchController(translate("choose"), ureq, getWindowControl(), true, false, new String[0], false, null);
-		listenTo(entrySearchCtrl);
-		// OLAT-Admin has search form
-		if (isAdministrator) {
-			entrySearchCtrl.displaySearchForm();
-		}
-		// an Author gets the list of his repository
-		else {
-			// admin is responsible for not inserting wrong visibility entries!!
-			entrySearchCtrl.doSearchByOwnerLimitAccess(ureq.getIdentity());
+
+		catModificationLock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockRes, getIdentity(), LOCK_TOKEN);
+		if (catModificationLock.isSuccess()) {
+			entrySearchCtrl = new RepositorySearchController(translate("choose"), ureq, getWindowControl(), true, false, new String[0], false, null);
+			listenTo(entrySearchCtrl);
+			// OLAT-Admin has search form
+			if (isAdministrator) {
+				entrySearchCtrl.displaySearchForm();
+			}
+			// an Author gets the list of his repository
+			else {
+				// admin is responsible for not inserting wrong visibility entries!!
+				entrySearchCtrl.doSearchByOwnerLimitAccess(ureq.getIdentity());
+			}
+			// open form in dialog
+			cmc = new CloseableModalController(getWindowControl(), "close", entrySearchCtrl.getInitialComponent(), true, translate("tools.add.catalog.link"));
+			listenTo(cmc);
+			cmc.activate();	
+		} else {
+			String ownerName = userManager.getUserDisplayName(catModificationLock.getOwner());
+			showError("catalog.locked.by", ownerName);
 		}
-		// open form in dialog
-		cmc = new CloseableModalController(getWindowControl(), "close", entrySearchCtrl.getInitialComponent(), true, translate("tools.add.catalog.link"));
-		listenTo(cmc);
-		cmc.activate();	
 	}
 	
 	private void doAddResource(UserRequest ureq, RepositoryEntry selectedEntry) {
diff --git a/src/main/java/org/olat/repository/ui/catalog/CatalogSiteMainController.java b/src/main/java/org/olat/repository/ui/catalog/CatalogSiteMainController.java
index abfc1cd5d108feed9e926527ef64fc900a695574..c488df4c0d1be502c6707af763b8438b35b21dfe 100644
--- a/src/main/java/org/olat/repository/ui/catalog/CatalogSiteMainController.java
+++ b/src/main/java/org/olat/repository/ui/catalog/CatalogSiteMainController.java
@@ -22,7 +22,6 @@ package org.olat.repository.ui.catalog;
 import java.util.List;
 
 import org.olat.core.CoreSpringFactory;
-import org.olat.core.commons.chiefcontrollers.BaseChiefController;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.stack.BreadcrumbedStackedPanel;
@@ -30,13 +29,10 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
-import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
-import org.olat.core.util.Util;
 import org.olat.repository.CatalogEntry;
 import org.olat.repository.manager.CatalogManager;
-import org.olat.repository.ui.catalog.CatalogNodeController;
 
 /**
  * 
@@ -53,16 +49,19 @@ public class CatalogSiteMainController extends BasicController implements Activa
 		super(ureq, wControl);
 
 		stackPanel = new BreadcrumbedStackedPanel("catstack", getTranslator(), this);
+		stackPanel.setInvisibleCrumb(0); // show root level
+
 		putInitialPanel(stackPanel);
 
 		CatalogManager catalogManager = CoreSpringFactory.getImpl(CatalogManager.class);
 		List<CatalogEntry> rootNodes = catalogManager.getRootCatalogEntries();
+		CatalogEntry root = rootNodes.get(0);
+		// use same title as catalog site title
+		
 		if(rootNodes.size() == 1) {
-			nodeController = new CatalogNodeController(ureq, getWindowControl(), getWindowControl(), rootNodes.get(0), stackPanel, true);
+			nodeController = new CatalogNodeController(ureq, getWindowControl(), getWindowControl(), root, stackPanel, true);
 		}
-		// use same title as catalog site title
-		Translator catTrans = Util.createPackageTranslator(BaseChiefController.class, getLocale());
-		stackPanel.pushController(catTrans.translate("topnav.catalog"), nodeController);
+		stackPanel.pushController(root.getShortTitle(), nodeController);
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/repository/ui/catalog/NodeEntryRow.java b/src/main/java/org/olat/repository/ui/catalog/NodeEntryRow.java
index e785878faf188b2806d2c035cc865c4ea89f264b..29cbb493df5de03a9c3d733d02a40e7207f2f7c1 100644
--- a/src/main/java/org/olat/repository/ui/catalog/NodeEntryRow.java
+++ b/src/main/java/org/olat/repository/ui/catalog/NodeEntryRow.java
@@ -21,6 +21,7 @@ package org.olat.repository.ui.catalog;
 
 import java.util.Date;
 
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.repository.CatalogEntry;
 
 /**
@@ -35,6 +36,7 @@ public class NodeEntryRow {
 	private String name;
 	private Date creationDate;
 	private int position;
+	private FormLink positionLink;
 	
 	public NodeEntryRow(CatalogEntry view) {
 		key = view.getKey();
@@ -62,4 +64,12 @@ public class NodeEntryRow {
 	public int getPosition() {
 		return position;
 	}
+	
+	public FormLink getPositionLink() {
+		return positionLink;
+	}
+	
+	public void setPositionLink(FormLink positionLink) {
+		this.positionLink = positionLink;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/catalog/NodeEntryRowModel.java b/src/main/java/org/olat/repository/ui/catalog/NodeEntryRowModel.java
index 1f30361da3849d4a0658d5d6806ed739c6479490..129fe0e43b875b1360d41023ad13c06a6071ff2b 100644
--- a/src/main/java/org/olat/repository/ui/catalog/NodeEntryRowModel.java
+++ b/src/main/java/org/olat/repository/ui/catalog/NodeEntryRowModel.java
@@ -58,9 +58,9 @@ public class NodeEntryRowModel extends DefaultFlexiTableDataModel<NodeEntryRow>
 			case type: return item;
 			case displayName: return item.getDisplayname();
 			case creationDate: return item.getCreationDate();
-			case position: return item.getPosition();
+			case position: return item.getPositionLink();
+			default: return "ERROR";
 		}
-		return null;
 	}
 	
 	public enum NodeCols {
diff --git a/src/main/java/org/olat/repository/ui/catalog/_content/catPosition.html b/src/main/java/org/olat/repository/ui/catalog/_content/catPosition.html
new file mode 100644
index 0000000000000000000000000000000000000000..04c9e5729b3d8714a252ca3e6539bccb34e2c042
--- /dev/null
+++ b/src/main/java/org/olat/repository/ui/catalog/_content/catPosition.html
@@ -0,0 +1,32 @@
+	<div class="row">
+		<div class="col-sm-12 form-group">
+			<center>
+				<h4>$r.get("catalog_entry_name")</h4>
+			</center>
+		</div>
+	</div>
+	<div class="row">
+		<center>
+			<div class="col-sm-12 form-group">
+				<div class="o_block_inline">$r.render("catalog.popup.position.smallest")</div>
+				<div class="o_block_inline">$r.render("catalog.popup.position.smaller")</div>
+				
+				<div class="o_block_inline #if($f.hasError('catalog.popup.position.set')) has-error	#end">
+					$r.render("catalog.popup.position.set")
+				</div>
+				<div class="o_block_inline">$r.render("catalog.popup.position.bigger")</div>
+				<div class="o_block_inline">$r.render("catalog.popup.position.biggest")</div>
+				#if($f.hasError("catalog.popup.position.set"))
+					<div class="">
+						$r.render("catalog.popup.position.set_ERROR")
+					</div>
+				#end
+			</div>
+		</center>
+	</div>
+	
+	<div class="row">
+		<div class="col-sm-offset-3 col-sm-6 form-group">
+			<center>$r.render("save")</center>
+		</div>
+	</div>
diff --git a/src/main/java/org/olat/repository/ui/catalog/_content/node.html b/src/main/java/org/olat/repository/ui/catalog/_content/node.html
index 232d65918ad5ef51b67093377bad931a9ea6af44..486c8ee254a85875fd3f6a1e85991138fd883b88 100644
--- a/src/main/java/org/olat/repository/ui/catalog/_content/node.html
+++ b/src/main/java/org/olat/repository/ui/catalog/_content/node.html
@@ -3,18 +3,19 @@
 		#if ($isGuest)
 		<div class="o_warning">${r.translate("filtered.first")}${r.render("cat.login")}${r.translate("filtered.second")}</div>
 		#end
-
+		
+		#if (!$isOrdering)
 		<div class="o_level o_level_${catalogLevel} row">
 			<div class="o_visual">
 				#if($catThumbnail)
-					<img src="$mapperThumbnailUrl/${catThumbnail}" alt="$r.escapeHtml($catalogEntryName)"/>
+					<img src="$mapperThumbnailUrl/${catThumbnail}" alt="$r.escapeHtml($catalogEntryTitle)"/>
 				#else
 					<div class="o_visual_not_available"></div>			
 				#end
 			</div>
 			<div class="o_meta clearfix">
-				<h2 class="o_title">
-					$r.escapeHtml($catalogEntryName)
+				<h2 class="o_title" title="$catalogEntryShortTitle">
+					$r.escapeHtml($catalogEntryTitle)
 				</h2>
 				#if($catalogEntryDesc)	
 				<div class="o_desc o_user_content_block">
@@ -23,7 +24,6 @@
 				#end
 			</div>
 		</div>
-	#if(!$isOrdering)
 		#if($subCategories.size() != 0)	
 			#if($listStyle == "list")
 				<div class="o_sublevels_list row clearfix">
@@ -57,12 +57,13 @@
 					#foreach($id in $subCategories)
 						#set($imgId = "image_${id}")
 						#set($catId = "kcat_${id}")
-						<div class="o_sublevel">
+						#set($shortTitleId = "short_title_${id}")
+						<div class="o_sublevel"  title="$catalogEntryTitle">
 							<div class="o_visual"><a $r.hrefAndOnclick("img_select",false,false,"node","$r.get($catId)")>
 								<span class="o_visual_not_available" #if($r.get($imgId)) style="background-image:url('$mapperThumbnailUrl/${r.get($imgId)}');" #end></span>
 							</a></div>
 							<div class="o_meta">
-								<h4 class="o_title">$r.render("cat_${id}")</h4>
+								<h4 class="o_title">$r.get("short_title_${id}")</h4>
 							</div>
 						</div>
 					#end
@@ -82,35 +83,38 @@
 	#end
 	
 	#if($r.available("closedEntries") && $r.visible("closedEntries"))
+		<br>
 		<h3><i class="o_icon o_CourseModule_icon_closed"> </i> $r.translate("closed.resources.title")</h3>
 		$r.render("closedEntries")
 	#end
 	
-	#if($extLink || $guestExtLink)
-	<div class="o_extlink clearfix o_block_large_bottom">
-		<h4>$r.translate("cat.externalLink")</h4>
-		#if($extLink)
-			<div class="o_copy_code o_nowrap"><a href="javascript:;" id="o_extlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode">&nbsp;</i></a><input type="text" value="$extLink" onclick="this.select()"/>
-				<script>
-				/* <![CDATA[ */
-					jQuery(function() {
-						o_QRCodePopup('o_extlink', '$extLink', 'right');
-					});
-				/* ]]> */
-				</script>
-			</div>
-		#end
-		#if($guestExtLink)
-			<div class="o_copy_code o_nowrap"><a href="javascript:;" id="o_guestextlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode">&nbsp;</i></a><input type="text" value="$guestExtLink" onclick="this.select()"/>
-				<script>
-				/* <![CDATA[ */
-					jQuery(function() {
-						o_QRCodePopup('o_guestextlink', '$guestExtLink', 'right');
-					});
-				/* ]]> */
-				</script>
-			</div>
+	#if(!$isOrdering)
+		#if($extLink || $guestExtLink)
+		<div class="o_extlink clearfix o_block_large_bottom">
+			<h4>$r.translate("cat.externalLink")</h4>
+			#if($extLink)
+				<div class="o_copy_code o_nowrap"><a href="javascript:;" id="o_extlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode">&nbsp;</i></a><input type="text" value="$extLink" onclick="this.select()"/>
+					<script>
+					/* <![CDATA[ */
+						jQuery(function() {
+							o_QRCodePopup('o_extlink', '$extLink', 'right');
+						});
+					/* ]]> */
+					</script>
+				</div>
+			#end
+			#if($guestExtLink)
+				<div class="o_copy_code o_nowrap"><a href="javascript:;" id="o_guestextlink"><i class="o_icon o_icon-lg o_icon-fw o_icon_qrcode">&nbsp;</i></a><input type="text" value="$guestExtLink" onclick="this.select()"/>
+					<script>
+					/* <![CDATA[ */
+						jQuery(function() {
+							o_QRCodePopup('o_guestextlink', '$guestExtLink', 'right');
+						});
+					/* ]]> */
+					</script>
+				</div>
+			#end
+		</div>
 		#end
-	</div>
 	#end
 </div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_de.properties
index 2c01bc12f67d898ae5a2e06a1a5f8f90ecf43507..6ce5125fdc385d2bef8afa9d123fd2805073e647 100644
--- a/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_de.properties
@@ -7,6 +7,15 @@ cat.login=Login
 cat.move.submit=Element verschieben.
 cat.move.title=Eintrag an Kategorie anh\u00E4ngen\!
 catalog.locked.by=Die Aktion kann nicht ausgef\u00fchrt werden, da der Katalog zur Zeit vom Benutzer {0} bearbeitet wird.
+catalog.popup.edit.shorttitle.desc=Setzen Sie einen Kurztitel zur Anzeige bei den Tiles.
+catalog.popup.position.error.number.format=Nur Zahlen eingeben
+catalog.popup.position.error.number=Werte von {0} bis {1} sind zul\u00e4ssig
+catalog.popup.position.bigger=\u003E
+catalog.popup.position.biggest=\u226B
+catalog.popup.position.save=Speichern
+catalog.popup.position.smaller=\u003C
+catalog.popup.position.smallest=\u226A
+catalog.position.deactivated=Bitte f\u00FCgen Sie weiter Elemente hinzu um die Sortierung zu verändern!
 catalog.tree.add.already.exists=Die Lernressource {0} ist bereits in dieser Katalogkategorie vorhanden.
 catalog.tree.add.intro=W\u00E4hlen Sie eine Kategorie aus, in die Sie die Lernressource {0} verschieben m\u00F6chten.
 catalog.tree.add.title=Lernressource "{0}" in Katalog hinzuf\u00FCgen
@@ -27,7 +36,7 @@ contact.caretaker=Anfrage schicken
 contact.to.groupname.caretaker=Verwaltergruppe der Kategorie
 dialog.modal.leaf.delete.text=Wollen Sie den Link "{0}" wirklich l\u00F6schen?
 dialog.modal.subtree.delete.text=Wollen Sie die Kategorie "{0}" und alle damit verbundenen Unterkategorien respektive Links, wirklich l\u00F6schen?
-entry.category=Name
+entry.category=Titel
 entry.description=Beschreibung
 entry.leaf=Lernressource
 entry.shorttitle=Kurztitel
@@ -55,4 +64,5 @@ tools.move.catalog.entry.success=Der Katalogeintrag "{0}" wurde erfolgreich vers
 tools.new.catalog.categoryrequest=Verwalter kontaktieren
 tools.order.catalog=Manuell ordnen
 tools.pastestructure=Struktur einf\u00FCgen
+tools.set.catalog.position=Position anpassen
 entry.pic=Bild
diff --git a/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_en.properties
index 6bbc8a90b90aeb6ce2603a3eedb54e5afd568878..5240d1290a633068556b96e0d8faeb6af826a496 100644
--- a/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/repository/ui/catalog/_i18n/LocalStrings_en.properties
@@ -10,6 +10,15 @@ catalog.classic=Catalog in learning resources
 catalog.courses=My courses
 catalog.locked.by=Cannot start action at this time because this catalog is currently being edited by user {0}
 catalog.new=Catalog in own site
+catalog.popup.edit.shorttitle.desc=Add a short title for tiles view.
+catalog.popup.position.error.number.format=Only numeric inputs
+catalog.popup.position.error.number=Only values from {0} to {1}
+catalog.popup.position.bigger=\u003E
+catalog.popup.position.biggest=\u226B
+catalog.popup.position.save=Save
+catalog.popup.position.smaller=\u003C
+catalog.popup.position.smallest=\u226A
+catalog.position.deactivated=Please add more elements to customize the order! 
 catalog.tree.add.already.exists=The learning resource {0} is already attached to this catalog category
 catalog.tree.add.intro=Select a catalog category to which you want to move the learning resource {0}
 catalog.tree.add.title=Add learning resource "{0}" to catalog
@@ -23,7 +32,7 @@ contact.caretaker=Send request
 contact.to.groupname.caretaker=Administrator group of category
 dialog.modal.leaf.delete.text=Do you really want to delete the link "{0}"?
 dialog.modal.subtree.delete.text=Do you really want to delete category "{0}" as well as all associated sub-categories or links?
-entry.category=Name
+entry.category=Title
 entry.description=Description
 entry.leaf=Learning resource
 entry.pic=Image
@@ -56,3 +65,4 @@ tools.move.catalog.entry.success=Catalog entry "{0}" successfully moved
 tools.order.catalog=Manual ordering
 tools.new.catalog.categoryrequest=Contact administrator
 tools.pastestructure=Insert structure
+tools.set.catalog.position=Modifiy position
diff --git a/src/main/java/org/olat/repository/ui/list/OverviewRepositoryListController.java b/src/main/java/org/olat/repository/ui/list/OverviewRepositoryListController.java
index d607b447dcff1f6689ab2349ae75156c0401388e..5386cd22990abcfbe9f3b75a7f0d4d0d5ad0b9c2 100644
--- a/src/main/java/org/olat/repository/ui/list/OverviewRepositoryListController.java
+++ b/src/main/java/org/olat/repository/ui/list/OverviewRepositoryListController.java
@@ -297,7 +297,7 @@ public class OverviewRepositoryListController extends BasicController implements
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		markedStackPanel = new BreadcrumbedStackedPanel("mrkstack", getTranslator(), this);
-		markedCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "marked", markedStackPanel);
+		markedCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, true, "marked", markedStackPanel);
 		markedStackPanel.pushController(translate("search.mark"), markedCtrl);
 		listenTo(markedCtrl);
 		currentCtrl = markedCtrl;
@@ -320,7 +320,7 @@ public class OverviewRepositoryListController extends BasicController implements
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		myCoursesStackPanel = new BreadcrumbedStackedPanel("mystack", getTranslator(), this);
-		myCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "my", myCoursesStackPanel);
+		myCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, true, "my", myCoursesStackPanel);
 		myCoursesStackPanel.pushController(translate("search.mycourses.student"), myCoursesCtrl);
 		listenTo(myCoursesCtrl);
 		currentCtrl = myCoursesCtrl;
@@ -391,7 +391,7 @@ public class OverviewRepositoryListController extends BasicController implements
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		searchCoursesStackPanel = new BreadcrumbedStackedPanel("search", getTranslator(), this);
-		searchCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, false, true, "my-search", searchCoursesStackPanel);
+		searchCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, false, true, true, "my-search", searchCoursesStackPanel);
 		searchCoursesStackPanel.pushController(translate("search.mycourses.student"), searchCoursesCtrl);
 		listenTo(searchCoursesCtrl);
 		currentCtrl = searchCoursesCtrl;
@@ -413,7 +413,7 @@ public class OverviewRepositoryListController extends BasicController implements
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		myCoursesStackPanel = new BreadcrumbedStackedPanel("mystack", getTranslator(), this);
-		closedCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, "closed", myCoursesStackPanel);
+		closedCoursesCtrl = new RepositoryEntryListController(ureq, bwControl, searchParams, true, false, true, "closed", myCoursesStackPanel);
 		myCoursesStackPanel.pushController(translate("search.mycourses.student"), closedCoursesCtrl);
 		listenTo(closedCoursesCtrl);
 		currentCtrl = closedCoursesCtrl;
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
index 2199f297bc976e2d9506e07baa91731fdaa711dd..7d9e6aeba9d7afbc13397866fbdc33bf61b5ae0e 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
@@ -106,6 +106,7 @@ public class RepositoryEntryListController extends FormBasicController
 	private final List<Link> orderByLinks = new ArrayList<>();
 	
 	private boolean withSearch;
+	private boolean withSavedSettings;
 
 	private final String name;
 	private FlexiTableElement tableEl;
@@ -135,13 +136,14 @@ public class RepositoryEntryListController extends FormBasicController
 	
 	public RepositoryEntryListController(UserRequest ureq, WindowControl wControl,
 			SearchMyRepositoryEntryViewParams searchParams, boolean load, 
-			boolean withSearch, String name, BreadcrumbPanel stackPanel) {
+			boolean withSearch, boolean withSavedSettings, String name, BreadcrumbPanel stackPanel) {
 		super(ureq, wControl, "repoentry_table");
 		setTranslator(Util.createPackageTranslator(RepositoryManager.class, getLocale(), getTranslator()));
 		mapperThumbnailKey = mapperService.register(null, "repositoryentryImage", new RepositoryEntryImageMapper());
 		this.name = name;
 		this.stackPanel = stackPanel;
 		this.withSearch = withSearch;
+		this.withSavedSettings = withSavedSettings;
 		guestOnly = ureq.getUserSession().getRoles().isGuestOnly();
 
 		OLATResourceable ores = OresHelper.createOLATResourceableType("MyCoursesSite");
@@ -235,9 +237,15 @@ public class RepositoryEntryListController extends FormBasicController
 		initSorters(tableEl);
 		
 		tableEl.setAndLoadPersistedPreferences(ureq, "re-list-v2-".concat(name));
+		
+		if (!withSavedSettings) {
+			SortKey sortKey = new SortKey(OrderBy.custom.name(), true);
+			tableEl.sort(sortKey);
+		}
+		
 		loadFilterPreferences(ureq);
 	}
-	
+
 	private void initFilters(FlexiTableElement tableElement) {
 		List<FlexiTableFilter> filters = new ArrayList<>(16);
 		filters.add(new FlexiTableFilter(translate("filter.show.all"), Filter.showAll.name(), true));
diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_4.java b/src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_5.java
similarity index 95%
rename from src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_4.java
rename to src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_5.java
index c00d1667f3605277f8a41807c44c676dd82f90bf..d1f3fdfb2963d1c73641bf2b796bc6e4d6257fa1 100644
--- a/src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_4.java
+++ b/src/main/java/org/olat/upgrade/OLATUpgrade_15_pre_5.java
@@ -41,11 +41,11 @@ import org.springframework.beans.factory.annotation.Autowired;
  * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com
  *
  */
-public class OLATUpgrade_15_pre_4 extends OLATUpgrade {
+public class OLATUpgrade_15_pre_5 extends OLATUpgrade {
 
-	private static final Logger log = Tracing.createLoggerFor(OLATUpgrade_15_pre_4.class);
+	private static final Logger log = Tracing.createLoggerFor(OLATUpgrade_15_pre_5.class);
 
-	private static final String VERSION = "OLAT_15.pre.4";
+	private static final String VERSION = "OLAT_15.pre.5";
 	private static final String CATALOG_ORDER_INDEX = "CATALOG ORDER INDEX";
 
 	private AtomicInteger migrationCounter = new AtomicInteger(0);
@@ -53,7 +53,7 @@ public class OLATUpgrade_15_pre_4 extends OLATUpgrade {
 	@Autowired
 	private DB dbInstance;
 
-	public OLATUpgrade_15_pre_4() {
+	public OLATUpgrade_15_pre_5() {
 		super();
 	}
 
@@ -78,9 +78,9 @@ public class OLATUpgrade_15_pre_4 extends OLATUpgrade {
 		uhd.setInstallationComplete(allOk);
 		upgradeManager.setUpgradesHistory(uhd, VERSION);
 		if(allOk) {
-			log.info(Tracing.M_AUDIT, "Finished OLATUpgrade_15_pre_4 successfully!");
+			log.info(Tracing.M_AUDIT, "Finished OLATUpgrade_15_pre_5 successfully!");
 		} else {
-			log.info(Tracing.M_AUDIT, "OLATUpgrade_15_pre_4 not finished, try to restart OpenOlat!");
+			log.info(Tracing.M_AUDIT, "OLATUpgrade_15_pre_5 not finished, try to restart OpenOlat!");
 		}
 		return allOk;
 	}
diff --git a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml
index 53762a4d93acb03e261d4c8d774bfb771dd5ccf2..882f8e8cad8999420b72b4f852151224b8ae13c2 100644
--- a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml
+++ b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml
@@ -224,6 +224,10 @@
 					<constructor-arg index="0" value="OLAT_15.pre.4" />
 					<property name="alterDbStatements" value="alter_15_pre_0_to_15_pre_4.sql" />
 				</bean>
+				<bean id="database_upgrade_15_pre_5" class="org.olat.upgrade.DatabaseUpgrade">
+					<constructor-arg index="0" value="OLAT_15.pre.5" />
+					<property name="alterDbStatements" value="alter_15_pre_0_to_15_pre_5.sql" />
+				</bean>
 			</list>
 		</property>
 	</bean>
diff --git a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
index e3ba4be72ea0c375ad9b55c62d66f8163aa6ff06..d84720f54986300e1e8efa09ee2ec5075d2d67ea 100644
--- a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
+++ b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
@@ -54,7 +54,7 @@
 				<bean id="upgrade_14_0_5" class="org.olat.upgrade.OLATUpgrade_14_0_5"/>
 				<bean id="upgrade_14_1_0" class="org.olat.upgrade.OLATUpgrade_14_1_0"/>
 				<bean id="upgrade_14_2_0" class="org.olat.upgrade.OLATUpgrade_14_2_0"/>
-				<bean id="upgrade_15_pre_4" class="org.olat.upgrade.OLATUpgrade_15_pre_4"/><!-- because really quicker as pre.0 -->
+				<bean id="upgrade_15_pre_5" class="org.olat.upgrade.OLATUpgrade_15_pre_5"/><!-- because really quicker as pre.0 -->
 				<bean id="upgrade_15_pre_0" class="org.olat.upgrade.OLATUpgrade_15_pre_0"/>
 			</list>
 		</property>
diff --git a/src/main/resources/database/mysql/alter_15_pre_0_to_15_pre_5.sql b/src/main/resources/database/mysql/alter_15_pre_0_to_15_pre_5.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3a7de8e9146c691ee489f5578a5d0109f99e8c85
--- /dev/null
+++ b/src/main/resources/database/mysql/alter_15_pre_0_to_15_pre_5.sql
@@ -0,0 +1,2 @@
+-- CATALOG
+UPDATE o_catentry SET short_title = name;
\ No newline at end of file
diff --git a/src/main/resources/database/oracle/alter_15_pre_0_to_15_pre_5.sql b/src/main/resources/database/oracle/alter_15_pre_0_to_15_pre_5.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3a7de8e9146c691ee489f5578a5d0109f99e8c85
--- /dev/null
+++ b/src/main/resources/database/oracle/alter_15_pre_0_to_15_pre_5.sql
@@ -0,0 +1,2 @@
+-- CATALOG
+UPDATE o_catentry SET short_title = name;
\ No newline at end of file
diff --git a/src/main/resources/database/postgresql/alter_15_pre_0_to_15_pre_5.sql b/src/main/resources/database/postgresql/alter_15_pre_0_to_15_pre_5.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3a7de8e9146c691ee489f5578a5d0109f99e8c85
--- /dev/null
+++ b/src/main/resources/database/postgresql/alter_15_pre_0_to_15_pre_5.sql
@@ -0,0 +1,2 @@
+-- CATALOG
+UPDATE o_catentry SET short_title = name;
\ No newline at end of file
diff --git a/src/test/java/org/olat/repository/RepositoryManagerTest.java b/src/test/java/org/olat/repository/RepositoryManagerTest.java
index 57af128295da9e17f0a45e1677a2dc8d6586af78..297da1001c67b838f9a784996ef7bb0279d85fb9 100644
--- a/src/test/java/org/olat/repository/RepositoryManagerTest.java
+++ b/src/test/java/org/olat/repository/RepositoryManagerTest.java
@@ -56,6 +56,15 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.manager.BusinessGroupRelationDAO;
+import org.olat.repository.LeavingStatusList;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryAllowToLeaveOptions;
+import org.olat.repository.RepositoryEntryManagedFlag;
+import org.olat.repository.RepositoryEntryOrder;
+import org.olat.repository.RepositoryEntrySecurity;
+import org.olat.repository.RepositoryEntryStatusEnum;
+import org.olat.repository.RepositoryManager;
+import org.olat.repository.RepositoryService;
 import org.olat.repository.manager.RepositoryEntryLifecycleDAO;
 import org.olat.repository.manager.RepositoryEntryRelationDAO;
 import org.olat.repository.model.RepositoryEntryLifecycle;
diff --git a/src/test/java/org/olat/repository/manager/RepositoryServiceImplTest.java b/src/test/java/org/olat/repository/manager/RepositoryServiceImplTest.java
index 2120a6fbbe63a7bb1b7dd4a0bc2735ae49d8ccee..221b6beed141e9684a3af0538fcce3f686d133fd 100644
--- a/src/test/java/org/olat/repository/manager/RepositoryServiceImplTest.java
+++ b/src/test/java/org/olat/repository/manager/RepositoryServiceImplTest.java
@@ -137,7 +137,7 @@ public class RepositoryServiceImplTest extends OlatTestCase {
 	    catEntry.setName("Soft");
 	    catEntry.setRepositoryEntry(re);
 	    catEntry.setParent(rootEntries.get(0));
-	    catalogManager.saveCatalogEntry(catEntry);
+	    catalogManager.addCatalogEntry(rootEntries.get(0), catEntry);
 	    dbInstance.commit();
 	    
 	    //check the catalog
diff --git a/src/test/java/org/olat/repository/ui/catalog/CatalogManagerTest.java b/src/test/java/org/olat/repository/ui/catalog/CatalogManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1cb2d93cb065a1e9370cb0d94fd4ae71b041af9
--- /dev/null
+++ b/src/test/java/org/olat/repository/ui/catalog/CatalogManagerTest.java
@@ -0,0 +1,665 @@
+/**
+ * <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.repository.ui.catalog;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.basesecurity.BaseSecurity;
+import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.manager.SecurityGroupDAO;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.id.Organisation;
+import org.olat.course.CourseModule;
+import org.olat.repository.CatalogEntry;
+import org.olat.repository.CatalogEntry.Style;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryStatusEnum;
+import org.olat.repository.RepositoryManager;
+import org.olat.repository.RepositoryService;
+import org.olat.repository.manager.CatalogManager;
+import org.olat.resource.OLATResource;
+import org.olat.resource.OLATResourceManager;
+import org.olat.test.JunitTestHelper;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ *
+ * Initial date: 12.03.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CatalogManagerTest extends OlatTestCase {
+
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private CatalogManager catalogManager;
+	@Autowired
+	private RepositoryManager repositoryManager;
+	@Autowired
+	private OLATResourceManager orm;
+	@Autowired
+	private RepositoryService repositoryService;
+	@Autowired
+	private OrganisationService organisationService;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private SecurityGroupDAO securityGroupDao;
+	
+	Random random = new Random();
+	
+	private void afterPropoertiesSet() {
+		try {
+			catalogManager.afterPropertiesSet();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private CatalogEntry generateEntry(int type, String name, Style style) {
+		CatalogEntry catalogEntry = catalogManager.createCatalogEntry();
+		
+		catalogEntry.setName(name);
+		catalogEntry.setType(type);
+		catalogEntry.setStyle(style);
+		
+		return catalogEntry;
+	}
+	
+	private CatalogEntry saveEntry(CatalogEntry catalogEntry, CatalogEntry parentEntry) {
+		parentEntry = catalogManager.loadCatalogEntry(parentEntry);
+		
+		catalogEntry.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(catalogEntry);
+		
+		List<CatalogEntry> children = parentEntry.getChildren();
+		children.add(catalogEntry);
+		catalogManager.updateCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		return catalogEntry;
+	}
+
+	private CatalogEntry getRootEntry() {
+		return catalogManager.getRootCatalogEntries().get(0);
+	}
+	
+	private RepositoryEntry createRepository(String displayName, final Long resourceableId) {
+		OLATResourceable resourceable = new OLATResourceable() {
+			@Override
+			public String getResourceableTypeName() {	return CourseModule.ORES_TYPE_COURSE;}
+			@Override
+			public Long getResourceableId() {return resourceableId;}
+		};
+
+		// create course and persist as OLATResourceImpl
+
+		OLATResource r = orm.findResourceable(resourceable);
+		if(r == null) {
+			r = orm.createOLATResourceInstance(resourceable);
+		}
+		dbInstance.saveObject(r);
+		dbInstance.intermediateCommit();
+		
+		RepositoryEntry d = repositoryManager.lookupRepositoryEntry(resourceable, false);
+		if(d == null) {
+			Organisation defOrganisation = organisationService.getDefaultOrganisation();
+			d = repositoryService.create(null, "Rei Ayanami", "-", displayName, "Repo entry",
+					r, RepositoryEntryStatusEnum.trash, defOrganisation);
+			dbInstance.saveObject(d);
+		}
+		dbInstance.intermediateCommit();
+		return d;
+	}
+	
+	@Test
+	public void createCatalogEntry() {
+		afterPropoertiesSet();
+		CatalogEntry catalogEntry = catalogManager.createCatalogEntry();
+		
+		Assert.assertNotNull(catalogEntry);
+		Assert.assertNotNull(catalogEntry.getOwnerGroup());
+	}
+	
+	@Test
+	public void getNodesChildrenOf() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "1parent", Style.compact);
+		CatalogEntry child1 = generateEntry(CatalogEntry.TYPE_NODE, "1child1", Style.compact);
+		CatalogEntry child2 = generateEntry(CatalogEntry.TYPE_NODE, "1child2", Style.compact);
+		
+		parentEntry.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		List<CatalogEntry> rootChildren = rootEntry.getChildren();
+		rootChildren.add(parentEntry);
+		catalogManager.saveCatalogEntry(rootEntry);
+		dbInstance.commit();
+		
+		child1.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child1);
+		child2.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child2);
+		dbInstance.commit();
+
+		List<CatalogEntry> children = parentEntry.getChildren();
+		children.add(child1);
+		children.add(child2);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		children = catalogManager.getNodesChildrenOf(parentEntry);
+		
+		Assert.assertNotNull(children);
+		Assert.assertArrayEquals(new int[] {2}, new int[] {children.size()});
+	}
+	
+	@Test
+	public void getChildrenOf() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "2parent", Style.compact);
+		CatalogEntry child1 = generateEntry(CatalogEntry.TYPE_NODE, "2child1", Style.compact);
+		CatalogEntry child2 = generateEntry(CatalogEntry.TYPE_NODE, "2child2", Style.compact);
+		CatalogEntry child3 = generateEntry(CatalogEntry.TYPE_LEAF, "2child3", null);
+		CatalogEntry child4 = generateEntry(CatalogEntry.TYPE_LEAF, "2child4", null);
+		
+		parentEntry.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		List<CatalogEntry> rootChildren = rootEntry.getChildren();
+		rootChildren.add(parentEntry);
+		catalogManager.saveCatalogEntry(rootEntry);
+		dbInstance.commit();
+		
+		child1.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child1);
+		child2.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child2);
+		child3.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child3);
+		child4.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child4);
+		dbInstance.commit();
+
+		List<CatalogEntry> children = parentEntry.getChildren();
+		children.add(child1);
+		children.add(child2);
+		children.add(child3);
+		children.add(child4);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		children = catalogManager.getChildrenOf(parentEntry);
+		
+		Assert.assertNotNull(children);
+		Assert.assertArrayEquals(new int[] {4}, new int[] {children.size()});
+	}
+	
+	@Test
+	public void getAllCatalogNodes() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "3parent", Style.compact);
+		CatalogEntry child1 = generateEntry(CatalogEntry.TYPE_NODE, "3child1", Style.compact);
+		CatalogEntry child2 = generateEntry(CatalogEntry.TYPE_NODE, "3child2", Style.compact);
+		
+		parentEntry.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		List<CatalogEntry> rootChildren = rootEntry.getChildren();
+		rootChildren.add(parentEntry);
+		catalogManager.saveCatalogEntry(rootEntry);
+		dbInstance.commit();
+		
+		child1.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child1);
+		child2.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child2);
+		dbInstance.commit();
+
+		List<CatalogEntry> children = parentEntry.getChildren();
+		children.add(child1);
+		children.add(child2);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		List<CatalogEntry> nodes = catalogManager.getAllCatalogNodes();
+		
+		Assert.assertNotNull(nodes);
+		for (CatalogEntry catalogEntry : nodes) {
+			Assert.assertTrue(catalogEntry.getType() == CatalogEntry.TYPE_NODE);
+		}
+	}
+
+	@Test
+	public void hasChildEntries() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry child1 = generateEntry(CatalogEntry.TYPE_LEAF, "4child1", null);
+		CatalogEntry child2 = generateEntry(CatalogEntry.TYPE_NODE, "4child2", Style.compact);
+		
+		child1.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(child1);
+		child2.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(child2);
+		dbInstance.commit();
+
+		List<CatalogEntry> children = rootEntry.getChildren();
+		children.add(child1);
+		children.add(child2);
+		catalogManager.saveCatalogEntry(rootEntry);
+		dbInstance.commit();
+		
+		Assert.assertTrue(catalogManager.hasChildEntries(rootEntry, CatalogEntry.TYPE_LEAF));
+		Assert.assertTrue(catalogManager.hasChildEntries(rootEntry, CatalogEntry.TYPE_NODE));
+	}
+	
+	@Test
+	public void countChildrenOf() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "5parent", Style.compact);
+		CatalogEntry child1 = generateEntry(CatalogEntry.TYPE_NODE, "5child1", Style.compact);
+		CatalogEntry child2 = generateEntry(CatalogEntry.TYPE_NODE, "5child2", Style.compact);
+		CatalogEntry child3 = generateEntry(CatalogEntry.TYPE_LEAF, "5child3", null);
+		CatalogEntry child4 = generateEntry(CatalogEntry.TYPE_LEAF, "5child4", null);
+		
+		parentEntry.setParent(rootEntry);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		List<CatalogEntry> rootChildren = rootEntry.getChildren();
+		rootChildren.add(parentEntry);
+		catalogManager.saveCatalogEntry(rootEntry);
+		dbInstance.commit();
+		
+		child1.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child1);
+		child2.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child2);
+		child3.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child3);
+		child4.setParent(parentEntry);
+		catalogManager.saveCatalogEntry(child4);
+		dbInstance.commit();
+
+		List<CatalogEntry> children = parentEntry.getChildren();
+		children.add(child1);
+		children.add(child2);
+		children.add(child3);
+		children.add(child4);
+		catalogManager.saveCatalogEntry(parentEntry);
+		dbInstance.commit();
+		
+		children = catalogManager.getChildrenOf(parentEntry);
+		
+		Assert.assertArrayEquals(new int[] {2, 2}, new int[] {
+				catalogManager.countChildrenOf(parentEntry, CatalogEntry.TYPE_LEAF),
+				catalogManager.countChildrenOf(parentEntry, CatalogEntry.TYPE_NODE)
+		});
+	}
+	
+	@Test
+	public void loadCatalogEntryByKey() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry catalogEntry = generateEntry(CatalogEntry.TYPE_NODE, "6parent", Style.compact);
+		
+		saveEntry(catalogEntry, rootEntry);
+		
+		CatalogEntry compareEntry = catalogManager.getCatalogEntryByKey(catalogEntry.getKey());
+		
+		Assert.assertTrue(catalogEntry.equals(compareEntry));
+	}
+	
+	@Test
+	public void saveCatalogEntry() {
+		afterPropoertiesSet();
+		
+		String name = "7SaveTestName";
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry catalogEntry = generateEntry(CatalogEntry.TYPE_NODE, name, Style.compact);
+		
+		saveEntry(catalogEntry, rootEntry);
+		
+		CatalogEntry compareEntry = catalogManager.getCatalogEntryByKey(catalogEntry.getKey());
+		
+		Assert.assertEquals(catalogEntry.getName(), compareEntry.getName());
+	}
+	
+	@Test
+	public void deleteCatalogEntry() {
+		afterPropoertiesSet();
+		
+		String name = "8DeleteTestName";
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "8parentDelete", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, name, Style.compact);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_LEAF, name, null);
+		CatalogEntry catalogEntry3 = generateEntry(CatalogEntry.TYPE_LEAF, name, null);
+		
+		parentEntry = saveEntry(parentEntry, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry);
+		catalogEntry2 = saveEntry(catalogEntry2, parentEntry);
+		catalogEntry3 = saveEntry(catalogEntry3, parentEntry);
+		
+		catalogManager.deleteCatalogEntry(catalogEntry2);
+		catalogManager.deleteCatalogEntry(catalogEntry1);
+		dbInstance.commit();
+		
+		List<CatalogEntry> children = catalogManager.loadCatalogEntry(parentEntry).getChildren();
+		System.out.println(children.size());
+		
+		Assert.assertTrue(catalogManager.loadCatalogEntry(catalogEntry2) == null);		
+		assertThat(children).containsExactlyInAnyOrder(catalogEntry3);
+	}
+	
+	@Test
+	public void updateCatalogEntry() {
+		afterPropoertiesSet();
+		
+		String name = "9UpdateTestName";
+		String update = " - updated";
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry = generateEntry(CatalogEntry.TYPE_NODE, "9parentDelete", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, name, Style.compact);
+		
+		parentEntry = saveEntry(parentEntry, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry);
+		
+		catalogEntry1.setName(name + update);
+		catalogManager.updateCatalogEntry(catalogEntry1);
+		catalogEntry1 = catalogManager.loadCatalogEntry(catalogEntry1);
+		
+		assertThat(catalogEntry1.getName()).isEqualTo(name + update);
+	}
+	
+	@Test
+	public void getCatalogEntriesReferencing() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "10parent1", Style.compact);
+		CatalogEntry parentEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "10parent2", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "10parent1", Style.compact);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "10parent1", Style.compact);
+		
+		RepositoryEntry re = createRepository("10test-entry", random.nextLong());
+		catalogEntry1.setRepositoryEntry(re);
+		catalogEntry2.setRepositoryEntry(re);
+		
+		parentEntry1 = saveEntry(parentEntry1, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry1);
+		parentEntry2 = saveEntry(parentEntry2, rootEntry);
+		catalogEntry2 = saveEntry(catalogEntry2, parentEntry1);
+		
+		assertThat(catalogManager.getCatalogEntriesReferencing(re)).containsExactlyInAnyOrder(catalogEntry1, catalogEntry2);
+	}
+	
+	@Test
+	public void getCatalogCategoriesFor() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "11parent1", Style.compact);
+		CatalogEntry parentEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "11parent2", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "11parent1", Style.compact);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "11parent1", Style.compact);
+		
+		RepositoryEntry re = createRepository("test-entry", random.nextLong());
+		catalogEntry1.setRepositoryEntry(re);
+		catalogEntry2.setRepositoryEntry(re);
+		
+		parentEntry1 = saveEntry(parentEntry1, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry1);
+		parentEntry2 = saveEntry(parentEntry2, rootEntry);
+		catalogEntry2 = saveEntry(catalogEntry2, parentEntry2);
+		
+		assertThat(catalogManager.getCatalogCategoriesFor(re)).containsExactlyInAnyOrder(parentEntry1, parentEntry2);
+	}
+	
+	@Test
+	public void getCatalogEntryBy() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "12parent1", Style.compact);
+		CatalogEntry parentEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "12parent2", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "12parent1", Style.compact);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "12parent1", Style.compact);
+		
+		RepositoryEntry re = createRepository("test-entry", random.nextLong());
+		catalogEntry1.setRepositoryEntry(re);
+		
+		parentEntry1 = saveEntry(parentEntry1, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry1);
+		parentEntry2 = saveEntry(parentEntry2, rootEntry);
+		catalogEntry2 = saveEntry(catalogEntry2, parentEntry2);
+		
+		assertThat(catalogManager.getCatalogEntryBy(re, parentEntry1)).isEqualTo(catalogEntry1);
+		assertThat(catalogManager.getCatalogEntryBy(re, parentEntry2)).isNull();
+	}
+	
+	@Test
+	public void isOwner() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "13parent1", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "13parent1", Style.compact);
+		
+		parentEntry1 = saveEntry(parentEntry1, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry1);
+		
+		Identity id1 = JunitTestHelper.createAndPersistIdentityAsUser("13catalog-test-identity");
+		Identity admin = securityManager.findIdentityByName("administrator");
+		
+		securityGroupDao.addIdentityToSecurityGroup(admin, catalogEntry1.getOwnerGroup());
+		dbInstance.commit();
+		
+		assertThat(catalogManager.isOwner(admin)).isTrue();
+		assertThat(catalogManager.isOwner(id1)).isFalse();
+		assertThat(catalogManager.isOwner(catalogEntry1, admin)).isTrue();
+	}
+	
+	@Test
+	public void getOwners() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "14parent1", Style.compact);
+		CatalogEntry parentEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "14parent2", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "14parent1", Style.compact);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "14parent1", Style.compact);
+		
+		RepositoryEntry re = createRepository("test-entry", random.nextLong());
+		catalogEntry1.setRepositoryEntry(re);
+		
+		parentEntry1 = saveEntry(parentEntry1, rootEntry);
+		catalogEntry1 = saveEntry(catalogEntry1, parentEntry1);
+		parentEntry2 = saveEntry(parentEntry2, rootEntry);
+		catalogEntry2 = saveEntry(catalogEntry2, parentEntry2);	
+		
+		Identity id1 = JunitTestHelper.createAndPersistIdentityAsUser("14catalog-test-identity");
+		Identity admin = securityManager.findIdentityByName("administrator");
+		
+		securityGroupDao.addIdentityToSecurityGroup(admin, catalogEntry1.getOwnerGroup());
+		securityGroupDao.addIdentityToSecurityGroup(admin, catalogEntry2.getOwnerGroup());
+		securityGroupDao.addIdentityToSecurityGroup(id1, catalogEntry2.getOwnerGroup());
+		dbInstance.commit();
+		
+		assertThat(catalogManager.getOwners(catalogEntry1)).contains(admin);
+		assertThat(catalogManager.getOwners(catalogEntry2)).contains(admin, id1);
+	}
+	
+	@Test
+	public void addCatalogEntry() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntry1 = generateEntry(CatalogEntry.TYPE_NODE, "15parent1", Style.compact);
+		CatalogEntry parentEntry2 = generateEntry(CatalogEntry.TYPE_NODE, "15parent2", Style.compact);
+		CatalogEntry catalogEntry1 = generateEntry(CatalogEntry.TYPE_LEAF, "15child1", null);
+		CatalogEntry catalogEntry2 = generateEntry(CatalogEntry.TYPE_LEAF, "15child2", null);
+		
+		catalogManager.addCatalogEntry(rootEntry, parentEntry1);
+		catalogManager.addCatalogEntry(rootEntry, parentEntry2);
+		catalogManager.addCatalogEntry(parentEntry1, catalogEntry1);
+		catalogManager.addCatalogEntry(parentEntry2, catalogEntry2);
+		
+		rootEntry = catalogManager.loadCatalogEntry(rootEntry);
+		parentEntry1 = catalogManager.loadCatalogEntry(parentEntry1);
+		parentEntry2 = catalogManager.loadCatalogEntry(parentEntry2);
+		catalogEntry1 = catalogManager.loadCatalogEntry(catalogEntry1);
+		catalogEntry2 = catalogManager.loadCatalogEntry(catalogEntry2);
+		
+		assertThat(rootEntry.getChildren()).contains(parentEntry1, parentEntry2);
+		assertThat(parentEntry1.getChildren()).contains(catalogEntry1);
+		assertThat(parentEntry2.getChildren()).contains(catalogEntry2);
+		
+		assertThat(parentEntry1.getChildren()).doesNotContain(catalogEntry2);
+		assertThat(parentEntry2.getChildren()).doesNotContain(catalogEntry1);
+	}
+	
+	@Test
+	public void getRootCatalogEntries() {
+		afterPropoertiesSet();
+		assertThat(catalogManager.getRootCatalogEntries()).hasSize(1);
+	}
+	
+	@Test
+	public void moveCatalogEntry() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntryA = generateEntry(CatalogEntry.TYPE_NODE, "16parentA", Style.compact);
+		CatalogEntry parentEntryAA = generateEntry(CatalogEntry.TYPE_NODE, "16parentAA", Style.compact);
+		CatalogEntry parentEntryB = generateEntry(CatalogEntry.TYPE_NODE, "16parentB", Style.compact);
+		CatalogEntry parentEntryBA = generateEntry(CatalogEntry.TYPE_NODE, "16parentBA", Style.compact);
+		CatalogEntry catalogEntryAA1 = generateEntry(CatalogEntry.TYPE_LEAF, "16childAA1", null);
+		CatalogEntry catalogEntryAA2 = generateEntry(CatalogEntry.TYPE_LEAF, "16childAA2", null);
+		CatalogEntry catalogEntryAA3 = generateEntry(CatalogEntry.TYPE_LEAF, "16childAA3", null);
+		CatalogEntry catalogEntryB1 = generateEntry(CatalogEntry.TYPE_LEAF, "16childB1", null);
+		
+		catalogEntryAA1.setRepositoryEntry(createRepository("16test-entry" + random.nextInt(), random.nextLong()));
+		catalogEntryAA2.setRepositoryEntry(createRepository("16test-entry" + random.nextInt(), random.nextLong()));
+		catalogEntryAA3.setRepositoryEntry(createRepository("16test-entry" + random.nextInt(), random.nextLong()));
+		
+		catalogManager.addCatalogEntry(rootEntry, parentEntryA);
+		catalogManager.addCatalogEntry(rootEntry, parentEntryB);
+		catalogManager.addCatalogEntry(parentEntryA, parentEntryAA);
+		catalogManager.addCatalogEntry(parentEntryB, parentEntryBA);
+		
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA1);
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA2);
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA3);
+		catalogManager.addCatalogEntry(parentEntryB, catalogEntryB1);
+		
+		parentEntryA = catalogManager.loadCatalogEntry(parentEntryA);
+		parentEntryAA = catalogManager.loadCatalogEntry(parentEntryAA);
+		parentEntryB = catalogManager.loadCatalogEntry(parentEntryA);
+		parentEntryBA = catalogManager.loadCatalogEntry(parentEntryBA);
+		
+		catalogEntryAA1 = catalogManager.loadCatalogEntry(catalogEntryAA1);
+		catalogEntryAA2 = catalogManager.loadCatalogEntry(catalogEntryAA2);
+		catalogEntryAA3 = catalogManager.loadCatalogEntry(catalogEntryAA3);
+		catalogEntryB1 = catalogManager.loadCatalogEntry(catalogEntryB1);
+		
+		assertThat(catalogManager.moveCatalogEntry(parentEntryA, parentEntryAA)).isFalse();
+		assertThat(catalogEntryAA3.getPosition()).isEqualTo(2);
+		assertThat(catalogManager.moveCatalogEntry(catalogEntryAA2, parentEntryBA)).isTrue();
+		assertThat(catalogEntryAA2.getPosition()).isEqualTo(1);
+		assertThat(catalogManager.moveCatalogEntry(parentEntryAA, parentEntryBA));
+		assertThat(catalogEntryB1.getPosition()).isEqualTo(1);
+		assertThat(parentEntryAA.getPosition()).isEqualTo(0);
+	}
+	
+	@Test
+	public void reorderCatalogEntry() {
+		afterPropoertiesSet();
+		
+		CatalogEntry rootEntry = getRootEntry();
+		CatalogEntry parentEntryA = generateEntry(CatalogEntry.TYPE_NODE, "17parentA", Style.compact);
+		CatalogEntry parentEntryAA = generateEntry(CatalogEntry.TYPE_NODE, "17parentAA", Style.compact);
+		CatalogEntry parentEntryB = generateEntry(CatalogEntry.TYPE_NODE, "17parentB", Style.compact);
+		CatalogEntry parentEntryBA = generateEntry(CatalogEntry.TYPE_NODE, "17parentBA", Style.compact);
+		CatalogEntry catalogEntryAA1 = generateEntry(CatalogEntry.TYPE_LEAF, "17childAA1", null);
+		CatalogEntry catalogEntryAA2 = generateEntry(CatalogEntry.TYPE_LEAF, "17childAA2", null);
+		CatalogEntry catalogEntryAA3 = generateEntry(CatalogEntry.TYPE_LEAF, "17childAA3", null);
+		CatalogEntry catalogEntryB1 = generateEntry(CatalogEntry.TYPE_LEAF, "17childB1", null);
+		
+		catalogEntryAA1.setRepositoryEntry(createRepository("17test-entry" + random.nextInt(), random.nextLong()));
+		catalogEntryAA2.setRepositoryEntry(createRepository("17test-entry" + random.nextInt(), random.nextLong()));
+		catalogEntryAA3.setRepositoryEntry(createRepository("17test-entry" + random.nextInt(), random.nextLong()));
+		
+		catalogManager.addCatalogEntry(rootEntry, parentEntryA);
+		catalogManager.addCatalogEntry(rootEntry, parentEntryB);
+		catalogManager.addCatalogEntry(parentEntryA, parentEntryAA);
+		catalogManager.addCatalogEntry(parentEntryB, parentEntryBA);
+		
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA1);
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA2);
+		catalogManager.addCatalogEntry(parentEntryAA, catalogEntryAA3);
+		catalogManager.addCatalogEntry(parentEntryB, catalogEntryB1);
+		
+		parentEntryA = catalogManager.loadCatalogEntry(parentEntryA);
+		parentEntryAA = catalogManager.loadCatalogEntry(parentEntryAA);
+		parentEntryB = catalogManager.loadCatalogEntry(parentEntryA);
+		parentEntryBA = catalogManager.loadCatalogEntry(parentEntryBA);
+		
+		catalogEntryAA1 = catalogManager.loadCatalogEntry(catalogEntryAA1);
+		catalogEntryAA2 = catalogManager.loadCatalogEntry(catalogEntryAA2);
+		catalogEntryAA3 = catalogManager.loadCatalogEntry(catalogEntryAA3);
+		catalogEntryB1 = catalogManager.loadCatalogEntry(catalogEntryB1);
+		
+		assertThat(catalogManager.reorderCatalogEntry(parentEntryA.getKey(), catalogEntryB1.getKey(), true)).isEqualTo(1);
+		assertThat(catalogManager.reorderCatalogEntry(parentEntryAA.getKey(), catalogEntryAA1.getKey(), false)).isEqualTo(0);
+		
+		catalogEntryAA1 = catalogManager.loadCatalogEntry(catalogEntryAA1);
+		assertThat(catalogEntryAA1.getPosition()).isEqualTo(1);
+		
+		assertThat(catalogManager.setPosition(catalogEntryB1.getKey(), 10)).isEqualTo(2);
+		assertThat(catalogManager.setPosition(catalogEntryAA2.getKey(), 0)).isEqualTo(0);
+		
+		catalogEntryAA2 = catalogManager.loadCatalogEntry(catalogEntryAA2);
+		assertThat(catalogEntryAA2.getPosition()).isEqualTo(0);
+	}
+	
+}
\ No newline at end of file
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 5f2d79787a17a399b1d6ea98e88f1967b24cbd1b..a7e62c4b13987bb40a10b076a2a9af69e4ed3151 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -155,6 +155,7 @@ import org.junit.runners.Suite;
 	org.olat.user.manager.UserDataExportServiceTest.class,
 	org.olat.user.manager.AbsenceLeaveDAOTest.class,
 	org.olat.repository.manager.AutomaticLifecycleServiceTest.class,
+	org.olat.repository.ui.catalog.CatalogManagerTest.class,
 	org.olat.repository.manager.RepositoryEntryDAOTest.class,
 	org.olat.repository.manager.RepositoryEntryLifecycleDAOTest.class,
 	org.olat.repository.manager.RepositoryEntryRelationDAOTest.class,