diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
index 910a4210ac8a2bceeb8120a367fe62d21bf919d3..c81a11ee3e23c56d76ffc5bbfe7cf542dc794df8 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
@@ -28,6 +28,7 @@ package org.olat.core.gui.components.form.flexible.elements;
 import java.util.List;
 import java.util.Set;
 
+import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.ExtendedFlexiTableSearchController;
@@ -235,6 +236,12 @@ public interface FlexiTableElement extends FormItem {
 	 */
 	public void setSortSettings(FlexiTableSortOptions options);
 	
+	/**
+	 * Return the current sorting if any.
+	 * @return
+	 */
+	public SortKey[] getOrderBy();
+	
 	/**
 	 * Enable export
 	 * @return True if export is enabled
diff --git a/src/main/java/org/olat/modules/fo/ForumHelper.java b/src/main/java/org/olat/modules/fo/ForumHelper.java
index 31e7e62bf9f70683ae1059e4f539aa15fbe42f92..b1ad9a0b4f98ab070805c8709b206f98e45098d4 100644
--- a/src/main/java/org/olat/modules/fo/ForumHelper.java
+++ b/src/main/java/org/olat/modules/fo/ForumHelper.java
@@ -28,7 +28,6 @@ package org.olat.modules.fo;
 import java.io.File;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.Comparator;
 import java.util.Date;
 
 import org.olat.core.commons.modules.bc.FolderConfig;
@@ -36,7 +35,6 @@ import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
-import org.olat.modules.fo.archiver.MessageNode;
 
 /**
  * 
@@ -65,33 +63,4 @@ public class ForumHelper {
 		container = (VFSContainer) vfsItem;
 		return container;
 	}
-	
-
-	/**
-	 * Comparators can be passed to a sort method (such as Collections.sort) 
-	 * to allow precise control over the sort order.  
-	 * <p>
-	 * Sticky threads first, last modified first.
-	 * 
-	 * @return a MessageNode comparator.
-	 * @see java.util.Comparator 
-	 */
-	public static Comparator<MessageNode> getMessageNodeComparator() {
-		return new MessageNodeComparator();
-	}
-	
-	private static class MessageNodeComparator implements Comparator<MessageNode> {
-		@Override
-		public int compare(final MessageNode m1, final MessageNode m2) {			
-			if(m1.isSticky() && m2.isSticky()) {
-				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
-			} else if(m1.isSticky()) {
-				return -1;
-			} else if(m2.isSticky()){
-				return 1;
-			} else {
-				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
-			}				
-		}
-	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java b/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
index 56eeeb5439f432a2770c61a7960705df91a6e1ae..54843950fcce86005c6224ddc9d644ac03a0e54f 100644
--- a/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
+++ b/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
@@ -36,7 +36,6 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.util.tree.TreeVisitor;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.ForumCallback;
-import org.olat.modules.fo.ForumHelper;
 import org.olat.modules.fo.Message;
 import org.olat.modules.fo.archiver.formatters.ForumFormatter;
 import org.olat.modules.fo.manager.ForumManager;
@@ -117,19 +116,24 @@ public class ForumArchiveManager {
 					topNodeList.add(topNode);
 				}
 			}
-		}	
-		return getMessagesSorted(topNodeList);
+		}
+		Collections.sort(topNodeList, new MessageNodeComparator());
+		return topNodeList;
 	}
 	
