diff --git a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarServiceImpl.java
index 09deec221d..8f1a0a9a85 100755
--- a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarServiceImpl.java
@@ -71,6 +71,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
     }
 
     @Override
+    @Transactional
     public Either<SchedulingError, FinalSeminar> schedule(Project project, LocalDateTime when, FinalSeminarDetails details) {
         if (project.isFinalSeminarRuleExempted()) {
             return createSeminar(project, when, details);
@@ -86,7 +87,14 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
             return Either.left(new RoughDraftNotApproved());
         }
 
-        return createSeminar(project, when, details);
+        final FinalSeminar current = findByProject(project);
+        if (current == null) {
+            return createSeminar(project, when, details);
+        }
+        else {
+            // Assume double click sends the same data so no need to change anything
+            return Either.right(current);
+        }
     }
 
     private MovingError validateSchedulingRules(LocalDate date) {
diff --git a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java
index 56dc06e357..05642970d2 100644
--- a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java
@@ -51,8 +51,11 @@ public class BasicForumServiceImpl implements BasicForumService {
     @Override
     @Transactional
     public boolean setThreadRead(User user, ForumThread forumThread, boolean read) {
-        for (ForumPost post : forumThread.getPosts()) {
-            setRead(user, post, read);
+        readStateRepository.setThreadRead(user, forumThread, read);
+        if (read) {
+            for (ForumPost post : forumThread.getPosts()) {
+                eventBus.post(new ForumPostReadEvent(post, user));
+            }
         }
         return read;
     }
diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadEvent.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadEvent.java
index 244f44737c..816c477c38 100644
--- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadEvent.java
+++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadEvent.java
@@ -3,20 +3,5 @@ package se.su.dsv.scipro.forum;
 import se.su.dsv.scipro.forum.dataobjects.ForumPost;
 import se.su.dsv.scipro.system.User;
 
-public final class ForumPostReadEvent {
-    private final ForumPost post;
-    private final User user;
-
-    public ForumPostReadEvent(final ForumPost post, final User user) {
-        this.post = post;
-        this.user = user;
-    }
-
-    public ForumPost getPost() {
-        return post;
-    }
-
-    public User getUser() {
-        return user;
-    }
+public record ForumPostReadEvent(ForumPost post, User user) {
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepository.java
index 79f55f1c8d..d739c2bc0c 100644
--- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepository.java
+++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepository.java
@@ -6,6 +6,7 @@ import org.springframework.data.querydsl.QueryDslPredicateExecutor;
 import se.su.dsv.scipro.forum.dataobjects.ForumPost;
 import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState;
 import se.su.dsv.scipro.forum.dataobjects.ForumPostReadStateId;
+import se.su.dsv.scipro.forum.dataobjects.ForumThread;
 import se.su.dsv.scipro.system.User;
 
 @Transactional
@@ -13,4 +14,6 @@ public interface ForumPostReadStateRepository
         extends JpaRepository<ForumPostReadState, ForumPostReadStateId>, QueryDslPredicateExecutor<ForumPostReadState> {
 
     ForumPostReadState find(User user, ForumPost post);
+
+    void setThreadRead(User user, ForumThread forumThread, boolean read);
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepositoryImpl.java
index 9d324cc7ab..909c57693f 100644
--- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepositoryImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostReadStateRepositoryImpl.java
@@ -1,8 +1,11 @@
 package se.su.dsv.scipro.forum;
 
+import com.google.inject.persist.Transactional;
+import jakarta.persistence.LockModeType;
 import se.su.dsv.scipro.forum.dataobjects.ForumPost;
 import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState;
 import se.su.dsv.scipro.forum.dataobjects.ForumPostReadStateId;
+import se.su.dsv.scipro.forum.dataobjects.ForumThread;
 import se.su.dsv.scipro.forum.dataobjects.QForumPostReadState;
 import se.su.dsv.scipro.system.GenericRepo;
 import se.su.dsv.scipro.system.User;
@@ -23,4 +26,21 @@ public class ForumPostReadStateRepositoryImpl extends GenericRepo<ForumPostReadS
     public ForumPostReadState find(User user, ForumPost post) {
         return findOne(allOf(QForumPostReadState.forumPostReadState.id.user.eq(user), QForumPostReadState.forumPostReadState.id.post.eq(post)));
     }
+
+    @Override
+    @Transactional
+    public void setThreadRead(User user, ForumThread forumThread, boolean read) {
+        EntityManager em = em();
+        em.lock(forumThread, LockModeType.PESSIMISTIC_WRITE);
+        for (ForumPost post : forumThread.getPosts()) {
+            ForumPostReadState state = find(user, post);
+            if (state == null) {
+                state = new ForumPostReadState();
+                state.setId(new ForumPostReadStateId(user, post));
+            }
+            state.setRead(read);
+            em.persist(state);
+        }
+        em.lock(forumThread, LockModeType.NONE);
+    }
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/forum/notifications/ForumNotifications.java b/core/src/main/java/se/su/dsv/scipro/forum/notifications/ForumNotifications.java
index d0a9e19291..b294608351 100644
--- a/core/src/main/java/se/su/dsv/scipro/forum/notifications/ForumNotifications.java
+++ b/core/src/main/java/se/su/dsv/scipro/forum/notifications/ForumNotifications.java
@@ -97,7 +97,7 @@ public class ForumNotifications {
     @Subscribe
     @Transactional
     public void forumPostRead(ForumPostReadEvent forumPostReadEvent) {
-        forumNotificationRepository.findByForumPost(forumPostReadEvent.getPost()).ifPresent(connection ->
-                notificationService.setRead(forumPostReadEvent.getUser(), connection.getNotificationEvent(), true));
+        forumNotificationRepository.findByForumPost(forumPostReadEvent.post()).ifPresent(connection ->
+                notificationService.setRead(forumPostReadEvent.user(), connection.getNotificationEvent(), true));
     }
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/GradingService.java b/core/src/main/java/se/su/dsv/scipro/grading/GradingService.java
index b45da1614b..6172f3c280 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/GradingService.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/GradingService.java
@@ -7,6 +7,9 @@ import java.time.LocalDate;
 import java.util.*;
 
 public interface GradingService {
+    /**
+     * @return the list of examinations for the given project and author, or {@code null} if the request failed
+     */
     List<Examination> getExaminations(String token, long projectId, long authorId);
 
     Either<GetGradeError, Optional<Result>> getResult(String token, long projectId, long authorId, long examinationId);
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/GradingServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/grading/GradingServiceImpl.java
index afe38b5de9..efd271ba90 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/GradingServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/GradingServiceImpl.java
@@ -46,7 +46,7 @@ public class GradingServiceImpl implements GradingService {
             return response.readEntity(EXAMINATION_LIST);
         }
         else {
-            return Collections.emptyList();
+            return null;
         }
     }
 
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataService.java b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataService.java
index 173f85b9cc..7e3118d786 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataService.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataService.java
@@ -6,4 +6,6 @@ public interface PublicationMetadataService {
     PublicationMetadata getByProject(Project project);
 
     void save(PublicationMetadata publicationMetadata);
+
+    boolean hasSuppliedPublicationMetadata(Project project, boolean noNationalSubjectCategoriesAvailable);
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataServiceImpl.java
index a610cc3731..26f0e1801b 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataServiceImpl.java
@@ -1,6 +1,7 @@
 package se.su.dsv.scipro.grading;
 
 import se.su.dsv.scipro.project.Project;
+import se.su.dsv.scipro.system.Language;
 
 import jakarta.inject.Inject;
 import java.util.Objects;
@@ -29,4 +30,17 @@ class PublicationMetadataServiceImpl implements PublicationMetadataService {
     public void save(PublicationMetadata publicationMetadata) {
         publicationMetadataRepository.save(publicationMetadata);
     }
+
+    @Override
+    public boolean hasSuppliedPublicationMetadata(Project project, boolean noNationalSubjectCategoriesAvailable) {
+        final PublicationMetadata metadata = getByProject(project);
+        return notBlank(metadata.getAbstractEnglish()) &&
+                (project.getLanguage() == Language.ENGLISH || notBlank(metadata.getAbstractSwedish())) &&
+                (noNationalSubjectCategoriesAvailable || metadata.getNationalSubjectCategory() != null);
+    }
+
+    private boolean notBlank(String s) {
+        return s != null && !s.isBlank();
+    }
+
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/match/IdeaServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/match/IdeaServiceImpl.java
index 5ba42a3086..fdeae929fa 100755
--- a/core/src/main/java/se/su/dsv/scipro/match/IdeaServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/match/IdeaServiceImpl.java
@@ -45,7 +45,6 @@ public class IdeaServiceImpl extends AbstractServiceImpl<Idea, Long> implements
     public static final String NO_LONGER_AVAILABLE_ERROR = "Idea is no longer available";
     public static final String ALREADY_PARTICIPATING_ERROR = "You are already participating in another idea";
     public static final String PARTNER_ALREADY_PARTICIPATING_ERROR = "Your partner is already participating in another idea";
-    public static final String SELECTED_IDEA = "You selected idea: ";
     public static final String BACHELOR_NEED_PARTNER_ERROR = "You need to select a partner when the idea is on bachelor level";
     public static final String ADD_SELF_AS_PARTNER_ERROR = "You may not add yourself as project partner";
     public static final String NO_AUTHORS_ERROR = "The idea is submitted by a student, number of students is not allowed";
@@ -217,7 +216,8 @@ public class IdeaServiceImpl extends AbstractServiceImpl<Idea, Long> implements
             return new Pair<>(Boolean.FALSE, WRONG_LEVEL_FOR_YOU);
         }
 
-        return new Pair<>(Boolean.TRUE, SELECTED_IDEA + idea.getTitle());
+        return new Pair<>(Boolean.TRUE, "You have successfully selected the supervisor idea "
+                + idea.getTitle() + ", in the application period " + ap.getName());
 
     }
 
diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReport.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReport.java
index 2765d30161..4c4b70397c 100644
--- a/core/src/main/java/se/su/dsv/scipro/report/GradingReport.java
+++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReport.java
@@ -6,6 +6,7 @@ import se.su.dsv.scipro.system.ProjectType;
 import se.su.dsv.scipro.system.User;
 
 import jakarta.persistence.*;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -29,6 +30,10 @@ public abstract class GradingReport extends Report {
     @OneToMany(mappedBy = "gradingReport", cascade = {CascadeType.ALL})
     private List<GradingCriterion> gradingCriteria = new ArrayList<>();
 
+    @Basic
+    @Column(name = "date_submitted_to_examiner")
+    private Instant dateSubmittedToExaminer;
+
     protected GradingReport() {
         // JPA
     }
@@ -37,6 +42,7 @@ public abstract class GradingReport extends Report {
     public void submit() {
         super.submit();
         setState(State.FINALIZED);
+        setDateSubmittedToExaminer(Instant.now());
     }
 
     public Project getProject() {
@@ -51,6 +57,14 @@ public abstract class GradingReport extends Report {
         gradingCriteria.add(criterion);
     }
 
+    public Instant getDateSubmittedToExaminer(){
+        return this.dateSubmittedToExaminer;
+    }
+
+    public void setDateSubmittedToExaminer(Instant dateSubmittedToExaminer) {
+        this.dateSubmittedToExaminer = dateSubmittedToExaminer;
+    }
+
     public State getState() {
         return state;
     }
diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReportService.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReportService.java
index 507dc3025b..a2c1ac5c4e 100644
--- a/core/src/main/java/se/su/dsv/scipro/report/GradingReportService.java
+++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReportService.java
@@ -7,6 +7,7 @@ import se.su.dsv.scipro.system.GenericService;
 import se.su.dsv.scipro.system.User;
 import se.su.dsv.scipro.util.Either;
 
+import java.time.Instant;
 import java.util.List;
 
 public interface GradingReportService extends GenericService<GradingReport, Long> {
@@ -24,4 +25,6 @@ public interface GradingReportService extends GenericService<GradingReport, Long
     GradingBasis getGradingBasis(Project project);
 
     GradingBasis updateGradingBasis(Project project, GradingBasis gradingBasis);
+
+    Instant getDateSentToExaminer(Project project);
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java
index 4ed4b2ab9c..b57d2bee0c 100644
--- a/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java
@@ -16,6 +16,7 @@ import jakarta.inject.Inject;
 import jakarta.inject.Named;
 import jakarta.inject.Provider;
 import java.time.Clock;
+import java.time.Instant;
 import java.util.*;
 
 @Named
@@ -92,6 +93,16 @@ public class GradingReportServiceImpl extends AbstractServiceImpl<GradingReport,
         return getGradingBasis(project);
     }
 
+    @Override
+    public Instant getDateSentToExaminer(Project project) {
+        return getSupervisorGradingReports(project)
+                .stream()
+                .map(SupervisorGradingReport::getDateSubmittedToExaminer)
+                .filter(Objects::nonNull)
+                .max(Comparator.naturalOrder())
+                .orElse(null);
+    }
+
     private GradingBasis.Assessment toAssessment(
             Language language,
             GradingCriterion gc) {
diff --git a/core/src/main/resources/META-INF/persistence.xml b/core/src/main/resources/META-INF/persistence.xml
index 6f68a20ae8..fc5f0a5977 100755
--- a/core/src/main/resources/META-INF/persistence.xml
+++ b/core/src/main/resources/META-INF/persistence.xml
@@ -12,6 +12,9 @@
                       transaction-type="RESOURCE_LOCAL">
         <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
         <non-jta-data-source>java:/comp/env/jdbc/sciproDS</non-jta-data-source>
+        <properties>
+            <property name="hibernate.show_sql" value="false"/>
+        </properties>
     </persistence-unit>
 
     <!-- A JPA Persistence Unit used for tests -->
diff --git a/core/src/main/resources/db/migration/V385__grading_report_date_submitted_to_examiner.sql b/core/src/main/resources/db/migration/V385__grading_report_date_submitted_to_examiner.sql
new file mode 100644
index 0000000000..b188b7dbbc
--- /dev/null
+++ b/core/src/main/resources/db/migration/V385__grading_report_date_submitted_to_examiner.sql
@@ -0,0 +1,2 @@
+alter table GradingReport
+    add date_submitted_to_examiner datetime null;
diff --git a/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceImplTest.java b/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceImplTest.java
index 21032ade4b..339b24080e 100644
--- a/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceImplTest.java
+++ b/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceImplTest.java
@@ -11,8 +11,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
 import se.su.dsv.scipro.forum.dataobjects.ForumPost;
 import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState;
 import se.su.dsv.scipro.forum.dataobjects.ForumThread;
-import se.su.dsv.scipro.forummail.ForumMailSettingsService;
-import se.su.dsv.scipro.mail.MailEventService;
 import se.su.dsv.scipro.system.User;
 import se.su.dsv.scipro.test.ForumBuilder;
 import se.su.dsv.scipro.test.UserBuilder;
@@ -35,10 +33,6 @@ public class BasicForumServiceImplTest {
     @Mock
     private ForumPostRepository postRepository;
     @Mock
-    private MailEventService mailEventService;
-    @Mock
-    private ForumMailSettingsService mailSettingsService;
-    @Mock
     private EventBus eventBus;
     @InjectMocks
     private BasicForumServiceImpl basicForumService;
@@ -93,23 +87,20 @@ public class BasicForumServiceImplTest {
     }
 
     @Test
-    public void testMarkThreadRead() {
-        when(readStateRepository.find(any(User.class), any(ForumPost.class))).thenReturn(new ForumPostReadState());
-        when(readStateRepository.save(isA(ForumPostReadState.class))).thenAnswer(AdditionalAnswers.returnsFirstArg());
-
+    public void testMarkThreadReadPostsEvent() {
         User user = new User();
         ForumPost post = new ForumPost();
+        post.setContent("post 1");
         ForumPost post2 = new ForumPost();
+        post2.setContent("post 2");
         ForumThread forumThread = new ForumThread();
         forumThread.addPost(post);
         forumThread.addPost(post2);
 
         basicForumService.setThreadRead(user, forumThread, true);
 
-        ArgumentCaptor<ForumPostReadState> captor = ArgumentCaptor.forClass(ForumPostReadState.class);
-        verify(readStateRepository, times(2)).save(captor.capture());
-
-        assertTrue(captor.getValue().isRead(), "Did not save correct read state");
+        verify(eventBus).post(new ForumPostReadEvent(post, user));
+        verify(eventBus).post(new ForumPostReadEvent(post2, user));
     }
 
     @Test
@@ -181,8 +172,8 @@ public class BasicForumServiceImplTest {
         verify(eventBus).post(captor.capture());
 
         ForumPostReadEvent event = captor.getValue();
-        assertEquals(event.getPost(), post);
-        assertEquals(event.getUser(), user);
+        assertEquals(event.post(), post);
+        assertEquals(event.user(), user);
     }
 
     @Test
diff --git a/core/src/test/java/se/su/dsv/scipro/match/IdeaServiceImplTest.java b/core/src/test/java/se/su/dsv/scipro/match/IdeaServiceImplTest.java
index 8672081365..c46e2bdc48 100755
--- a/core/src/test/java/se/su/dsv/scipro/match/IdeaServiceImplTest.java
+++ b/core/src/test/java/se/su/dsv/scipro/match/IdeaServiceImplTest.java
@@ -204,7 +204,12 @@ public class IdeaServiceImplTest {
         when(applicationPeriodService.getTypesForStudent(applicationPeriod, student))
                 .thenReturn(List.of(bachelor));
 
-        assertPair(true, SELECTED_IDEA + idea.getTitle(), ideaService.validateStudentAcceptance(idea, student, coAuthor, applicationPeriod));
+        Pair<Boolean, String> acceptance = ideaService.validateStudentAcceptance(
+                idea,
+                student,
+                coAuthor,
+                applicationPeriod);
+        assertTrue(acceptance.getHead());
     }
 
     @Test
diff --git a/owasp.xml b/owasp.xml
index bbf57a768c..d851f615c4 100644
--- a/owasp.xml
+++ b/owasp.xml
@@ -51,4 +51,18 @@
         </notes>
         <cve>CVE-2023-35116</cve>
     </suppress>
+    <suppress>
+        <notes>
+            This is a complete nonsense vulnerability. Some automated tool has
+            gone completely bananas.
+        </notes>
+        <cve>CVE-2024-22949</cve>
+    </suppress>
+    <suppress>
+        <notes>
+            This is a complete nonsense vulnerability. Some automated tool has
+            gone completely bananas.
+        </notes>
+        <cve>CVE-2023-52070</cve>
+    </suppress>
 </suppressions>
diff --git a/view/pom.xml b/view/pom.xml
index 1321b7ce57..e3a1248be5 100644
--- a/view/pom.xml
+++ b/view/pom.xml
@@ -64,6 +64,11 @@
                     <groupId>com.lowagie</groupId>
                     <artifactId>itext</artifactId>
                 </exclusion>
+                <exclusion>
+                    <!-- until a new version containing https://github.com/wicketstuff/core/pull/873 is released -->
+                    <groupId>org.bouncycastle</groupId>
+                    <artifactId>bcprov-jdk18on</artifactId>
+                </exclusion>
             </exclusions>
         </dependency>
         <dependency>
diff --git a/view/src/main/java/se/su/dsv/scipro/SciProApplication.java b/view/src/main/java/se/su/dsv/scipro/SciProApplication.java
index 978a16437f..e5e2f46932 100755
--- a/view/src/main/java/se/su/dsv/scipro/SciProApplication.java
+++ b/view/src/main/java/se/su/dsv/scipro/SciProApplication.java
@@ -5,6 +5,7 @@ import org.apache.wicket.*;
 import org.apache.wicket.authorization.strategies.CompoundAuthorizationStrategy;
 import org.apache.wicket.csp.CSPDirective;
 import org.apache.wicket.csp.CSPDirectiveSrcValue;
+import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.resource.JQueryResourceReference;
@@ -24,6 +25,7 @@ import se.su.dsv.scipro.checklists.AdminChecklistPage;
 import se.su.dsv.scipro.checklists.AdminEditChecklistTemplatePage;
 import se.su.dsv.scipro.checklists.ProjectViewChecklistPage;
 import se.su.dsv.scipro.checklists.SupervisorViewChecklistPage;
+import se.su.dsv.scipro.components.DisableSubmitButtonsOnSubmit;
 import se.su.dsv.scipro.examiner.pages.ExaminerStartPage;
 import se.su.dsv.scipro.finalseminar.*;
 import se.su.dsv.scipro.finalthesis.SupervisorFinalThesisListingPage;
@@ -80,6 +82,7 @@ import se.su.dsv.scipro.util.AdditionalExceptionLogger;
 import jakarta.inject.Inject;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 
 public class SciProApplication extends LifecycleManagedWebApplication {
@@ -106,6 +109,12 @@ public class SciProApplication extends LifecycleManagedWebApplication {
                 return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             }
         });
+        converterLocator.set(ZonedDateTime.class, new LocalDateTimeConverter() {
+            @Override
+            protected DateTimeFormatter getDateTimeFormatter() {
+                return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            }
+        });
         return converterLocator;
     }
 
@@ -150,6 +159,12 @@ public class SciProApplication extends LifecycleManagedWebApplication {
                 .add(CSPDirective.IMG_SRC, "data:");
 
         WicketWebjars.install(this);
+
+        getComponentInstantiationListeners().add(component -> {
+            if (component instanceof Form) {
+                component.add(new DisableSubmitButtonsOnSubmit());
+            }
+        });
     }
 
     private void mountForumPage() {
diff --git a/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.html b/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.html
index 361716a247..96e62706e2 100644
--- a/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.html
+++ b/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.html
@@ -22,8 +22,10 @@
                 <dt>Research area</dt>
                 <dd wicket:id="research_area"></dd>
 
-                <dt>Language</dt>
-                <dd wicket:id="language"></dd>
+                <wicket:enclosure>
+                    <dt>Language</dt>
+                    <dd wicket:id="language"></dd>
+                </wicket:enclosure>
 
                 <wicket:enclosure>
                     <dt>Reviewer requested at</dt>
diff --git a/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.java b/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.java
index 3ff4d5de55..3d137d35b0 100644
--- a/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/admin/pages/AdminAssignReviewerPage.java
@@ -84,7 +84,13 @@ public class AdminAssignReviewerPage extends AbstractAdminProjectPage {
             add(new Label("title", projectModel.map(Project::getTitle)));
             add(new Label("research_area", projectModel.map(Project::getResearchArea).map(ResearchArea::getTitle)));
             add(new UserLinkPanel("supervisor", projectModel.map(Project::getHeadSupervisor)));
-            add(new EnumLabel<>("language", projectModel.map(Project::getLanguage)));
+            add(new EnumLabel<>("language", projectModel.map(Project::getLanguage)){
+                @Override
+                protected void onConfigure() {
+                    super.onConfigure();
+                    setVisible(getDefaultModelObject() != null);
+                }
+            });
             add(new ViewAttachmentPanel("rough_draft", roughDraftApproval.map(RoughDraftApproval::getCurrentThesis).map(FileReference::getFileDescription)));
             add(new DateLabel("requested_at", roughDraftApproval.map(RoughDraftApproval::getCurrentDecision).map(Decision::getRequested), DateStyle.DATETIME) {
                 @Override
diff --git a/view/src/main/java/se/su/dsv/scipro/components/DisableSubmitButtonsOnSubmit.java b/view/src/main/java/se/su/dsv/scipro/components/DisableSubmitButtonsOnSubmit.java
new file mode 100644
index 0000000000..3a98b9e500
--- /dev/null
+++ b/view/src/main/java/se/su/dsv/scipro/components/DisableSubmitButtonsOnSubmit.java
@@ -0,0 +1,30 @@
+package se.su.dsv.scipro.components;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnEventHeaderItem;
+import org.apache.wicket.markup.html.form.Form;
+
+/**
+ * Disables all elements with {@code [type=submit]}
+ */
+public class DisableSubmitButtonsOnSubmit extends Behavior {
+    @Override
+    public void bind(Component component) {
+        super.bind(component);
+        if (!(component instanceof Form<?>)) {
+            throw new RuntimeException("Can only be used on Form components");
+        }
+    }
+
+    @Override
+    public void renderHead(Component component, IHeaderResponse response) {
+        super.renderHead(component, response);
+        final String javaScript = "const submitButtons = event.target.querySelectorAll(\"[type=submit]\");\n" +
+                                  "for (const button of submitButtons) {\n" +
+                                  "    button.disabled = true;\n" +
+                                  "}\n";
+        response.render(OnEventHeaderItem.forComponent(component, "submit", javaScript));
+    }
+}
\ No newline at end of file
diff --git a/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel$ApprovedPanel.html b/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel$ApprovedPanel.html
index c48ae4331c..d9558b986f 100644
--- a/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel$ApprovedPanel.html
+++ b/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel$ApprovedPanel.html
@@ -4,7 +4,11 @@
 <wicket:panel>
     <strong>Status:</strong> <span wicket:id="status"></span>
     <br>
-    <span wicket:id="approvedDate"></span><br>
+    Approved by supervisor: <span wicket:id="approvedDate"></span><br>
+    <wicket:enclosure>
+        Submitted to examiner: <span wicket:id="submittedToExaminerTimestamp"></span><br>
+    </wicket:enclosure>
+    <br>
 </wicket:panel>
 </body>
 </html>
\ No newline at end of file
diff --git a/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel.java b/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel.java
index c05c498e6b..008bf88212 100644
--- a/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesisPanel.java
@@ -3,6 +3,7 @@ package se.su.dsv.scipro.finalthesis;
 import org.apache.wicket.feedback.FencedFeedbackPanel;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.EnumLabel;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.EnumChoiceRenderer;
 import org.apache.wicket.markup.html.form.Form;
@@ -19,6 +20,7 @@ import se.su.dsv.scipro.finalseminar.FinalSeminarService;
 import se.su.dsv.scipro.forum.pages.ProjectForumBasePage;
 import se.su.dsv.scipro.project.Project;
 import se.su.dsv.scipro.reflection.ReflectionService;
+import se.su.dsv.scipro.report.GradingReportService;
 import se.su.dsv.scipro.security.auth.ProjectModuleComponent;
 import se.su.dsv.scipro.session.SciProSession;
 import se.su.dsv.scipro.system.ProjectModule;
@@ -26,6 +28,8 @@ import se.su.dsv.scipro.util.PageParameterKeys;
 
 import jakarta.inject.Inject;
 
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.util.List;
 
 import static se.su.dsv.scipro.finalthesis.FinalThesis.Status;
@@ -40,6 +44,7 @@ public class FinalThesisPanel extends GenericPanel<Project> {
     public static final String APPROVED_PANEL = "approvedPanel";
     public static final String APPROVED_DATE = "approvedDate";
     public static final String NO_DECISION_PANEL = "noDecisionPanel";
+    public static final String SUBMITTED_TO_EXAMINER_TIMESTAMP = "submittedToExaminerTimestamp";
 
     @Inject
     private FinalThesisService finalThesisService;
@@ -49,6 +54,8 @@ public class FinalThesisPanel extends GenericPanel<Project> {
     private PublishingConsentService publishingConsentService;
     @Inject
     private ReflectionService reflectionService;
+    @Inject
+    private GradingReportService gradingReportService;
 
     public FinalThesisPanel(String id, IModel<Project> project) {
         super(id, project);
@@ -96,9 +103,17 @@ public class FinalThesisPanel extends GenericPanel<Project> {
     private class ApprovedPanel extends Panel {
         public ApprovedPanel(String id) {
             super(id);
-
             add(new EnumLabel<>("status", getModel().map(Project::getProjectStatus)));
             add(new DateLabel(APPROVED_DATE, getFinalThesis().map(FinalThesis::getDateApproved)));
+            IModel<ZonedDateTime> submittedToExaminerTimestamp = LoadableDetachableModel.of(() -> gradingReportService.getDateSentToExaminer(getModelObject()))
+                    .map(instant -> instant.atZone(ZoneId.systemDefault()));
+            add(new Label(SUBMITTED_TO_EXAMINER_TIMESTAMP, submittedToExaminerTimestamp) {
+                @Override
+                protected void onConfigure() {
+                    super.onConfigure();
+                    setVisible(submittedToExaminerTimestamp.getObject() != null);
+                }
+            });
         }
 
         @Override
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/CriteriaPanel.java b/view/src/main/java/se/su/dsv/scipro/grading/CriteriaPanel.java
index b017bbc5c0..2dcfa3420a 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/CriteriaPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/CriteriaPanel.java
@@ -246,7 +246,9 @@ public class CriteriaPanel extends GenericPanel<SupervisorGradingReport> {
 
         @Override
         public void setObject(GradingCriterionPoint object) {
-            criterionIModel.getObject().setPoints(object.getPoint());
+            if (object != null) {
+                criterionIModel.getObject().setPoints(object.getPoint());
+            }
         }
     }
 
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/GradingBasisPanel.utf8.properties b/view/src/main/java/se/su/dsv/scipro/grading/GradingBasisPanel.utf8.properties
index 4067415139..16048d4403 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/GradingBasisPanel.utf8.properties
+++ b/view/src/main/java/se/su/dsv/scipro/grading/GradingBasisPanel.utf8.properties
@@ -1,4 +1,4 @@
 save = Save
 overall_motivation = Overall motivation
 grading_basis_updated = Assessment saved at ${}
-rejection_comment_feedback.Required = Rejection commend feedback must be provided.
+rejection_comment_feedback.Required = Rejection comment feedback must be provided.
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.html b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.html
similarity index 98%
rename from view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.html
rename to view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.html
index ef28cf7891..1e31a1ac55 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.html
+++ b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.html
@@ -36,6 +36,7 @@
     <ul>
         <li wicket:id="status_final_thesis"></li>
         <li wicket:id="status_plagiarism"></li>
+        <li wicket:id="status_publication_metadata"></li>
         <li>
             <div wicket:id="status_grading_basis">></div>
             <ul wicket:id="grading_basis_missing">
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.java b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.java
similarity index 93%
rename from view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.java
rename to view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.java
index c1bc061ead..d76881782b 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.java
@@ -33,8 +33,10 @@ import java.util.List;
 import java.util.Objects;
 import java.util.function.Predicate;
 
-public class IndividualAuthorAssessment extends GenericPanel<User> {
+public class IndividualAuthorAssessmentPanel extends GenericPanel<User> {
 
+    @Inject
+    private NationalSubjectCategoryService nationalSubjectCategoryService;
     @Inject
     private GradingReportService gradingReportService;
     @Inject
@@ -43,10 +45,12 @@ public class IndividualAuthorAssessment extends GenericPanel<User> {
     private FinalThesisService finalThesisService;
     @Inject
     private FinalSeminarService finalSeminarService;
+    @Inject
+    private PublicationMetadataService publicationMetadataService;
 
     private final IModel<Project> projectModel;
 
-    public IndividualAuthorAssessment(String id, IModel<Project> projectModel, IModel<User> authorModel) {
+    public IndividualAuthorAssessmentPanel(String id, IModel<Project> projectModel, IModel<User> authorModel) {
         super(id, authorModel);
         this.projectModel = projectModel;
 
@@ -73,6 +77,10 @@ public class IndividualAuthorAssessment extends GenericPanel<User> {
         redGreen("status_plagiarism", hasSubmittedPlagiarismAnalysis,
                 "must_perform_plagiarism_check",
                 "plagiarism_check_performed");
+        IModel<Boolean> hasSuppliedPublicationMetadata = Model.of(publicationMetadataService.hasSuppliedPublicationMetadata(projectModel.getObject(), nationalSubjectCategoryService.listCategories().isEmpty()));
+        redGreen("status_publication_metadata", hasSuppliedPublicationMetadata,
+                "must_supply_publication_metadata",
+                "publication_metadata_supplied");
         IModel<Boolean> hasFilledInGradingBasis = gradingReport.map(this::gradingBasisDone);
         redGreen("status_grading_basis", hasFilledInGradingBasis,
                 "grading_basis_must_meet_minimum_requirements",
@@ -169,6 +177,7 @@ public class IndividualAuthorAssessment extends GenericPanel<User> {
                 super.onConfigure();
                 setVisible(hasApprovedFinalThesis.getObject()
                         && hasSubmittedPlagiarismAnalysis.getObject()
+                        && hasSuppliedPublicationMetadata.getObject()
                         && hasFilledInGradingBasis.getObject()
                         && hasFilledInIndividualAssessment.getObject());
             }
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.utf8.properties b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.utf8.properties
similarity index 93%
rename from view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.utf8.properties
rename to view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.utf8.properties
index d70f2b382d..29f7ff0ecc 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessment.utf8.properties
+++ b/view/src/main/java/se/su/dsv/scipro/grading/IndividualAuthorAssessmentPanel.utf8.properties
@@ -4,6 +4,8 @@ must_approve_final_thesis = You must approve the final thesis.
 final_thesis_approved = Final thesis approved.
 must_perform_plagiarism_check = You have to check the text matching report and perform a plagiarism analysis.
 plagiarism_check_performed = Plagiarism analysis submitted.
+must_supply_publication_metadata = You must supply publication metadata.
+publication_metadata_supplied = Publication metadata supplied.
 grading_basis_must_meet_minimum_requirements = General criteria not met.
 grading_basis_minimum_requirements_met = General criteria met.
 individual_assessment_must_meet_minimum_requirements = Not all individual criteria are met.
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.html b/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.html
index 23a1b6ca0b..416e983b21 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.html
+++ b/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.html
@@ -3,12 +3,12 @@
 <body>
 <wicket:panel>
     <div class="mb-3">
-        <label class="form-label" for="abstract_en">Abstract (English)</label>
+        <label class="form-label" for="abstract_en">Abstract (English) (required)</label>
         <textarea class="form-control" id="abstract_en" wicket:id="abstract_en"></textarea>
     </div>
     <wicket:enclosure>
         <div class="mb-3">
-            <label class="form-label" for="abstract_sv">Abstract (Swedish)</label>
+            <label class="form-label" for="abstract_sv">Abstract (Swedish) (required)</label>
             <textarea class="form-control" id="abstract_sv" wicket:id="abstract_sv"></textarea>
         </div>
     </wicket:enclosure>
@@ -22,11 +22,13 @@
             <input class="form-control" id="keywords_sv" wicket:id="keywords_sv">
         </div>
     </wicket:enclosure>
-    <div class="mb-3">
-        <label class="form-label" for="national_subject_category">National subject category</label>
-        <select class="form-select" id="national_subject_category" wicket:id="national_subject_category">
-        </select>
-    </div>
+    <wicket:enclosure>
+        <div class="mb-3">
+            <label class="form-label" for="national_subject_category">National subject category (required)</label>
+            <select class="form-select" id="national_subject_category" wicket:id="national_subject_category">
+            </select>
+        </div>
+    </wicket:enclosure>
 </wicket:panel>
 </body>
 </html>
\ No newline at end of file
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.java b/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.java
index 095a1b0dbd..aea827cb11 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/PublicationMetadataFormComponentPanel.java
@@ -45,6 +45,7 @@ public class PublicationMetadataFormComponentPanel extends GenericPanel<Publicat
                     .ifPresent(nationalSubjectCategoryChoice::setDefaultModelObject);
         }
         nationalSubjectCategoryChoice.setNullValid(true);
+        nationalSubjectCategoryChoice.setVisible(!availableCategories.getObject().isEmpty());
         add(nationalSubjectCategoryChoice);
     }
 
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.html b/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.html
index a460fb8bf4..ed018da808 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.html
+++ b/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.html
@@ -2,9 +2,20 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org" lang="en">
 <body>
 <wicket:panel>
-    <wicket:enclosure child="send">
+    <wicket:enclosure child="form">
         <div wicket:id="feedback"></div>
-        <button type="button" class="btn btn-success scrollSneak" wicket:id="send">Send thesis for examination</button>
+        <form wicket:id="form">
+            <div class="mb-3">
+                <label for="examinationDate" class="form-label">Examination date</label>
+                <input type="text" class="form-control" id="examinationDate" wicket:id="examinationDate" required>
+                <small class="form-text">
+                    The examination date is suggested based on the last student activity (submitted final thesis,
+                    opposition, or active participation). You should only change this date if the last activity was at a
+                    different date.
+                </small>
+            </div>
+            <button type="submit" class="btn btn-success scrollSneak" wicket:id="send">Send thesis for examination</button>
+        </form>
     </wicket:enclosure>
     <p class="card-text" wicket:id="already_sent">
         <span class="fa fa-check text-success"></span>
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.java b/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.java
index ea08ce958d..3ccf7680a8 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/SendToExaminer.java
@@ -2,10 +2,13 @@ package se.su.dsv.scipro.grading;
 
 import org.apache.wicket.feedback.FencedFeedbackPanel;
 import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.markup.html.panel.GenericPanel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
-import se.su.dsv.scipro.components.ConfirmationLink;
+import org.apache.wicket.model.Model;
+import se.su.dsv.scipro.components.BootstrapDatePicker;
 import se.su.dsv.scipro.daisyExternal.http.DaisyAPI;
 import se.su.dsv.scipro.file.FileDescription;
 import se.su.dsv.scipro.file.FileService;
@@ -33,6 +36,7 @@ import se.su.dsv.scipro.system.Language;
 import se.su.dsv.scipro.system.ResearchArea;
 import se.su.dsv.scipro.system.User;
 import se.su.dsv.scipro.util.Either;
+import se.su.dsv.scipro.util.JavascriptEventConfirmation;
 
 import jakarta.inject.Inject;
 import java.time.LocalDate;
@@ -75,10 +79,16 @@ public class SendToExaminer extends GenericPanel<Project> {
         super(id, projectModel);
 
         needsSending = LoadableDetachableModel.of(() -> hasGradedExaminationWithoutSuggestion(authorModel.getObject()));
-        add(new ConfirmationLink<>("send", authorModel, confirmationMessage) {
+
+        IModel<LocalDate> examinationDate = new Model<>();
+        FinalThesis finalThesis = finalThesisService.findByProject(projectModel.getObject());
+        examinationDate.setObject(getExaminationDate(authorModel.getObject(), projectModel.getObject(), finalThesis));
+
+        Form<Void> form = new Form<>("form") {
             @Override
-            public void onClick() {
-                sendToExaminer(getModelObject());
+            protected void onSubmit() {
+                super.onSubmit();
+                sendToExaminer(authorModel.getObject(), examinationDate.getObject());
             }
 
             @Override
@@ -86,7 +96,20 @@ public class SendToExaminer extends GenericPanel<Project> {
                 super.onConfigure();
                 setVisible(needsSending.getObject());
             }
-        });
+        };
+        add(form);
+
+        WebMarkupContainer sendButton = new WebMarkupContainer("send");
+        if (confirmationMessage.getObject() != null) {
+            sendButton.add(new JavascriptEventConfirmation("click", confirmationMessage));
+        }
+        form.add(sendButton);
+
+        TextField<LocalDate> examinationDateField = new TextField<>("examinationDate", examinationDate, LocalDate.class);
+        examinationDateField.setRequired(true);
+        examinationDateField.add(new BootstrapDatePicker());
+        form.add(examinationDateField);
+
         add(new WebMarkupContainer("already_sent") {
             @Override
             protected void onConfigure() {
@@ -101,6 +124,10 @@ public class SendToExaminer extends GenericPanel<Project> {
         String token = getSession().getMetaData(OAuth.TOKEN);
         Project project = getModelObject();
         List<Examination> examinations = gradingService.getExaminations(token, project.getIdentifier(), author.getIdentifier());
+        if (examinations == null) {
+            // if we can't tell assume it is not sent
+            return true;
+        }
         for (Examination examination : examinations) {
             if (examination.hasManyPassingGrades()) {
                 Either<GetGradeError, Optional<Result>> result = gradingService.getResult(token, project.getIdentifier(), author.getIdentifier(), examination.id());
@@ -112,7 +139,7 @@ public class SendToExaminer extends GenericPanel<Project> {
         return false;
     }
 
-    private void sendToExaminer(User author) {
+    private void sendToExaminer(User author, LocalDate examinationDate) {
         checkStepsMissing();
         if (hasErrorMessage()) {
             // some steps have not been completed
@@ -125,6 +152,10 @@ public class SendToExaminer extends GenericPanel<Project> {
             return;
         }
         List<Examination> examinations = gradingService.getExaminations(token, project.getIdentifier(), author.getIdentifier());
+        if (examinations == null) {
+            getSession().error("Failed to get the examination setup for " + author.getFullName());
+            return;
+        }
         List<Examination> gradedExaminations = examinations
                 .stream()
                 .filter(Examination::hasManyPassingGrades)
@@ -138,7 +169,7 @@ public class SendToExaminer extends GenericPanel<Project> {
         } else if (gradedExaminations.isEmpty()) {
             getSession().info("Nothing to report on " + author.getFullName());
         } else {
-            sendSuggestion(project, author, gradedExaminations.get(0));
+            sendSuggestion(project, author, gradedExaminations.get(0), examinationDate);
         }
         needsSending.detach();
     }
@@ -176,7 +207,7 @@ public class SendToExaminer extends GenericPanel<Project> {
         return missing;
     }
 
-    private void sendSuggestion(Project project, User author, Examination examination) {
+    private void sendSuggestion(Project project, User author, Examination examination, LocalDate examinationDate) {
         String token = getSession().getMetaData(OAuth.TOKEN);
 
         Either<GetGradeError, Optional<Result>> currentResult
@@ -197,7 +228,6 @@ public class SendToExaminer extends GenericPanel<Project> {
         GradeCalculator gradeCalculator = gradeCalculatorService.getSupervisorCalculator(project);
         SupervisorGradingReport supervisorGradingReport = gradingReportService.getSupervisorGradingReport(getModelObject(), author);
         GradingReport.Grade grade = gradeCalculator.getGrade(supervisorGradingReport);
-        LocalDate examinationDate = getExaminationDate(author, project, finalThesis);
         Either<ReportGradeError, Void> reported =
                 gradingService.reportGrade(
                         token,
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingPage.java b/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingPage.java
index 040e444e5a..695354d4c9 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingPage.java
@@ -56,7 +56,8 @@ public class SupervisorGradingPage extends AbstractSupervisorProjectDetailsPage
             @Override
             protected void populateItem(final ListItem<User> item) {
                 item.add(new UserLabel("authorName", item.getModel()));
-                final IModel<List<Examination>> examinations = SupervisorGradingPage.this.getExaminations(item.getModel());
+                final IModel<List<Examination>> examinations = SupervisorGradingPage.this.getExaminations(item.getModel())
+                        .orElseGet(Collections::emptyList);
 
                 final IModel<List<Examination>> nonGradedExaminations = getSpecificExaminations(examinations, false);
                 item.add(new NonGradedPanel(
diff --git a/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingReportPage.java b/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingReportPage.java
index 39bb707829..b4590290a6 100644
--- a/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingReportPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/grading/SupervisorGradingReportPage.java
@@ -46,6 +46,8 @@ import java.util.Set;
 
 @ProjectModuleComponent(ProjectModule.GRADING)
 public class SupervisorGradingReportPage extends AbstractSupervisorProjectDetailsPage {
+    @Inject
+    private NationalSubjectCategoryService nationalSubjectCategoryService;
     @Inject
     private GeneralSystemSettingsService generalSystemSettingsService;
     @Inject
@@ -76,11 +78,7 @@ public class SupervisorGradingReportPage extends AbstractSupervisorProjectDetail
                         .isPresent();
         add(newGreenHighlight("step_plagiarism", hasCheckedForPlagiarism, new ResourceModel("step_plagiarism")));
 
-        IModel<Boolean> hasProvidedPublicationMetadata =
-                projectModel.map(publicationMetadataService::getByProject)
-                        .filter(metadata -> notBlank(metadata.getAbstractEnglish()) || notBlank(metadata.getAbstractSwedish()))
-                        .filter(metadata -> notBlank(metadata.getKeywordsEnglish()) || notBlank(metadata.getKeywordsSwedish()))
-                        .isPresent();
+        IModel<Boolean> hasProvidedPublicationMetadata = Model.of(publicationMetadataService.hasSuppliedPublicationMetadata(projectModel.getObject(), nationalSubjectCategoryService.listCategories().isEmpty()));
         add(newGreenHighlight("step_publication_metadata", hasProvidedPublicationMetadata, new ResourceModel("step_publication_metadata")));
 
         IModel<List<SupervisorGradingReport>> gradingReports = LoadableDetachableModel.of(() ->
@@ -131,7 +129,7 @@ public class SupervisorGradingReportPage extends AbstractSupervisorProjectDetail
                 .map(author -> new DetachableServiceModel<>(userService, author))
                 .map(authorModel -> createTab(
                         authorModel.map(User::getFullName),
-                        panelId -> new IndividualAuthorAssessment(panelId, projectModel, authorModel)))
+                        panelId -> new IndividualAuthorAssessmentPanel(panelId, projectModel, authorModel)))
                 .toList();
         tabs.addAll(authorTabs);
 
@@ -151,10 +149,6 @@ public class SupervisorGradingReportPage extends AbstractSupervisorProjectDetail
         add(new ExaminerTimelinePanel("examiner_timeline", projectModel));
     }
 
-    private boolean notBlank(String s) {
-        return s != null && !s.isBlank();
-    }
-
     private Component newGreenHighlight(String id, IModel<Boolean> completed, IModel<String> text) {
         return new RedGreenLabel(id, completed, text, text);
     }
@@ -176,6 +170,10 @@ public class SupervisorGradingReportPage extends AbstractSupervisorProjectDetail
         String token = getSession().getMetaData(OAuth.TOKEN);
         Project project = projectModel.getObject();
         List<Examination> examinations = gradingService.getExaminations(token, project.getIdentifier(), author.getIdentifier());
+        if (examinations == null) {
+            // if grading service is down, assume not sent
+            return false;
+        }
         for (Examination examination : examinations) {
             if (examination.hasManyPassingGrades()) {
                 Either<GetGradeError, Optional<Result>> result = gradingService.getResult(token, project.getIdentifier(), author.getIdentifier(), examination.id());
diff --git a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPage.html b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPage.html
index 7a47688ae3..01e2105bc6 100755
--- a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPage.html
+++ b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPage.html
@@ -1,9 +1,10 @@
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org">
 <body>
-<wicket:extend> 
-<div class="row"></div>
-    <div wicket:id="submissionPanel"></div>
+<wicket:extend>
+    <div class="row">
+        <div class="col-lg-8 col-xl-6" wicket:id="submissionPanel"></div>
+    </div>
 </wicket:extend>
 </body>
 </html>
\ No newline at end of file
diff --git a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.java b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.java
index e94fd1df1b..ebc4a70d71 100755
--- a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.java
@@ -4,6 +4,7 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.*;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
 import org.apache.wicket.markup.html.link.ExternalLink;
@@ -116,7 +117,7 @@ public class ProjectIdeaSubmissionPanel extends GenericPanel<Idea> {
             addResearchAreaAndKeywordsSelection();
             addContract();
             addDeleteButton();
-            add(new Button("save"));
+            add(new Label("save", isNewIdea ? new ResourceModel("save") : new ResourceModel("update")));
         }
 
         @Override
@@ -321,8 +322,13 @@ public class ProjectIdeaSubmissionPanel extends GenericPanel<Idea> {
 
         @Override
         protected void onSubmit() {
-            ideaService.saveStudentIdea(getModelObject(), creator, programDropDownChoice.getModelObject(), new HashSet<>(coAuthorChoice.getModelObject()),
+            Idea idea = ideaService.saveStudentIdea(getModelObject(), creator, programDropDownChoice.getModelObject(), new HashSet<>(coAuthorChoice.getModelObject()),
                     new ArrayList<>(keywords), isNewIdea);
+            if (isNewIdea) {
+                getSession().success(getString("ideaSubmitted", Model.of(idea)));
+            } else {
+                getSession().success(getString("ideaUpdated", Model.of(idea)));
+            }
             setResponsePage(ProjectIdeaStartPage.class);
         }
 
diff --git a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.properties b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.properties
index c11cc14769..f713e10b6b 100644
--- a/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.properties
+++ b/view/src/main/java/se/su/dsv/scipro/match/ProjectIdeaSubmissionPanel.properties
@@ -27,6 +27,10 @@ too.many.authors= Too many authors for a ${name}-idea. May not be more than ${ma
 too.few.authors= Too few authors for a ${name}-idea. Must be at least ${minAuthors} including yourself.
 keywordError= You need to select between 1 and 5 keywords.
 submissionFailed= Idea could not be submitted.
+ideaSubmitted= You have successfully submitted your ${projectType.name} student idea, for the application period \
+  ${applicationPeriod.name}.
+ideaUpdated= You have successfully updated your ${projectType.name} student idea, in the application period \
+  ${applicationPeriod.name}.
 titleInfo= The idea title will become the project title once the idea has been matched to a supervisor and the course started. The title can then only be changed by the supervisor.
 researchAreaInfo= The idea should be connected to a research area.
 languageInfo= The language the thesis will be written in. This will affect many areas of the thesis writing process \
@@ -35,3 +39,5 @@ programInfo= Select the program within the context of which you are doing this i
 programDropDown.nullValid=Not within a program
 you.already.have.an.active.project.on.this.level= You already have an active project on this level.
 partner.already.has.an.active.project.on.this.level= ${fullName} already has an active project on this level.
+save= Submit idea
+update= Update idea
diff --git a/view/src/main/java/se/su/dsv/scipro/match/ProjectMyIdeasPanel.java b/view/src/main/java/se/su/dsv/scipro/match/ProjectMyIdeasPanel.java
index 8c42b37190..9841cbf78a 100755
--- a/view/src/main/java/se/su/dsv/scipro/match/ProjectMyIdeasPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/match/ProjectMyIdeasPanel.java
@@ -106,7 +106,25 @@ public class ProjectMyIdeasPanel extends Panel {
         columns.add(new AbstractColumn<>(Model.of("Status"), "match.status") {
             @Override
             public void populateItem(Item<ICellPopulator<Idea>> item, String id, IModel<Idea> model) {
-                item.add(new StudentIdeaStatusColumnPanel(id, model));
+                item.add(new Label(id, model.map(idea -> switch (idea.getMatchStatus()) {
+                    case UNMATCHED -> "Submitted, waiting for matching by administrator";
+                    case MATCHED -> {
+                        if (applicationPeriodService.courseStartHasPassed(idea.getApplicationPeriod())) {
+                            yield "Matched, project creation delayed. This is under investigation and handled manually. No action needed from you.";
+                        } else {
+                            yield "Matched, awaiting course start date";
+                        }
+                    }
+                    case COMPLETED -> "Matched, project started";
+                    case INACTIVE -> "Inactive";
+                })));
+            }
+        });
+
+        columns.add(new AbstractColumn<>(Model.of("Course start date")) {
+            @Override
+            public void populateItem(Item<ICellPopulator<Idea>> item, String id, IModel<Idea> iModel) {
+                item.add(new Label(id, iModel.map(Idea::getApplicationPeriod).map(ApplicationPeriod::getCourseStartDate)));
             }
         });
 
diff --git a/view/src/main/java/se/su/dsv/scipro/notifications/pages/NotificationLandingPage.java b/view/src/main/java/se/su/dsv/scipro/notifications/pages/NotificationLandingPage.java
index e802947b73..b3b73a4bec 100644
--- a/view/src/main/java/se/su/dsv/scipro/notifications/pages/NotificationLandingPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/notifications/pages/NotificationLandingPage.java
@@ -9,6 +9,7 @@ import se.su.dsv.scipro.activityplan.SupervisorActivityPlanPage;
 import se.su.dsv.scipro.finalseminar.FinalSeminar;
 import se.su.dsv.scipro.finalseminar.ProjectFinalSeminarDetailsPage;
 import se.su.dsv.scipro.finalseminar.ProjectFinalSeminarPage;
+import se.su.dsv.scipro.finalseminar.ProjectOppositionPage;
 import se.su.dsv.scipro.finalseminar.SupervisorFinalSeminarPage;
 import se.su.dsv.scipro.forum.pages.ProjectForumBasePage;
 import se.su.dsv.scipro.forum.pages.SupervisorForumBasePage;
@@ -170,6 +171,9 @@ public class NotificationLandingPage extends WebPage {
             case FIRST_MEETING:
                 defaultSplit.accept(ProjectFirstMeetingPage.class, SupervisorFirstMeetingPage.class);
                 break;
+            case OPPOSITION_FAILED:
+                defaultSplit.accept(ProjectOppositionPage.class, SupervisorProjectDetailsPage.class);
+                break;
             default:
                 // no specific redirect, will default to start page
         }
diff --git a/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.html b/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.html
index 42429c31a0..443adc9faf 100644
--- a/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.html
+++ b/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.html
@@ -15,6 +15,9 @@
     <p wicket:id="final_seminar_done_no_final_thesis_done_has_reflection">
         The final seminar has taken place, your final thesis has been rejected. You need to upload the new version of your final thesis to have your thesis assessed.
     </p>
+    <p wicket:id="author_done_supervisor_not_done">
+        Final thesis and reflection uploaded.
+    </p>
     <p wicket:id="all_done">
         Your thesis project is completed.
     </p>
diff --git a/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.java b/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.java
index c390060c5f..c86cb81149 100644
--- a/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.java
+++ b/view/src/main/java/se/su/dsv/scipro/project/panels/FinalThesisReflectionInstructionsPanel.java
@@ -1,7 +1,5 @@
 package se.su.dsv.scipro.project.panels;
 
-import org.apache.wicket.Component;
-import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.panel.GenericPanel;
 import org.apache.wicket.model.IModel;
@@ -23,14 +21,18 @@ public class FinalThesisReflectionInstructionsPanel extends GenericPanel<Project
     @Inject
     private FinalSeminarService finalSeminarService;
 
+    private final IModel<Boolean> hasSubmittedReflection;
+    private final IModel<Boolean> hasFinalThesis;
+    private final IModel<Boolean> hasHadFinalSeminar;
+
     public FinalThesisReflectionInstructionsPanel(String id, IModel<Project> projectModel) {
         super(id, projectModel);
 
-        IModel<Boolean> hasSubmittedReflection = LoadableDetachableModel.of(() ->
+        hasSubmittedReflection = LoadableDetachableModel.of(() ->
                 reflectionService.getSubmittedReflection(projectModel.getObject(), SciProSession.get().getUser()) != null);
-        IModel<Boolean> hasFinalThesis = LoadableDetachableModel.of(() ->
+        hasFinalThesis = LoadableDetachableModel.of(() ->
                 !finalThesisService.isUploadAllowed(projectModel.getObject()));
-        IModel<Boolean> hasHadFinalSeminar = LoadableDetachableModel.of(() ->
+        hasHadFinalSeminar = LoadableDetachableModel.of(() ->
                 finalSeminarService.hasHadFinalSeminar(projectModel.getObject()));
         add(new WebMarkupContainer("nothing_done") {
             @Override
@@ -60,23 +62,29 @@ public class FinalThesisReflectionInstructionsPanel extends GenericPanel<Project
                 setVisible(hasHadFinalSeminar.getObject() && !hasFinalThesis.getObject() && hasSubmittedReflection.getObject());
             }
         });
+        add(new WebMarkupContainer("author_done_supervisor_not_done") {
+            @Override
+            protected void onConfigure() {
+                super.onConfigure();
+                boolean projectIsCompleted = projectModel.getObject().getProjectStatus() == ProjectStatus.COMPLETED;
+                setVisible(hasHadFinalSeminar.getObject() && hasFinalThesis.getObject() && hasSubmittedReflection.getObject() && !projectIsCompleted);
+            }
+        });
         add(new WebMarkupContainer("all_done") {
             @Override
             protected void onConfigure() {
                 super.onConfigure();
-                setVisible(hasHadFinalSeminar.getObject() && hasFinalThesis.getObject() && hasSubmittedReflection.getObject());
-            }
-        });
-        add(new Behavior() {
-            @Override
-            public void onConfigure(Component component) {
-                super.onConfigure(component);
-                component.setVisible(
-                        !hasHadFinalSeminar.getObject()
-                                || !hasFinalThesis.getObject()
-                                || !hasSubmittedReflection.getObject()
-                                || projectModel.getObject().getProjectStatus() == ProjectStatus.COMPLETED);
+                boolean projectIsCompleted = projectModel.getObject().getProjectStatus() == ProjectStatus.COMPLETED;
+                setVisible(hasHadFinalSeminar.getObject() && hasFinalThesis.getObject() && hasSubmittedReflection.getObject() && projectIsCompleted);
             }
         });
     }
+
+    @Override
+    protected void onDetach() {
+        hasFinalThesis.detach();
+        hasSubmittedReflection.detach();
+        hasHadFinalSeminar.detach();
+        super.onDetach();
+    }
 }
diff --git a/view/src/main/java/se/su/dsv/scipro/reviewer/RoughDraftApprovalDecisionPage.java b/view/src/main/java/se/su/dsv/scipro/reviewer/RoughDraftApprovalDecisionPage.java
index 52a1455d59..b87df07354 100644
--- a/view/src/main/java/se/su/dsv/scipro/reviewer/RoughDraftApprovalDecisionPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/reviewer/RoughDraftApprovalDecisionPage.java
@@ -228,8 +228,8 @@ public class RoughDraftApprovalDecisionPage extends ReviewerPage {
             for (User author : authors.getObject()) {
                 try {
                     List<Examination> examinations = getPassFailExaminations(author);
-                    if (examinations.isEmpty()) {
-                        // an empty list is returned if there's an error from the grading service
+                    if (examinations == null) {
+                        // null is returned if there's an error from the grading service
                         return false;
                     }
                 } catch (RuntimeException e) {
diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/pages/SupervisorViewGroupThreadPage.java b/view/src/main/java/se/su/dsv/scipro/supervisor/pages/SupervisorViewGroupThreadPage.java
index 80bc74cf2a..840930e001 100644
--- a/view/src/main/java/se/su/dsv/scipro/supervisor/pages/SupervisorViewGroupThreadPage.java
+++ b/view/src/main/java/se/su/dsv/scipro/supervisor/pages/SupervisorViewGroupThreadPage.java
@@ -1,6 +1,5 @@
 package se.su.dsv.scipro.supervisor.pages;
 
-import com.google.common.base.Throwables;
 import org.apache.wicket.Component;
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
@@ -9,8 +8,6 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorMyGroups;
-import se.su.dsv.scipro.file.FileService;
-import se.su.dsv.scipro.forum.BasicForumService;
 import se.su.dsv.scipro.forum.GroupForumService;
 import se.su.dsv.scipro.forum.dataobjects.GroupThread;
 import se.su.dsv.scipro.forum.dataobjects.ForumThread;
@@ -19,16 +16,11 @@ import se.su.dsv.scipro.group.GroupForumThread;
 import se.su.dsv.scipro.util.PageParameterKeys;
 
 import jakarta.inject.Inject;
-import java.sql.SQLIntegrityConstraintViolationException;
 
 public class SupervisorViewGroupThreadPage extends AbstractSupervisorGroupPage implements MenuHighlightSupervisorMyGroups {
 
     @Inject
     private GroupForumService groupForumService;
-    @Inject
-    private BasicForumService basicForumService;
-    @Inject
-    private FileService fileDescriptionService;
 
     public SupervisorViewGroupThreadPage(final PageParameters parameters) {
         super(parameters);
@@ -48,21 +40,6 @@ public class SupervisorViewGroupThreadPage extends AbstractSupervisorGroupPage i
 
         add(new FeedbackPanel("feedback"));
 
-        try {
-            basicForumService.setThreadRead(loggedInUser(), groupThread.getForumThread(), true);
-        } catch (RuntimeException e) {
-            Throwable rootCause = Throwables.getRootCause(e);
-            if (rootCause instanceof SQLIntegrityConstraintViolationException) {
-                // One specific user keep getting weird constraint integrity violations.
-                // All attempts at replication have failed.
-                // To get rid of the error we catch it and ignore it. If we failed to
-                // mark a thread as read because it is already read, it does not matter.
-            }
-            else {
-                throw e;
-            }
-        }
-
         add(new ViewForumThreadPanel<>("thread", groupThreadModel, new GroupForumThread(groupForumService)) {
             @Override
             protected Component newBackLink(final String id) {
diff --git a/view/src/test/java/se/su/dsv/scipro/finalseminar/SeminarThesisPanelTest.java b/view/src/test/java/se/su/dsv/scipro/finalseminar/SeminarThesisPanelTest.java
index ba32119328..ac2a37fde4 100644
--- a/view/src/test/java/se/su/dsv/scipro/finalseminar/SeminarThesisPanelTest.java
+++ b/view/src/test/java/se/su/dsv/scipro/finalseminar/SeminarThesisPanelTest.java
@@ -3,7 +3,6 @@ package se.su.dsv.scipro.finalseminar;
 import org.apache.wicket.Component;
 import org.apache.wicket.feedback.FencedFeedbackPanel;
 import org.apache.wicket.model.Model;
-import org.jfree.data.time.Month;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -23,6 +22,7 @@ import se.su.dsv.scipro.test.ObjectMother;
 import se.su.dsv.scipro.test.UserBuilder;
 
 import java.time.LocalDate;
+import java.time.Month;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.Date;
@@ -79,7 +79,7 @@ public class SeminarThesisPanelTest extends SciProTest {
     @Test
     public void DeadlineInformationContainsDeadlineDate() {
         // given
-        ZonedDateTime seminarDate = ZonedDateTime.of(2012, Month.APRIL, 21, 10, 10, 0, 0, ZoneId.systemDefault());
+        ZonedDateTime seminarDate = ZonedDateTime.of(2012, Month.APRIL.getValue(), 21, 10, 10, 0, 0, ZoneId.systemDefault());
         int daysAhead = 10;
 
         FinalSeminarSettings settings = new FinalSeminarSettings();
diff --git a/view/src/test/java/se/su/dsv/scipro/grading/SendToExaminerTest.java b/view/src/test/java/se/su/dsv/scipro/grading/SendToExaminerTest.java
index 7976171fa6..a699f1e6ad 100644
--- a/view/src/test/java/se/su/dsv/scipro/grading/SendToExaminerTest.java
+++ b/view/src/test/java/se/su/dsv/scipro/grading/SendToExaminerTest.java
@@ -1,5 +1,6 @@
 package se.su.dsv.scipro.grading;
 
+import org.apache.wicket.util.tester.FormTester;
 import org.junit.jupiter.api.Test;
 import se.su.dsv.scipro.SciProTest;
 import se.su.dsv.scipro.file.FileDescription;
@@ -144,8 +145,9 @@ public class SendToExaminerTest extends SciProTest {
                 .thenReturn(Either.right(null));
 
         tester.startComponentInPage(new SendToExaminer("id", () -> project, () -> biden, () -> null));
+        FormTester formTester = tester.newFormTester(path("id", "form"));
 
-        tester.clickLink(path("id", "send"));
+        formTester.submit();
 
         verify(gradingService).reportGrade(TOKEN, project.getIdentifier(), biden.getIdentifier(), gw.id(), grade.name(), finalThesis.getUploadDate());
     }