diff --git a/colleges/permissions.py b/colleges/permissions.py
index edfd198daba4bae9d7879cd27f371cb384fb8ee6..1130c79fce04a6cd65a74abb9d782f8b62922f68 100644
--- a/colleges/permissions.py
+++ b/colleges/permissions.py
@@ -7,9 +7,7 @@ from django.core.exceptions import PermissionDenied
 
 
 def fellowship_required():
-    """
-    Require user to have any Fellowship or Administrational permissions.
-    """
+    """Require user to have any Fellowship or Administrational permissions."""
     def test(u):
         if u.is_authenticated():
             if hasattr(u, 'contributor') and u.contributor.fellowships.exists():
@@ -20,9 +18,7 @@ def fellowship_required():
 
 
 def fellowship_or_admin_required():
-    """
-    Require user to have any Fellowship or Administrational permissions.
-    """
+    """Require user to have any Fellowship or Administrational permissions."""
     def test(u):
         if u.is_authenticated():
             if hasattr(u, 'contributor') and u.contributor.fellowships.exists():
diff --git a/journals/forms.py b/journals/forms.py
index 3bda2b4d1a31926f423b4cbdc89a037547cf1128..ee50f2522245e2e98af619cb787c90047598e9f3 100644
--- a/journals/forms.py
+++ b/journals/forms.py
@@ -31,6 +31,7 @@ from production.models import ProductionEvent
 from production.signals import notify_stream_status_change
 from scipost.forms import RequestFormMixin
 from scipost.services import DOICaller
+from submissions.constants import STATUS_PUBLISHED
 from submissions.models import Submission
 
 
@@ -624,7 +625,7 @@ class PublicationPublishForm(RequestFormMixin, forms.ModelForm):
         # Mark the submission as having been published:
         submission = self.instance.accepted_submission
         submission.published_as = self.instance
-        submission.status = 'published'
+        submission.status = STATUS_PUBLISHED
         submission.save()
 
         # Add SubmissionEvents
diff --git a/submissions/constants.py b/submissions/constants.py
index 61ec2e59e4478fd97c69d06b92b3ddfa44d6ce12..80cfdc7f191bc81cb63682acebee427410b00045 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -181,7 +181,7 @@ DECISION_FIXED, DEPRECATED = 'decision_fixed', 'deprecated'
 EIC_REC_STATUSES = (
     (VOTING_IN_PREP, 'Voting in preparation'),
     (PUT_TO_VOTING, 'Undergoing voting at the Editorial College'),
-    (VOTE_COMPLETED, 'Editorial College voting rounded up'),
+    (VOTE_COMPLETED, 'Editorial College voting rounded up'),  # Seemlingly dead?
     (DECISION_FIXED, 'Editorial Recommendation fixed'),
     (DEPRECATED, 'Editorial Recommendation deprecated'),
 )
diff --git a/submissions/forms.py b/submissions/forms.py
index 3032ccba35cb1e4d76faf19f23e9e2d3c5afd9e6..a1bc8675ecd513bfdf58ef1d0af7a66d38463255 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -510,12 +510,10 @@ class ConsiderAssignmentForm(forms.Form):
 
 
 class RefereeSelectForm(forms.Form):
-    last_name = forms.CharField()
+    """Pre-fill form to get the last name of the requested referee."""
 
-    def __init__(self, *args, **kwargs):
-        super(RefereeSelectForm, self).__init__(*args, **kwargs)
-        self.fields['last_name'].widget.attrs.update(
-            {'size': 20, 'placeholder': 'Search in contributors database'})
+    last_name = forms.CharField(widget=forms.TextInput({
+        'placeholder': 'Search in contributors database'}))
 
 
 class RefereeRecruitmentForm(forms.ModelForm):
@@ -1091,7 +1089,7 @@ class FixCollegeDecisionForm(forms.ModelForm):
         """Fix decision of EICRecommendation."""
         EICRecommendation.objects.filter(id=recommendation.id).update(status=DECISION_FIXED)
         submission = recommendation.submission