-  /**
-   * Sorts the input list by adding the sticky messages first.
-   * @param topNodeList
-   * @return the sorted list.
-   */	
-	private List<MessageNode> getMessagesSorted(List<MessageNode> topNodeList) { 
-		 Comparator<MessageNode> messageNodeComparator = ForumHelper.getMessageNodeComparator();
-		 Collections.sort(topNodeList, messageNodeComparator);
-		 return topNodeList;
+	public static class MessageNodeComparator implements Comparator<MessageNode> {
+		@Override
+		public int compare(final MessageNode m1, final MessageNode m2) {			
+			if(m1.isSticky() && m2.isSticky()) {
+				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
+			} else if(m1.isSticky()) {
+				return -1;
+			} else if(m2.isSticky()){
+				return 1;
+			} else {
+				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
+			}				
+		}
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/modules/fo/ui/ForumMessageListController.java b/src/main/java/org/olat/modules/fo/ui/ForumMessageListController.java
index f56811de6e97183fd34d47ee65ab9f36ec074c78..83bfd0c0cccdcd5f3cbbcb9ba559529941f940a0 100644
--- a/src/main/java/org/olat/modules/fo/ui/ForumMessageListController.java
+++ b/src/main/java/org/olat/modules/fo/ui/ForumMessageListController.java
@@ -20,7 +20,11 @@
 package org.olat.modules.fo.ui;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -46,6 +50,7 @@ import org.olat.core.id.UserConstants;
 import org.olat.core.util.Util;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.MessageLight;
+import org.olat.modules.fo.Status;
 import org.olat.modules.fo.manager.ForumManager;
 import org.olat.modules.fo.ui.ForumMessageDataModel.ForumMessageCols;
 import org.olat.modules.fo.ui.events.SelectMessageEvent;
@@ -128,40 +133,29 @@ public class ForumMessageListController extends FormBasicController implements F
 			keyToViews.put(view.getKey(), view);
 		}
 
-		//TODO forum: implement a reorder method which works on threads and parent line
-		/*calculate depth
-		
+		//calculate depth
+		Map<Long, List<Long>> keyToParentline = new HashMap<>();
 		for(MessageLightView view:views) {
 			if(view.getParentKey() == null) {
 				view.setDepth(0);
 			} else {
+				List<Long> parentLine = new ArrayList<>(5);
 				view.setDepth(1);
 				for(MessageLightView parent = keyToViews.get(view.getParentKey()); parent != null; parent = keyToViews.get(parent.getParentKey())) {
 					view.setDepth(view.getDepth() + 1);
+					parentLine.add(parent.getKey());
 				}
+				keyToParentline.put(view.getKey(), parentLine);
 			}
 		}
 		
 		//order
-		 */
-
-		dataModel.setObjects(views);
-	}
-	/*
-	private class MessageComparator implements Comparator<MessageLightView> {
-
-		@Override
-		public int compare(MessageLightView v1, MessageLightView v2) {
-			Long tt1 = v1.getThreadtopKey() == null ? v1.getKey() : v1.getThreadtopKey();
-			Long tt2 = v2.getThreadtopKey() == null ? v2.getKey() : v2.getThreadtopKey();
-			int c = Long.compare(tt1.longValue(), tt2.longValue());
-			if(c == 0) {
-				
-			}
-			return c;
-		}
+		List<MessageNode> threads = convertToThreadTrees(views);
+		Collections.sort(threads, new MessageNodeComparator());
+		List<MessageLightView> orderedViews = new ArrayList<>(allMessages.size());
+		flatTree(threads, orderedViews);
+		dataModel.setObjects(orderedViews);
 	}
-	*/
 	
 	public void loadMessages(List<MessageLightView> views) {
 		dataModel.setObjects(views);
@@ -229,4 +223,95 @@ public class ForumMessageListController extends FormBasicController implements F
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
+	
+	private void flatTree(List<MessageNode> nodes, List<MessageLightView> orderedViews) {
+		for(MessageNode node:nodes) {
+			orderedViews.add(node.getView());
+			if(node.hasChildren()) {
+				flatTree(node.getChildren(), orderedViews);
+			}
+		}
+	}
+	
+	private List<MessageNode> convertToThreadTrees(List<MessageLightView> messages){
+		List<MessageNode> topNodeList = new ArrayList<>();
+	
+		for (Iterator<MessageLightView> iterTop = messages.iterator(); iterTop.hasNext();) {
+			MessageLightView msg = iterTop.next();
+			if (msg.getParentKey() == null) {
+				iterTop.remove();
+				MessageNode topNode = new MessageNode(msg);
+				addChildren(messages, topNode);
+				topNodeList.add(topNode);
+			}
+		}	
+		return topNodeList;
+	}
+	
+	private void addChildren(List<MessageLightView> messages, MessageNode mn){
+		for(Iterator<MessageLightView> iterMsg = messages.iterator(); iterMsg.hasNext(); ) {
+			MessageLightView msg = iterMsg.next();
+			if ((msg.getParentKey() != null) && (msg.getParentKey().equals(mn.getKey()))){
+				MessageNode childNode = new MessageNode(msg);
+				mn.addChild(childNode);
+				addChildren(messages, childNode);
+			}
+		}
+	}
+	
+	private static class MessageNode {
+		
+		private final MessageLightView view;
+		private List<MessageNode> children;
+		
+		public MessageNode(MessageLightView view) {
+			this.view = view;
+		}
+		
+		public Long getKey() {
+			return view.getKey();
+		}
+		
+		public boolean isSticky() {
+			return Status.getStatus(view.getStatusCode()).isSticky();
+		}
+		
+		public Date getLastModified() {
+			return view.getLastModified();
+		}
+		
+		public MessageLightView getView() {
+			return view;
+		}
+		
+		public boolean hasChildren() {
+			return children != null && children.size() > 0;
+		}
+		
+		public void addChild(MessageNode child) {
+			if(children == null) {
+				children = new ArrayList<>();
+			}
+			children.add(child);
+		}
+		
+		public List<MessageNode> getChildren() {
+			return children;
+		}
+	}
+	
+	public static class MessageNodeComparator implements Comparator<MessageNode> {
+		@Override
+		public int compare(final MessageNode m1, final MessageNode m2) {			
+			if(m1.isSticky() && m2.isSticky()) {
+				return m2.getLastModified().compareTo(m1.getLastModified()); //last first
+			} else if(m1.isSticky()) {
+				return -1;
+			} else if(m2.isSticky()){
+				return 1;
+			} else {
+				return m2.getLastModified().compareTo(m1.getLastModified()); //last first
+			}				
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/fo/ui/IndentCellRenderer.java b/src/main/java/org/olat/modules/fo/ui/IndentCellRenderer.java
index d4bdcf7de56348c34d6021d27d91a39d10826cb4..4578b8f352cc5fefa424ec0eee066d0349c75738 100644
--- a/src/main/java/org/olat/modules/fo/ui/IndentCellRenderer.java
+++ b/src/main/java/org/olat/modules/fo/ui/IndentCellRenderer.java
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.fo.ui;
 
+import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
 import org.olat.core.gui.render.Renderer;
@@ -41,19 +42,26 @@ public class IndentCellRenderer implements FlexiCellRenderer {
 	public void render(Renderer renderer, StringOutput target, Object cellValue, int row,
 			FlexiTableComponent source, URLBuilder ubu, Translator translator) {
 		
-		Object m = source.getFlexiTableElement().getTableDataModel().getObject(row);
-		if(m instanceof MessageLightView && cellValue instanceof String) {
-			MessageLightView message = (MessageLightView)m;
-			int indent = message.getDepth();
-			if (indent > MAXINDENTS) {
-				indent = MAXINDENTS;
+		SortKey[] keys = source.getFlexiTableElement().getOrderBy();
+		if(keys != null && keys.length > 0 && keys[0] != null) {
+			if(cellValue instanceof String) {
+				target.append((String)cellValue);
+			}
+		} else {
+			Object m = source.getFlexiTableElement().getTableDataModel().getObject(row);
+			if(m instanceof MessageLightView && cellValue instanceof String) {
+				MessageLightView message = (MessageLightView)m;
+				int indent = message.getDepth();
+				if (indent > MAXINDENTS) {
+					indent = MAXINDENTS;
+				}
+				target.append("<div style=\"white-space: nowrap;")
+				      .append("padding-left: ").append(indent).append("em;\">")
+				      .append(Formatter.truncate((String)cellValue, 50 - indent))
+				      .append("</div>");
+			} else if(cellValue instanceof String) {
+				target.append((String)cellValue);
 			}
-			target.append("<div style=\"white-space: nowrap;")
-			      .append("padding-left: ").append(indent).append("em;\">")
-			      .append(Formatter.truncate((String)cellValue, 50 - indent))
-			      .append("</div>");
-		} else if(cellValue instanceof String) {
-			target.append((String)cellValue);
 		}
 	}
 }