diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 717768e786de473b2a0e6ec5cbb5c232e2af0999..6ab1e2093cdd2ef7dc677d0ecaee47a58badcc50 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -83,6 +83,7 @@ INSTALLED_APPS = (
     'django_extensions',
     'affiliations',
     'ajax_select',
+    'haystack',
     'captcha',
     'colleges',
     'commentaries',
@@ -137,6 +138,7 @@ HAYSTACK_CONNECTIONS = {
         'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
         'PATH': 'local_files/haystack/',
         'EXCLUDED_INDEXES': ['sphinxdoc.search_indexes.DocumentIndex'],
+        'INCLUDE_SPELLING': True,
     },
 }
 
diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py
index 0840aa4ce343a40cc0a942c058e01a17201b5596..5438dce4b4ba398806efc6ae295118e47b269ab2 100644
--- a/SciPost_v1/urls.py
+++ b/SciPost_v1/urls.py
@@ -10,7 +10,7 @@ from django.contrib import admin
 from ajax_select import urls as ajax_select_urls
 from rest_framework import routers
 
-from conflicts.viewsets import ConflictOfInterestViewSet
+# from conflicts.viewsets import ConflictOfInterestViewSet
 from journals.viewsets import PublicationViewSetForGoogleScholar
 from news.viewsets import NewsItemViewSet
 from journals.constants import REGEX_CHOICES
@@ -23,7 +23,7 @@ JOURNAL_REGEX = '(?P<doi_label>%s)' % REGEX_CHOICES
 # API Routing
 router = routers.SimpleRouter()
 router.register(r'news', NewsItemViewSet)
-router.register(r'conflicts', ConflictOfInterestViewSet)
+# router.register(r'conflicts', ConflictOfInterestViewSet)
 router.register(r'publications/GoogleScholar', PublicationViewSetForGoogleScholar)
 
 
diff --git a/comments/models.py b/comments/models.py
index 482df7a1e2e550b4b4dd91b3ed1feaa48d41fe3d..be9a3678b2a50eabb989c354259d5e1a2eca6a56 100644
--- a/comments/models.py
+++ b/comments/models.py
@@ -114,6 +114,7 @@ class Comment(TimeStampedModel):
 
         to_object = self.content_object
         while True:
+            # Loop because of possible nested relations
             if (isinstance(to_object, Submission) or isinstance(to_object, Commentary) or
                isinstance(to_object, ThesisLink)):
                 return to_object
diff --git a/comments/views.py b/comments/views.py
index ed8bbb8e6d3b4e84e2a491cdf00e616a55b631f2..b79ee9d9d3496a24ad1dd98bb0cefdcf3893e42d 100644
--- a/comments/views.py
+++ b/comments/views.py
@@ -1,7 +1,7 @@
 __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
-
+import time
 from django.contrib.auth.decorators import permission_required, login_required
 from django.contrib import messages
 from django.core.urlresolvers import reverse
@@ -47,6 +47,18 @@ def new_comment(request, **kwargs):
         new_comment.save()
         new_comment.grant_permissions()
 
+        # Mails
+        mail_sender = DirectMailUtil(
+            mail_code='commenters/inform_commenter_comment_received',
+            instance=new_comment)
+        mail_sender.send()
+
+        if isinstance(new_comment.core_content_object, Submission):
+            mail_sender = DirectMailUtil(
+                mail_code='eic/inform_eic_comment_received',
+                instance=new_comment)
+            mail_sender.send()
+
         messages.success(request, strings.acknowledge_submit_comment)
         return redirect(_object.get_absolute_url())
     context = {'form': form}
@@ -168,6 +180,7 @@ def vet_submitted_comment(request, comment_id):
 
 
 @permission_required('scipost.can_submit_comments', raise_exception=True)
+@transaction.atomic
 def reply_to_comment(request, comment_id):
     comment = get_object_or_404(Comment, pk=comment_id)
 
@@ -184,7 +197,6 @@ def reply_to_comment(request, comment_id):
     else:
         # No idea what this could be, but just to be sure
         is_author = related_object.author == request.user.contributor
-
     form = CommentForm(request.POST or None, request.FILES or None)
     if form.is_valid():
         newcomment = form.save(commit=False)
@@ -194,6 +206,19 @@ def reply_to_comment(request, comment_id):
         newcomment.save()
         newcomment.grant_permissions()
 
+        mail_sender = DirectMailUtil(
+            mail_code='commenters/inform_commenter_comment_received',
+            instance=newcomment,
+            delayed_processing=True)
+        mail_sender.send()
+
+        if isinstance(newcomment.core_content_object, Submission):
+            mail_sender = DirectMailUtil(
+                mail_code='eic/inform_eic_comment_received',
+                instance=newcomment,
+                delayed_processing=True)
+            mail_sender.send()
+
         messages.success(request, '<h3>Thank you for contributing a Reply</h3>'
                                   'It will soon be vetted by an Editor.')
         return redirect(newcomment.content_object.get_absolute_url())
@@ -218,6 +243,18 @@ def reply_to_report(request, report_id):
         newcomment.save()
         newcomment.grant_permissions()
 
+        mail_sender = DirectMailUtil(
+            mail_code='eic/inform_eic_comment_received',
+            instance=newcomment,
+            delayed_processing=True)
+        mail_sender.send()
+
+        mail_sender = DirectMailUtil(
+            mail_code='commenters/inform_commenter_comment_received',
+            instance=newcomment,
+            delayed_processing=True)
+        mail_sender.send()
+
         messages.success(request, '<h3>Thank you for contributing a Reply</h3>'
                                   'It will soon be vetted by an Editor.')
         return redirect(newcomment.content_object.get_absolute_url())
diff --git a/conflicts/admin.py b/conflicts/admin.py
index da79e8bb603ee3df97efb33bf5d2867d8dba86ce..00315cd9c8cc6c6c3f877e02f25b93d58158352b 100644
--- a/conflicts/admin.py
+++ b/conflicts/admin.py
@@ -4,19 +4,21 @@ __license__ = "AGPL v3"
 
 from django.contrib import admin
 
-from .models import ConflictOfInterest, ConflictGroup
-
-
-class ConflictGroupAdmin(admin.ModelAdmin):
-    search_fields = ['title', 'conflicts__to_name']
-    list_display = ('__str__',)
-
-
-class ConflictOfInterestAdmin(admin.ModelAdmin):
-    search_fields = ['to_contributor__user__last_name', 'to_name']
-    list_filter = ('status', 'type')
-    list_display = ('__str__', 'status', 'type', 'conflict_group')
-
-
-admin.site.register(ConflictGroup, ConflictGroupAdmin)
-admin.site.register(ConflictOfInterest, ConflictOfInterestAdmin)
+from conflicts.models import ConflictOfInterest
+
+# from .models import ConflictOfInterest, ConflictGroup
+#
+#
+# class ConflictGroupAdmin(admin.ModelAdmin):
+#     search_fields = ['title', 'conflicts__to_name']
+#     list_display = ('__str__',)
+#
+#
+# class ConflictOfInterestAdmin(admin.ModelAdmin):
+#     search_fields = ['to_contributor__user__last_name', 'to_name']
+#     list_filter = ('status', 'type')
+#     list_display = ('__str__', 'status', 'type', 'conflict_group')
+#
+#
+admin.site.register(ConflictOfInterest)
+# admin.site.register(ConflictOfInterest, ConflictOfInterestAdmin)
diff --git a/conflicts/constants.py b/conflicts/constants.py
deleted file mode 100644
index fabe525b3f656608e589a3ea3e9c9672744cfecd..0000000000000000000000000000000000000000
--- a/conflicts/constants.py
+++ /dev/null
@@ -1,18 +0,0 @@
-__copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-STATUS_UNVERIFIED, STATUS_VERIFIED = 'unverified', 'verified'
-STATUS_DEPRECATED = 'deprecated'
-CONFLICT_OF_INTEREST_STATUSES = (
-    (STATUS_UNVERIFIED, 'Unverified'),
-    (STATUS_VERIFIED, 'Verified by Admin'),   # Confirmed // rejected
-    (STATUS_DEPRECATED, 'Deprecated'),
-)
-
-
-TYPE_OTHER, TYPE_COAUTHOR = 'other', 'coauthor'
-CONFLICT_OF_INTEREST_TYPES = (
-    (TYPE_COAUTHOR, 'Co-authorship'),
-    (TYPE_OTHER, 'Other'),
-)
diff --git a/conflicts/management/commands/update_coi_via_arxiv.py b/conflicts/management/commands/update_coi_via_arxiv.py
index 8c46c8e522a9465e990a67ac9aecdfc79ce65889..4a2224d68b3b3ea25b32491f171e8c41cccd605e 100644
--- a/conflicts/management/commands/update_coi_via_arxiv.py
+++ b/conflicts/management/commands/update_coi_via_arxiv.py
@@ -3,8 +3,9 @@ __license__ = "AGPL v3"
 
 
 from django.core.management.base import BaseCommand
+from django.db.models import Q
 
-from scipost.models import Contributor
+from profiles.models import Profile
 from submissions.models import Submission
 
 from ...services import ArxivCaller
@@ -19,16 +20,29 @@ class Command(BaseCommand):
             dest='arxiv', help='ArXiv id of Submission to force update of conflicts.')
 
     def handle(self, *args, **options):
+        caller = ArxivCaller()
+
         if options['arxiv']:
             submissions = Submission.objects.filter(preprint__identifier_w_vn_nr=options['arxiv'])
         else:
-            submissions = Submission.objects.needs_conflicts_update()
+            submissions = Submission.objects.needs_conflicts_update()[:5]
 
+        n_new_conflicts = 0
         for sub in submissions:
             fellow_ids = sub.fellows.values_list('id', flat=True)
-            fellows = Contributor.objects.filter(fellowships__id__in=fellow_ids)
+            fellow_profiles = Profile.objects.filter(contributor__fellowships__id__in=fellow_ids)
+
+            # Get all possibly relevant Profiles
+            author_str_list = [a.split()[-1] for a in sub.author_list.split(',')]
             if 'entries' in sub.metadata:
-                caller = ArxivCaller(sub.metadata['entries'][0]['authors'])
-                caller.compare_to(fellows)
-                caller.add_to_db(sub)
-                Submission.objects.filter(id=sub.id).update(needs_conflicts_update=False)
+                sub.metadata['entries'][0]['authors']
+                # last_names = []
+                author_str_list += [
+                    a['name'].split()[-1] for a in sub.metadata['entries'][0]['authors']]
+                author_str_list = set(author_str_list)  # Distinct operator
+            author_profiles = Profile.objects.filter(
+                Q(contributor__in=sub.authors.all()) |
+                Q(last_name__in=author_str_list)).distinct()
+
+            n_new_conflicts += caller.compare(author_profiles, fellow_profiles)
+        return n_new_conflicts
diff --git a/conflicts/managers.py b/conflicts/managers.py
index 70e7d2881b0f18ac1605ccde6004f21e75de3c42..98dee2a0f69fe59e6b282804c7e5a29270aad3e6 100644
--- a/conflicts/managers.py
+++ b/conflicts/managers.py
@@ -4,12 +4,10 @@ __license__ = "AGPL v3"
 
 from django.db import models
 
-from .constants import STATUS_UNVERIFIED, STATUS_DEPRECATED
-
 
 class ConflictOfInterestQuerySet(models.QuerySet):
     def unverified(self):
-        return self.filter(status=STATUS_UNVERIFIED)
+        return self.filter(status='unverified')
 
     def non_deprecated(self):
-        return self.exclude(status=STATUS_DEPRECATED)
+        return self.exclude(status='deprecated')
diff --git a/conflicts/migrations/0008_auto_20181219_2017.py b/conflicts/migrations/0008_auto_20181219_2017.py
new file mode 100644
index 0000000000000000000000000000000000000000..36157c74c17feff7ecc6333018058b5db49c4894
--- /dev/null
+++ b/conflicts/migrations/0008_auto_20181219_2017.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-19 19:17
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('conflicts', '0007_auto_20180526_1336'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='conflictgroup',
+            name='related_submissions',
+        ),
+        migrations.RemoveField(
+            model_name='conflictofinterest',
+            name='conflict_group',
+        ),
+        migrations.RemoveField(
+            model_name='conflictofinterest',
+            name='origin',
+        ),
+        migrations.RemoveField(
+            model_name='conflictofinterest',
+            name='to_contributor',
+        ),
+        migrations.DeleteModel(
+            name='ConflictGroup',
+        ),
+        migrations.DeleteModel(
+            name='ConflictOfInterest',
+        ),
+    ]
diff --git a/conflicts/migrations/0009_conflictofinterest.py b/conflicts/migrations/0009_conflictofinterest.py
new file mode 100644
index 0000000000000000000000000000000000000000..50c73670faffe7ae7dfe4c1a0593f861a5687a29
--- /dev/null
+++ b/conflicts/migrations/0009_conflictofinterest.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-19 19:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('conflicts', '0008_auto_20181219_2017'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ConflictOfInterest',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('status', models.CharField(choices=[('unverified', 'Unverified'), ('verified', 'Verified by Admin'), ('deprecated', 'Deprecated')], default='unverified', max_length=16)),
+                ('type', models.CharField(choices=[('coworker', 'Co-worker'), ('coauthor', 'Co-authorship'), ('other', 'Other')], default='other', max_length=16)),
+                ('title', models.CharField(blank=True, max_length=265)),
+                ('url', models.URLField(blank=True)),
+                ('comment', models.TextField(blank=True)),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('modified', models.DateTimeField(auto_now=True)),
+            ],
+        ),
+    ]
diff --git a/conflicts/migrations/0010_auto_20181219_2036.py b/conflicts/migrations/0010_auto_20181219_2036.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d189f50e8ae7e815af0c0d53bd2123e663ecb55
--- /dev/null
+++ b/conflicts/migrations/0010_auto_20181219_2036.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-19 19:36
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0015_auto_20181118_0849'),
+        ('conflicts', '0009_conflictofinterest'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='conflictofinterest',
+            name='profile',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='conflicts', to='profiles.Profile'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='conflictofinterest',
+            name='related_profile',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='profiles.Profile'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/conflicts/migrations/0011_auto_20181219_2040.py b/conflicts/migrations/0011_auto_20181219_2040.py
new file mode 100644
index 0000000000000000000000000000000000000000..369c02557785faa55fa4f0e2e05db61c6eeafe37
--- /dev/null
+++ b/conflicts/migrations/0011_auto_20181219_2040.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-19 19:40
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('conflicts', '0010_auto_20181219_2036'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='conflictofinterest',
+            old_name='title',
+            new_name='header',
+        ),
+    ]
diff --git a/conflicts/migrations/0012_auto_20181219_2041.py b/conflicts/migrations/0012_auto_20181219_2041.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e6639767eb5e4f4250c1b13e781b57848e0374d
--- /dev/null
+++ b/conflicts/migrations/0012_auto_20181219_2041.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-19 19:41
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('conflicts', '0011_auto_20181219_2040'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='conflictofinterest',
+            name='header',
+            field=models.CharField(max_length=265),
+        ),
+    ]
diff --git a/conflicts/models.py b/conflicts/models.py
index b15a0cfe97d790aeac4c2dcc97263c4eaa8255ac..5dd97b21dcae06f31e6dc54780d15bc556d7ae85 100644
--- a/conflicts/models.py
+++ b/conflicts/models.py
@@ -2,57 +2,45 @@ __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
-from django.core.exceptions import ValidationError
 from django.db import models
 
-from .constants import (
-    CONFLICT_OF_INTEREST_STATUSES, STATUS_UNVERIFIED, CONFLICT_OF_INTEREST_TYPES, TYPE_OTHER)
 from .managers import ConflictOfInterestQuerySet
 
 
-class ConflictGroup(models.Model):
-    """Group of related ConflictOfInterest objects linking conflicts based on meta data."""
-
-    url = models.URLField(blank=True)
-    title = models.CharField(max_length=256)
-
-    related_submissions = models.ManyToManyField(
-        'submissions.Submission', blank=True, related_name='conflict_groups')
-    created = models.DateTimeField(auto_now_add=True)
-    modified = models.DateTimeField(auto_now=True)
-
-    def __str__(self):
-        return 'Conflict group {}'.format(self.title[:30])
-
-
 class ConflictOfInterest(models.Model):
-    """Conflict of Interest is a flagged relation between scientists."""
+    """
+    A flagged relation between two scientists that could be conflicting in a refereeing
+    phase.
+    """
+    STATUS_UNVERIFIED, STATUS_VERIFIED = 'unverified', 'verified'
+    STATUS_DEPRECATED = 'deprecated'
+    CONFLICT_OF_INTEREST_STATUSES = (
+        (STATUS_UNVERIFIED, 'Unverified'),
+        (STATUS_VERIFIED, 'Verified by Admin'),
+        (STATUS_DEPRECATED, 'Deprecated'),
+    )
+
+    TYPE_OTHER, TYPE_COAUTHOR, TYPE_COWORKER = 'other', 'coauthor', 'coworker'
+    COI_TYPES = (
+        (TYPE_COWORKER, 'Co-worker'),
+        (TYPE_COAUTHOR, 'Co-authorship'),
+        (TYPE_OTHER, 'Other'),
+    )
 
     status = models.CharField(
-        max_length=16, choices=CONFLICT_OF_INTEREST_STATUSES, default=STATUS_UNVERIFIED)
-    origin = models.ForeignKey('scipost.Contributor')
-    to_contributor = models.ForeignKey(
-        'scipost.Contributor', blank=True, null=True, related_name='+')
-    to_name = models.CharField(max_length=128, blank=True)
-    type = models.CharField(
-        max_length=16, choices=CONFLICT_OF_INTEREST_TYPES, default=TYPE_OTHER)
+         max_length=16, choices=CONFLICT_OF_INTEREST_STATUSES, default=STATUS_UNVERIFIED)
+    type = models.CharField(max_length=16, choices=COI_TYPES, default=TYPE_OTHER)
+    profile = models.ForeignKey('profiles.Profile', related_name='conflicts')
+    related_profile = models.ForeignKey('profiles.Profile', related_name='+')
 
-    conflict_group = models.ForeignKey('conflicts.ConflictGroup', null=True, blank=True)
+    header = models.CharField(max_length=265)
+    url = models.URLField(blank=True)
+    comment = models.TextField(blank=True)
 
     created = models.DateTimeField(auto_now_add=True)
     modified = models.DateTimeField(auto_now=True)
 
     objects = ConflictOfInterestQuerySet.as_manager()
 
-    class Meta:
-        default_related_name = 'conflicts'
-
     def __str__(self):
-        _str = '{} {} to {}'.format(self.get_type_display(), self.origin, self.to_name)
-        return _str
-
-    def clean(self):
-        """Check if Conflict of Interest is complete."""
-        if not self.to_contributor and not self.to_unregistered:
-            raise ValidationError(
-                'Conflict of Interest must be related to Contributor or UnregisteredAuthor.')
+        return '{} - {} ({})'.format(self.profile, self.related_profile, self.get_type_display())
diff --git a/conflicts/services.py b/conflicts/services.py
index 5aff67070710de36cea5982574b049b717ee1ccb..bf2ea51e4d3154b7e69678161c6db7a7ea9e6f4d 100644
--- a/conflicts/services.py
+++ b/conflicts/services.py
@@ -6,86 +6,62 @@ __license__ = "AGPL v3"
 import feedparser
 import logging
 
-from scipost.models import Contributor
+from profiles.models import Profile
 
-from .constants import TYPE_COAUTHOR
-from .models import ConflictOfInterest, ConflictGroup
+from .models import ConflictOfInterest
 
 logger = logging.getLogger('scipost.conflicts.arxiv')
 
 
 class ArxivCaller:
