Sort examples by (hopefully) most relevant
diff --git a/src/main/java/org/apache/tomee/website/LearningLinks.java b/src/main/java/org/apache/tomee/website/LearningLinks.java
index 9f170f4..aa0f488 100644
--- a/src/main/java/org/apache/tomee/website/LearningLinks.java
+++ b/src/main/java/org/apache/tomee/website/LearningLinks.java
@@ -24,6 +24,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.UncheckedIOException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -80,7 +81,9 @@
         if (!source.getName().contains("jakarta")) return;
         final Map<String, JavadocSource> sources = getJavadocSources(source.stream());
 
-        for (final Example example : examples.getExamples()) {
+        final List<Example> examples = sort(this.examples.getExamples());
+
+        for (final Example example : examples) {
             final List<String> apisUsed = getImports(example).stream()
                     .filter(sources::containsKey)
                     .collect(Collectors.toList());
@@ -101,6 +104,40 @@
         }
     }
 
+    protected static List<Example> sort(final List<Example> list) {
+        final List<Example> examples = new ArrayList<>(list);
+
+        // Sort by size of example description (favor better documented examples)
+        examples.sort(LearningLinks::compareBySize);
+
+        // Sort by TomEE version
+        examples.sort(LearningLinks::compareByVersion);
+
+        // Sort "latest" to the top
+        examples.sort(LearningLinks::compareByLatest);
+
+        return examples;
+    }
+
+    protected static int compareByLatest(final Example a, final Example b) {
+        return Integer.compare(rankLatest(b), rankLatest(a));
+    }
+
+    protected static int compareByVersion(final Example a, final Example b) {
+        return pathFromContentRoot(b.getDestReadme()).compareTo(pathFromContentRoot(a.getDestReadme()));
+    }
+
+    protected static int compareBySize(final Example a, final Example b) {
+        return Long.compare(b.getDestReadme().length(), a.getDestReadme().length());
+    }
+
+    private static int rankLatest(final Example example) {
+        final String path = pathFromContentRoot(example.getDestReadme());
+        if (path.startsWith("latest/")) return 1;
+        if (path.startsWith("master/")) return -1;
+        return 0;
+    }
+
     private void addApisUsed(final Example example, final List<String> apisUsed, final Map<String, JavadocSource> sources, final Source source) {
         Collections.sort(apisUsed);
 
diff --git a/src/test/java/org/apache/tomee/website/LearningLinksTest.java b/src/test/java/org/apache/tomee/website/LearningLinksTest.java
index 09e8b37..9f26e55 100644
--- a/src/test/java/org/apache/tomee/website/LearningLinksTest.java
+++ b/src/test/java/org/apache/tomee/website/LearningLinksTest.java
@@ -17,8 +17,15 @@
 package org.apache.tomee.website;
 
 import org.junit.Test;
+import org.tomitribe.util.Archive;
+import org.tomitribe.util.Files;
+import org.tomitribe.util.Join;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
 
@@ -37,4 +44,181 @@
         final String basePath = LearningLinks.pathFromContentRoot(file);
         assertEquals("tomee-9.0/pt/examples/injection-of-entitymanager.adoc", basePath);
     }