-        if recommendation in [REPORT_PUBLISH_1, REPORT_PUBLISH_2, REPORT_PUBLISH_3]:
+        if recommendation.recommendation in [REPORT_PUBLISH_1, REPORT_PUBLISH_2, REPORT_PUBLISH_3]:
             # Publish as Tier I, II or III
             Submission.objects.filter(id=submission.id).update(
                 visible_public=True, status=STATUS_ACCEPTED, acceptance_date=datetime.date.today(),
@@ -1124,7 +1122,7 @@ class FixCollegeDecisionForm(forms.ModelForm):
         EICRecommendation.objects.filter(id=recommendation.id).update(
             status=DEPRECATED, active=False)
         recommendation.submission.add_event_for_eic(
-            'The Editorial Recommendation (v{version}) has been deprecated: {decision}.'.format(
+            'The Editorial Recommendation (version {version}) has been deprecated: {decision}.'.format(
                 version=recommendation.version,
                 decision=recommendation.get_recommendation_display()))
 
diff --git a/submissions/plagiarism.py b/submissions/plagiarism.py
index 96aa68e46eafc76c525b6c0bfb00451ffe93d7da..f09bab2c44e210a0af433c59f85e00d4601ad175 100644
--- a/submissions/plagiarism.py
+++ b/submissions/plagiarism.py
@@ -14,14 +14,18 @@ class iThenticate:
         self.client = self.get_client()
 
     def get_client(self):
-        client = iThenticateAPI.API.Client(settings.ITHENTICATE_USERNAME,
-                                           settings.ITHENTICATE_PASSWORD)
+        client = iThenticateAPI.API.Client(
+            settings.ITHENTICATE_USERNAME, settings.ITHENTICATE_PASSWORD)
         if client.login():
             return client
         self.add_error(None, "Failed to login to iThenticate.")
         return None
 
     def determine_folder_group(self, group_re):
+        """Return the folder group id to which the system should upload a new document to.
+
+        Generates a new folder group if needed.
+        """
         groups = self.client.groups.all()
         if groups['status'] != 200:
             raise InvalidDocumentError("Uploading failed. iThenticate didn't return"
@@ -41,8 +45,7 @@ class iThenticate:
         return response['data'][0]['id']
 
     def determine_folder_id(self, submission):
-        """
-        Return the folder id to which the system should upload a new document to.
+        """Return the folder id to which the system should upload a new document to.
 
         Generates a new folder and id if needed.
         """
@@ -72,8 +75,7 @@ class iThenticate:
         return data['data'][0]['id']
 
     def upload_submission(self, document, submission):
-        """
-        Upload a document related to a submission
+        """Upload a document related to a submission.
 
         :document: The document to upload
         :submission: submission which should be uploaded
@@ -96,9 +98,7 @@ class iThenticate:
         return None
 
     def get_url(self, document_id):
-        """
-        Return report url for given document
-        """
+        """Return report url for given document."""
         response = self.client.reports.get(document_id)
 
         if response['status'] == 200:
diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html
index 1c27d127c1bfbeb5d0239821f8e7e4a1766f4453..d9e53d58fc7d0bc5940f7321faf5fc492a950424 100644
--- a/submissions/templates/submissions/submission_detail.html
+++ b/submissions/templates/submissions/submission_detail.html
@@ -74,11 +74,13 @@
 
 </div>
 
-{% if is_author or user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' %}
+{% if can_read_editorial_information or is_author %}
     {% for recommendation in recommendations %}
-        {% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' or recommendation|is_viewable_by_authors %}
-            {% include 'partials/submissions/recommendation_author_content.html' with recommendation=recommendation %}
-        {% endif %}
+        {% with is_author and recommendation|is_viewable_by_authors as author_viewable %}
+            {% if author_viewable or can_read_editorial_information %}
+                {% include 'partials/submissions/recommendation_author_content.html' with recommendation=recommendation %}
+            {% endif %}
+        {% endwith %}
     {% endfor %}
 
     <div class="mb-4">
@@ -89,8 +91,8 @@
     </div>
 {% endif %}
 
-{% if is_author or user|is_in_group:'Editorial Administrators' %}
-    {% if submission.production_stream.proofs.for_authors.exists %}
+{% if is_author or perms.scipost.can_oversee_refereeing %}
+
         <div class="mb-4" id="proofsslist">
             <h3>Proofs</h3>
             <ul>
@@ -115,7 +117,7 @@
     {% endif %}
 {% endif %}
 
-{% if user.is_authenticated and user|is_in_group:'Registered Contributors' %}
+{% if perms.scipost.can_submit_comments %}
 <div class="row">
     <div class="col-12">
         <h2 class="highlight">Actions</h2>
@@ -218,10 +220,12 @@
 
 
 {# This is an apparent redundant logic block; however, it makes sure the "login to ..." links wouldn't be shown twice! #}
-{% if not user.is_authenticated and submission.comments.vetted.exists %}
-    {% include 'comments/new_comment.html' with object_id=submission.id type_of_object='submission' open_for_commenting=submission.open_for_commenting user_is_referee=submission|user_is_referee:request.user %}
-{% elif user.is_authenticated %}
-    {% include 'comments/new_comment.html' with object_id=submission.id type_of_object='submission' open_for_commenting=submission.open_for_commenting user_is_referee=submission|user_is_referee:request.user %}
+{% if form=comment_form %}
+    {% if not user.is_authenticated and submission.comments.vetted.exists %}
+        {% include 'comments/new_comment.html' with form=comment_form object_id=submission.id type_of_object='submission' open_for_commenting=submission.open_for_commenting user_is_referee=submission|user_is_referee:request.user %}
+    {% elif user.is_authenticated %}
+        {% include 'comments/new_comment.html' with form=comment_form object_id=submission.id type_of_object='submission' open_for_commenting=submission.open_for_commenting user_is_referee=submission|user_is_referee:request.user %}
+    {% endif %}
 {% endif %}
 
 {% endblock content %}
diff --git a/submissions/views.py b/submissions/views.py
index a1c69ff7d62d52ba21f726bd848769200831e884..f70391cd51302e97ee151829f196226796ef47b5 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -192,7 +192,10 @@ def submission_detail_wo_vn_nr(request, arxiv_identifier_wo_vn_nr):
 def submission_detail(request, arxiv_identifier_w_vn_nr):
     """Public detail page of Submission."""
     submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
-    context = {}
+    context = {
+        'can_read_editorial_information': False
+    }
+
     if hasattr(request.user, 'contributor'):
         # Check if Contributor is author of the Submission
         is_author = submission.authors.filter(user=request.user).exists()
@@ -218,7 +221,8 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
                 contributor__user=request.user).exists():
                     raise Http404
 
-    form = CommentForm()
+    if submission.open_for_commenting and request.user.perms.has_perms('scipost.can_submit_comments'):
+        context['comment_form'] = CommentForm()
 
     invited_reports = submission.reports.accepted().invited()
     contributed_reports = submission.reports.accepted().contributed()
@@ -228,6 +232,16 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
     # User is referee for the Submission
     if request.user.is_authenticated:
         invitations = submission.referee_invitations.filter(referee__user=request.user)
+
+        # User may read eg. Editorial Recommendations if he/she is in the Pool.
+        context['can_read_editorial_information'] = submission.fellows.filter(
+            contributor__user=request.user).exists()
+
+        # User may also read eg. Editorial Recommendations if he/she is editorial administrator.
+        if not context['can_read_editorial_information']:
+            context['can_read_editorial_information'] = request.user.has_perm(
+                'can_oversee_refereeing')
+
     else:
         invitations = None
     if invitations:
@@ -244,7 +258,6 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
         'contributed_reports': contributed_reports,
         'unfinished_report_for_user': unfinished_report_for_user,
         'author_replies': author_replies,
-        'form': form,
         'is_author': is_author,
         'is_author_unchecked': is_author_unchecked,
         'invitations': invitations,
@@ -284,8 +297,8 @@ def reports_accepted_list(request):
 
     This gives an overview of Report that need a PDF update/compilation.
     """
-    reports = (Report.objects.accepted()
-               .order_by('pdf_report', 'submission').prefetch_related('submission'))
+    reports = Report.objects.accepted().order_by(
+        'pdf_report', 'submission').prefetch_related('submission')
 
     if request.GET.get('submission'):
         reports = reports.filter(submission__arxiv_identifier_w_vn_nr=request.GET.get('submission'))
@@ -828,7 +841,8 @@ def recruit_referee(request, arxiv_identifier_w_vn_nr):
 @fellowship_or_admin_required()
 @transaction.atomic
 def send_refereeing_invitation(request, arxiv_identifier_w_vn_nr, contributor_id):
-    """
+    """Send RefereeInvitation to a registered Contributor.
+
     This method is called by the EIC from the submission's editorial_page,
     in the case where the referee is an identified Contributor.
     For a referee who isn't a Contributor yet, the method recruit_referee above
@@ -874,7 +888,8 @@ def send_refereeing_invitation(request, arxiv_identifier_w_vn_nr, contributor_id
 @login_required
 @fellowship_or_admin_required()
 def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id):
-    """
+    """Send reminder email to pending RefereeInvitations.
+
     This method is used by the Editor-in-charge from the editorial_page
     when a referee has been invited but hasn't answered yet.
     It can be used for registered as well as unregistered referees.
@@ -900,7 +915,8 @@ def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id):
 @login_required
 @permission_required('scipost.can_referee', raise_exception=True)
 def accept_or_decline_ref_invitations(request, invitation_id=None):
-    """
+    """Decide on RefereeInvitation.
+
     RefereeInvitations need to be either accepted or declined by the invited user
     using this view. The decision will be taken one invitation at a time.
     """
@@ -959,6 +975,7 @@ def accept_or_decline_ref_invitations(request, invitation_id=None):
 
 
 def decline_ref_invitation(request, invitation_key):
+    """Decline a RefereeInvitation."""
     invitation = get_object_or_404(RefereeInvitation, invitation_key=invitation_key,
                                    accepted__isnull=True)
 
@@ -991,12 +1008,12 @@ def decline_ref_invitation(request, invitation_key):
 
 @login_required
 def cancel_ref_invitation(request, arxiv_identifier_w_vn_nr, invitation_id):
-    """
-    This method is used by the Editor-in-charge from the editorial_page
-    to remove a referee for the list of invited ones.
-    It can be used for registered as well as unregistered referees.
+    """Cancel a RefereeInvitation.
 
-    Accessible for: Editor-in-charge and Editorial Administration
+    This method is used by the Editor-in-charge from the editorial_page to remove a referee
+    from the list of invited ones. It can be used for registered as well as unregistered referees.
+
+    Accessible for: Editor-in-charge and Editorial Administration.
     """
     try:
         submissions = Submission.objects.filter_for_eic(request.user)
@@ -1069,14 +1086,13 @@ def set_refereeing_deadline(request, arxiv_identifier_w_vn_nr):
 
 @login_required
 def close_refereeing_round(request, arxiv_identifier_w_vn_nr):
-    """
-    Called by the Editor-in-charge when a satisfactory number of
-    reports have been gathered.
-    Automatically emails the authors to ask them if they want to
-    round off any replies to reports or comments before the
-    editorial recommendation is formulated.
+    """Close Submission for refereeing.
 
-    Accessible for: Editor-in-charge and Editorial Administration
+    Called by the Editor-in-charge when a satisfactory number of reports have been gathered.
+    Automatically emails the authors to ask them if they want to round off any replies to
+    reports or comments before the editorial recommendation is formulated.
+
+    Accessible for: Editor-in-charge and Editorial Administration.
     """
     submission = get_object_or_404(Submission.objects.filter_for_eic(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
@@ -1104,9 +1120,9 @@ def refereeing_overview(request):
 
 @login_required
 def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None):
-    """
-    Communication between editor-in-charge, author or referee
-    occurring during the submission refereeing.
+    """Send refereeing related communication.
+
+    Communication may be between two of: editor-in-charge, author and referee.
     """
     referee = None
     if comtype in ['EtoA', 'EtoR', 'EtoS']:
@@ -1177,8 +1193,7 @@ def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None):
 @fellowship_or_admin_required()
 @transaction.atomic
 def eic_recommendation(request, arxiv_identifier_w_vn_nr):
-    """
-    Write EIC Recommendation.
+    """Write EIC Recommendation.
 
     Accessible for: Editor-in-charge and Editorial Administration
     """
@@ -1350,9 +1365,7 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
 @login_required
 @fellowship_or_admin_required()
 def vet_submitted_reports_list(request):
-    """
-    Reports with status `unvetted` will be shown (oldest first).
-    """
+    """List Reports with status `unvetted`."""
     submissions = get_list_or_404(Submission.objects.filter_for_eic(request.user))
     reports_to_vet = Report.objects.filter(
         submission__in=submissions).awaiting_vetting().order_by('date_submitted')
@@ -1364,16 +1377,21 @@ def vet_submitted_reports_list(request):
 @fellowship_or_admin_required()
 @transaction.atomic
 def vet_submitted_report(request, report_id):
-    """
-    Report with status `unvetted` will be shown. A user may only vet reports of submissions
-    he/she is EIC of or if he/she is SciPost Admin or Vetting Editor.
+    """List Reports with status `unvetted` for vetting purposes.
+
+    A user may only vet reports of submissions he/she is EIC of or if he/she is
+    SciPost Administratoror Vetting Editor.
 
     After vetting an email is sent to the report author, bcc EIC. If report
     has not been refused, the submission author is also mailed.
     """
-    submissions = Submission.objects.filter_for_eic(request.user)
-    report = get_object_or_404(Report.objects.filter(
-        submission__in=submissions).awaiting_vetting(), id=report_id)
+    if request.user.has_perms('scipost.can_vet_submitted_reports'):
+        # Vetting Editors may vote on everything.
+        report = get_object_or_404(Report.objects.awaiting_vetting(), id=report_id)
+    else:
+        submissions = Submission.objects.filter_for_eic(request.user)
+        report = get_object_or_404(Report.objects.filter(
+            submission__in=submissions).awaiting_vetting(), id=report_id)
 
     form = VetReportForm(request.POST or None, initial={'report': report})
     if form.is_valid():
@@ -1394,9 +1412,9 @@ def vet_submitted_report(request, report_id):
             # Add SubmissionEvent to tell the author about the new report
             report.submission.add_event_for_author('A new Report has been submitted.')
 
-        message = 'Submitted Report vetted for <a href="%s">%s</a>.' % (
-                    report.submission.get_absolute_url(),
-                    report.submission.arxiv_identifier_w_vn_nr)
+        message = 'Submitted Report vetted for <a href="{url}">{arxiv}</a>.'.format(
+            url=report.submission.get_absolute_url(),
+            arxiv=report.submission.arxiv_identifier_w_vn_nr)
         messages.success(request, message)
 
         if report.submission.editor_in_charge == request.user.contributor:
@@ -1496,11 +1514,11 @@ def vote_on_rec(request, rec_id):
 
 @permission_required('scipost.can_prepare_recommendations_for_voting', raise_exception=True)
 def remind_Fellows_to_vote(request):
-    """
-    This method sends an email to all Fellow with pending voting duties.
+    """Send an email to all Fellow with pending voting duties.
+
     It must be called by and Editorial Administrator.
 
-    TODO: This reminder function doesn't filter per submission?!
+    Possible TODO: This reminder function doesn't filter per submission?!
     """
     submissions = Submission.objects.pool_editable(request.user)
     recommendations = EICRecommendation.objects.active().filter(
@@ -1532,6 +1550,7 @@ def remind_Fellows_to_vote(request):
 class PreScreeningView(SubmissionAdminViewMixin, UpdateView):
     """Do pre-screening of new incoming Submissions."""
 
+    permission_required = 'scipost.can_run_pre_screening'
     queryset = Submission.objects.prescreening()
     template_name = 'submissions/admin/submission_prescreening.html'
     form_class = SubmissionPrescreeningForm