-    """ArXiv Caller will help retrieve author data from arXiv API."""
+    """
+    ArXiv Caller will help retrieve author data from arXiv API.
+    """
 
     query_base_url = 'https://export.arxiv.org/api/query?search_query={query}'
 
-    def __init__(self, author_list):
-        """Init ArXivCaller with list `author_list` as per Submission meta data."""
-        self.author_query = ''
-        self.conflicts = []
-
-        last_names = []
-        for author in author_list:
-            # Gather author data to do conflict-of-interest queries with
-            last_names.append(author['name'].split()[-1])
-        self.author_query = '+OR+'.join(last_names)
-
-        logger.info('Update from ArXiv for author list [{0}]'.format(author_list[:30]))
-
-    def compare_to(self, contributors_list):
-        """Add list of Contributors to compare the `author_list` with."""
-        for contributor in contributors_list:
-            # For each fellow found, so a query with the authors to check for conflicts
-            search_query = 'au:({fellow}+AND+({authors}))'.format(
-                fellow=contributor.user.last_name, authors=self.author_query)
-            queryurl = self.query_base_url.format(query=search_query)
-            queryurl += '&sortBy=submittedDate&sortOrder=descending&max_results=5'
-            queryurl = queryurl.replace(' ', '+')  # Fallback for some last names with spaces
-
-            # Call the API
-            response_content = feedparser.parse(queryurl)
-            valid = False
-            logger.info('GET [{contributor}] [request] | {url}'.format(
-                contributor=contributor.user.last_name, url=queryurl))
-            if self._search_result_present(response_content):
-                valid = True
-                self.conflicts.append({
-                    'from': contributor,
-                    'results': response_content
-                })
-            logger.info('{result} | {response}.'.format(
-                result='Found results' if valid else 'No results',
-                response=response_content))
-        return
+    def __init__(self):
+        """
+        Init ArXivCaller.
+        """
+        logger.info('Update COI from ArXiv')
 
     def _search_result_present(self, data):
         if len(data.get('entries', [])) > 0:
             return 'title' in data['entries'][0]
         return False
 
-    def add_to_db(self, submission=None):
-        """Add found conflicts to database as unverfied co-author conflicts."""
-        logger.info('Pushing {} query results to database.'.format(len(self.conflicts)))
+    def compare(self, author_profiles, relating_profiles):
+        """
+        Compare two list of Profiles using the ArXiv API.
+        """
 
         count = 0
-        for conflict in self.conflicts:
-            # Loop all separate queries
-            for result in conflict['results']['entries']:
-                coi_group, __ = ConflictGroup.objects.get_or_create(
-                    url=result['link'].replace('http:', 'https:'), title=result['title'])
-                if submission:
-                    coi_group.related_submissions.add(submission)
-
-                # Read all results in one query
-                for author in result['authors']:
-                    # Try to find an registered Contributor first.
-                    contributor = Contributor.objects.active().filter(
-                        user__first_name__istartswith=author['name'][0],  # Only use first letter due to database inconsistency
-                        user__last_name__iendswith=author['name'].split(' ')[-1]).first()
-
-                    coi, new = ConflictOfInterest.objects.get_or_create(
-                        conflict_group=coi_group, origin=conflict['from'],
-                        to_contributor=contributor, to_name=author['name'], type=TYPE_COAUTHOR)
-                    if new:
-                        count += 1
-        logger.info('{} new conflicts added.'.format(count))
+        for profile in author_profiles:
+            for rel_profile in relating_profiles:
+                search_query = 'au:({profile}+AND+({rel_profile}))'.format(
+                    profile=profile.last_name,
+                    rel_profile=rel_profile.last_name,
+                )
+                queryurl = self.query_base_url.format(query=search_query)
+                queryurl += '&sortBy=submittedDate&sortOrder=descending&max_results=5'
+                queryurl = queryurl.replace(' ', '+')
+
+                # Call the API
+                response_content = feedparser.parse(queryurl)
+                logger.info('GET [{profile}] [request] | {url}'.format(
+                    profile=profile.last_name, url=queryurl))
+
+                if self._search_result_present(response_content):
+
+                    for conflict in response_content['entries']:
+                        coi, new = ConflictOfInterest.objects.get_or_create(
+                            header=conflict['title'],
+                            url=conflict['link'].replace('http:', 'https:'),
+                            profile=profile,
+                            related_profile=rel_profile,
+                            type='coauthor',
+                        )
+                        count += 1 if new else 0
+                    logger.info('Found results | {response}.'.format(response=response_content))
+        return count
diff --git a/conflicts/templatetags/conflict_tags.py b/conflicts/templatetags/conflict_tags.py
index 0a2b721533dcb56137e6807cb744ca5a40eabba3..02cbfe26e9e2d85df1df92c9890e79106589bac2 100644
--- a/conflicts/templatetags/conflict_tags.py
+++ b/conflicts/templatetags/conflict_tags.py
@@ -7,7 +7,8 @@ from django import template
 register = template.Library()
 
 
-@register.filter
-def filter_for_contributor(qs, contributor):
-    """Filter ConflictGroup query for specific Contributor."""
-    return qs.filter(conflicts__origin=contributor).distinct()
+# @register.filter
+# def filter_for_contributor(qs, contributor):
+#     """Filter ConflictGroup query for specific Contributor."""
+#     # raise
+#     return qs.filter(conflicts__origin=contributor).distinct()
diff --git a/conflicts/viewsets.py b/conflicts/viewsets.py
index 1fb3da6201e3df06bf460e33ca5c86052c408a35..8148b5ebdf18bf6b98f62e02bfc4ef2221279df6 100644
--- a/conflicts/viewsets.py
+++ b/conflicts/viewsets.py
@@ -7,36 +7,36 @@ from rest_framework import viewsets, permissions, response, serializers
 from rest_framework.decorators import action
 
 from .constants import STATUS_VERIFIED, STATUS_DEPRECATED
-from .models import ConflictOfInterest
-from .serializers import ConflictOfInterestSerializer
-
-
-class IsEditorialAdministrator(permissions.BasePermission):
-    """Check if User is Editorial Administrator to allow permission to API."""
-
-    def has_object_permission(self, request, view, obj):
-        """Check user's permissions."""
-        return request.user.has_perm('scipost.can_oversee_refereeing')
-
-
-class ConflictOfInterestViewSet(viewsets.ModelViewSet):
-    """API view for ConflictOfInterest."""
-
-    queryset = ConflictOfInterest.objects.all()
-    serializer_class = ConflictOfInterestSerializer
-    permission_classes = [permissions.IsAuthenticated, IsEditorialAdministrator]
-
-    @action(methods=['post'], detail=True, permission_classes=[IsEditorialAdministrator],
-            url_path='verify-conflict', url_name='verify_conflict')
-    def verify_conflict(self, request, pk=None):
-        """Verify a ConflictOfInterest or delete."""
-        coi = get_object_or_404(ConflictOfInterest.objects.unverified(), pk=pk)
-        if request.POST['status'] == 'verified':
-            coi.status = STATUS_VERIFIED
-        elif request.POST['status'] == 'delete':
-            coi.status = STATUS_DEPRECATED
-        else:
-            raise serializers.ValidationError('Invalid status value.')
-        coi.save()
-        serializer = self.serializer_class(coi)
-        return response.Response(serializer.data)
+# from .models import ConflictOfInterest
+# from .serializers import ConflictOfInterestSerializer
+#
+#
+# class IsEditorialAdministrator(permissions.BasePermission):
+#     """Check if User is Editorial Administrator to allow permission to API."""
+#
+#     def has_object_permission(self, request, view, obj):
+#         """Check user's permissions."""
+#         return request.user.has_perm('scipost.can_oversee_refereeing')
+#
+#
+# class ConflictOfInterestViewSet(viewsets.ModelViewSet):
+#     """API view for ConflictOfInterest."""
+#
+#     queryset = ConflictOfInterest.objects.all()
+#     serializer_class = ConflictOfInterestSerializer
+#     permission_classes = [permissions.IsAuthenticated, IsEditorialAdministrator]
+#
+#     @action(methods=['post'], detail=True, permission_classes=[IsEditorialAdministrator],
+#             url_path='verify-conflict', url_name='verify_conflict')
+#     def verify_conflict(self, request, pk=None):
+#         """Verify a ConflictOfInterest or delete."""
+#         coi = get_object_or_404(ConflictOfInterest.objects.unverified(), pk=pk)
+#         if request.POST['status'] == 'verified':
+#             coi.status = STATUS_VERIFIED
+#         elif request.POST['status'] == 'delete':
+#             coi.status = STATUS_DEPRECATED
+#         else:
+#             raise serializers.ValidationError('Invalid status value.')
+#         coi.save()
+#         serializer = self.serializer_class(coi)
+#         return response.Response(serializer.data)
diff --git a/mails/admin.py b/mails/admin.py
index 6967486fda3158c00f55d1233d4b8b1d568be0a8..7fa9f68ca1ae63a3c6fe1de6fba0c9b1be615140 100644
--- a/mails/admin.py
+++ b/mails/admin.py
@@ -8,7 +8,8 @@ from .models import MailLog
 
 
 class MailLogAdmin(admin.ModelAdmin):
-    list_display = ['__str__', 'to_recipients', 'created', 'processed']
+    list_display = ['__str__', 'to_recipients', 'created', 'status']
+    list_filter = ['status']
     readonly_fields = ('created', 'latest_activity')
 
 
diff --git a/mails/backends/filebased.py b/mails/backends/filebased.py
index 1c0e26d9f14c23b5e337bcaface786a3933f714d..71688950a3c5ad2eefc6748415643ce13c39c5b7 100644
--- a/mails/backends/filebased.py
+++ b/mails/backends/filebased.py
@@ -49,11 +49,23 @@ class ModelEmailBackend(FileBacked):
         except AttributeError:
             pass
 