+
+    @Test
+    public void sortBySize() throws IOException {
+        final File dir = Archive.archive()
+                .add("target/jbake/content/tomee-9.0/examples/b.adoc", new byte[141])
+                .add("target/jbake/content/tomee-9.0/examples/a.adoc", new byte[60])
+                .add("target/jbake/content/tomee-9.0/examples/c.adoc", new byte[10])
+                .add("target/jbake/content/tomee-8.0/examples/b.adoc", new byte[123])
+                .add("target/jbake/content/tomee-8.0/examples/a.adoc", new byte[61])
+                .add("target/jbake/content/tomee-8.0/examples/c.adoc", new byte[4])
+                .add("target/jbake/content/latest/examples/b.adoc", new byte[12])
+                .add("target/jbake/content/latest/examples/a.adoc", new byte[5])
+                .add("target/jbake/content/latest/examples/c.adoc", new byte[90])
+                .toDir();
+
+        final List<Example> examples = Files.collect(dir).stream()
+                .filter(file -> file.getName().endsWith(".adoc"))
+                .map(Example::from)
+                .peek(example -> example.setDestReadme(example.getSrcReadme()))
+                .collect(Collectors.toList());
+
+        Collections.shuffle(examples);
+
+        examples.sort(LearningLinks::compareBySize);
+
+        final List<String> collect = examples.stream()
+                .map(Example::getDestReadme)
+                .map(LearningLinks::pathFromContentRoot)
+                .collect(Collectors.toList());
+
+        assertEquals("tomee-9.0/examples/b.adoc\n" +
+                "tomee-8.0/examples/b.adoc\n" +
+                "latest/examples/c.adoc\n" +
+                "tomee-8.0/examples/a.adoc\n" +
+                "tomee-9.0/examples/a.adoc\n" +
+                "latest/examples/b.adoc\n" +
+                "tomee-9.0/examples/c.adoc\n" +
+                "latest/examples/a.adoc\n" +
+                "tomee-8.0/examples/c.adoc", Join.join("\n", collect));
+    }
+
+    @Test
+    public void sortByVersion() throws IOException {
+        final File dir = Archive.archive()
+                .add("target/jbake/content/tomee-9.0/examples/b.adoc", new byte[141])
+                .add("target/jbake/content/tomee-9.0/examples/a.adoc", new byte[60])
+                .add("target/jbake/content/tomee-9.0/examples/c.adoc", new byte[10])
+                .add("target/jbake/content/tomee-8.0/examples/b.adoc", new byte[123])
+                .add("target/jbake/content/tomee-8.0/examples/a.adoc", new byte[61])
+                .add("target/jbake/content/tomee-8.0/examples/c.adoc", new byte[4])
+                .add("target/jbake/content/latest/examples/b.adoc", new byte[12])
+                .add("target/jbake/content/latest/examples/a.adoc", new byte[5])
+                .add("target/jbake/content/latest/examples/c.adoc", new byte[90])
+                .toDir();
+
+        final List<Example> examples = Files.collect(dir).stream()
+                .filter(file -> file.getName().endsWith(".adoc"))
+                .map(Example::from)
+                .peek(example -> example.setDestReadme(example.getSrcReadme()))
+                .collect(Collectors.toList());
+
+        Collections.shuffle(examples);
+
+        examples.sort(LearningLinks::compareBySize); // for stability
+        examples.sort(LearningLinks::compareByVersion);
+
+        final List<String> collect = examples.stream()
+                .map(Example::getDestReadme)
+                .map(LearningLinks::pathFromContentRoot)
+                .collect(Collectors.toList());
+
+        assertEquals("" +
+                "tomee-9.0/examples/c.adoc\n" +
+                "tomee-9.0/examples/b.adoc\n" +
+                "tomee-9.0/examples/a.adoc\n" +
+                "tomee-8.0/examples/c.adoc\n" +
+                "tomee-8.0/examples/b.adoc\n" +
+                "tomee-8.0/examples/a.adoc\n" +
+                "latest/examples/c.adoc\n" +
+                "latest/examples/b.adoc\n" +
+                "latest/examples/a.adoc", Join.join("\n", collect));
+    }
+
+    @Test
+    public void sortByLatest() throws IOException {
+        final File dir = Archive.archive()
+                .add("target/jbake/content/master/examples/b.adoc", new byte[111])
+                .add("target/jbake/content/master/examples/a.adoc", new byte[70])
+                .add("target/jbake/content/master/examples/c.adoc", new byte[20])
+                .add("target/jbake/content/tomee-9.0/examples/b.adoc", new byte[141])
+                .add("target/jbake/content/tomee-9.0/examples/a.adoc", new byte[60])
+                .add("target/jbake/content/tomee-9.0/examples/c.adoc", new byte[10])
+                .add("target/jbake/content/tomee-8.0/examples/b.adoc", new byte[123])
+                .add("target/jbake/content/tomee-8.0/examples/a.adoc", new byte[61])
+                .add("target/jbake/content/tomee-8.0/examples/c.adoc", new byte[4])
+                .add("target/jbake/content/latest/examples/b.adoc", new byte[12])
+                .add("target/jbake/content/latest/examples/a.adoc", new byte[5])
+                .add("target/jbake/content/latest/examples/c.adoc", new byte[90])
+                .toDir();
+
+        final List<Example> examples = Files.collect(dir).stream()
+                .filter(file -> file.getName().endsWith(".adoc"))
+                .map(Example::from)
+                .peek(example -> example.setDestReadme(example.getSrcReadme()))
+                .collect(Collectors.toList());
+
+        Collections.shuffle(examples);
+
+        examples.sort(LearningLinks::compareBySize);
+        examples.sort(LearningLinks::compareByLatest);
+        assertEquals("" +
+                "latest/examples/c.adoc\n" +
+                "latest/examples/b.adoc\n" +
+                "latest/examples/a.adoc\n" +
+                "tomee-9.0/examples/b.adoc\n" +
+                "tomee-8.0/examples/b.adoc\n" +
+                "tomee-8.0/examples/a.adoc\n" +
+                "tomee-9.0/examples/a.adoc\n" +
+                "tomee-9.0/examples/c.adoc\n" +
+                "tomee-8.0/examples/c.adoc\n" +
+                "master/examples/b.adoc\n" +
+                "master/examples/a.adoc\n" +
+                "master/examples/c.adoc", toPaths(examples));
+    }
+
+    @Test
+    public void sort() throws IOException {
+        final File dir = Archive.archive()
+                .add("target/jbake/content/master/examples/b.adoc", new byte[111])
+                .add("target/jbake/content/master/examples/a.adoc", new byte[70])
+                .add("target/jbake/content/master/examples/c.adoc", new byte[20])
+                .add("target/jbake/content/tomee-9.0/examples/b.adoc", new byte[141])
+                .add("target/jbake/content/tomee-9.0/examples/a.adoc", new byte[60])
+                .add("target/jbake/content/tomee-9.0/examples/c.adoc", new byte[10])
+                .add("target/jbake/content/tomee-8.0/examples/b.adoc", new byte[123])
+                .add("target/jbake/content/tomee-8.0/examples/a.adoc", new byte[61])
+                .add("target/jbake/content/tomee-8.0/examples/c.adoc", new byte[4])
+                .add("target/jbake/content/latest/examples/b.adoc", new byte[12])
+                .add("target/jbake/content/latest/examples/a.adoc", new byte[5])
+                .add("target/jbake/content/latest/examples/c.adoc", new byte[90])
+                .toDir();
+
+        final List<Example> examples = Files.collect(dir).stream()
+                .filter(file -> file.getName().endsWith(".adoc"))
+                .map(Example::from)
+                .peek(example -> example.setDestReadme(example.getSrcReadme()))
+                .collect(Collectors.toList());
+
+        Collections.shuffle(examples);
+
+        final List<Example> sorted = LearningLinks.sort(examples);
+
+        assertEquals("" +
+                "latest/examples/c.adoc\n" +
+                "latest/examples/b.adoc\n" +
+                "latest/examples/a.adoc\n" +
+                "tomee-9.0/examples/c.adoc\n" +
+                "tomee-9.0/examples/b.adoc\n" +
+                "tomee-9.0/examples/a.adoc\n" +
+                "tomee-8.0/examples/c.adoc\n" +
+                "tomee-8.0/examples/b.adoc\n" +
+                "tomee-8.0/examples/a.adoc\n" +
+                "master/examples/c.adoc\n" +
+                "master/examples/b.adoc\n" +
+                "master/examples/a.adoc", toPaths(sorted));
+    }
+
+    private static String toPaths(final List<Example> examples) {
+        final List<String> collect = examples.stream()
+                .map(Example::getDestReadme)
+                .map(LearningLinks::pathFromContentRoot)
+                .collect(Collectors.toList());
+
+        final String actual = Join.join("\n", collect);
+        return actual;
+    }
+
 }