+        content_object = None
+        mail_code = ''
+        if 'delayed_processing' in email_message.extra_headers and email_message.extra_headers:
+            status = 'not_rendered'
+            content_object = email_message.extra_headers.get('content_object', None)
+            mail_code = email_message.extra_headers.get('mail_code', '')
+        else:
+            status = 'rendered'
+
         MailLog.objects.create(
             body=body,
             subject=subject,
             body_html=body_html,
             to_recipients=to_recipients,
             bcc_recipients=bcc_recipients,
-            from_email=from_email)
+            from_email=from_email,
+            status=status,
+            content_object=content_object,
+            mail_code=mail_code)
         return True
diff --git a/mails/management/commands/send_mails.py b/mails/management/commands/send_mails.py
index c684889d1b0d83caff363ed2422b52963fcb0b9a..a810d2fcd96d88ce9ee67246875f352c8acdb801 100644
--- a/mails/management/commands/send_mails.py
+++ b/mails/management/commands/send_mails.py
@@ -2,7 +2,7 @@ from django.core.management.base import BaseCommand
 from django.conf import settings
 
 from ...models import MailLog
-
+from ...utils import DirectMailUtil
 
 class Command(BaseCommand):
     """
@@ -13,6 +13,19 @@ class Command(BaseCommand):
             '--id', type=int, required=False,
             help='The id in the `MailLog` table for a specific mail, Leave blank to send all')
 
+    def _process_mail(self, mail):
+        """
+        Render the templates for the mail if not done yet.
+        """
+        mail_util = DirectMailUtil(
+            mail_code=mail.mail_code,
+            instance=mail.content_object)  # This will process the mail, but: not send yet!
+
+        MailLog.objects.filter(id=mail.id).update(
+            body=mail_util.mail_data['message'],
+            body_html=mail_util.mail_data['html_message'],
+            status='rendered')
+
     def send_mails(self, mails):
         from django.core.mail import get_connection, EmailMultiAlternatives
 
@@ -28,6 +41,10 @@ class Command(BaseCommand):
         connection = get_connection(backend=backend, fail_silently=False)
         count = 0
         for db_mail in mails:
+            if db_mail.status == 'not_rendered':
+                self._process_mail(db_mail)
+                db_mail.refresh_from_db()
+
             mail = EmailMultiAlternatives(
                 db_mail.subject,
                 db_mail.body,
@@ -42,6 +59,7 @@ class Command(BaseCommand):
             if response:
                 count += 1
                 db_mail.processed = True
+                db_mail.status = 'sent'
                 db_mail.save()
         return count
 
@@ -49,6 +67,6 @@ class Command(BaseCommand):
         if options.get('id'):
             mails = MailLog.objects.filter(id=options['id'])
         else:
-            mails = MailLog.objects.unprocessed()
+            mails = MailLog.objects.not_sent()
         nr_mails = self.send_mails(mails)
         self.stdout.write('Sent {} mails.'.format(nr_mails))
diff --git a/mails/managers.py b/mails/managers.py
index 1be95a3768d1353c9452e5dec6b7df91d3e6aa5a..782b3ebdefe6f72d467558879ad6d3e59c89939a 100644
--- a/mails/managers.py
+++ b/mails/managers.py
@@ -2,5 +2,11 @@ from django.db import models
 
 
 class MailLogQuerySet(models.QuerySet):
-    def unprocessed(self):
-        return self.filter(processed=False)
+    def not_sent(self):
+        return self.filter(status__in=['not_rendered',  'rendered'])
+
+    def unrendered(self):
+        return self.filter(status='not_rendered')
+
+    def rendered(self):
+        return self.filter(status='rendered')
diff --git a/mails/migrations/0004_auto_20181217_1050.py b/mails/migrations/0004_auto_20181217_1050.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c0c98cc78df395af5b042a57457b36714e551cf
--- /dev/null
+++ b/mails/migrations/0004_auto_20181217_1050.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-17 09:50
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('mails', '0003_auto_20180502_1807'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='maillog',
+            name='content_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'),
+        ),
+        migrations.AddField(
+            model_name='maillog',
+            name='mail_code',
+            field=models.CharField(blank=True, max_length=254),
+        ),
+        migrations.AddField(
+            model_name='maillog',
+            name='object_id',
+            field=models.PositiveIntegerField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='maillog',
+            name='status',
+            field=models.CharField(choices=[('not_rendered', 'Not rendered'), ('rendered', 'Rendered'), ('sent', 'Sent')], default='rendered', max_length=16),
+        ),
+    ]
diff --git a/mails/migrations/0005_auto_20181217_1051.py b/mails/migrations/0005_auto_20181217_1051.py
new file mode 100644
index 0000000000000000000000000000000000000000..e1f8697828702b72183a411f43733e16bba0907b
--- /dev/null
+++ b/mails/migrations/0005_auto_20181217_1051.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-17 09:51
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def set_statuses(apps, schema_editor):
+    MailLog = apps.get_model('mails', 'MailLog')
+    MailLog.objects.filter(processed=True).update(status='sent')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('mails', '0004_auto_20181217_1050'),
+    ]
+
+    operations = [
+        migrations.RunPython(set_statuses, reverse_code=migrations.RunPython.noop),
+    ]
diff --git a/mails/mixins.py b/mails/mixins.py
index 1dbb645792a5083b3a085362e3fdc456fde8d2e3..00a40447701e0dd7e3247f6eadf22092f9f64fef 100644
--- a/mails/mixins.py
+++ b/mails/mixins.py
@@ -2,6 +2,7 @@ __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import time
 import re
 import json
 import inspect
@@ -25,6 +26,7 @@ class MailUtilsMixin:
     message = ''
     original_recipient = ''
     mail_sent = False
+    delayed_processing = False
 
     def __init__(self, *args, **kwargs):
         """Init an instance for a specific mail_code.
@@ -68,10 +70,11 @@ class MailUtilsMixin:
         self.instance = self.get_object(**kwargs)
 
         # Digest the templates
-        mail_template = loader.get_template('email/%s.html' % self.mail_code)
-        if self.instance and self.mail_data.get('context_object'):
-            kwargs[self.mail_data['context_object']] = self.instance
-        self.mail_template = mail_template.render(kwargs)
+        if not self.delayed_processing:
+            mail_template = loader.get_template('email/%s.html' % self.mail_code)
+            if self.instance and self.mail_data.get('context_object'):
+                kwargs[self.mail_data['context_object']] = self.instance
+            self.mail_template = mail_template.render(kwargs)  # Damn slow.
 
         # Gather Recipients data
         try:
@@ -200,7 +203,12 @@ class MailUtilsMixin:
             '%s <%s>' % (self.mail_data['from_address_name'], self.mail_data['from_address']),
             self.mail_data['recipients'],
             bcc=self.mail_data['bcc_list'],
-            reply_to=[self.mail_data['from_address']])
+            reply_to=[self.mail_data['from_address']],
+            headers={
+                'delayed_processing': self.delayed_processing,
+                'content_object': self.get_object(),
+                'mail_code': self.mail_code,
+            })
 
         # Send html version if available
         if 'html_message' in self.mail_data:
diff --git a/mails/models.py b/mails/models.py
index e77a920cb305247cf47a914e1deb278d65bc24d6..88d210eeca6dfc20e78688c37f2ae5c3c1e972b9 100644
--- a/mails/models.py
+++ b/mails/models.py
@@ -3,10 +3,20 @@ __license__ = "AGPL v3"
 
 
 from django.db import models
+from django.contrib.contenttypes.fields import GenericForeignKey
+from django.contrib.contenttypes.models import ContentType
 from django.contrib.postgres.fields import ArrayField
 
 from .managers import MailLogQuerySet
 
+MAIL_NOT_RENDERED, MAIL_RENDERED = 'not_rendered', 'rendered'
+MAIL_SENT = 'sent'
+MAIL_STATUSES = (
+    (MAIL_NOT_RENDERED, 'Not rendered'),
+    (MAIL_RENDERED, 'Rendered'),
+    (MAIL_SENT, 'Sent'),
+)
+
 
 class MailLog(models.Model):
     """
@@ -15,6 +25,12 @@ class MailLog(models.Model):
     the chosen MailBackend.
     """
     processed = models.BooleanField(default=False)
+    status = models.CharField(max_length=16, choices=MAIL_STATUSES, default=MAIL_RENDERED)
+
+    mail_code = models.CharField(max_length=254, blank=True)
+    content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.CASCADE)
+    object_id = models.PositiveIntegerField(blank=True, null=True)
+    content_object = GenericForeignKey('content_type', 'object_id')
 
     body = models.TextField()
     body_html = models.TextField(blank=True)
diff --git a/mails/utils.py b/mails/utils.py
index 8eb019df4dad59996a94c3a0efabccff6fbccafa..9ac090d6e5a46ebd472bfed436dfcfaa1d2fe450 100644
--- a/mails/utils.py
+++ b/mails/utils.py
@@ -14,5 +14,6 @@ class DirectMailUtil(MailUtilsMixin):
     def __init__(self, mail_code, *args, **kwargs):
         kwargs['mail_code'] = mail_code
         kwargs['instance'] = kwargs.pop('instance', None)
+        self.delayed_processing = kwargs.pop('delayed_processing', False)
         super().__init__(*args, **kwargs)
         self.validate()
diff --git a/scipost/forms.py b/scipost/forms.py
index f2c7ed99a716539fdf156a0b47dd8a953f4b26a7..ae8cd11d205ce54247ab4324c54dbd4568c16f37 100644
--- a/scipost/forms.py
+++ b/scipost/forms.py
@@ -652,7 +652,16 @@ class SearchForm(HayStackSearchForm):
     end = forms.DateField(widget=MonthYearWidget(end=True), required=False)  # Month
 
     def search(self):
-        sqs = super().search()
+        if not self.is_valid():
+            return self.no_query_found()
+
+        if not self.cleaned_data.get("q"):
+            return self.no_query_found()
+
+        sqs = self.searchqueryset.filter(content__contains=self.cleaned_data["q"])
+
+        if self.load_all:
+            sqs = sqs.load_all()
 
         if self.cleaned_data['start']:
             sqs = sqs.filter(date__gte=self.cleaned_data['start'])
diff --git a/scipost/static/scipost/assets/config/preconfig.scss b/scipost/static/scipost/assets/config/preconfig.scss
index f088db22de2bb3dab0775cb03e44aa960cf0568f..411c2f2a1a041a6ad3b4fd42058d06a1e3caecf1 100644
--- a/scipost/static/scipost/assets/config/preconfig.scss
+++ b/scipost/static/scipost/assets/config/preconfig.scss
@@ -5,9 +5,9 @@
 // General variable structure
 //
 //
-$base-border-radius: 0;
-$border-radius: 0;
-$border-radius-lg: 2px;
+$border-radius-base: 1px;
+$border-radius-small: 1px;
+$border-radius-large: 2px;
 
 // Alert
 //
@@ -55,11 +55,11 @@ $body-color: $scipost-darkblue;
 
 // Alerts
 //
-$alert-border-radius: $base-border-radius;
+$alert-border-radius: $border-radius-base;
 
 // Cards
 //
-$card-border-radius: $base-border-radius;
+$card-border-radius: $border-radius-base;
 $card-spacer-x: 0.75rem;
 $card-spacer-y: 0.5rem;
 $card-shadow-color: #ccc;
@@ -76,7 +76,7 @@ $breadcrumb-divider-color: $scipost-orange;
 
 // Dropdown
 //
-$dropdown-border-radius: $base-border-radius;
+$dropdown-border-radius: $border-radius-base;
 $dropdown-border-color: $scipost-darkblue;
 $dropdown-item-padding-y: 0.35rem;
 $dropdown-item-padding-x: 1.0rem;
@@ -89,11 +89,10 @@ $input-btn-padding-y: 0.25rem;
 $input-btn-padding-x-lg: 0.75rem;
 $input-btn-padding-y-lg: 0.325rem;
 $input-btn-line-height-lg: 1.4;
-$input-border-radius-sm: $base-border-radius;
-$input-border-radius: $base-border-radius;
-$input-border-radius-lg: $base-border-radius;
+$input-border-radius-sm: $border-radius-base;
+$input-border-radius: $border-radius-base;
+$input-border-radius-lg: $border-radius-base;
 $enable-rounded: true !important;
-$btn-transition: none;
 
 $input-height: calc(1.5rem + 2px);
 $input-height-lg: calc(2.0rem + 2px);
@@ -148,10 +147,20 @@ $navbar-padding-y: 0.2rem;
 $nav-tabs-border-color: $scipost-darkblue;
 $nav-tabs-link-active-border-color: $scipost-darkblue $scipost-darkblue $nav-tabs-link-active-bg;
 
-$input-border-radius: 0;
-$btn-border-radius: $base-border-radius;
-$btn-border-radius-sm: $base-border-radius;
-$btn-border-radius-lg: $base-border-radius;
+$input-border-radius:            $border-radius-base;
+$input-border-radius-large:      $border-radius-large;
+$input-border-radius-small:      $border-radius-small;
+
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius:         $border-radius-base;
+$btn-border-radius-lg:        $border-radius-large;
+$btn-border-radius-sm:        $border-radius-small;
+
+$btn-line-height-sm: 1.2;
+$btn-line-height-sm: 1.2;
+
+$btn-transition: none;
 
 
 // Block quote
diff --git a/scipost/static/scipost/assets/css/_form.scss b/scipost/static/scipost/assets/css/_form.scss
index 5776122ffdd1a469f4ad315dc8cb5a94a6b535c3..c51ab07815a8be92e27189eb9d6bdedd747e2d60 100644
--- a/scipost/static/scipost/assets/css/_form.scss
+++ b/scipost/static/scipost/assets/css/_form.scss
@@ -4,7 +4,7 @@
  */
 .form-control {
     font-family: inherit;
-    border-radius: $base-border-radius;
+    border-radius: $border-radius-base;
 }
 
 .has-error .form-control {
diff --git a/scipost/static/scipost/assets/css/_labels.scss b/scipost/static/scipost/assets/css/_labels.scss
index 5d5a4108092e561bb08cda51e68d5d7665db30bd..afafcdc1de6c1b460fad5db918e6f2b6a6ac210a 100644
--- a/scipost/static/scipost/assets/css/_labels.scss
+++ b/scipost/static/scipost/assets/css/_labels.scss
@@ -5,7 +5,9 @@
 
 $label-padding-x:                  0.6rem !default;
 $label-padding-y:                  0.25rem !default;
-$label-line-height:                1.2;
+$label-line-height:                1.0;
+$label-line-height-sm:             0.9;
+$label-line-height-lg:             1.2;
 $label-font-weight:                $font-weight-normal !default;
 $label-box-shadow:                 none;
 $label-font-size:                  inherit;
@@ -38,8 +40,8 @@ $label-danger-color:               $white;
 $label-danger-bg:                  $red !default;
 $label-danger-border:              $red !default;
 
-$label-padding-x-sm:               0.25rem;
-$label-padding-y-sm:               0.15rem;
+$label-padding-x-sm:               $label-padding-x;
+$label-padding-y-sm:               $label-padding-y;
 
 $label-padding-x-lg:               0.75rem !default;
 $label-padding-y-lg:               0.5rem !default;
@@ -57,7 +59,7 @@ $label-transition:                 all .2s ease-in-out !default;
 .label {
     display: inline-block;
     font-weight: $label-font-weight;
-    line-height: $label-line-height !important;
+    line-height: $label-line-height;
     text-align: center;
     white-space: nowrap;
     vertical-align: middle;
@@ -68,7 +70,7 @@ $label-transition:                 all .2s ease-in-out !default;
     border: $label-border-width solid transparent;
     box-shadow: $label-box-shadow;
 
-    @include button-size($label-padding-y, $label-padding-x, $label-font-size, $label-border-radius, $label-border-radius);
+    @include button-size($label-padding-y, $label-padding-x, $label-font-size, $label-line-height, $label-border-radius);
     @include transition($label-transition);
 }
 
@@ -151,11 +153,11 @@ a.label-danger,
 
 .label-lg {
   // line-height: ensure even-numbered height of button next to large input
-  @include button-size($label-padding-y-lg, $label-padding-x-lg, $font-size-lg, $label-border-radius-lg, $btn-border-radius-lg);
+  @include button-size($label-padding-y-lg, $label-padding-x-lg, $font-size-lg, $label-line-height-lg, $label-border-radius-lg);
 }
 .label-sm {
   // line-height: ensure proper height of button next to small input
-  @include button-size($label-padding-y-sm, $label-padding-x-sm, $font-size-sm, $label-border-radius-sm, $btn-border-radius-sm);
+  @include button-size($label-padding-y-sm, $label-padding-x-sm, $font-size-sm, $label-line-height-sm, $label-border-radius-sm);
 }
 
 
diff --git a/scipost/static/scipost/assets/css/_list_group.scss b/scipost/static/scipost/assets/css/_list_group.scss
index 264f3b0cc35a92fc8ecc210a1b31a0c501241250..3eba4ebb4a87c24b1c427517cb1a7e39cfefce2f 100644
--- a/scipost/static/scipost/assets/css/_list_group.scss
+++ b/scipost/static/scipost/assets/css/_list_group.scss
@@ -18,9 +18,7 @@ ul.events-list {
         border: 0;
 
         .time {
-            max-width: 10rem;
             min-width: 10rem;
-            width: 10rem;
         }
     }
 }
diff --git a/submissions/admin.py b/submissions/admin.py
index 43a8cf5f2693715798f60c5fa9be8f2c55555fa7..4535d7767c20f104f586128b6a730318a496158b 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -36,6 +36,7 @@ class SubmissionAdminForm(forms.ModelForm):
         required=False,
         queryset=Contributor.objects.order_by('user__last_name'))
     is_resubmission_of = forms.ModelChoiceField(
+        required=False,
         queryset=Submission.objects.order_by('-preprint__identifier_w_vn_nr'))
 
     class Meta:
diff --git a/submissions/forms.py b/submissions/forms.py
index d1409ffe6239699749a970d5d2c2e31b68663d8c..6055a553ad48e67b3caf1b197b16403406443eca 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -7,6 +7,7 @@ import re
 
 from django import forms
 from django.conf import settings
+from django.contrib.postgres.search import TrigramSimilarity
 from django.db import transaction
 from django.db.models import Q
 from django.forms.formsets import ORDERING_FIELD_NAME
@@ -22,6 +23,7 @@ from .constants import (
     STATUS_EIC_ASSIGNED, CYCLE_DEFAULT, CYCLE_DIRECT_REC, STATUS_PREASSIGNED, STATUS_REPLACED,
     STATUS_FAILED_PRESCREENING, STATUS_DEPRECATED, STATUS_ACCEPTED, STATUS_DECLINED)
 from . import exceptions, helpers
+from .helpers import to_ascii_only
 from .models import (
     Submission, RefereeInvitation, Report, EICRecommendation, EditorialAssignment,
     iThenticateReport, EditorialCommunication)
@@ -34,6 +36,7 @@ from mails.utils import DirectMailUtil
 from preprints.helpers import generate_new_scipost_identifier
 from preprints.models import Preprint
 from production.utils import get_or_create_production_stream
+from profiles.models import Profile
 from scipost.constants import SCIPOST_SUBJECT_AREAS
 from scipost.services import ArxivCaller
 from scipost.models import Contributor, Remark
@@ -455,7 +458,12 @@ class SubmissionForm(forms.ModelForm):
         Check if author list matches the Contributor submitting.
         """
         author_list = self.cleaned_data['author_list']
-        if not self.requested_by.last_name.lower() in author_list.lower():
+
+        # Remove punctuation and convert to ASCII-only string.
+        clean_author_name = to_ascii_only(self.requested_by.last_name)
+        clean_author_list = to_ascii_only(author_list)
+
+        if not clean_author_name in clean_author_list:
             error_message = ('Your name does not match that of any of the authors. '
                              'You are not authorized to submit this preprint.')
             self.add_error('author_list', error_message)
@@ -905,6 +913,11 @@ class RefereeSearchForm(forms.Form):
     last_name = forms.CharField(widget=forms.TextInput({
         'placeholder': 'Search for a referee in the SciPost Profiles database'}))
 
+    def search(self):
+        return Profile.objects.annotate(
+            similarity=TrigramSimilarity('last_name', self.cleaned_data['last_name']),
+        ).filter(similarity__gt=0.3).order_by('-similarity')
+
 
 class ConsiderRefereeInvitationForm(forms.Form):
     accept = forms.ChoiceField(widget=forms.RadioSelect, choices=ASSIGNMENT_BOOL,
@@ -1119,19 +1132,23 @@ class VetReportForm(forms.Form):
 
     def process_vetting(self, current_contributor):
         """Set the right report status and update submission fields if needed."""
-        self.report.vetted_by = current_contributor
+        report = self.cleaned_data['report']
         if self.cleaned_data['action_option'] == REPORT_ACTION_ACCEPT:
             # Accept the report as is
-            self.report.status = STATUS_VETTED
-            self.report.submission.latest_activity = timezone.now()
-            self.report.submission.save()
+            Report.objects.filter(id=report.id).update(
+                status=STATUS_VETTED,
+                vetted_by=current_contributor,
+            )
+            report.submission.touch()
         elif self.cleaned_data['action_option'] == REPORT_ACTION_REFUSE:
             # The report is rejected
-            self.report.status = self.cleaned_data['refusal_reason']
+            Report.objects.filter(id=report.id).update(
+                status=self.cleaned_data['refusal_reason'],
+            )
         else:
             raise exceptions.InvalidReportVettingValue(self.cleaned_data['action_option'])
-        self.report.save()
-        return self.report
+        report.refresh_from_db()
+        return report
 
 
 ###################
diff --git a/submissions/helpers.py b/submissions/helpers.py
index f5f6c2eec90610caaee1abe4aa4ce9d3560ba11a..b9cac5c9b25be45f47de78637c9c06c48883b2a0 100644
--- a/submissions/helpers.py
+++ b/submissions/helpers.py
@@ -2,7 +2,9 @@ __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import re
 import requests
+import unicodedata
 
 from .exceptions import ArxivPDFNotFound
 
@@ -43,3 +45,11 @@ def check_unverified_author(submission, user):
     return (
         user.last_name in submission.author_list and
         not submission.authors_false_claims.filter(user=user).exists())
+
+
+def to_ascii_only(str):
+    """
+    Convert string to lowercase, ASCII-only characters without punctuation and whitespaces.
+    """
+    str = re.sub(r'[^\w]','', str).lower()
+    return unicodedata.normalize('NFKD', str).encode('ascii','ignore')
diff --git a/submissions/migrations/0051_auto_20181218_2201.py b/submissions/migrations/0051_auto_20181218_2201.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba283d598ba89b96dd225f5b62ac40832e6a1837
--- /dev/null
+++ b/submissions/migrations/0051_auto_20181218_2201.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-18 21:01
+from __future__ import unicode_literals
+
+from django.db import migrations
+from django.contrib.postgres.operations import TrigramExtension
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0050_merge_20181207_1008'),
+    ]
+
+    operations = [
+        TrigramExtension(),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 4a1edea25c95267902bb2ca1bccf432bd9b22948..581cff18f76398ac4e406404aa359af9d2b3dd3d 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -37,6 +37,7 @@ from scipost.behaviors import TimeStampedModel
 from scipost.constants import TITLE_CHOICES
 from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS
 from scipost.fields import ChoiceArrayField
+from scipost.models import Contributor
 from scipost.storage import SecureFileStorage
 from journals.constants import SCIPOST_JOURNALS_DOMAINS
 from journals.models import Publication
@@ -377,6 +378,21 @@ class Submission(models.Model):
 
         return self.editorial_assignments.filter(status=STATUS_PREASSIGNED).exists()
 
+    def has_inadequate_pool_composition(self):
+        """
+        Check whether the EIC actually in the pool of the Submission.
+
+        (Could happen on resubmission or reassignment after wrong Journal selection)
+        """
+        if not self.editor_in_charge:
+            # None assigned yet.
+            return False
+
+        pool_contributors_ids = Contributor.objects.filter(
+            fellowships__pool=self).values_list('id', flat=True)
+        return self.editor_in_charge.id not in pool_contributors_ids
+
+
 
 class SubmissionEvent(SubmissionRelatedObjectMixin, TimeStampedModel):
     """Private message directly related to a Submission.
diff --git a/submissions/templates/partials/submissions/pool/required_actions_block.html b/submissions/templates/partials/submissions/pool/required_actions_block.html
index 7ae18b18c3b9d3334e7a41f495fc10c74ced96c7..388cdf8eb97c84b015442f9e7beff716f0a39957 100644
--- a/submissions/templates/partials/submissions/pool/required_actions_block.html
+++ b/submissions/templates/partials/submissions/pool/required_actions_block.html
@@ -5,8 +5,8 @@
         </div>
         <div class="card-body">
             <ul class="mb-0">
-                {% for key, action in submission.cycle.required_actions.items %}
-                    <li>{{ action|safe }}</li>
+                {% for code, action in submission.cycle.required_actions.items %}
+                    <li>{{ action }}</li>
                 {% empty %}
                     <li>No actions required</li>
                 {% endfor %}
diff --git a/submissions/templates/partials/submissions/pool/required_actions_tooltip.html b/submissions/templates/partials/submissions/pool/required_actions_tooltip.html
index b4fd08f7745729e83a4a3aea6cac65e4374e16c0..0fd1c822b83ac0866e1bcc4e0f908b7048aa2303 100644
--- a/submissions/templates/partials/submissions/pool/required_actions_tooltip.html
+++ b/submissions/templates/partials/submissions/pool/required_actions_tooltip.html
@@ -2,7 +2,7 @@
     <i class="fa fa-exclamation-circle {{ classes }}" data-toggle="tooltip" data-html="true" title="
         Required Actions:
         <ul class='mb-0 pl-3 text-left'>
-            {% for key, action in submission.cycle.required_actions.items %}
+            {% for code, action in submission.cycle.required_actions.items %}
                 <li>{{ action }}</li>
             {% endfor %}
         </ul>
diff --git a/submissions/templates/partials/submissions/pool/submission_li.html b/submissions/templates/partials/submissions/pool/submission_li.html
index d20e0cafddf9cdda00505c57206eca29dc73d350..e0478684cadc51d2c5ede8c314de8908e1693d97 100644
--- a/submissions/templates/partials/submissions/pool/submission_li.html
+++ b/submissions/templates/partials/submissions/pool/submission_li.html
@@ -1,4 +1,7 @@
 {% load submissions_pool %}
+{% load user_groups %}
+
+{% is_edcol_admin request.user as is_editorial_admin %}
 
 <div class="icons">
     {% include 'partials/submissions/pool/submission_tooltip.html' with submission=submission %}
@@ -53,7 +56,14 @@
             <span class="label label-sm label-secondary">{{ submission.get_status_display }}</span>
         </div>
     </div>
-
+    {% if is_editorial_admin and submission.has_inadequate_pool_composition %}
+        <div class="border border-danger text-danger mt-1 py-1 px-2">
+            <strong>
+                <i class="fa fa-exclamation-triangle"></i>
+                Notice to admin: The current editor is not assigned to the pool. Therefore, the editor will not be able to reach the editorial page.
+            </strong>
+        </div>
+    {% endif %}
     {% if submission.cycle.has_required_actions %}
         <div class="card-text bg-danger text-white mt-1 py-1 px-2">
             <a href="{% url 'submissions:pool' submission.preprint.identifier_w_vn_nr %}" class="text-white mr-1" data-toggle="dynamic" data-target="#container_{{ submission.id }}">This Submission contains required actions, click here to see details.</a>
diff --git a/submissions/templates/partials/submissions/pool/submission_reports_summary_table.html b/submissions/templates/partials/submissions/pool/submission_reports_summary_table.html
index be733be294f8a265ac1360a58b639d33822bc3c4..76c0b2924b33edbc67da1168437e794b605c703a 100644
--- a/submissions/templates/partials/submissions/pool/submission_reports_summary_table.html
+++ b/submissions/templates/partials/submissions/pool/submission_reports_summary_table.html
@@ -12,13 +12,8 @@
     <tbody>
         {% for report in submission.reports.all %}
             <tr{% if report.is_unvetted %} class="table-warning"{% endif %}>
-                <td class="text-center">
-                    {% if report.is_unvetted %}
-                    <div class="text-center" data-toggle="tooltip" data-title="This Report has not yet been vetted." data-html="true">
-                        <i class="fa fa-info"></i>
-                        <i class="fa fa-long-arrow-right" ></i>
-                    </div>
-                    {% endif %}
+                <td class="px-4">
+                    <strong>{{ report.report_nr }}</strong>
                 </td>
                 <td>
                     {{ report.author }}
diff --git a/submissions/templates/submissions/admin/submission_presassign_editors.html b/submissions/templates/submissions/admin/submission_presassign_editors.html
index 8b4724bd259ee02760ee7b371ec8600d7ff7d690..f525000a3929a0850bff518286295d887f91a683 100644
--- a/submissions/templates/submissions/admin/submission_presassign_editors.html
+++ b/submissions/templates/submissions/admin/submission_presassign_editors.html
@@ -179,7 +179,8 @@
                                 <div class="single d-inline specialization" data-specialization="{{expertise|lower}}" data-toggle="tooltip" data-placement="bottom" title="{{expertise|get_specialization_display}}">{{expertise|get_specialization_code}}</div>
                             {% endfor %}
                         </td>
-                        <td>
+                        <td>{{ form.get_fellow }}
+                            {% comment %}
                             {% with submission.conflict_groups.all|filter_for_contributor:form.get_fellow as conflict_groups %}
                                 {% if conflict_groups %}
                                     {{ conflict_groups|length }} potential conflict{{ conflict_groups|length|pluralize }} found
@@ -227,6 +228,7 @@
                                     <em><i class="fa fa-check text-success" aria-hidden="true"></i> No conflicts found</em>
                                 {% endif %}
                             {% endwith %}
+                            {% endcomment %}
                         </td>
                     </tr>
                 {% endfor %}
@@ -265,7 +267,7 @@
         function update_conflict(conflict_id, status) {
             $.ajax({
                 "method": "POST",
-                "url": "{% url 'api:conflictofinterest-verify_conflict' 0 %}".replace("0", conflict_id),
+                {# "url": "{% url 'api:conflictofinterest-verify_conflict' 0 %}".replace("0", conflict_id), #}
                 "data": {
                     'status': status,
                     'csrftoken': getCookie('csrftoken'),
diff --git a/submissions/templates/submissions/pool/editorial_page.html b/submissions/templates/submissions/pool/editorial_page.html
index 8838426481a95ffc161e402f03de1f9736c63f6f..4a24c7fcb56decdccc777e5affceae81f2ab7fd2 100644
--- a/submissions/templates/submissions/pool/editorial_page.html
+++ b/submissions/templates/submissions/pool/editorial_page.html
@@ -312,6 +312,90 @@
         {% endif %}
     {% else %}
         {% if full_access %}
+                <h3>All available actions</h3>
+                <ul class="mb-5">
+                    {% if submission.refereeing_cycle != 'direct_rec' %}
+                        {% if submission.in_refereeing_phase %}
+                            <li>
+                                {% if submission.referee_invitations.all %}
+                                    <a href="{% url 'submissions:select_referee' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">Invite an additional referee</a>
+                                {% else %}
+                                    <a href="{% url 'submissions:select_referee' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">Invite the first referee here</a>
+                                {% endif %}
+                            </li>
+                            <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline|date:'Y-m-d' }}{% if submission.reporting_deadline_has_passed %} <span class="ml-1 label label-sm label-outline-danger text-uppercase">The reporting deadline has passed</span>{% endif %}) by
+                                <a href="{% url 'submissions:extend_refereeing_deadline' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr days=2 %}">2 days</a>,
+                                <a href="{% url 'submissions:extend_refereeing_deadline' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr days=7 %}">1 week</a> or
+                                <a href="{% url 'submissions:extend_refereeing_deadline' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr days=14 %}">2 weeks</a>
+                            </li>
+                        {% endif %}
+                        <li>
+                            Set refereeing deadline:
+                            <form class="form-inline d-inline-block" action="{% url 'submissions:set_refereeing_deadline' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" method="post">
+                                {% csrf_token %}
+                                <div class="d-inline-block mx-2">
+                                    {% for field in set_deadline_form.visible_fields %}
+                                        {{ field|add_css_class:'form-control' }}
+                                        {{ field }}
+                                    {% endfor %}
+                                </div>
+
+                                <input class="btn btn-outline-secondary btn-sm" type="submit" value="Set deadline"/>
+                            </form>
+                        </li>
+
+                        {% if submission.is_open_for_reporting %}
+                            <li><a href="{% url 'submissions:close_refereeing_round' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">Close the refereeing round</a> &nbsp;(deactivates submission of new Reports and Comments)</li>
+                        {% endif %}
+                    {% endif %}
+                    {% with submission.reports.awaiting_vetting as reports %}
+                        {% if reports %}
+                            <li>
+                                Vet submitted Report{{reports|pluralize}}:
+                                <ul class="mb-1">
+                                    {% for report in reports %}
+                                        <li><a href="{% url 'submissions:vet_submitted_report' report.id %}">Report {{ report.report_nr }} by {{ report.author }} ({{ report.get_report_type_display }})</a></li>
+                                    {% endfor %}
+                                </ul>
+                            </li>
+                        {% else %}
+                            <li>All Reports have been vetted.</li>
+                        {% endif %}
+                    {% endwith %}
+
+                    {% with submission.comments_set_complete.awaiting_vetting as comments %}
+                        {% if comments %}
+                            <li>
+                                Vet submitted Comment{{comments|pluralize}}:
+                                <ul class="mb-1">
+                                    {% for comment in comments %}
+                                        <li><a href="{% url 'comments:vet_submitted_comment' comment.id %}">{{comment}}</a></li>
+                                    {% endfor %}
+                                </ul>
+                            </li>
+                        {% else %}
+                            <li>All Comments have been vetted.</li>
+                        {% endif %}
+                    {% endwith %}
+                    {% if submission.eic_recommendation_required %}
+                        <li>
+                            {% if submission.eicrecommendations.last %}
+                                <a href="{% url 'submissions:reformulate_eic_recommendation' submission.preprint.identifier_w_vn_nr %}">Reformulate Editorial Recommendation</a>
+                            {% else %}
+                                <a href="{% url 'submissions:eic_recommendation' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">Formulate an Editorial Recommendation.</a>
+                            {% endif %}
+                            <p>
+                                If you recommend revisions, this will be communicated directly to the Authors, who will be asked to resubmit.
+                                <br>
+                                If you recommend acceptance or rejection, this will be put to the Editorial College for ratification.
+                            </p>
+                        </li>
+                    {% elif submission.eicrecommendations.last %}
+                        {% if submission.eicrecommendations.last.may_be_reformulated %}
+                            <li><a href="{% url 'submissions:reformulate_eic_recommendation' submission.preprint.identifier_w_vn_nr %}">Reformulate Editorial Recommendation</a></li>
+                        {% endif %}
+                    {% endif %}
+                </ul>
 
                 {% if submission.refereeing_cycle != 'direct_rec' %}
                     <h3 class="mt-3" id="referee-details">Refereeing invitations</h3>
diff --git a/submissions/utils.py b/submissions/utils.py
index 813c9e5031a78e4e6cbc0b4ab0977204ad0c81b5..0165b036a6df382470582e534f2ada440307b11d 100644
--- a/submissions/utils.py
+++ b/submissions/utils.py
@@ -581,20 +581,6 @@ class SubmissionUtils(BaseMailUtil):
                        [cls._context['invitation'].referee.user.email],
                        email_subject)
 
-    @classmethod
-    def email_EIC_report_delivered(cls):
-        """ Requires loading 'report' attribute. """
-        cls._send_mail(cls, 'report_delivered_eic',
-                       [cls._context['report'].submission.editor_in_charge.user.email],
-                       'Report delivered')
-
-    @classmethod
-    def email_referee_report_delivered(cls):
-        """ Requires loading 'report' attribute. """
-        cls._send_mail(cls, 'report_delivered_referee',
-                       [cls._context['report'].author.user.email],
-                       'Report delivered')
-
     @classmethod
     def acknowledge_report_email(cls):
         """ Requires loading 'report' attribute. """
diff --git a/submissions/views.py b/submissions/views.py
index 65f82868b4005d024527aa5bed8a5125d7531f8d..bcba648b0a60353bec278f373158554e687ef002 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -1,6 +1,7 @@
 __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
+
 import datetime
 import feedparser
 import strings
@@ -51,6 +52,7 @@ from common.utils import workdays_between
 from invitations.constants import STATUS_SENT
 from invitations.models import RegistrationInvitation
 from journals.models import Journal
+from mails.utils import DirectMailUtil
 from mails.views import MailEditingSubView
 from ontology.models import Topic
 from ontology.forms import SelectTopicForm
@@ -689,6 +691,12 @@ def editorial_assignment(request, identifier_w_vn_nr, assignment_id=None):
             if form.is_normal_cycle():
                 # Inform authors about new status.
                 SubmissionUtils.send_author_prescreening_passed_email()
+            else:
+                # Inform authors about new status.
+                mail_sender = DirectMailUtil(
+                    mail_code='authors/inform_authors_eic_assigned_direct_eic',
+                    assignment=submission)
+                mail_sender.send()
 
             submission.add_general_event('The Editor-in-charge has been assigned.')
             notify_editor_assigned(request.user, assignment, False)
@@ -917,11 +925,9 @@ def select_referee(request, identifier_w_vn_nr):
                                    preprint__identifier_w_vn_nr=identifier_w_vn_nr)
     context = {}
     queryresults = ''
-    referee_search_form = RefereeSearchForm(request.GET or None)
-    if referee_search_form.is_valid():
-        profiles_found = Profile.objects.filter(
-            last_name__icontains=referee_search_form.cleaned_data['last_name'])
-        context['profiles_found'] = profiles_found
+    form = RefereeSearchForm(request.GET or None)
+    if form.is_valid():
+        context['profiles_found'] = form.search()
         # Check for recent co-authorship (thus referee disqualification)
         try:
             sub_auth_boolean_str = '((' + (submission
@@ -930,7 +936,7 @@ def select_referee(request, identifier_w_vn_nr):
             for author in submission.metadata['entries'][0]['authors'][1:]:
                 sub_auth_boolean_str += '+OR+' + author['name'].split()[-1]
             sub_auth_boolean_str += ')+AND+'
-            search_str = sub_auth_boolean_str + referee_search_form.cleaned_data['last_name'] + ')'
+            search_str = sub_auth_boolean_str + form.cleaned_data['last_name'] + ')'
             queryurl = ('https://export.arxiv.org/api/query?search_query=au:%s'
                         % search_str + '&sortBy=submittedDate&sortOrder=descending'
                         '&max_results=5')
@@ -942,7 +948,7 @@ def select_referee(request, identifier_w_vn_nr):
     context.update({
         'submission': submission,
         'workdays_left_to_report': workdays_between(timezone.now(), submission.reporting_deadline),
-        'referee_search_form': referee_search_form,
+        'referee_search_form': form,
         'queryresults': queryresults,
         'profile_email_form': ProfileEmailForm(initial={'primary': True}),
     })
@@ -1534,9 +1540,16 @@ def submit_report(request, identifier_w_vn_nr):
                 'identifier_w_vn_nr': identifier_w_vn_nr}))
 
         # Send mails if report is submitted
-        SubmissionUtils.load({'report': newreport}, request)
-        SubmissionUtils.email_EIC_report_delivered()
-        SubmissionUtils.email_referee_report_delivered()
+        mail_sender = DirectMailUtil(
+            mail_code='referees/inform_referee_report_received',
+            instance=newreport,
+            delayed_processing=True)
+        mail_sender.send()
+        mail_sender = DirectMailUtil(
+            mail_code='eic/inform_eic_report_received',
+            instance=newreport,
+            delayed_processing=True)
+        mail_sender.send()
 
         # Add SubmissionEvents for the EIC only, as it can also be rejected still
         submission.add_event_for_eic('%s has submitted a new Report.'
@@ -1596,7 +1609,6 @@ def vet_submitted_report(request, report_id):
         # Add SubmissionEvent for the EIC
         report.submission.add_event_for_eic('The Report by %s is vetted.'
                                             % report.author.user.last_name)
-
         if report.status == STATUS_VETTED:
             SubmissionUtils.send_author_report_received_email()
 
diff --git a/templates/email/authors/inform_authors_eic_assigned_direct_rec.html b/templates/email/authors/inform_authors_eic_assigned_direct_rec.html
new file mode 100644
index 0000000000000000000000000000000000000000..e2f489e94ae9dc7430be4b0c90f6f6134ebd57dc
--- /dev/null
+++ b/templates/email/authors/inform_authors_eic_assigned_direct_rec.html
@@ -0,0 +1,19 @@
+<p>
+    Dear {{ submission.submitted_by.get_title_display }} {{ submission.submitted_by.user.last_name }},
+</p>
+<p>
+  For your information, a Contributor Comment has been posted on a recent Report on your Submission
+  <br><br>
+  {{ submission.title }}
+  <br>by {{ submission.author_list }}<br>
+  (see https://scipost.org{{ submission.get_absolute_url }}.
+</p>
+
+<p>has been assigned to an editor. The editor chose to directly formulate an Editorial Recommendation.</p>
+<p>You will be informed shortly by email about the status of this Editorial Recommendation.</p>
+
+<p>
+    Sincerely,
+    <br>
+    The SciPost Team.
+</p>
diff --git a/templates/email/authors/inform_authors_eic_assigned_direct_rec.json b/templates/email/authors/inform_authors_eic_assigned_direct_rec.json
new file mode 100644
index 0000000000000000000000000000000000000000..8d952bcb257fede2c6d20158fe25f078df5d1ed2
--- /dev/null
+++ b/templates/email/authors/inform_authors_eic_assigned_direct_rec.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: Editor assigned",
+    "to_address": "submitted_by.user.email",
+    "bcc_to": "edadmin@scipost.org",
+    "from_address_name": "SciPost Refereeing",
+    "from_address": "refereeing@scipost.org",
+    "context_object": "submission"
+}
diff --git a/templates/email/commenters/inform_commenter_comment_received.html b/templates/email/commenters/inform_commenter_comment_received.html
new file mode 100644
index 0000000000000000000000000000000000000000..4f648aba05a3470f9bdda7871a4cbe8ece242a04
--- /dev/null
+++ b/templates/email/commenters/inform_commenter_comment_received.html
@@ -0,0 +1,32 @@
+<p>Dear {{comment.author.get_title_display}} {{comment.author.user.last_name}},</p>
+<p>
+    We hereby confirm reception of your Comment, concerning
+
+    <br/>
+    {{comment.core_content_object.title}}
+    {% if comment.core_content_object.author_list %}
+        <br>
+        by {{comment.core_content_object.author_list}}.
+    {% elif comment.core_content_object.author %}
+        <br>
+        by {{comment.core_content_object.author}}.
+    {% endif %}
+</p>
+<p>
+    We copy it below for your convenience.
+    <br>
+    Your Comment will soon be vetted, at which point you will receive an email update from us.
+</p>
+<p>
+    Thank you for your contribution,<br><br>
+    The SciPost Team.
+</p>
+
+<br>
+<p>
+    Comment:
+    <br>
+    {{ comment.comment_text|linebreaksbr }}
+</p>
+
+{% include 'email/_footer.html' %}
diff --git a/templates/email/commenters/inform_commenter_comment_received.json b/templates/email/commenters/inform_commenter_comment_received.json
new file mode 100644
index 0000000000000000000000000000000000000000..d70d7953ed6e60d3f6c4dfb37383dba28fe481a9
--- /dev/null
+++ b/templates/email/commenters/inform_commenter_comment_received.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: Comment received",
+    "to_address": "author.user.email",
+    "bcc_to": "edadmin@scipost.org",
+    "from_address_name": "SciPost Comments",
+    "from_address": "edadmin@scipost.org",
+    "context_object": "comment"
+}
diff --git a/templates/email/eic/inform_eic_comment_received.html b/templates/email/eic/inform_eic_comment_received.html
new file mode 100644
index 0000000000000000000000000000000000000000..b4e2c780466369e3196e6478cdb40ee125bd6de4
--- /dev/null
+++ b/templates/email/eic/inform_eic_comment_received.html
@@ -0,0 +1,19 @@
+<p>Dear {{ comment.core_content_object.editor_in_charge.get_title_display }} {{ comment.core_content_object.editor_in_charge.user.last_name }},</p>
+
+<p>
+    {{ comment.author.get_title_display }} {{ comment.author.user.last_name }} has delivered a Comment for Submission:
+</p>
+<p>
+    {{ comment.core_content_object.title }}
+    <br/>
+    by {{ comment.core_content_object.author_list }}.
+</p>
+<p>
+    Please vet this Comment on <a href="https://scipost.org{% url 'submissions:editorial_page' comment.core_content_object.preprint.identifier_w_vn_nr %}">the editorial page</a>.
+</p>
+<p>
+    Many thanks in advance for your collaboration,<br>
+    The SciPost Team.
+</p>
+
+{% include 'email/_footer.html' %}
diff --git a/templates/email/eic/inform_eic_comment_received.json b/templates/email/eic/inform_eic_comment_received.json
new file mode 100644
index 0000000000000000000000000000000000000000..90f695dc362f97df8a00f14d636d9f2de08681ec
--- /dev/null
+++ b/templates/email/eic/inform_eic_comment_received.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: Comment delivered",
+    "to_address": "core_content_object.editor_in_charge.user.email",
+    "bcc_to": "edadmin@scipost.org",
+    "from_address_name": "SciPost Refereeing",
+    "from_address": "refereeing@scipost.org",
+    "context_object": "comment"
+}
diff --git a/templates/email/report_delivered_eic.html b/templates/email/eic/inform_eic_report_received.html
similarity index 100%
rename from templates/email/report_delivered_eic.html
rename to templates/email/eic/inform_eic_report_received.html
diff --git a/templates/email/eic/inform_eic_report_received.json b/templates/email/eic/inform_eic_report_received.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6ebfd554488bcca4b930d499b6b1124a7ab62fc
--- /dev/null
+++ b/templates/email/eic/inform_eic_report_received.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: Report delivered",
+    "to_address": "submission.editor_in_charge.user.email",
+    "bcc_to": "edadmin@scipost.org",
+    "from_address_name": "SciPost Editorial Admin",
+    "from_address": "submissions@scipost.org",
+    "context_object": "report"
+}
diff --git a/templates/email/report_delivered_referee.html b/templates/email/referees/inform_referee_report_received.html
similarity index 100%
rename from templates/email/report_delivered_referee.html
rename to templates/email/referees/inform_referee_report_received.html
diff --git a/templates/email/referees/inform_referee_report_received.json b/templates/email/referees/inform_referee_report_received.json
new file mode 100644
index 0000000000000000000000000000000000000000..300cb92e972cfa9438809bbff7211c26e8686440
--- /dev/null
+++ b/templates/email/referees/inform_referee_report_received.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: Report delivered",
+    "to_address": "author.user.email",
+    "bcc_to": "edadmin@scipost.org",
+    "from_address_name": "SciPost Editorial Admin",
+    "from_address": "submissions@scipost.org",
+    "context_object": "report"
+}
diff --git a/templates/email/report_delivered_eic.txt b/templates/email/report_delivered_eic.txt
deleted file mode 100644
index dae336cd5874d192c31780ad5ddde5a4891839fa..0000000000000000000000000000000000000000
--- a/templates/email/report_delivered_eic.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Dear {{ report.submission.editor_in_charge.get_title_display }} {{ report.submission.editor_in_charge.user.last_name }},
-
-Referee {{ report.author.get_title_display }} {{ report.author.user.last_name }} has delivered a Report for Submission
-
-{{ report.submission.title }}
-by {{ report.submission.author_list }}.
-
-Please vet this Report via your personal page at
-https://scipost.org{% url 'scipost:personal_page' %}, under the Editorial Actions tab.
-
-Many thanks in advance for your collaboration,
-The SciPost Team.
diff --git a/templates/email/report_delivered_referee.txt b/templates/email/report_delivered_referee.txt
deleted file mode 100644
index 0f1ad9982bdd609c5a7b25feda58af55a8483714..0000000000000000000000000000000000000000
--- a/templates/email/report_delivered_referee.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Dear {{ report.author.get_title_display }} {{ report.author.user.last_name }},
-
-We hereby confirm reception of your Report on Submission
-
-{{ report.submission.title }}
-by {{ report.submission.author_list }}.
-
-We are immensely grateful for your time and effort. Your Report will soon be vetted by the Submission's Editor-in-charge, at which point you will receive an email update from us.
-
-Many thanks again,
-The SciPost Team.