diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 861544adb28ad4486484f1974dffafa2cb563a9a..28b54d4d47b36226691056e38982ab5f4569efe6 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -95,6 +95,7 @@ INSTALLED_APPS = (
     'virtualmeetings',
     'production',
     'partners',
+    'funders',
     'webpack_loader',
 )
 
diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py
index adf26e3aa41c52e07475da80c70f1e99700c13c7..cb5b11d4bc6ea39ec73f242818ed3c5c5ebd5435 100644
--- a/SciPost_v1/urls.py
+++ b/SciPost_v1/urls.py
@@ -20,6 +20,7 @@ urlpatterns = [
     url(r'^commentaries/', include('commentaries.urls', namespace="commentaries")),
     url(r'^commentary/', include('commentaries.urls', namespace="commentaries")),
     url(r'^comments/', include('comments.urls', namespace="comments")),
+    url(r'^funders/', include('funders.urls', namespace="funders")),
     url(r'^journals/', include('journals.urls.general', namespace="journals")),
     url(r'^mailing_list/', include('mailing_lists.urls', namespace="mailing_lists")),
     url(r'^submissions/', include('submissions.urls', namespace="submissions")),
diff --git a/commentaries/models.py b/commentaries/models.py
index da8321b411630469c64122437bb5de53f452a870..27db6d732b4144dfb15a8ca6c86997a6ac04b7b1 100644
--- a/commentaries/models.py
+++ b/commentaries/models.py
@@ -4,7 +4,7 @@ from django.core.urlresolvers import reverse
 from django.template import Template, Context
 
 from journals.constants import SCIPOST_JOURNALS_DOMAINS
-from scipost.behaviors import ArxivCallable, TimeStampedModel
+from scipost.behaviors import TimeStampedModel
 from scipost.models import Contributor
 from scipost.constants import SCIPOST_DISCIPLINES, DISCIPLINE_PHYSICS, SCIPOST_SUBJECT_AREAS
 
@@ -12,7 +12,7 @@ from .constants import COMMENTARY_TYPES
 from .managers import CommentaryManager
 
 
-class Commentary(ArxivCallable, TimeStampedModel):
+class Commentary(TimeStampedModel):
     """
     A Commentary contains all the contents of a SciPost Commentary page for a given publication.
     """
@@ -72,10 +72,6 @@ class Commentary(ArxivCallable, TimeStampedModel):
     def __str__(self):
         return self.pub_title
 
-    @classmethod
-    def same_version_exists(self, identifier):
-        return self.objects.filter(arxiv_identifier=identifier).exists()
-
     def title_label(self):
         context = Context({
             'scipost_url': reverse('commentaries:commentary', args=(self.arxiv_or_DOI_string,)),
diff --git a/comments/templates/comments/_comment_identifier.html b/comments/templates/comments/_comment_identifier.html
index f30c460f3925344561cf1272f2c3c705523c92c9..3247be4b6f071feae71a2f1279ded6e0973f9f74 100644
--- a/comments/templates/comments/_comment_identifier.html
+++ b/comments/templates/comments/_comment_identifier.html
@@ -16,7 +16,7 @@
             {% if comment.in_reply_to_comment %}
                 (in reply to <a href="#comment_id{{comment.in_reply_to_comment.id}}">{{comment.in_reply_to_comment.comment.get_author_str}}</a> on {{comment.in_reply_to_comment.date_submitted|date:'Y-m-d'}})
             {% elif comment.in_reply_to_report %}
-                (in reply to <a href="#report_id{{comment.in_reply_to_report.id}}">
+                (in reply to <a href="#report_{{comment.in_reply_to_report.report_nr}}">
 
                 {% if not comment.in_reply_to_report.anonymous %}
                     {{comment.in_reply_to_report.get_author_str}}
diff --git a/comments/templates/comments/_comment_tex_template.html b/comments/templates/comments/_comment_tex_template.html
new file mode 100644
index 0000000000000000000000000000000000000000..b6540e82c6d45520961cb04feacc921b65b4e5d0
--- /dev/null
+++ b/comments/templates/comments/_comment_tex_template.html
@@ -0,0 +1,11 @@
+{% spaceless %}
+Received {{comment.date_submitted|date:'d-m-Y'}}\ \\
+{% if comment.file_attachment %}- \textit{This {% if comment.is_author_reply %}Author Reply{% else %}Comment{% endif %} has an Attachment, please download it online.}\ \\{% endif %}\ \\{{comment.comment_text}}
+{% endspaceless %}
+
+{% for subcomment in comment.nested_comments.vetted %}
+    \addcontentsline{toc}{subsection}{\protect\numberline{}{% if subcomment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.counter}} by {% if subcomment.anonymous %}anonymous{% else %}{{subcomment.author.user.first_name}} {{subcomment.author.user.last_name}}{% endif %} }
+
+    \subsection*{ {% if subcomment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.parentloop.counter}}.{{forloop.counter}} by {% if subcomment.anonymous %}anonymous{% else %}{{subcomment.author.user.first_name}} {{subcomment.author.user.last_name}}{% endif %} }
+    {% include 'comments/_comment_tex_template.html' with comment=subcomment %}
+{% endfor %}
diff --git a/comments/templates/comments/reply_to_report.html b/comments/templates/comments/reply_to_report.html
index 348d82701826f73a80777e21357ef24fbc042db9..d796bb1210d20cd90057e987d2eb59a5c9755c63 100644
--- a/comments/templates/comments/reply_to_report.html
+++ b/comments/templates/comments/reply_to_report.html
@@ -14,7 +14,7 @@
     <div class="row">
         <div class="col-12">
             {% if not is_author %}
-                <h2>(you are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page)</h2>
+                <h2>You are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page.</h2>
             {% else %}
                 <h2>The Submission concerned:</h2>
 
diff --git a/funders/__init__.py b/funders/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/funders/admin.py b/funders/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..d049c6c0f9c56085ce4857538938ef681b322d2a
--- /dev/null
+++ b/funders/admin.py
@@ -0,0 +1,9 @@
+from django.contrib import admin
+
+from .models import Funder, Grant
+
+
+admin.site.register(Funder)
+
+
+admin.site.register(Grant)
diff --git a/funders/apps.py b/funders/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..413a2e31ce19ca0141ad1185bba7b99059676c38
--- /dev/null
+++ b/funders/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class FundersConfig(AppConfig):
+    name = 'funders'
diff --git a/funders/forms.py b/funders/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..64676af4446f442411f856981a0393bf8a512945
--- /dev/null
+++ b/funders/forms.py
@@ -0,0 +1,22 @@
+from django import forms
+
+from .models import Funder, Grant
+
+class FunderRegistrySearchForm(forms.Form):
+    name = forms.CharField(max_length=128)
+
+
+class FunderForm(forms.ModelForm):
+    class Meta:
+        model = Funder
+        fields = ['name', 'identifier',]
+
+
+class GrantForm(forms.ModelForm):
+    class Meta:
+        model = Grant
+        fields = ['funder', 'number', 'recipient_name', 'recipient',]
+
+
+class GrantSelectForm(forms.Form):
+    grant = forms.ModelChoiceField(queryset=Grant.objects.all())
diff --git a/funders/migrations/0001_initial.py b/funders/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..bf7e7e4fbf8e63399cdbd03efaeaad0edc080a0d
--- /dev/null
+++ b/funders/migrations/0001_initial.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 15:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('scipost', '0059_auto_20170701_1356'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Funder',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=256)),
+                ('identifier', models.CharField(max_length=200, unique=True)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Grant',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('number', models.CharField(max_length=64)),
+                ('recipient_name', models.CharField(blank=True, max_length=64, null=True)),
+                ('funder', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='funders.Funder')),
+                ('recipient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor')),
+            ],
+        ),
+    ]
diff --git a/funders/migrations/0002_auto_20170725_2011.py b/funders/migrations/0002_auto_20170725_2011.py
new file mode 100644
index 0000000000000000000000000000000000000000..c689cf120f8d2cb66918c65a7d4726e3250c0ac9
--- /dev/null
+++ b/funders/migrations/0002_auto_20170725_2011.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 18:11
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funders', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='funder',
+            options={'ordering': ['name']},
+        ),
+        migrations.AlterModelOptions(
+            name='grant',
+            options={'ordering': ['funder', 'recipient', 'recipient_name', 'number']},
+        ),
+    ]
diff --git a/funders/migrations/0003_auto_20170726_0606.py b/funders/migrations/0003_auto_20170726_0606.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7c8df068e205aade1009695525a669cf16c6100
--- /dev/null
+++ b/funders/migrations/0003_auto_20170726_0606.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-26 04:06
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funders', '0002_auto_20170725_2011'),
+    ]
+
+    operations = [
+        migrations.AlterUniqueTogether(
+            name='grant',
+            unique_together=set([('funder', 'number')]),
+        ),
+    ]
diff --git a/funders/migrations/__init__.py b/funders/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/funders/models.py b/funders/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..3957bf92f13ae9a3825a06aa780e68c6063e6b73
--- /dev/null
+++ b/funders/models.py
@@ -0,0 +1,41 @@
+from django.db import models
+
+
+class Funder(models.Model):
+    """
+    Funding info metadata is linked to funders from Crossref's
+    Fundref registry.
+    """
+    name = models.CharField(max_length=256)
+    identifier = models.CharField(max_length=200, unique=True)
+
+    class Meta:
+        ordering = ['name']
+
+    def __str__(self):
+        return self.name
+
+
+class Grant(models.Model):
+    """
+    An instance of a grant, award or other funding.
+    In a Publication's metadata, all grants are listed
+    in the Crossmark part of the metadata.
+    """
+    funder = models.ForeignKey(Funder, on_delete=models.CASCADE)
+    number = models.CharField(max_length=64)
+    recipient_name = models.CharField(max_length=64, blank=True, null=True)
+    recipient = models.ForeignKey('scipost.Contributor', blank=True, null=True,
+                                  on_delete=models.CASCADE)
+
+    class Meta:
+        ordering = ['funder', 'recipient', 'recipient_name', 'number']
+        unique_together = ('funder', 'number')
+
+    def __str__(self):
+        grantstring = '%s, grant number %s' % (str(self.funder), self.number)
+        if self.recipient:
+            grantstring += ' (%s)' % str(self.recipient)
+        elif self.recipient_name:
+            grantstring += ' (%s)' % self.recipient_name
+        return grantstring
diff --git a/funders/templates/funders/funders.html b/funders/templates/funders/funders.html
new file mode 100644
index 0000000000000000000000000000000000000000..7ae67d06b8fa03d6fb504cd5475f30f1c22120cb
--- /dev/null
+++ b/funders/templates/funders/funders.html
@@ -0,0 +1,133 @@
+{% extends 'scipost/base.html' %}
+
+{% block pagetitle %}: Funders{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block content %}
+
+<div class="row">
+  <div class="col-12">
+        <h1 class="highlight">Funders (and associated grants)</h1>
+  </div>
+</div>
+
+
+<div class="row">
+    <div class="col-12">
+        <div class="tab-nav-container">
+            <div class="tab-nav-inner">
+                <!-- Nav tabs -->
+                <ul class="nav btn-group personal-page-nav" role="tablist">
+                  <li class="nav-item btn btn-secondary">
+                    <a href="#funders" class="nav-link active" data-toggle="tab">Funders</a>
+                  </li>
+                  <li class="nav-item btn btn-secondary">
+                    <a href="#grants" class="nav-link" data-toggle="tab">Grants</a>
+                  </li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+
+<div class="tab-content">
+
+  <!-- Tab: Funders -->
+  <div class="tab-pane active" id="funders" role="tabpanel">
+    <div class="row">
+      <div class="col-12">
+        <h2 class="highlight">Funders</h2>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="col-12">
+	<h2>Find a new funder in the Fundref registry</h2>
+        <form action="{% url 'funders:query_crossref_for_funder' %}" method="post">
+          {% csrf_token %}
+          {{form|bootstrap}}
+          <input class="btn btn-secondary" type="submit" value="Search">
+        </form>
+	<br/>
+	<h2>Funders in the SciPost database</h2>
+	<table class="table table-hover mb-5">
+	  <thead class="thead-default">
+	    <tr>
+	      <th>Name</th>
+	      <th>Identifier</th>
+	    </tr>
+	  </thead>
+	  <tbody id="accordion" role="tablist" aria-multiselectable="true">
+	    {% for funder in funders %}
+	    <tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ funder.id }}" aria-expanded="true" aria-controls="collapse{{ funder.id }}" style="cursor: pointer;">
+	      <td>{{ funder.name }}</td>
+	      <td>{{ funder.identifier }}</td>
+	    </tr>
+            {% empty %}
+            <tr>
+              <td colspan="3">No funders found</td>
+            </tr>
+	    {% endfor %}
+	  </tbody>
+	</table>
+      </div>
+    </div>
+  </div>
+
+
+  <!-- Tab: Grants -->
+  <div class="tab-pane" id="grants" role="tabpanel">
+    <div class="row">
+      <div class="col-12">
+        <h2 class="highlight">Grants</h2>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="col-12">
+	<h2>Add a grant</h2>
+        <form action="{% url 'funders:add_grant' %}" method="post">
+          {% csrf_token %}
+          {{grant_form|bootstrap}}
+          <input class="btn btn-secondary" type="submit" value="Add">
+        </form>
+	<br/>
+	<h2>Grants in the SciPost database</h2>
+	<table class="table table-hover mb-5">
+	  <thead class="thead-default">
+	    <tr>
+	      <th>Funder Name</th>
+	      <th>Recipient</th>
+	      <th>Number</th>
+	    </tr>
+	  </thead>
+	  <tbody id="accordion" role="tablist" aria-multiselectable="true">
+	    {% for grant in grants %}
+	    <tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ grant.id }}" aria-expanded="true" aria-controls="collapse{{ grant.id }}" style="cursor: pointer;">
+	      <td>{{ grant.funder.name }}</td>
+	      {% if grant.recipient %}
+	      <td>{{ grant.recipient }}</td>
+	      {% elif grant.recipient_name %}
+	      <td>{{ grant.recipient_name }}</td>
+	      {% else %}
+	      <td></td>
+	      {% endif %}
+	      <td>{{ grant.number }}</td>
+	    </tr>
+            {% empty %}
+            <tr>
+              <td colspan="3">No grants found</td>
+            </tr>
+	    {% endfor %}
+	  </tbody>
+	</table>
+      </div>
+    </div>
+  </div>
+</div>
+
+
+{% endblock content %}
diff --git a/funders/templates/funders/query_crossref_for_funder.html b/funders/templates/funders/query_crossref_for_funder.html
new file mode 100644
index 0000000000000000000000000000000000000000..b8459c8a21ff63b830f9c8919fdefb2fe28f9174
--- /dev/null
+++ b/funders/templates/funders/query_crossref_for_funder.html
@@ -0,0 +1,48 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block pagetitle %}: Query Crossref for funder{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block content %}
+
+<div class="row">
+  <div class="col-12">
+        <h1 class="highlight">Query Crossref Fundref Registry for Funders</h1>
+        <form action="{% url 'funders:query_crossref_for_funder' %}" method="post">
+          {% csrf_token %}
+          {{form|bootstrap}}
+          <input class="btn btn-secondary" type="submit" value="Search">
+        </form>
+	{% if response_headers %}
+	<p>{{ response_headers }}</p>
+	{% endif %}
+	{% if response_text %}
+	<p>{{ response_text }}</p>
+	{% endif %}
+	{% if response %}
+	<p>{{ response }}</p>
+	<ul>
+	  {% for item in response.message.items %}
+	  <li>
+	    {{ item.name }}, {{ item.id }}, {{ item.uri }}
+	    <form action="{% url 'funders:add_funder' %}" method="post">
+              {% csrf_token %}
+	      <input name='name' style="width: 64%" value='{{ item.name }}'>
+	      <input name='identifier' style="width: 64%" value='{{ item.uri }}'>
+              <input class="btn btn-secondary" type="submit" value="Add this funder">
+	    </form>
+	  </li>
+	  {% endfor %}
+	</ul>
+	<form action="{% url 'funders:add_funder' %}" method="post">
+          {% csrf_token %}
+          {{funder_form|bootstrap}}
+          <input class="btn btn-secondary" type="submit" value="Submit">
+        </form>
+	{% endif %}
+  </div>
+</div>
+
+
+{% endblock content %}
diff --git a/funders/tests.py b/funders/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/funders/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/funders/urls.py b/funders/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec3521ede5af0392724a07aca2ab22f95403c0c7
--- /dev/null
+++ b/funders/urls.py
@@ -0,0 +1,18 @@
+from django.conf.urls import url
+from django.views.generic import TemplateView
+
+from . import views
+
+urlpatterns = [
+    url(r'^$', views.funders,
+        name='funders'),
+    url(r'^query_crossref_for_funder$',
+        views.query_crossref_for_funder,
+        name='query_crossref_for_funder'),
+    url(r'^add_funder$',
+        views.add_funder,
+        name='add_funder'),
+    url(r'^add_grant$',
+        views.add_grant,
+        name='add_grant'),
+]
diff --git a/funders/views.py b/funders/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..50f46f967e463036e4f4d78e4a3a641643ed182c
--- /dev/null
+++ b/funders/views.py
@@ -0,0 +1,65 @@
+import requests
+import json
+
+from django.contrib import messages
+from django.contrib.auth.decorators import permission_required
+from django.core.urlresolvers import reverse
+from django.shortcuts import render, redirect
+
+from .models import Funder, Grant
+from .forms import FunderRegistrySearchForm, FunderForm, GrantForm
+
+
+@permission_required('scipost.can_publish_accepted_submission', raise_exception=True)
+def funders(request):
+    funders = Funder.objects.all()
+    form = FunderRegistrySearchForm()
+    grants = Grant.objects.all()
+    grant_form = GrantForm()
+    context = {'form': form, 'funders': funders,
+               'grants': grants, 'grant_form': grant_form}
+    return render(request, 'funders/funders.html', context)
+
+
+@permission_required('scipost.can_publish_accepted_submission', raise_exception=True)
+def query_crossref_for_funder(request):
+    """
+    Checks Crossref's Fundref Registry for an entry
+    corresponding to the funder name being looked for.
+    If found, creates a funders.Funder instance.
+    """
+    form = FunderRegistrySearchForm(request.POST or None)
+    context = {'form': form}
+    if form.is_valid():
+        queryurl = 'http://api.crossref.org/funders?query=%s' % form.cleaned_data['name']
+        query = requests.get(queryurl)
+        response = json.loads(query.text)
+        context['response_headers'] = query.headers
+        context['response_text'] = query.text
+        context['response'] = response
+        context['funder_form'] = FunderForm()
+    return render(request, 'funders/query_crossref_for_funder.html', context)
+
+
+@permission_required('scipost.can_publish_accepted_submission', raise_exception=True)
+def add_funder(request):
+    form = FunderForm(request.POST or None)
+    if form.is_valid():
+        funder = form.save()
+        messages.success(request, ('<h3>Funder %s successfully created</h3>') %
+                         str(funder))
+    elif form.has_changed():
+        messages.warning(request, 'The form was invalidly filled.')
+    return redirect(reverse('funders:funders'))
+
+
+@permission_required('scipost.can_publish_accepted_submission', raise_exception=True)
+def add_grant(request):
+    grant_form = GrantForm(request.POST or None)
+    if grant_form.is_valid():
+        grant = grant_form.save()
+        messages.success(request, ('<h3>Grant %s successfully added</h3>') %
+                         str(grant))
+    elif grant_form.has_changed():
+        messages.warning(request, 'The form was invalidly filled (grant already exists?).')
+    return redirect(reverse('funders:funders'))
diff --git a/journals/admin.py b/journals/admin.py
index 6b5f4cecdf14c7289cd748ca007979ae20f083c9..0ed07f17e294622f403b9d3823ca201d673bb53e 100644
--- a/journals/admin.py
+++ b/journals/admin.py
@@ -64,6 +64,7 @@ class PublicationAdmin(admin.ModelAdmin):
 admin.site.register(Publication, PublicationAdmin)
 
 
+
 class DepositAdmin(admin.ModelAdmin):
     list_display = ('publication', 'timestamp', 'doi_batch_id', 'deposition_date',)
     readonly_fields = ('publication', 'doi_batch_id', 'metadata_xml', 'deposition_date',)
diff --git a/journals/forms.py b/journals/forms.py
index eb54e4deb587df7ccbc6bbb533d2eb6450988883..688ade7e6c2f450da0473aeadc48cabb756c1dff 100644
--- a/journals/forms.py
+++ b/journals/forms.py
@@ -8,21 +8,13 @@ from .models import UnregisteredAuthor, Issue, Publication
 from submissions.models import Submission
 
 
-
 class InitiatePublicationForm(forms.Form):
-    accepted_submission = forms.ModelChoiceField(
-        queryset=Submission.objects.filter(status='accepted'))
-    original_submission_date = forms.DateField()
-    acceptance_date = forms.DateField()
+    accepted_submission = forms.ModelChoiceField(queryset=Submission.objects.accepted())
     to_be_issued_in = forms.ModelChoiceField(
         queryset=Issue.objects.filter(until_date__gt=timezone.now()))
 
     def __init__(self, *args, **kwargs):
         super(InitiatePublicationForm, self).__init__(*args, **kwargs)
-        self.fields['original_submission_date'].widget.attrs.update(
-            {'placeholder': 'YYYY-MM-DD'})
-        self.fields['acceptance_date'].widget.attrs.update(
-            {'placeholder': 'YYYY-MM-DD'})
 
 
 class ValidatePublicationForm(forms.ModelForm):
@@ -30,7 +22,7 @@ class ValidatePublicationForm(forms.ModelForm):
         model = Publication
         exclude = ['authors', 'authors_claims', 'authors_false_claims',
                    'metadata', 'metadata_xml',
-                   'latest_activity', ]
+                   'latest_activity']
 
 
 class UnregisteredAuthorForm(forms.ModelForm):
@@ -66,16 +58,22 @@ class FundingInfoForm(forms.Form):
     funding_statement = forms.CharField(widget=forms.Textarea())
 
     def __init__(self, *args, **kwargs):
-        super(FundingInfoForm, self).__init__(*args, **kwargs)
-        self.fields['funding_statement'].widget.attrs.update(
-            {'rows': 10, 'cols': 50,
-             'placeholder': 'Paste the funding info statement here'})
+        super().__init__(*args, **kwargs)
+        self.fields['funding_statement'].widget.attrs.update({
+            'rows': 10,
+            'cols': 50,
+            'placeholder': 'Paste the funding info statement here'
+        })
 
 
-class CreateMetadataXMLForm(forms.Form):
-    metadata_xml = forms.CharField(widget=forms.Textarea())
+class CreateMetadataXMLForm(forms.ModelForm):
+    class Meta:
+        model = Publication
+        fields = ['metadata_xml']
 
     def __init__(self, *args, **kwargs):
-        super(CreateMetadataXMLForm, self).__init__(*args, **kwargs)
-        self.fields['metadata_xml'].widget.attrs.update(
-            {'rows': 50, 'cols': 50, })
+        super().__init__(*args, **kwargs)
+        self.fields['metadata_xml'].widget.attrs.update({
+            'rows': 50,
+            'cols': 50
+        })
diff --git a/journals/migrations/0036_auto_20170725_1729.py b/journals/migrations/0036_auto_20170725_1729.py
new file mode 100644
index 0000000000000000000000000000000000000000..65ec9846bc191d8d6962a9c67e79a59a8af30302
--- /dev/null
+++ b/journals/migrations/0036_auto_20170725_1729.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 15:29
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('scipost', '0059_auto_20170701_1356'),
+        ('journals', '0035_auto_20170714_0609'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Funder',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=256)),
+                ('identifier', models.CharField(max_length=200, unique=True)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Grant',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('number', models.CharField(max_length=64)),
+                ('recipient_name', models.CharField(blank=True, max_length=64, null=True)),
+                ('funder', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Funder')),
+                ('recipient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='grants',
+            field=models.ManyToManyField(blank=True, null=True, to='journals.Grant'),
+        ),
+    ]
diff --git a/journals/migrations/0036_auto_20170725_2048.py b/journals/migrations/0036_auto_20170725_2048.py
new file mode 100644
index 0000000000000000000000000000000000000000..0f740ec130985368925a88ae469fc465d5b4d1a9
--- /dev/null
+++ b/journals/migrations/0036_auto_20170725_2048.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 18:48
+from __future__ import unicode_literals
+
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0035_auto_20170714_0609'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='publication',
+            name='metadata_DOAJ',
+            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default={}, null=True),
+        ),
+    ]
diff --git a/journals/migrations/0037_auto_20170725_1730.py b/journals/migrations/0037_auto_20170725_1730.py
new file mode 100644
index 0000000000000000000000000000000000000000..db456745ef9aa668ae34fc88ee197461a03ec30f
--- /dev/null
+++ b/journals/migrations/0037_auto_20170725_1730.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 15:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0036_auto_20170725_1729'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='publication',
+            name='grants',
+            field=models.ManyToManyField(blank=True, to='journals.Grant'),
+        ),
+    ]
diff --git a/journals/migrations/0038_auto_20170725_1738.py b/journals/migrations/0038_auto_20170725_1738.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d32403d115b27f88615e7f48c243a70f6c71d9b
--- /dev/null
+++ b/journals/migrations/0038_auto_20170725_1738.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 15:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0037_auto_20170725_1730'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='grant',
+            name='funder',
+        ),
+        migrations.RemoveField(
+            model_name='grant',
+            name='recipient',
+        ),
+        migrations.RemoveField(
+            model_name='publication',
+            name='grants',
+        ),
+        migrations.DeleteModel(
+            name='Funder',
+        ),
+        migrations.DeleteModel(
+            name='Grant',
+        ),
+    ]
diff --git a/journals/migrations/0039_publication_grants.py b/journals/migrations/0039_publication_grants.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b2f9b1c3e2c66f38a68cc2d6290d5e4c2da2614
--- /dev/null
+++ b/journals/migrations/0039_publication_grants.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 15:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funders', '0001_initial'),
+        ('journals', '0038_auto_20170725_1738'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='publication',
+            name='grants',
+            field=models.ManyToManyField(blank=True, to='funders.Grant'),
+        ),
+    ]
diff --git a/journals/migrations/0040_merge_20170726_0945.py b/journals/migrations/0040_merge_20170726_0945.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2c7a67aca6e2f637275e1ea48b8fc99b88b63eb
--- /dev/null
+++ b/journals/migrations/0040_merge_20170726_0945.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-26 07:45
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0036_auto_20170725_2048'),
+        ('journals', '0039_publication_grants'),
+    ]
+
+    operations = [
+    ]
diff --git a/journals/models.py b/journals/models.py
index 722fdccdf2790733789b411c760645a8a462d4e4..0953c805a28042c65e1c62ea131ea8772344c48f 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -142,10 +142,11 @@ class Publication(models.Model):
     abstract = models.TextField()
     pdf_file = models.FileField(upload_to='UPLOADS/PUBLICATIONS/%Y/%m/', max_length=200)
     cc_license = models.CharField(max_length=32, choices=CC_LICENSES, default=CCBY4)
+    grants = models.ManyToManyField('funders.Grant', blank=True)
     metadata = JSONField(default={}, blank=True, null=True)
     metadata_xml = models.TextField(blank=True, null=True)  # for Crossref deposit
     latest_metadata_update = models.DateTimeField(blank=True, null=True)
-    metadata_DOAJ = JSONField(blank=True, null=True)
+    metadata_DOAJ = JSONField(default={}, blank=True, null=True)
     BiBTeX_entry = models.TextField(blank=True, null=True)
     doi_label = models.CharField(max_length=200, unique=True, db_index=True,
                                  validators=[doi_publication_validator])
@@ -216,7 +217,6 @@ class Publication(models.Model):
         return template.render(context)
 
 
-
 class Deposit(models.Model):
     """
     Each time a Crossref deposit is made for a Publication,
diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html
index b9ca627d8401da8c0d6225fff22d306c32f39045..89f1796afce4c103f9dba4c3e3b991e10555f8b6 100644
--- a/journals/templates/journals/manage_metadata.html
+++ b/journals/templates/journals/manage_metadata.html
@@ -56,11 +56,12 @@ event: "focusin"
     </tr>
     <tr id="collapse{{ publication.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ publication.id }}" style="background-color: #fff;">
       <td colspan="5">
-	<h3 class="ml-3">Actions</h3>
-        <ul>
-          <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }} {% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %})
-	    <div class="row">
-              <div class="col-md-5">
+
+	<h2 class="ml-3">Actions</h2>
+	<div class="row">
+          <div class="col-md-5">
+            <ul>
+              <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }} {% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %})
                 <p>registered authors:</p>
                 <ul>
                   {% for author in publication.authors.all %}
@@ -69,8 +70,6 @@ event: "focusin"
                   </li>
                   {% endfor %}
                 </ul>
-              </div>
-              <div class="col-md-5">
                 <p>unregistered authors:</p>
                 <ul>
                   {% for author_unreg in publication.authors_unregistered.all %}
@@ -79,20 +78,50 @@ event: "focusin"
                   </li>
                   {% endfor %}
                 </ul>
-              </div>
-	    </div>
-          </li>
-          <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li>
-          <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li>
-          <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li>
-
-          <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">(re)create metadata</a></li>
-          <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li>
-          <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li>
-	  <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li>
-	  <li><a href="{% url 'journals:metadata_DOAJ_deposit' doi_label=publication.doi_label %}">Deposit the metadata to DOAJ</a></li>
-        </ul>
-	<h3 class="ml-3">Crossref Deposits</h3>
+	      </li>
+              <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li>
+              <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li>
+              <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li>
+
+              <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">(re)create metadata</a></li>
+              <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li>
+              <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li>
+	      <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li>
+	      <li><a href="{% url 'journals:metadata_DOAJ_deposit' doi_label=publication.doi_label %}">Deposit the metadata to DOAJ</a></li>
+            </ul>
+          </div>
+
+          <div class="col-md-5">
+	    <h2>Funding info for this publication:</h2>
+	    {% if publication.funding_info %}
+	    <p>{{ publication.funding_info }}</p>
+	    {% else %}
+	    <p>No funding info was found</p>
+	    {% endif %}
+	    <h2>Grants associated to this publication:</h2>
+	    <ul>
+	      {% for grant in publication.grants.all %}
+	      <li> {{ grant }}</li>
+	      {% empty %}
+	      <li>no associated grants found</li>
+	      {% endfor %}
+	    </ul>
+	    <br/>
+	    <h3>Associate a grant to this publication:</h3>
+	    <form action="{% url 'journals:add_associated_grant' publication.doi_label %}" method="post">
+	      {% csrf_token %}
+	      {{associate_grant_form|bootstrap}}
+	      <input class="btn btn-secondary" type="submit" value="Add">
+	    </form>
+	    <h3>Other grant-related actions:</h3>
+	    <ul>
+	      <li><a href="{% url 'funders:funders' %}" target="_blank">go to the Funders page to add a Funder and/or Grant instance</a></li>
+	    </ul>
+	  </div>
+	</div>
+
+
+	<h2 class="ml-3">Crossref Deposits</h2>
 	<table class="ml-5">
 	  <thead class="thead-default">
 	    <th>Timestamp</th>
@@ -123,7 +152,7 @@ event: "focusin"
 	  </tbody>
 	</table>
 
-	<h3 class="ml-3">DOAJ Deposits</h3>
+	<h2 class="ml-3">DOAJ Deposits</h2>
 	<table class="ml-5">
 	  <thead class="thead-default">
 	    <th>Timestamp</th>
diff --git a/journals/urls/general.py b/journals/urls/general.py
index c785ce47b247e68ad07e3e2fa2422214f2ae15b7..b1ba8d539c6094835068874e38bb11008623b14e 100644
--- a/journals/urls/general.py
+++ b/journals/urls/general.py
@@ -50,6 +50,9 @@ urlpatterns = [
     url(r'^create_funding_info_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
         journals_views.create_funding_info_metadata,
         name='create_funding_info_metadata'),
+    url(r'^add_associated_grant/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
+        journals_views.add_associated_grant,
+        name='add_associated_grant'),
     url(r'^create_metadata_xml/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
         journals_views.create_metadata_xml,
         name='create_metadata_xml'),
diff --git a/journals/views.py b/journals/views.py
index bcfa7155dfcab9fd7881050ee0fca52a880dbc9d..4f073a1a6d6f7550840ed21fe9d4014398ca920b 100644
--- a/journals/views.py
+++ b/journals/views.py
@@ -9,10 +9,9 @@ from django.core.urlresolvers import reverse
 from django.core.files.base import ContentFile
 from django.conf import settings
 from django.contrib import messages
+from django.http import Http404
 from django.utils import timezone
 from django.shortcuts import get_object_or_404, render, redirect
-from django.template import Context
-from django.template.loader import get_template
 from django.db import transaction
 from django.http import HttpResponse
 
@@ -23,9 +22,12 @@ from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublication
                    UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm
 from .utils import JournalUtils
 
+from funders.models import Funder
 from submissions.models import Submission
 from scipost.models import Contributor
 
+from funders.forms import GrantSelectForm
+
 from guardian.decorators import permission_required
 
 
@@ -91,9 +93,9 @@ def accepted(request, doi_label):
     have been accepted but are not yet published.
     """
     journal = get_object_or_404(Journal, doi_label=doi_label)
-    accepted_SP_submissions = Submission.objects.filter(
-        submitted_to_journal=journal.name, status='accepted'
-    ).order_by('-latest_activity')
+    accepted_SP_submissions = (Submission.objects.accepted()
+                               .filter(submitted_to_journal=journal.name)
+                               .order_by('-latest_activity'))
     context = {
         'accepted_SP_submissions': accepted_SP_submissions,
         'journal': journal
@@ -151,72 +153,61 @@ def initiate_publication(request):
     This method prefills a ValidatePublicationForm for further
     processing (verification in validate_publication method).
     """
-    if request.method == 'POST':
-        initiate_publication_form = InitiatePublicationForm(request.POST)
-        if initiate_publication_form.is_valid():
-            submission = get_object_or_404(Submission, pk=initiate_publication_form.cleaned_data[
-                                                'accepted_submission'].id)
-            current_issue = get_object_or_404(Issue, pk=initiate_publication_form.cleaned_data[
-                                                'to_be_issued_in'].id)
-
-            # Determine next available paper number:
-            papers_in_current_volume = Publication.objects.filter(
-                in_issue__in_volume=current_issue.in_volume)
-            paper_nr = 1
-            while papers_in_current_volume.filter(paper_nr=paper_nr).exists():
-                paper_nr += 1
-                if paper_nr > 999:
-                    raise PaperNumberingError(paper_nr)
-            doi_label = (
-                current_issue.in_volume.in_journal.name
-                + '.' + str(current_issue.in_volume.number)
-                + '.' + str(current_issue.number) + '.' + paper_nr_string(paper_nr)
-            )
-            doi_string = '10.21468/' + doi_label
-            BiBTeX_entry = (
-                '@Article{' + doi_label + ',\n'
-                '\ttitle={{' + submission.title + '}},\n'
-                '\tauthor={' + submission.author_list.replace(',', ' and') + '},\n'
-                '\tjournal={'
-                + current_issue.in_volume.in_journal.get_abbreviation_citation()
-                + '},\n'
-                '\tvolume={' + str(current_issue.in_volume.number) + '},\n'
-                '\tissue={' + str(current_issue.number) + '},\n'
-                '\tpages={' + paper_nr_string(paper_nr) + '},\n'
-                '\tyear={' + current_issue.until_date.strftime('%Y') + '},\n'
-                '\tpublisher={SciPost},\n'
-                '\tdoi={' + doi_string + '},\n'
-                '\turl={https://scipost.org/' + doi_string + '},\n'
-                '}\n'
-            )
-            initial = {
-                'accepted_submission': submission,
-                'in_issue': current_issue,
-                'paper_nr': paper_nr,
-                'discipline': submission.discipline,
-                'domain': submission.domain,
-                'subject_area': submission.subject_area,
-                'secondary_areas': submission.secondary_areas,
-                'title': submission.title,
-                'author_list': submission.author_list,
-                'abstract': submission.abstract,
-                'BiBTeX_entry': BiBTeX_entry,
-                'doi_label': doi_label,
-                'submission_date': initiate_publication_form.cleaned_data['original_submission_date'],
-                'acceptance_date': initiate_publication_form.cleaned_data['acceptance_date'],
-                'publication_date': timezone.now(),
-                'latest_activity': timezone.now(),
-            }
-            validate_publication_form = ValidatePublicationForm(initial=initial)
-            context = {'validate_publication_form': validate_publication_form, }
-            return render(request, 'journals/validate_publication.html', context)
-        else:
-            errormessage = 'The form was not filled validly.'
-            context = {'initiate_publication_form': initiate_publication_form,
-                       'errormessage': errormessage}
-            return render(request, 'journals/initiate_publication.html', context)
-    else:
-        initiate_publication_form = InitiatePublicationForm()
+    initiate_publication_form = InitiatePublicationForm(request.POST or None)
+    if initiate_publication_form.is_valid():
+        submission = initiate_publication_form.cleaned_data['accepted_submission']
+        current_issue = initiate_publication_form.cleaned_data['to_be_issued_in']
+
+        # Determine next available paper number:
+        paper_nr = Publication.objects.filter(in_issue__in_volume=current_issue.in_volume).count()
+        paper_nr += 1
+        if paper_nr > 999:
+            raise PaperNumberingError(paper_nr)
+
+        # Build form data
+        doi_label = (
+            current_issue.in_volume.in_journal.name
+            + '.' + str(current_issue.in_volume.number)
+            + '.' + str(current_issue.number) + '.' + paper_nr_string(paper_nr)
+        )
+        doi_string = '10.21468/' + doi_label
+        BiBTeX_entry = (
+            '@Article{' + doi_label + ',\n'
+            '\ttitle={{' + submission.title + '}},\n'
+            '\tauthor={' + submission.author_list.replace(',', ' and') + '},\n'
+            '\tjournal={'
+            + current_issue.in_volume.in_journal.get_abbreviation_citation()
+            + '},\n'
+            '\tvolume={' + str(current_issue.in_volume.number) + '},\n'
+            '\tissue={' + str(current_issue.number) + '},\n'
+            '\tpages={' + paper_nr_string(paper_nr) + '},\n'
+            '\tyear={' + current_issue.until_date.strftime('%Y') + '},\n'
+            '\tpublisher={SciPost},\n'
+            '\tdoi={' + doi_string + '},\n'
+            '\turl={https://scipost.org/' + doi_string + '},\n'
+            '}\n'
+        )
+        initial = {
+            'accepted_submission': submission,
+            'in_issue': current_issue,
+            'paper_nr': paper_nr,
+            'discipline': submission.discipline,
+            'domain': submission.domain,
+            'subject_area': submission.subject_area,
+            'secondary_areas': submission.secondary_areas,
+            'title': submission.title,
+            'author_list': submission.author_list,
+            'abstract': submission.abstract,
+            'BiBTeX_entry': BiBTeX_entry,
+            'doi_label': doi_label,
+            'acceptance_date': submission.acceptance_date,
+            'submission_date': submission.submission_date,
+            'publication_date': timezone.now(),
+        }
+        validate_publication_form = ValidatePublicationForm(initial=initial)
+        context = {'validate_publication_form': validate_publication_form}
+        return render(request, 'journals/validate_publication.html', context)
+
     context = {'initiate_publication_form': initiate_publication_form}
     return render(request, 'journals/initiate_publication.html', context)
 
@@ -237,6 +228,7 @@ def validate_publication(request):
                                                         request.FILES or None)
     if validate_publication_form.is_valid():
         publication = validate_publication_form.save()
+
         # Fill in remaining data
         publication.pdf_file = request.FILES['pdf_file']
         submission = publication.accepted_submission
@@ -244,6 +236,7 @@ def validate_publication(request):
         publication.authors_claims.add(*submission.authors_claims.all())
         publication.authors_false_claims.add(*submission.authors_false_claims.all())
         publication.save()
+
         # Move file to final location
         initial_path = publication.pdf_file.path
         new_dir = (settings.MEDIA_ROOT + publication.in_issue.path + '/'
@@ -253,17 +246,23 @@ def validate_publication(request):
         os.rename(initial_path, new_path)
         publication.pdf_file.name = new_path
         publication.save()
+
         # Mark the submission as having been published:
-        publication.accepted_submission.published_as = publication
-        publication.accepted_submission.status = 'published'
-        publication.accepted_submission.save()
+        submission.published_as = publication
+        submission.status = 'published'
+        submission.save()
+
         # TODO: Create a Commentary Page
         # Email authors
         JournalUtils.load({'publication': publication})
         JournalUtils.send_authors_paper_published_email()
-        ack_header = 'The publication has been validated.'
-        context['ack_header'] = ack_header
-        return render(request, 'scipost/acknowledgement.html', context)
+
+        # Add SubmissionEvents
+        submission.add_general_event('The Submission has been published as %s.'
+                                     % publication.doi_label)
+
+        messages.success(request, 'The publication has been validated.')
+        return redirect(publication.get_absolute_url())
     else:
         context['errormessage'] = 'The form was invalid.'
 
@@ -274,8 +273,10 @@ def validate_publication(request):
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
 def manage_metadata(request):
     publications = Publication.objects.order_by('-publication_date', '-paper_nr')
+    associate_grant_form = GrantSelectForm()
     context = {
-        'publications': publications
+        'publications': publications,
+        'associate_grant_form': associate_grant_form,
     }
     return render(request, 'journals/manage_metadata.html', context)
 
@@ -361,14 +362,10 @@ def add_new_unreg_author(request, publication_id):
     if request.method == 'POST':
         new_unreg_author_form = UnregisteredAuthorForm(request.POST)
         if new_unreg_author_form.is_valid():
-            new_unreg_author = UnregisteredAuthor(
-                first_name=new_unreg_author_form.cleaned_data['first_name'],
-                last_name=new_unreg_author_form.cleaned_data['last_name'],)
-            new_unreg_author.save()
+            new_unreg_author = new_unreg_author_form.save()
             publication.authors_unregistered.add(new_unreg_author)
             return redirect(publication.get_absolute_url())
-    errormessage = 'Method add_new_unreg_author can only be called with POST.'
-    return render(request, 'scipost/error.html', context={'errormessage': errormessage})
+    raise Http404
 
 
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
@@ -404,27 +401,43 @@ def create_funding_info_metadata(request, doi_label):
     in the metadata field in a Publication instance.
     """
     publication = get_object_or_404(Publication, doi_label=doi_label)
-    if request.method == 'POST':
-        funding_info_form = FundingInfoForm(request.POST)
-        if funding_info_form.is_valid():
-            publication.metadata['funding_statement'] = funding_info_form.cleaned_data[
-                                                            'funding_statement']
-            publication.save()
 
-    initial = {'funding_statement': '', }
-    funding_statement = ''
+    funding_info_form = FundingInfoForm(request.POST or None)
+    if funding_info_form.is_valid():
+        publication.metadata['funding_statement'] = funding_info_form.cleaned_data[
+                                                        'funding_statement']
+        publication.save()
+
     try:
-        initial['funding_statement'] = publication.metadata['funding_statement']
+        initial = {'funding_statement': publication.metadata['funding_statement']}
         funding_statement = initial['funding_statement']
     except KeyError:
-        pass
+        initial = {'funding_statement': ''}
+        funding_statement = ''
+
     context = {'publication': publication,
                'funding_info_form': FundingInfoForm(initial=initial),
-               'funding_statement': funding_statement, }
+               'funding_statement': funding_statement}
 
     return render(request, 'journals/create_funding_info_metadata.html', context)
 
 
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+@transaction.atomic
+def add_associated_grant(request, doi_label):
+    """
+    Called by an Editorial Administrator.
+    This associates a grant from the database to this publication.
+    """
+    publication = get_object_or_404(Publication, doi_label=doi_label)
+    grant_select_form = GrantSelectForm(request.POST or None)
+    if grant_select_form.is_valid():
+        publication.grants.add(grant_select_form.cleaned_data['grant'])
+        publication.save()
+        messages.success(request, 'Grant added to publication %s' % str(publication))
+    return redirect(reverse('journals:manage_metadata'))
+
+
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
 @transaction.atomic
 def create_metadata_xml(request, doi_label):
@@ -436,12 +449,11 @@ def create_metadata_xml(request, doi_label):
     """
     publication = get_object_or_404(Publication, doi_label=doi_label)
 
-    if request.method == 'POST':
-        create_metadata_xml_form = CreateMetadataXMLForm(request.POST)
-        if create_metadata_xml_form.is_valid():
-            publication.metadata_xml = create_metadata_xml_form.cleaned_data['metadata_xml']
-            publication.save()
-            return redirect(reverse('journals:manage_metadata'))
+    create_metadata_xml_form = CreateMetadataXMLForm(request.POST or None, instance=publication)
+    if create_metadata_xml_form.is_valid():
+        create_metadata_xml_form.save()
+        messages.success(request, 'Metadata XML saved')
+        return redirect(reverse('journals:manage_metadata'))
 
     # create a doi_batch_id
     salt = ""
@@ -457,6 +469,7 @@ def create_metadata_xml(request, doi_label):
         '<?xml version="1.0" encoding="UTF-8"?>\n'
         '<doi_batch version="4.4.0" xmlns="http://www.crossref.org/schema/4.4.0" '
         'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
+        'xmlns:fr="http://www.crossref.org/fundref.xsd" '
         'xsi:schemaLocation="http://www.crossref.org/schema/4.4.0 '
         'http://www.crossref.org/shema/deposit/crossref4.4.0.xsd">\n'
         '<head>\n'
@@ -497,6 +510,7 @@ def create_metadata_xml(request, doi_label):
         '<titles><title>' + publication.title + '</title></titles>\n'
         '<contributors>\n'
     )
+
     # Precondition: all authors MUST be listed in authors field of publication instance,
     # this to be checked by EdAdmin before publishing.
     for author in publication.authors.all():
@@ -547,6 +561,31 @@ def create_metadata_xml(request, doi_label):
         '<crossmark_domain><domain>scipost.org</domain></crossmark_domain>\n'
         '</crossmark_domains>\n'
         '<crossmark_domain_exclusive>false</crossmark_domain_exclusive>\n'
+        '<custom_metadata>\n'
+        )
+    funders = Funder.objects.filter(grant__in=publication.grants.all()).distinct()
+    nr_funders = funders.count()
+    if nr_funders > 0:
+        initial['metadata_xml'] += '<fr:program name="fundref">\n'
+        for funder in funders:
+            if nr_funders > 1:
+                initial['metadata_xml'] += '<fr:assertion name="fundgroup">\n'
+            initial['metadata_xml'] += (
+                '<fr:assertion name="funder_name">' + funder.name + '\n'
+                '<fr:assertion name="funder_identifier">'
+                + funder.identifier + '</fr:assertion>\n'
+                '</fr:assertion>\n')
+            for grant in publication.grants.all():
+                if grant.funder == funder:
+                    initial['metadata_xml'] += (
+                        '<fr:assertion name="award_number">'
+                        + grant.number + '</fr:assertion>\n')
+            if nr_funders > 1:
+                initial['metadata_xml'] += '</fr:assertion>\n'
+        initial['metadata_xml'] += '</fr:program>\n'
+
+    initial['metadata_xml'] += (
+        '</custom_metadata>\n'
         '</crossmark>\n'
         '<archive_locations><archive name="CLOCKSS"></archive></archive_locations>\n'
         '<doi_data>\n'
@@ -576,12 +615,13 @@ def create_metadata_xml(request, doi_label):
         '</journal>\n'
     )
     initial['metadata_xml'] += '</body>\n</doi_batch>'
+
     publication.latest_metadata_update = timezone.now()
     publication.save()
-
-    context = {'publication': publication,
-               'create_metadata_xml_form': CreateMetadataXMLForm(initial=initial),
-               }
+    context = {
+        'publication': publication,
+        'create_metadata_xml_form': CreateMetadataXMLForm(initial=initial, instance=publication),
+    }
     return render(request, 'journals/create_metadata_xml.html', context)
 
 
@@ -621,10 +661,7 @@ def metadata_xml_deposit(request, doi_label, option='test'):
         'login_passwd': settings.CROSSREF_LOGIN_PASSWORD,
         }
     files = {'fname': ('metadata.xml', publication.metadata_xml, 'multipart/form-data')}
-    r = requests.post(url,
-                      params=params,
-                      files=files,
-                      )
+    r = requests.post(url, params=params, files=files)
     response_headers = r.headers
     response_text = r.text
 
@@ -731,13 +768,6 @@ def metadata_DOAJ_deposit(request, doi_label):
     f.write(publication.metadata_DOAJ)
     f.close()
 
-    # response_headers = r.headers
-    # response_text = r.text
-    # context = {
-    #     'publication': publication,
-    #     'response_headers': response_headers,
-    #     'response_text': response_text,
-    # }
     messages.success(request, '<h3>%s</h3>Successfull deposit of metadata DOAJ.'
                               % publication.doi_label)
     return redirect(reverse('journals:manage_metadata'))
@@ -795,7 +825,7 @@ def harvest_citedby_links(request, doi_label):
               'pwd': settings.CROSSREF_LOGIN_PASSWORD,
               'qdata': query_xml,
               'doi': publication.doi_string, }
-    r = requests.post(url, params=params,)
+    r = requests.post(url, params=params)
     if r.status_code == 401:
         messages.warning(request, ('<h3>Crossref credentials are invalid.</h3>'
                                    'Please contact the SciPost Admin.'))
diff --git a/partners/managers.py b/partners/managers.py
index 2b3e4b390a9ce49512f1a0dc01783ea7c582a968..d542b138578ce59188e4a7e20b462d54d0dec067 100644
--- a/partners/managers.py
+++ b/partners/managers.py
@@ -1,5 +1,4 @@
 from django.db import models
-from django.db.models import F
 from django.utils import timezone
 
 from .constants import MEMBERSHIP_SUBMITTED, PROSPECTIVE_PARTNER_PROCESSED, REQUEST_INITIATED
diff --git a/partners/migrations/0012_auto_20170625_1253.py b/partners/migrations/0012_auto_20170625_1253.py
new file mode 100644
index 0000000000000000000000000000000000000000..30925ad9583c28dc83c6796e46480923b23d73f2
--- /dev/null
+++ b/partners/migrations/0012_auto_20170625_1253.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-25 10:53
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0011_auto_20170609_2234'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='prospectivepartnerevent',
+            name='event',
+            field=models.CharField(choices=[('requested', 'Requested (from online form)'), ('comment', 'Comment added'), ('email_sent', 'Email sent'), ('negotiating', 'Initiated negotiation'), ('marked_as_uninterested', 'Marked as uninterested'), ('promoted', 'Promoted to Partner')], max_length=64),
+        ),
+    ]
diff --git a/partners/migrations/0027_merge_20170707_1857.py b/partners/migrations/0027_merge_20170707_1857.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7cc870609266767c610c3011cac24be5ecca2c0
--- /dev/null
+++ b/partners/migrations/0027_merge_20170707_1857.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-07 16:57
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0012_auto_20170625_1253'),
+        ('partners', '0026_auto_20170627_1809'),
+    ]
+
+    operations = [
+    ]
diff --git a/partners/migrations/0028_merge_20170724_1840.py b/partners/migrations/0028_merge_20170724_1840.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f4c6d0143be160c234a0e5284516bc1145d53a3
--- /dev/null
+++ b/partners/migrations/0028_merge_20170724_1840.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 16:40
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0027_merge_20170707_1857'),
+        ('partners', '0027_membershipagreement_end_date'),
+    ]
+
+    operations = [
+    ]
diff --git a/partners/migrations/0028_merge_20170724_1958.py b/partners/migrations/0028_merge_20170724_1958.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f39aef937f2a6b8532c416da7a1d1504a6cabc6
--- /dev/null
+++ b/partners/migrations/0028_merge_20170724_1958.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 17:58
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0027_membershipagreement_end_date'),
+        ('partners', '0027_merge_20170707_1857'),
+    ]
+
+    operations = [
+    ]
diff --git a/partners/migrations/0029_merge_20170726_0945.py b/partners/migrations/0029_merge_20170726_0945.py
new file mode 100644
index 0000000000000000000000000000000000000000..04f23ee6b5245d487ce7c1e100e37fdec75ef684
--- /dev/null
+++ b/partners/migrations/0029_merge_20170726_0945.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-26 07:45
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0028_merge_20170724_1958'),
+        ('partners', '0028_merge_20170724_1840'),
+    ]
+
+    operations = [
+    ]
diff --git a/scipost/behaviors.py b/scipost/behaviors.py
index 1140c889dd21a75820f85e10182286069b4a13f3..7904262e934152b73b11ce7374c979ee55b02c1f 100644
--- a/scipost/behaviors.py
+++ b/scipost/behaviors.py
@@ -4,16 +4,6 @@ from django.utils import timezone
 from .db.fields import AutoDateTimeField
 
 
-class ArxivCallable(object):
-    '''Models that contain a Arxiv identification should contain these
-    methods to be compatible with the ArxivCaller().
-    '''
-    @classmethod
-    def same_version_exists(self, identifier):
-        '''Check if the given identifier already is present in the database.'''
-        raise NotImplementedError
-
-
 class TimeStampedModel(models.Model):
     """
     All objects should inherit from this abstract model.
diff --git a/scipost/constants.py b/scipost/constants.py
index 7a37244c270c6ec72a85cc3312c5695332e9cc8f..30565b7314c13104136891ffca8981cfd41d6be7 100644
--- a/scipost/constants.py
+++ b/scipost/constants.py
@@ -1,5 +1,3 @@
-
-
 DISCIPLINE_PHYSICS = 'physics'
 DISCIPLINE_ASTROPHYSICS = 'astrophysics'
 DISCIPLINE_MATH = 'mathematics'
diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py
index d3d038c9c4facfd50eb84c6d950e4be179c5613a..f0c48b82fcd072ae442c9d478b61f52408025418 100644
--- a/scipost/management/commands/add_groups_and_permissions.py
+++ b/scipost/management/commands/add_groups_and_permissions.py
@@ -174,6 +174,12 @@ class Command(BaseCommand):
             name='Can oversee refereeing',
             content_type=content_type)
 
+        # Reports
+        can_manage_reports, created = Permission.objects.get_or_create(
+            codename='can_manage_reports',
+            name='Can manage Reports',
+            content_type=content_type)
+
         # Voting
         can_prepare_recommendations_for_voting, created = Permission.objects.get_or_create(
             codename='can_prepare_recommendations_for_voting',
@@ -252,6 +258,7 @@ class Command(BaseCommand):
             can_view_timesheets,
             can_publish_accepted_submission,
             can_attend_VGMs,
+            can_manage_reports,
         ])
 
         EditorialCollege.permissions.set([
diff --git a/scipost/services.py b/scipost/services.py
index 7a6707e8f7b84fab44f80726a0046724ed38bd23..9e61ccd731882f140a3095e7d0b7dfb786250892 100644
--- a/scipost/services.py
+++ b/scipost/services.py
@@ -1,15 +1,9 @@
 # Module for making external api calls as needed in the submissions cycle
 import feedparser
 import requests
-import re
 import datetime
 import dateutil.parser
 
-from django.template import Template, Context
-from .behaviors import ArxivCallable
-
-from strings import arxiv_caller_errormessages
-
 
 class DOICaller:
     def __init__(self, doi_string):
diff --git a/scipost/static/scipost/assets/css/_code.scss b/scipost/static/scipost/assets/css/_code.scss
index 6ef7af126c765ddc43e46b916902bc3ad54eea65..4a8d281e75da807866bdf5bc6a927612fb854f70 100644
--- a/scipost/static/scipost/assets/css/_code.scss
+++ b/scipost/static/scipost/assets/css/_code.scss
@@ -9,3 +9,7 @@ pre {
         margin: 0;
     }
 }
+
+.clickfocus {
+    cursor: pointer;
+}
diff --git a/scipost/static/scipost/assets/css/_list_group.scss b/scipost/static/scipost/assets/css/_list_group.scss
index 773da713e8db185741b7b2c6288588e6f557b5a8..53b101c3fca8f20a15148c8065f733cd8ea12217 100644
--- a/scipost/static/scipost/assets/css/_list_group.scss
+++ b/scipost/static/scipost/assets/css/_list_group.scss
@@ -2,3 +2,47 @@
  .list-group-noborder .list-group-item {
      border: 0;
  }
+
+ul.events-list {
+    padding-left: 30px;
+
+    &:before {
+        content: '';
+        width: 3px;
+        height: calc(100% - 16px);
+        position: absolute;
+        left: 20px;
+        background: $scipost-darkblue;
+        top: 16px;
+        z-index: 97;
+    }
+
+    li {
+        padding-top: 0.5rem;
+        padding-bottom: 0.5rem;
+
+        &:before {
+            content: '';
+            width: 13px;
+            height: 13px;
+            left: -25px;
+            border-radius: 99px;
+            position: absolute;
+            top: 11px;
+            background: #fff;
+            border: 3px solid $scipost-darkblue;
+            z-index: 99;
+        }
+
+        &:last-child:after {
+            content: '';
+            width: 3px;
+            height: calc(100% - 16px);
+            position: absolute;
+            left: -20px;
+            background: #fff;
+            bottom: 0;
+            z-index: 98;
+        }
+    }
+}
diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html
index 0e9f37b82cf2420c147d8329978e11a0877838e9..66207b001f604fe14d31e5234325c6fcb33daaf6 100644
--- a/scipost/templates/scipost/personal_page.html
+++ b/scipost/templates/scipost/personal_page.html
@@ -267,8 +267,12 @@
                             <h3>Editorial Admin actions</h3>
                             <ul>
                               {% if perms.scipost.can_publish_accepted_submission %}
-			      <li><a href="{% url 'journals:manage_metadata' %}">Manage metadata</a></li>
-                              <li><a href="{% url 'journals:harvest_citedby_list' %}">Harvest citedby data</a></li>
+                			      <li><a href="{% url 'journals:manage_metadata' %}">Manage metadata</a></li>
+                                  <li><a href="{% url 'journals:harvest_citedby_list' %}">Harvest citedby data</a></li>
+                              {% endif %}
+                              {% if perms.scipost.can_manage_reports %}
+                                  <li><a href="{% url 'submissions:reports_accepted_list' %}">Accepted Reports</a>{% if nr_reports_without_pdf %} ({{nr_reports_without_pdf}} unfinished){% endif %}</li>
+                                  <li><a href="{% url 'submissions:treated_submissions_list' %}">Fully treated Submissions</a>{% if nr_treated_submissions_without_pdf %} ({{nr_treated_submissions_without_pdf}} unfinished){% endif %}</li>
                               {% endif %}
                             </ul>
                         {% endif %}
@@ -392,17 +396,50 @@
                     </div>
                 </div>
 
-                {% if unfinished_reports %}
+                {% if contributor.reports.in_draft.exists %}
                     <div class="row">
                         <div class="col-12">
                             <h3>Unfinished reports:</h3>
                         </div>
                         <div class="col-12">
                             <ul class="list-group list-group-flush">
-                            {% for report in unfinished_reports %}
+                            {% for report in contributor.reports.in_draft.all %}
                                 <li class="list-group-item">
                                     <div class="w-100">{% include 'submissions/_submission_card_content.html' with submission=report.submission %}</div>
-                                    <div class="px-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
+                                    <div class="px-2 mb-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
+                                </li>
+                            {% endfor %}
+                            </ul>
+                        </div>
+                    </div>
+                {% endif %}
+
+                {% if contributor.reports.non_draft.exists %}
+                    <div class="row">
+                        <div class="col-12">
+                            <h3>Finished reports:</h3>
+                        </div>
+                        <div class="col-12">
+                            <ul class="list-group list-group-flush">
+                            {% for report in contributor.reports.non_draft.all %}
+                                <li class="list-group-item">
+                                    {% comment %}
+                                        Temporary: There is already a template for a "Report summary" in a parallel (unmerged) branch. Awaiting merge to use that template.
+                                    {% endcomment %}
+                                    <div class="card-block {% block cardblock_class_block %}{% endblock %}">
+                                        <h3>Report on Submission <a href="{{report.submission.get_absolute_url}}">{{report.submission.title}}</a></h3>
+                                        <table>
+                                            <tr>
+                                                <th style='min-width: 100px;'>Received:</th><td>{{ report.date_submitted|date:'Y-n-j' }}<td>
+                                            </tr>
+                                            <tr>
+                                                <th>Status:</th><td {% if report.status == 'vetted' %}class="text-success"{% elif report.status == 'unvetted' %}class="text-danger"{% endif %}>{{report.get_status_display}}</td>
+                                            </tr>
+                                            <tr>
+                                                <th>Anonymous:</th><td>{{report.anonymous|yesno:'Yes,No'}}</td>
+                                            </tr>
+                                        </table>
+                                    </div>
                                 </li>
                             {% endfor %}
                             </ul>
diff --git a/scipost/templatetags/texfilters.py b/scipost/templatetags/texfilters.py
new file mode 100644
index 0000000000000000000000000000000000000000..f8e3d05e6f587e54ef526741ccd29c4e0f7ebce7
--- /dev/null
+++ b/scipost/templatetags/texfilters.py
@@ -0,0 +1,26 @@
+from django import template
+from django.utils.html import escape
+from django.utils.text import normalize_newlines
+from django.utils.safestring import SafeData, mark_safe
+
+register = template.Library()
+
+
+@register.filter(is_safe=False, needs_autoescape=True)
+def linebreaktex(value, autoescape=True):
+    """
+    Convert all newlines in a piece of plain text to HTML line breaks
+    """
+    autoescape = autoescape and not isinstance(value, SafeData)
+    value = normalize_newlines(value)
+    if autoescape:
+        value = escape(value)
+    return mark_safe(value.replace('\n', '&#92;&#92; \n'))
+
+
+@register.filter(is_safe=False, needs_autoescape=True)
+def safe_tex_url(value, autoescape=True):
+    """
+    Convert all newlines in a piece of plain text to HTML line breaks
+    """
+    return mark_safe(value.replace('#', '&#92;#'))
diff --git a/scipost/views.py b/scipost/views.py
index 146b08f53e11cdf3b330c898eb4a6c7ed62a2094..cbaf80452b461c83839133e8c7707353f93fb18f 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -98,7 +98,7 @@ def documentsSearchResults(query):
                                    .filter(publication_query).order_by('-publication_date'))
     commentary_search_queryset = (Commentary.objects.vetted()
                                   .filter(commentary_query).order_by('-pub_date'))
-    submission_search_queryset = (Submission.objects.public()
+    submission_search_queryset = (Submission.objects.public_unlisted()
                                   .filter(submission_query).order_by('-submission_date'))
     thesislink_search_list = (ThesisLink.objects.vetted()
                               .filter(thesislink_query).order_by('-defense_date'))
@@ -175,9 +175,8 @@ def index(request):
     '''Main page.'''
     context = {
         'latest_newsitems': NewsItem.objects.all().order_by('-date')[:1],
-        'submissions': Submission.objects.public().order_by('-submission_date')[:3],
-        'publications': Publication.objects.published().order_by('-publication_date',
-                                                                 '-paper_nr')[:3]
+        'submissions': Submission.objects.public_unlisted().order_by('-submission_date')[:3],
+        'publications': Publication.objects.published().order_by('-publication_date')[:3]
     }
     return render(request, 'scipost/index.html', context)
 
@@ -796,8 +795,6 @@ def personal_page(request):
     nr_submissions_to_assign = 0
     nr_recommendations_to_prepare_for_voting = 0
     if contributor.is_SP_Admin():
-        intwodays = now + timezone.timedelta(days=2)
-
         # count the number of pending registration requests
         nr_reg_to_vet = Contributor.objects.filter(user__is_active=True, status=0).count()
         nr_reg_awaiting_validation = (Contributor.objects.awaiting_validation()
@@ -806,6 +803,7 @@ def personal_page(request):
         nr_submissions_to_assign = Submission.objects.filter(status__in=['unassigned']).count()
         nr_recommendations_to_prepare_for_voting = EICRecommendation.objects.filter(
             submission__status__in=['voting_in_preparation']).count()
+
     nr_assignments_to_consider = 0
     active_assignments = None
     nr_reports_to_vet = 0
@@ -833,9 +831,8 @@ def personal_page(request):
         referee=contributor, accepted=None, cancelled=False).count()
     pending_ref_tasks = RefereeInvitation.objects.filter(
         referee=contributor, accepted=True, fulfilled=False)
-    unfinished_reports = Report.objects.in_draft().filter(author=contributor)
     refereeing_tab_total_count = nr_ref_inv_to_consider + len(pending_ref_tasks)
-    refereeing_tab_total_count += len(unfinished_reports)
+    refereeing_tab_total_count += Report.objects.in_draft().filter(author=contributor).count()
 
     # Verify if there exist objects authored by this contributor,
     # whose authorship hasn't been claimed yet
@@ -895,13 +892,20 @@ def personal_page(request):
         'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
         'pending_ref_tasks': pending_ref_tasks,
         'refereeing_tab_total_count': refereeing_tab_total_count,
-        'unfinished_reports': unfinished_reports,
         'own_submissions': own_submissions,
         'own_commentaries': own_commentaries,
         'own_thesislinks': own_thesislinks,
-        'own_comments': own_comments, 'own_authorreplies': own_authorreplies,
+        'own_comments': own_comments,
+        'own_authorreplies': own_authorreplies,
     }
 
+    # Only add variables if user has right permission
+    if request.user.has_perm('scipost.can_manage_reports'):
+        context['nr_reports_without_pdf'] = (Report.objects.accepted()
+                                             .filter(pdf_report='').count())
+        context['nr_treated_submissions_without_pdf'] = (Submission.objects.treated()
+                                                         .filter(pdf_refereeing_pack='').count())
+
     return render(request, 'scipost/personal_page.html', context)
 
 
@@ -1112,7 +1116,7 @@ def contributor_info(request, contributor_id):
     """
     contributor = get_object_or_404(Contributor, pk=contributor_id)
     contributor_publications = Publication.objects.published().filter(authors=contributor)
-    contributor_submissions = Submission.objects.public().filter(authors=contributor)
+    contributor_submissions = Submission.objects.public_unlisted().filter(authors=contributor)
     contributor_commentaries = Commentary.objects.filter(authors=contributor)
     contributor_theses = ThesisLink.objects.vetted().filter(author_as_cont=contributor)
     contributor_comments = (Comment.objects.vetted()
diff --git a/submissions/admin.py b/submissions/admin.py
index 0e394cedfb8da410dfbcda6c3c72047380a6b39e..1095426dbbb30269de89a0db9bb3979aea60546a 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -4,7 +4,7 @@ from django import forms
 from guardian.admin import GuardedModelAdmin
 
 from submissions.models import Submission, EditorialAssignment, RefereeInvitation, Report,\
-                               EditorialCommunication, EICRecommendation
+                               EditorialCommunication, EICRecommendation, SubmissionEvent
 
 from scipost.models import Contributor
 
@@ -100,6 +100,7 @@ class ReportAdmin(admin.ModelAdmin):
     list_display_links = ('author',)
     date_hierarchy = 'date_submitted'
     list_filter = ('status',)
+    readonly_fields = ('report_nr',)
     form = ReportAdminForm
 
 
@@ -148,3 +149,5 @@ class EICRecommendationAdmin(admin.ModelAdmin):
 
 
 admin.site.register(EICRecommendation, EICRecommendationAdmin)
+
+admin.site.register(SubmissionEvent)
diff --git a/submissions/constants.py b/submissions/constants.py
index 2b247ffa6a78a9c83e72934b3871e42c21ec3435..aac77500f373188103b1435b6b7d50599df0bc72 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -45,7 +45,7 @@ SUBMISSION_HTTP404_ON_EDITORIAL_PAGE = [
 ]
 
 SUBMISSION_STATUS_OUT_OF_POOL = SUBMISSION_HTTP404_ON_EDITORIAL_PAGE + [
-    'resubmitted'
+    STATUS_RESUBMITTED
 ]
 
 SUBMISSION_EXCLUDE_FROM_REPORTING = SUBMISSION_HTTP404_ON_EDITORIAL_PAGE + [
@@ -69,24 +69,22 @@ SUBMISSION_STATUS_PUBLICLY_INVISIBLE = [
     STATUS_UNASSIGNED,
     STATUS_RESUBMISSION_INCOMING,
     'assignment_failed',
-    'resubmitted_rejected',
     STATUS_RESUBMITTED_REJECTED,
-    'rejected',
+    STATUS_REJECTED,
     'withdrawn',
 ]
 
 # Submissions which should not appear in search lists
 SUBMISSION_STATUS_PUBLICLY_UNLISTED = SUBMISSION_STATUS_PUBLICLY_INVISIBLE + [
-    'resubmitted',
-    'resubmitted_rejected_visible',
+    STATUS_RESUBMITTED,
     STATUS_RESUBMITTED_REJECTED_VISIBLE,
-    'published'
+    STATUS_PUBLISHED
 ]
 
 # Submissions for which voting on a related recommendation is deprecated:
 SUBMISSION_STATUS_VOTING_DEPRECATED = [
-    'rejected',
-    'published',
+    STATUS_REJECTED,
+    STATUS_PUBLISHED,
     'withdrawn',
 ]
 
@@ -124,6 +122,7 @@ ASSIGNMENT_REFUSAL_REASONS = (
 )
 
 REFEREE_QUALIFICATION = (
+    (None, '-'),
     (4, 'expert in this subject'),
     (3, 'very knowledgeable in this subject'),
     (2, 'knowledgeable in this subject'),
@@ -132,6 +131,7 @@ REFEREE_QUALIFICATION = (
 )
 
 QUALITY_SPEC = (
+    (None, '-'),
     (6, 'perfect'),
     (5, 'excellent'),
     (4, 'good'),
@@ -143,7 +143,7 @@ QUALITY_SPEC = (
 
 # Only values between 0 and 100 are kept, anything outside those limits is discarded.
 RANKING_CHOICES = (
-    (101, '-'),
+    (None, '-'),
     (100, 'top'),
     (80, 'high'),
     (60, 'good'),
@@ -153,6 +153,7 @@ RANKING_CHOICES = (
 )
 
 REPORT_REC = (
+    (None, '-'),
     (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'),
     (2, 'Publish as Tier II (top 50% of papers in this journal)'),
     (3, 'Publish as Tier III (meets the criteria of this journal)'),
@@ -205,3 +206,12 @@ SUBMISSION_CYCLES = (
     (CYCLE_SHORT, 'Short cycle'),
     (CYCLE_DIRECT_REC, 'Direct editorial recommendation'),
 )
+
+EVENT_GENERAL = 'gen'
+EVENT_FOR_EIC = 'eic'
+EVENT_FOR_AUTHOR = 'auth'
+EVENT_TYPES = (
+    (EVENT_GENERAL, 'General comment'),
+    (EVENT_FOR_EIC, 'Comment for Editor-in-charge'),
+    (EVENT_FOR_AUTHOR, 'Comment for author'),
+)
diff --git a/submissions/exceptions.py b/submissions/exceptions.py
index 0e8794a8cc841af0df2896138ce2ec0209ee0c7e..a6e26c2d6c946fec39d3b402415bd0110e63378a 100644
--- a/submissions/exceptions.py
+++ b/submissions/exceptions.py
@@ -1,4 +1,4 @@
-class CycleUpdateDeadlineError(Exception):
+class BaseCustomException(Exception):
     def __init__(self, name):
         self.name = name
 
@@ -6,9 +6,9 @@ class CycleUpdateDeadlineError(Exception):
         return self.name
 
 
-class InvalidReportVettingValue(Exception):
-    def __init__(self, name):
-        self.name = name
+class CycleUpdateDeadlineError(BaseCustomException):
+    pass
 
-    def __str__(self):
-        return self.name
+
+class InvalidReportVettingValue(BaseCustomException):
+    pass
diff --git a/submissions/forms.py b/submissions/forms.py
index 7f2d39772f1086f15e09c39ef36facb7bda4cb61..e6b3cd433e0f6adc4f31f247a07fd4751ce104fa 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -32,7 +32,7 @@ class SubmissionSearchForm(forms.Form):
 
     def search_results(self):
         """Return all Submission objects according to search"""
-        return Submission.objects.public_overcomplete().filter(
+        return Submission.objects.public_newest().filter(
             title__icontains=self.cleaned_data.get('title', ''),
             author_list__icontains=self.cleaned_data.get('author', ''),
             abstract__icontains=self.cleaned_data.get('abstract', ''),
@@ -332,6 +332,12 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
         return submission
 
 
+class SubmissionReportsForm(forms.ModelForm):
+    class Meta:
+        model = Submission
+        fields = ['pdf_refereeing_pack']
+
+
 ######################
 # Editorial workflow #
 ######################
@@ -412,6 +418,12 @@ class VotingEligibilityForm(forms.Form):
 # Reports:
 ############
 
+class ReportPDFForm(forms.ModelForm):
+    class Meta:
+        model = Report
+        fields = ['pdf_report']
+
+
 class ReportForm(forms.ModelForm):
     class Meta:
         model = Report
@@ -420,6 +432,17 @@ class ReportForm(forms.ModelForm):
                   'recommendation', 'remarks_for_editors', 'anonymous']
 
     def __init__(self, *args, **kwargs):
+        if kwargs.get('instance'):
+            if kwargs['instance'].is_followup_report:
+                # Prefill data from latest report in the series
+                latest_report = kwargs['instance'].latest_report_from_series()
+                kwargs.update({
+                    'initial': {
+                        'qualification': latest_report.qualification,
+                        'anonymous': latest_report.anonymous
+                    }
+                })
+
         super(ReportForm, self).__init__(*args, **kwargs)
         self.fields['strengths'].widget.attrs.update({
             'placeholder': ('Give a point-by-point '
@@ -440,7 +463,28 @@ class ReportForm(forms.ModelForm):
             'cols': 100
         })
 
-    def save(self, submission, current_contributor):
+        # If the Report is not a followup: Explicitly assign more fields as being required!
+        if not self.instance.is_followup_report:
+            required_fields = [
+                'strengths',
+                'weaknesses',
+                'requested_changes',
+                'validity',
+                'significance',
+                'originality',
+                'clarity',
+                'formatting',
+                'grammar'
+            ]
+            for field in required_fields:
+                self.fields[field].required = True
+
+        # Let user know the field is required!
+        for field in self.fields:
+            if self.fields[field].required:
+                self.fields[field].label += ' *'
+
+    def save(self, submission):
         """
         Update meta data if ModelForm is submitted (non-draft).
         Possibly overwrite the default status if user asks for saving as draft.
@@ -448,7 +492,6 @@ class ReportForm(forms.ModelForm):
         report = super().save(commit=False)
 
         report.submission = submission
-        report.author = current_contributor
         report.date_submitted = timezone.now()
 
         # Save with right status asked by user
@@ -458,7 +501,7 @@ class ReportForm(forms.ModelForm):
             report.status = STATUS_UNVETTED
 
             # Update invitation and report meta data if exist
-            invitation = submission.referee_invitations.filter(referee=current_contributor).first()
+            invitation = submission.referee_invitations.filter(referee=report.author).first()
             if invitation:
                 invitation.fulfilled = True
                 invitation.save()
@@ -466,7 +509,7 @@ class ReportForm(forms.ModelForm):
 
             # Check if report author if the report is being flagged on the submission
             if submission.referees_flagged:
-                if current_contributor.user.last_name in submission.referees_flagged:
+                if report.author.user.last_name in submission.referees_flagged:
                     report.flagged = True
         report.save()
         return report
@@ -597,6 +640,6 @@ class SubmissionCycleChoiceForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['refereeing_cycle'].default = None
-        other_submission = self.instance.other_versions().first()
+        other_submission = self.instance.other_versions.first()
         if other_submission:
             self.fields['referees_reinvite'].queryset = other_submission.referee_invitations.all()
diff --git a/submissions/managers.py b/submissions/managers.py
index 7e8a148b350b085842210c73263aba07e4e7832c..cba54e4f69b167a34a4a550b2b3a34339991fc49 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -4,8 +4,10 @@ from django.db.models import Q
 from .constants import SUBMISSION_STATUS_OUT_OF_POOL, SUBMISSION_STATUS_PUBLICLY_UNLISTED,\
                        SUBMISSION_STATUS_PUBLICLY_INVISIBLE, STATUS_UNVETTED, STATUS_VETTED,\
                        STATUS_UNCLEAR, STATUS_INCORRECT, STATUS_NOT_USEFUL, STATUS_NOT_ACADEMIC,\
-                       SUBMISSION_HTTP404_ON_EDITORIAL_PAGE, STATUS_DRAFT,\
-                       SUBMISSION_EXCLUDE_FROM_REPORTING
+                       SUBMISSION_HTTP404_ON_EDITORIAL_PAGE, STATUS_DRAFT, STATUS_PUBLISHED,\
+                       SUBMISSION_EXCLUDE_FROM_REPORTING, STATUS_REJECTED_VISIBLE,\
+                       STATUS_ACCEPTED, STATUS_RESUBMITTED, STATUS_RESUBMITTED_REJECTED_VISIBLE,\
+                       EVENT_FOR_EIC, EVENT_GENERAL, EVENT_FOR_AUTHOR
 
 
 class SubmissionManager(models.Manager):
@@ -57,6 +59,13 @@ class SubmissionManager(models.Manager):
                 .order_by('-submission_date'))
 
     def public(self):
+        """
+        This query contains set of public submissions, i.e. also containing
+        submissions with status "published" or "resubmitted".
+        """
+        return self.exclude(status__in=SUBMISSION_STATUS_PUBLICLY_INVISIBLE)
+
+    def public_unlisted(self):
         """
         List only all public submissions. Should be used as a default filter!
 
@@ -66,13 +75,12 @@ class SubmissionManager(models.Manager):
         """
         return self.exclude(status__in=SUBMISSION_STATUS_PUBLICLY_UNLISTED)
 
-    def public_overcomplete(self):
+    def public_newest(self):
         """
-        This query contains an overcomplete set of public submissions, i.e. also containing
-        submissions with status "published" or "resubmitted".
+        This query contains set of public() submissions, filtered to only the newest available
+        version.
         """
-        queryset = self.exclude(status__in=SUBMISSION_STATUS_PUBLICLY_INVISIBLE)
-        return self._newest_version_only(queryset)
+        return self._newest_version_only(self.public())
 
     def open_for_reporting(self):
         """
@@ -81,6 +89,30 @@ class SubmissionManager(models.Manager):
         """
         return self.exclude(status__in=SUBMISSION_EXCLUDE_FROM_REPORTING)
 
+    def treated(self):
+        """
+        This query returns all Submissions that are expected to be 'done'.
+        """
+        return self.filter(status__in=[STATUS_ACCEPTED, STATUS_REJECTED_VISIBLE, STATUS_PUBLISHED,
+                                       STATUS_RESUBMITTED, STATUS_RESUBMITTED_REJECTED_VISIBLE])
+
+    def accepted(self):
+        return self.filter(status=STATUS_ACCEPTED)
+
+
+class SubmissionEventQuerySet(models.QuerySet):
+    def for_author(self):
+        """
+        Return all events that are meant to be for the author(s) of a submission.
+        """
+        return self.filter(event__in=[EVENT_FOR_AUTHOR, EVENT_GENERAL])
+
+    def for_eic(self):
+        """
+        Return all events that are meant to be for the Editor-in-charge of a submission.
+        """
+        return self.filter(event__in=[EVENT_FOR_EIC, EVENT_GENERAL])
+
 
 class EditorialAssignmentManager(models.Manager):
     def get_for_user_in_pool(self, user):
@@ -129,3 +161,6 @@ class ReportManager(models.Manager):
 
     def in_draft(self):
         return self.filter(status=STATUS_DRAFT)
+
+    def non_draft(self):
+        return self.exclude(status=STATUS_DRAFT)
diff --git a/submissions/migrations/0046_auto_20170625_1311.py b/submissions/migrations/0046_auto_20170625_1311.py
new file mode 100644
index 0000000000000000000000000000000000000000..d33f029e92a097989c4398e3319df4cb57609b32
--- /dev/null
+++ b/submissions/migrations/0046_auto_20170625_1311.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-25 11:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def set_report_counters(apps, schema_editor):
+    Report = apps.get_model('submissions', 'Report')
+    for report in Report.objects.order_by('date_submitted'):
+        if not report.report_nr:
+            report.report_nr = report.submission.reports.filter(report_nr__gte=1).count() + 1
+        report.save()
+    print('Updated all Report counters.')
+
+
+def do_nothing(*args):
+    pass
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0045_auto_20170608_1710'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='report',
+            name='report_nr',
+            field=models.PositiveSmallIntegerField(default=0),
+        ),
+        migrations.RunPython(set_report_counters, do_nothing)
+    ]
diff --git a/submissions/migrations/0047_auto_20170625_1331.py b/submissions/migrations/0047_auto_20170625_1331.py
new file mode 100644
index 0000000000000000000000000000000000000000..151166d05dd98ce29eef6b9b44b137516fe1b4bb
--- /dev/null
+++ b/submissions/migrations/0047_auto_20170625_1331.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-06-25 11:31
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0046_auto_20170625_1311'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='report',
+            name='pdf_report',
+            field=models.FileField(blank=True, max_length=200, upload_to='UPLOADS/REPORTS/%Y/%m/'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='report_nr',
+            field=models.PositiveSmallIntegerField(default=0, help_text='This number is a unique number refeering to the Report nr. of the Submission'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='report',
+            unique_together=set([('submission', 'report_nr')]),
+        ),
+    ]
diff --git a/submissions/migrations/0048_auto_20170721_0931.py b/submissions/migrations/0048_auto_20170721_0931.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f0a084e264d15c611c97fe05ec58596f3769f18
--- /dev/null
+++ b/submissions/migrations/0048_auto_20170721_0931.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 07:31
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_submission_acceptance_date'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='requested_changes',
+            field=models.TextField(blank=True, verbose_name='requested changes'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='strengths',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='weaknesses',
+            field=models.TextField(blank=True),
+        ),
+    ]
diff --git a/submissions/migrations/0048_auto_20170721_0936.py b/submissions/migrations/0048_auto_20170721_0936.py
new file mode 100644
index 0000000000000000000000000000000000000000..657a049399d2aadca650ebbc94e78fbd0b70712d
--- /dev/null
+++ b/submissions/migrations/0048_auto_20170721_0936.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 07:36
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_submission_acceptance_date'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='requested_changes',
+            field=models.TextField(blank=True, verbose_name='requested changes'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='strengths',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='weaknesses',
+            field=models.TextField(blank=True),
+        ),
+    ]
diff --git a/submissions/migrations/0048_merge_20170707_1857.py b/submissions/migrations/0048_merge_20170707_1857.py
new file mode 100644
index 0000000000000000000000000000000000000000..e0b38b3d8fe4c76efb193145855351d562885c9b
--- /dev/null
+++ b/submissions/migrations/0048_merge_20170707_1857.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-07 16:57
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_auto_20170625_1331'),
+        ('submissions', '0047_submission_acceptance_date'),
+    ]
+
+    operations = [
+    ]
diff --git a/submissions/migrations/0049_auto_20170721_1010.py b/submissions/migrations/0049_auto_20170721_1010.py
new file mode 100644
index 0000000000000000000000000000000000000000..4627f2592d5f4a8d77755911038deb9dc7fe64a1
--- /dev/null
+++ b/submissions/migrations/0049_auto_20170721_1010.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0048_auto_20170721_0936'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='formatting',
+            field=models.SmallIntegerField(blank=True, choices=[(6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of paper formatting'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='grammar',
+            field=models.SmallIntegerField(blank=True, choices=[(6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of English grammar'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='qualification',
+            field=models.PositiveSmallIntegerField(choices=[(4, 'expert in this subject'), (3, 'very knowledgeable in this subject'), (2, 'knowledgeable in this subject'), (1, 'generally qualified'), (0, 'not qualified')], verbose_name='Qualification to referee this: I am'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='remarks_for_editors',
+            field=models.TextField(blank=True, verbose_name='optional remarks for the Editors only'),
+        ),
+    ]
diff --git a/submissions/migrations/0049_submission_pdf_refereeing_pack.py b/submissions/migrations/0049_submission_pdf_refereeing_pack.py
new file mode 100644
index 0000000000000000000000000000000000000000..32166d197857ea1466eae54f2008776c5d3499f3
--- /dev/null
+++ b/submissions/migrations/0049_submission_pdf_refereeing_pack.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-07 16:59
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0048_merge_20170707_1857'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='submission',
+            name='pdf_refereeing_pack',
+            field=models.FileField(blank=True, max_length=200, upload_to='UPLOADS/REFEREE/%Y/%m/'),
+        ),
+    ]
diff --git a/submissions/migrations/0050_auto_20170707_2126.py b/submissions/migrations/0050_auto_20170707_2126.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a454b3e19e435c2e0ac9c57536c3faccc598db8
--- /dev/null
+++ b/submissions/migrations/0050_auto_20170707_2126.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-07 19:26
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0049_submission_pdf_refereeing_pack'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='report',
+            options={'ordering': ['report_nr']},
+        ),
+        migrations.AddField(
+            model_name='report',
+            name='doi_label',
+            field=models.CharField(blank=True, max_length=200),
+        ),
+    ]
diff --git a/submissions/migrations/0050_auto_20170721_1042.py b/submissions/migrations/0050_auto_20170721_1042.py
new file mode 100644
index 0000000000000000000000000000000000000000..f81add96676950e1daed51e7c308e02dc48f82d2
--- /dev/null
+++ b/submissions/migrations/0050_auto_20170721_1042.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def report_101_to_none(apps, schema_editor):
+    Report = apps.get_model('submissions', 'Report')
+    for rep in Report.objects.all():
+        if rep.clarity == 101:
+            rep.clarity = None
+        if rep.originality == 101:
+            rep.originality = None
+        if rep.significance == 101:
+            rep.significance = None
+        if rep.validity == 101:
+            rep.validity = None
+        rep.save()
+    print('\nChanged all Report fields: {clarites,originality,significance,validity} with value'
+          ' `101` to `None`.')
+
+
+def report_none_to_101(apps, schema_editor):
+    Report = apps.get_model('submissions', 'Report')
+    for rep in Report.objects.all():
+        if not rep.clarity:
+            rep.clarity = 101
+        if not rep.originality:
+            rep.originality = 101
+        if not rep.significance:
+            rep.significance = 101
+        if not rep.validity:
+            rep.validity = 101
+        rep.save()
+    print('\nChanged all Report fields: {clarites,originality,significance,validity} with value'
+          ' `None` to `101`.')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0049_auto_20170721_1010'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='clarity',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='originality',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='significance',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='validity',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.RunPython(report_101_to_none, report_none_to_101),
+    ]
diff --git a/submissions/migrations/0051_auto_20170721_1049.py b/submissions/migrations/0051_auto_20170721_1049.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ccf06a410f6f585b3f2ce23faecf963d0a88af6
--- /dev/null
+++ b/submissions/migrations/0051_auto_20170721_1049.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:49
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0050_auto_20170721_1042'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='formatting',
+            field=models.SmallIntegerField(blank=True, choices=[(None, '-'), (6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of paper formatting'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='grammar',
+            field=models.SmallIntegerField(blank=True, choices=[(None, '-'), (6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of English grammar'),
+        ),
+    ]
diff --git a/submissions/migrations/0051_merge_20170721_0934.py b/submissions/migrations/0051_merge_20170721_0934.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f8075edd4eaf34bd361875a9bf701fd761d7b83
--- /dev/null
+++ b/submissions/migrations/0051_merge_20170721_0934.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 07:34
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0050_auto_20170707_2126'),
+        ('submissions', '0048_auto_20170721_0931'),
+    ]
+
+    operations = [
+    ]
diff --git a/submissions/migrations/0052_auto_20170721_1057.py b/submissions/migrations/0052_auto_20170721_1057.py
new file mode 100644
index 0000000000000000000000000000000000000000..c89df6fc0f4aba11de3118a756d79c46e47f29d5
--- /dev/null
+++ b/submissions/migrations/0052_auto_20170721_1057.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0051_auto_20170721_1049'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='eicrecommendation',
+            name='recommendation',
+            field=models.SmallIntegerField(choices=[(None, '-'), (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), (2, 'Publish as Tier II (top 50% of papers in this journal)'), (3, 'Publish as Tier III (meets the criteria of this journal)'), (-1, 'Ask for minor revision'), (-2, 'Ask for major revision'), (-3, 'Reject')]),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='qualification',
+            field=models.PositiveSmallIntegerField(choices=[(None, '-'), (4, 'expert in this subject'), (3, 'very knowledgeable in this subject'), (2, 'knowledgeable in this subject'), (1, 'generally qualified'), (0, 'not qualified')], verbose_name='Qualification to referee this: I am'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='recommendation',
+            field=models.SmallIntegerField(choices=[(None, '-'), (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), (2, 'Publish as Tier II (top 50% of papers in this journal)'), (3, 'Publish as Tier III (meets the criteria of this journal)'), (-1, 'Ask for minor revision'), (-2, 'Ask for major revision'), (-3, 'Reject')]),
+        ),
+    ]
diff --git a/submissions/migrations/0053_auto_20170721_1100.py b/submissions/migrations/0053_auto_20170721_1100.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebb3fc0bfb4327f4c5a8ed239a130468efd4eae1
--- /dev/null
+++ b/submissions/migrations/0053_auto_20170721_1100.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 09:00
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0052_auto_20170721_1057'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='author',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reports', to='scipost.Contributor'),
+        ),
+    ]
diff --git a/submissions/migrations/0054_auto_20170721_1148.py b/submissions/migrations/0054_auto_20170721_1148.py
new file mode 100644
index 0000000000000000000000000000000000000000..983b6b8409fd3f8249dac03b25e01f8eef31e516
--- /dev/null
+++ b/submissions/migrations/0054_auto_20170721_1148.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 09:48
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0053_auto_20170721_1100'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='report',
+            options={'ordering': ['-date_submitted']},
+        ),
+    ]
diff --git a/submissions/migrations/0055_auto_20170724_1734.py b/submissions/migrations/0055_auto_20170724_1734.py
new file mode 100644
index 0000000000000000000000000000000000000000..aeab30e64171c0ae2c5b0c3247c932b218882b80
--- /dev/null
+++ b/submissions/migrations/0055_auto_20170724_1734.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 15:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import scipost.db.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0054_auto_20170721_1148'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='SubmissionEvent',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('created', models.DateTimeField(default=django.utils.timezone.now)),
+                ('latest_activity', scipost.db.fields.AutoDateTimeField(blank=True, default=django.utils.timezone.now, editable=False)),
+                ('event', models.CharField(choices=[('gen', 'General comment'), ('eic', 'Comment for Editor-in-charge'), ('auth', 'Comment for author')], default='gen', max_length=4)),
+                ('blub', models.TextField()),
+                ('submission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='submissions.Submission')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.AlterModelOptions(
+            name='editorialcommunication',
+            options={'ordering': ['timestamp']},
+        ),
+        migrations.AlterField(
+            model_name='editorialcommunication',
+            name='submission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='editorial_communications', to='submissions.Submission'),
+        ),
+    ]
diff --git a/submissions/migrations/0055_merge_20170724_1958.py b/submissions/migrations/0055_merge_20170724_1958.py
new file mode 100644
index 0000000000000000000000000000000000000000..54ca985482cecb5aa225e844789ea2733674e3fc
--- /dev/null
+++ b/submissions/migrations/0055_merge_20170724_1958.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 17:58
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0051_merge_20170721_0934'),
+        ('submissions', '0054_auto_20170721_1148'),
+    ]
+
+    operations = [
+    ]
diff --git a/submissions/migrations/0056_auto_20170724_1818.py b/submissions/migrations/0056_auto_20170724_1818.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa28c521016056f66eca92029c5996d37d01eb35
--- /dev/null
+++ b/submissions/migrations/0056_auto_20170724_1818.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 16:18
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0055_auto_20170724_1734'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='submissionevent',
+            old_name='blub',
+            new_name='text',
+        ),
+    ]
diff --git a/submissions/migrations/0057_merge_20170724_1840.py b/submissions/migrations/0057_merge_20170724_1840.py
new file mode 100644
index 0000000000000000000000000000000000000000..4aadf6b7eb41e6a1e83106facef409d5b80a739e
--- /dev/null
+++ b/submissions/migrations/0057_merge_20170724_1840.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 16:40
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0056_auto_20170724_1818'),
+        ('submissions', '0051_merge_20170721_0934'),
+    ]
+
+    operations = [
+    ]
diff --git a/submissions/migrations/0058_auto_20170724_1857.py b/submissions/migrations/0058_auto_20170724_1857.py
new file mode 100644
index 0000000000000000000000000000000000000000..788449d8efc8b6e3819f5f81fd765c5041f56791
--- /dev/null
+++ b/submissions/migrations/0058_auto_20170724_1857.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-24 16:57
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0057_merge_20170724_1840'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='report',
+            options={'ordering': ['-date_submitted']},
+        ),
+    ]
diff --git a/submissions/migrations/0059_auto_20170725_2048.py b/submissions/migrations/0059_auto_20170725_2048.py
new file mode 100644
index 0000000000000000000000000000000000000000..292342c7362a11dccd2e418283798f970769fca8
--- /dev/null
+++ b/submissions/migrations/0059_auto_20170725_2048.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-25 18:48
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0058_auto_20170724_1857'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='submissionevent',
+            options={'ordering': ['-created']},
+        ),
+        migrations.AlterField(
+            model_name='eicrecommendation',
+            name='remarks_for_editorial_college',
+            field=models.TextField(blank=True, default='', verbose_name='optional remarks for the Editorial College'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/submissions/migrations/0060_merge_20170726_0945.py b/submissions/migrations/0060_merge_20170726_0945.py
new file mode 100644
index 0000000000000000000000000000000000000000..c48723096d587337ff501c4aef5f3885769a7edd
--- /dev/null
+++ b/submissions/migrations/0060_merge_20170726_0945.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-26 07:45
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0055_merge_20170724_1958'),
+        ('submissions', '0059_auto_20170725_2048'),
+    ]
+
+    operations = [
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 6aa62b53228b673f215516a6866c70a54952983f..790619f7d3891d2ee7a4f93118c8f52bd5a30c2b 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -4,18 +4,20 @@ from django.utils import timezone
 from django.db import models
 from django.contrib.postgres.fields import JSONField
 from django.urls import reverse
+from django.utils.functional import cached_property
 
 from .constants import ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL,\
                        SUBMISSION_TYPE, ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC,\
                        RANKING_CHOICES, REPORT_REC, SUBMISSION_STATUS, STATUS_UNASSIGNED,\
                        REPORT_STATUSES, STATUS_UNVETTED, SUBMISSION_EIC_RECOMMENDATION_REQUIRED,\
-                       SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT, CYCLE_DIRECT_REC
+                       SUBMISSION_CYCLES, CYCLE_DEFAULT, CYCLE_SHORT, CYCLE_DIRECT_REC,\
+                       EVENT_GENERAL, EVENT_TYPES, EVENT_FOR_AUTHOR, EVENT_FOR_EIC
 from .managers import SubmissionManager, EditorialAssignmentManager, EICRecommendationManager,\
-                      ReportManager
+                      ReportManager, SubmissionEventQuerySet
 from .utils import ShortSubmissionCycle, DirectRecommendationSubmissionCycle,\
                    GeneralSubmissionCycle
 
-from scipost.behaviors import ArxivCallable
+from scipost.behaviors import TimeStampedModel
 from scipost.constants import TITLE_CHOICES
 from scipost.fields import ChoiceArrayField
 from scipost.models import Contributor
@@ -27,7 +29,7 @@ from journals.models import Publication
 ###############
 # Submissions:
 ###############
-class Submission(ArxivCallable, models.Model):
+class Submission(models.Model):
     # Main submission fields
     author_comments = models.TextField(blank=True, null=True)
     author_list = models.CharField(max_length=1000, verbose_name="author list")
@@ -75,6 +77,9 @@ class Submission(ArxivCallable, models.Model):
     arxiv_vn_nr = models.PositiveSmallIntegerField(default=1)
     arxiv_link = models.URLField(verbose_name='arXiv link (including version nr)')
 
+    pdf_refereeing_pack = models.FileField(upload_to='UPLOADS/REFEREE/%Y/%m/',
+                                           max_length=200, blank=True)
+
     # Metadata
     metadata = JSONField(default={}, blank=True, null=True)
     submission_date = models.DateField(verbose_name='submission date', default=datetime.date.today)
@@ -132,6 +137,7 @@ class Submission(ArxivCallable, models.Model):
     def reporting_deadline_has_passed(self):
         return timezone.now() > self.reporting_deadline
 
+    @cached_property
     def other_versions(self):
         return Submission.objects.filter(
             arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr
@@ -156,11 +162,54 @@ class Submission(ArxivCallable, models.Model):
     def count_obtained_reports(self):
         return self.reports.accepted().filter(invited__isnull=False).count()
 
-    def count_refused_reports(self):
-        return self.reports.rejected().count()
+    def add_general_event(self, message):
+        event = SubmissionEvent(
+            submission=self,
+            event=EVENT_GENERAL,
+            text=message,
+        )
+        event.save()
+
+    def add_event_for_author(self, message):
+        event = SubmissionEvent(
+            submission=self,
+            event=EVENT_FOR_AUTHOR,
+            text=message,
+        )
+        event.save()
+
+    def add_event_for_eic(self, message):
+        event = SubmissionEvent(
+            submission=self,
+            event=EVENT_FOR_EIC,
+            text=message,
+        )
+        event.save()
+
+
+class SubmissionEvent(TimeStampedModel):
+    """
+    The SubmissionEvent's goal is to act as a messaging/logging model
+    for the Submission cycle. Its main audience will be the author(s) and
+    the Editor-in-charge of a Submission.
+
+    Be aware!
+    Both the author and editor-in-charge will read the submission event.
+    Make sure the right text is given to the right event-type, to protect
+    the fellow's identity.
+    """
+    submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
+                                   related_name='events')
+    event = models.CharField(max_length=4, choices=EVENT_TYPES, default=EVENT_GENERAL)
+    text = models.TextField()
 
-    def count_awaiting_vetting(self):
-        return self.reports.awaiting_vetting().count()
+    objects = SubmissionEventQuerySet.as_manager()
+
+    class Meta:
+        ordering = ['-created']
+
+    def __str__(self):
+        return '%s: %s' % (str(self.submission), self.get_event_display())
 
 
 ######################
@@ -235,47 +284,108 @@ class RefereeInvitation(models.Model):
 ###########
 
 class Report(models.Model):
-    """ Both types of reports, invited or contributed. """
+    """
+    Both types of reports, invited or contributed.
+
+    This Report model acts as both a regular `Report` and a `FollowupReport`; A normal Report
+    should have all fields required, whereas a FollowupReport only has the `report` field as
+    a required field.
+
+    Important note!
+    Due to the construction of the two different types within a single model, it is important
+    to explicitly implement the perticular differences in for example the form used.
+    """
     status = models.CharField(max_length=16, choices=REPORT_STATUSES, default=STATUS_UNVETTED)
     submission = models.ForeignKey('submissions.Submission', related_name='reports',
                                    on_delete=models.CASCADE)
+    report_nr = models.PositiveSmallIntegerField(default=0,
+                                                 help_text='This number is a unique number '
+                                                           'refeering to the Report nr. of '
+                                                           'the Submission')
     vetted_by = models.ForeignKey('scipost.Contributor', related_name="report_vetted_by",
                                   blank=True, null=True, on_delete=models.CASCADE)
+
     # `invited' filled from RefereeInvitation objects at moment of report submission
     invited = models.BooleanField(default=False)
+
     # `flagged' if author of report has been flagged by submission authors (surname check only)
     flagged = models.BooleanField(default=False)
     date_submitted = models.DateTimeField('date submitted')
     author = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
     qualification = models.PositiveSmallIntegerField(
         choices=REFEREE_QUALIFICATION,
-        verbose_name="Qualification to referee this: I am ")
+        verbose_name="Qualification to referee this: I am")
+
     # Text-based reporting
-    strengths = models.TextField()
-    weaknesses = models.TextField()
+    strengths = models.TextField(blank=True)
+    weaknesses = models.TextField(blank=True)
     report = models.TextField()
-    requested_changes = models.TextField(verbose_name="requested changes")
+    requested_changes = models.TextField(verbose_name="requested changes", blank=True)
+
     # Qualities:
-    validity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    significance = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    originality = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    clarity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    formatting = models.SmallIntegerField(choices=QUALITY_SPEC,
+    validity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                null=True, blank=True)
+    significance = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                    null=True, blank=True)
+    originality = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                   null=True, blank=True)
+    clarity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                               null=True, blank=True)
+    formatting = models.SmallIntegerField(choices=QUALITY_SPEC, null=True, blank=True,
                                           verbose_name="Quality of paper formatting")
-    grammar = models.SmallIntegerField(choices=QUALITY_SPEC,
+    grammar = models.SmallIntegerField(choices=QUALITY_SPEC, null=True, blank=True,
                                        verbose_name="Quality of English grammar")
 
     recommendation = models.SmallIntegerField(choices=REPORT_REC)
-    remarks_for_editors = models.TextField(default='', blank=True,
+    remarks_for_editors = models.TextField(blank=True,
                                            verbose_name='optional remarks for the Editors only')
+    doi_label = models.CharField(max_length=200, blank=True)
     anonymous = models.BooleanField(default=True, verbose_name='Publish anonymously')
+    pdf_report = models.FileField(upload_to='UPLOADS/REPORTS/%Y/%m/', max_length=200, blank=True)
 
     objects = ReportManager()
 
+    class Meta:
+        unique_together = ('submission', 'report_nr')
+        default_related_name = 'reports'
+        ordering = ['-date_submitted']
+
     def __str__(self):
         return (self.author.user.first_name + ' ' + self.author.user.last_name + ' on ' +
                 self.submission.title[:50] + ' by ' + self.submission.author_list[:50])
 
+    def get_absolute_url(self):
+        return self.submission.get_absolute_url() + '#report_' + str(self.report_nr)
+
+    @property
+    def doi_string(self):
+        if self.doi_label:
+            return '10.21468/' + self.doi_label
+
+    def save(self, *args, **kwargs):
+        # Control Report count per Submission.
+        if not self.report_nr:
+            self.report_nr = self.submission.reports.count() + 1
+        return super().save(*args, **kwargs)
+
+    @cached_property
+    def is_followup_report(self):
+        """
+        Check if current Report is a `FollowupReport`. A Report is a `FollowupReport` if the
+        author of the report already has a vetted report in the series of the specific Submission.
+        """
+        return (self.author.reports.accepted()
+                .filter(submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
+                .exists())
+
+    def latest_report_from_series(self):
+        """
+        Get latest Report from the same author for the Submission series.
+        """
+        return (self.author.reports.accepted()
+                .filter(submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
+                .order_by('submission__arxiv_identifier_wo_vn_nr').last())
+
 
 ##########################
 # EditorialCommunication #
@@ -286,13 +396,17 @@ class EditorialCommunication(models.Model):
     Each individual communication between Editor-in-charge
     to and from Referees and Authors becomes an instance of this class.
     """
-    submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE)
+    submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE,
+                                   related_name='editorial_communications')
     referee = models.ForeignKey('scipost.Contributor', related_name='referee_in_correspondence',
                                 blank=True, null=True, on_delete=models.CASCADE)
     comtype = models.CharField(max_length=4, choices=ED_COMM_CHOICES)
     timestamp = models.DateTimeField(default=timezone.now)
     text = models.TextField()
 
+    class Meta:
+        ordering = ['timestamp']
+
     def __str__(self):
         output = self.comtype
         if self.referee is not None:
@@ -313,10 +427,11 @@ class EICRecommendation(models.Model):
     date_submitted = models.DateTimeField('date submitted', default=timezone.now)
     remarks_for_authors = models.TextField(blank=True, null=True)
     requested_changes = models.TextField(verbose_name="requested changes", blank=True, null=True)
-    remarks_for_editorial_college = models.TextField(
-        default='', blank=True, null=True,
-        verbose_name='optional remarks for the Editorial College')
+    remarks_for_editorial_college = models.TextField(blank=True,
+                                                     verbose_name='optional remarks for the'
+                                                                  ' Editorial College')
     recommendation = models.SmallIntegerField(choices=REPORT_REC)
+
     # Editorial Fellows who have assessed this recommendation:
     eligible_to_vote = models.ManyToManyField(Contributor, blank=True,
                                               related_name='eligible_to_vote')
diff --git a/submissions/templates/submissions/_refereeing_pack_tex_template.html b/submissions/templates/submissions/_refereeing_pack_tex_template.html
new file mode 100644
index 0000000000000000000000000000000000000000..536202975620088d90e191870ed6d99f45f55df6
--- /dev/null
+++ b/submissions/templates/submissions/_refereeing_pack_tex_template.html
@@ -0,0 +1,200 @@
+{% load texfilters %}\documentclass{SciPost}
+
+% Prevent all line breaks in inline equations.
+\binoppenalty=10000
+\relpenalty=10000
+
+\hypersetup{
+    colorlinks,
+    linkcolor={red!50!black},
+    citecolor={blue!50!black},
+    urlcolor={blue!80!black}
+}
+
+\usepackage[bitstream-charter]{mathdesign}
+\urlstyle{sf}
+
+\fancypagestyle{SPstyle}{
+\fancyhf{}
+\lhead{\raisebox{-1.5mm}[0pt][0pt]{\href{https://scipost.org}{\includegraphics[width=20mm]{logo_scipost_with_bgd.pdf}}}}
+
+{% if report.doi_string %}
+    \rhead{\small \href{https://scipost.org{{report.doi_string|safe_tex_url}} }{ {{report.doi_string|safe_tex_url}} ({{report.date_submitted|date:'Y'}})}}
+{% endif %}
+
+\renewcommand{\headrulewidth}{1pt}
+\fancyfoot[C]{\textbf{\thepage}}
+}
+
+\begin{document}
+
+\pagestyle{SPstyle}
+
+\begin{center}
+\Large\color{scipostdeepblue}{\textbf{
+%%%%%%%%%% TITLE + AUTHORS
+Refereeing Package of\href{https://scipost.org{{submission.get_absolute_url|safe_tex_url}} }{\color{scipostdeepblue}{ {{submission.title}} }}by {{submission.author_list}}
+}}
+\end{center}
+
+\begin{center}
+\Large\color{scipostdeepblue}{\textbf{
+%%%%%%%%%% ARXIV CODE
+\href{https://scipost.org{{submission.get_absolute_url|safe_tex_url}} }{\color{scipostdeepblue}{ {{submission.arxiv_identifier_w_vn_nr}} }}
+}}
+\end{center}
+
+\vspace{10pt}
+
+%%%%%%%%%% DATES
+\small{\ \\Received {{submission.submission_date|date:'d-m-Y'}}\newline
+{% if submission.acceptance_date %}Accepted {{submission.acceptance_date|date:'d-m-Y'}} \newline{% endif %}
+Submitted to {{submission.get_submitted_to_journal_display}}
+}
+
+
+%%%%% TABLE OF CONTENT
+\vspace{10pt}
+\noindent\rule{\textwidth}{1pt}
+\tableofcontents
+\noindent\rule{\textwidth}{1pt}
+\vspace{10pt}
+
+
+%%%%%%%%%% CONTENT
+
+{% for report in submission.reports.accepted %}
+    \newpage
+    \setcounter{section}{0}
+
+    \addcontentsline{toc}{section}{\protect\numberline{}Report {{report.report_nr}}{% if report.doi_string %} $\cdot$ doi: {{report.doi_string|safe_tex_url}}{% endif %} }
+
+    \fancypagestyle{SPstylereport{{report.id}} }{
+    \fancyhf{}
+    \lhead{\raisebox{-1.5mm}[0pt][0pt]{\href{https://scipost.org}{\includegraphics[width=20mm]{logo_scipost_with_bgd.pdf}}}}
+
+    {% if report.doi_string %}
+        \rhead{\small \href{https://scipost.org{{report.doi_string|safe_tex_url}} }{ {{report.doi_string|safe_tex_url}} ({{report.date_submitted|date:'Y'}})}}
+    {% endif %}
+
+    \renewcommand{\headrulewidth}{1pt}
+    \fancyfoot[C]{\textbf{\thepage}}
+    }
+    \pagestyle{SPstylereport{{report.id}} }
+
+    \begin{center}
+    \Large\color{scipostdeepblue}{\textbf{
+    %%%%%%%%%% TITLE
+    Report {{report.report_nr}} on\href{https://scipost.org{{report.get_absolute_url|safe_tex_url}} }{\color{scipostdeepblue}{ {{report.submission.title}} }}by {{report.submission.author_list}}
+    }}
+    \end{center}
+
+    {% if report.doi_string %}
+        \begin{center}
+        \Large\color{scipostdeepblue}{\textbf{
+        %%%%%%%%%% TITLE
+        doi:\href{https://scipost.org{{report.get_absolute_url|safe_tex_url}} }{\color{scipostdeepblue}{ {{report.doi_string|safe_tex_url}} }}
+        }}
+        \end{center}
+    {% endif %}
+
+    \begin{center}
+    \large\textbf{
+    %%%%%%%%%% AUTHORS
+    Report by {% if report.anonymous %}anonymous{% else %}{{report.author.user.first_name}} {{report.author.user.last_name}}\textsuperscript{1}{% endif %}
+    }
+    \end{center}
+
+    {% if not report.anonymous %}
+        \begin{center}
+        %%%%%%%%%% AFFILIATIONS
+        {\bf 1} {{report.author.affiliation}}\\
+        \end{center}
+    {% endif %}
+
+
+    \vspace{10pt}
+
+
+    \begin{center}
+    \begin{tabular}{lr}
+    \begin{minipage}{0.5\textwidth}
+    \raisebox{-1mm}[0pt][0pt]{\includegraphics[width=12mm]{by.eps}}
+
+    %%%%%%%%%% COPYRIGHT
+
+    {\small Copyright {% if report.anonymous %}anonymous{% else %}{{report.author.user.first_name}} {{report.author.user.last_name}}{% endif %}. \newline
+    This work is licensed under the Creative Commons \newline
+    \href{http://creativecommons.org/licenses/by/4.0/}{Attribution 4.0 International License}. \newline
+    Published by the SciPost Foundation.
+    }
+    \end{minipage}
+    &
+    \begin{minipage}{0.5\textwidth}
+    %%%%%%%%%% DATES
+    {\small Received {{report.date_submitted|date:'d-m-Y'}}
+    {% if report.doi_string %}
+        doi:\href{//dx.doi.org{{report.doi_string|safe_tex_url}} }{ {{report.doi_string|safe_tex_url}} }
+    {% endif %}
+    }
+    \end{minipage}
+    \end{tabular}
+    \end{center}
+
+    \vspace{10pt}
+    \noindent\rule{\textwidth}{1pt}
+
+    %%%%%%%% CONTENTS
+
+    \section*{Ratings}
+    \begin{center}
+    \begin{tabular}{r p{0.15\columnwidth} r l}
+    	{\bf Validity} & {{report.get_validity_display}} & {\bf Clarity} & {{report.get_clarity_display}} \\
+    	{\bf Significance} & {{report.get_significance_display}} & {\bf Formatting} & {{report.get_formatting_display}} \\
+    	{\bf Originality} & {{report.get_originality_display}} & {\bf Grammar} & {{report.get_grammar_display}}
+    \end{tabular}
+    \end{center}
+
+    \section*{Strengths}
+    {{report.strengths|linebreaktex}}
+
+    \section*{Weaknesses}
+    {{report.weaknesses|linebreaktex}}
+
+    \section*{Report}
+    {{report.report|linebreaktex}}
+
+
+    \section*{Requested changes}
+    {{report.requested_changes|linebreaktex}}
+
+
+    {% if report.comment_set.vetted %}
+        \newpage
+        \pagestyle{SPstyle}
+        \section*{Comments and Author Replies to this Report}
+
+        {% for comment in report.comment_set.vetted %}
+            \addcontentsline{toc}{subsection}{\protect\numberline{}{% if comment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.counter}} to Report by {% if comment.anonymous %}anonymous{% else %}{{comment.author.user.first_name}} {{comment.author.user.last_name}}{% endif %} }
+
+            \subsection*{ {% if comment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.counter}} to Report by {% if comment.anonymous %}anonymous{% else %}{{comment.author.user.first_name}} {{comment.author.user.last_name}}{% endif %} }
+            {% include 'comments/_comment_tex_template.html' with comment=comment %}
+        {% endfor %}
+    {% endif %}
+
+{% endfor %}
+
+{% if submission.comments.vetted %}
+    \newpage
+    \setcounter{section}{0}
+    \pagestyle{SPstyle}
+
+    {% for comment in submission.comments.vetted %}
+        \addcontentsline{toc}{section}{\protect\numberline{}{% if comment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.counter}} by {% if comment.anonymous %}anonymous{% else %}{{comment.author.user.first_name}} {{comment.author.user.last_name}}{% endif %} }
+
+        \section*{ {% if comment.is_author_reply %}Author Reply{% else %}Comment{% endif %} {{forloop.counter}} by {% if comment.anonymous %}anonymous{% else %}{{comment.author.user.first_name}} {{comment.author.user.last_name}}{% endif %} }
+        {% include 'comments/_comment_tex_template.html' with comment=comment %}
+    {% endfor %}
+{% endif %}
+
+\end{document}
diff --git a/submissions/templates/submissions/_report_tex_template.html b/submissions/templates/submissions/_report_tex_template.html
new file mode 100644
index 0000000000000000000000000000000000000000..edb59afc172ed68722591107bcd2b97c5a737a01
--- /dev/null
+++ b/submissions/templates/submissions/_report_tex_template.html
@@ -0,0 +1,112 @@
+{% load texfilters %}\documentclass{SciPost}
+
+% Prevent all line breaks in inline equations.
+\binoppenalty=10000
+\relpenalty=10000
+
+\hypersetup{
+    colorlinks,
+    linkcolor={red!50!black},
+    citecolor={blue!50!black},
+    urlcolor={blue!80!black}
+}
+
+\usepackage[bitstream-charter]{mathdesign}
+\urlstyle{sf}
+
+\fancypagestyle{SPstyle}{
+\fancyhf{}
+\lhead{\raisebox{-1.5mm}[0pt][0pt]{\href{https://scipost.org}{\includegraphics[width=20mm]{logo_scipost_with_bgd.pdf}}}}
+
+{% if report.doi_string %}
+    \rhead{\small \href{https://scipost.org{{report.doi_string|safe_tex_url}} }{ {{report.doi_string|safe_tex_url}} ({{report.date_submitted|date:'Y'}})}}
+{% endif %}
+
+\renewcommand{\headrulewidth}{1pt}
+\fancyfoot[C]{\textbf{\thepage}}
+}
+
+\begin{document}
+
+\pagestyle{SPstyle}
+
+\begin{center}
+\Large\color{scipostdeepblue}{\textbf{
+%%%%%%%%%% TITLE
+Report {{report.report_nr}} on\href{https://scipost.org{{report.get_absolute_url|safe_tex_url}} }{\color{scipostdeepblue}{ {{report.submission.title}} }}by {{report.submission.author_list}}
+}}
+\end{center}
+
+\begin{center}
+\large\textbf{
+%%%%%%%%%% AUTHORS
+Report by {% if report.anonymous %}anonymous{% else %}{{report.author.user.first_name}} {{report.author.user.last_name}}\textsuperscript{1}{% endif %}
+}
+\end{center}
+
+{% if not report.anonymous %}
+    \begin{center}
+    %%%%%%%%%% AFFILIATIONS
+    {\bf 1} {{report.author.affiliation}}\\
+    \end{center}
+{% endif %}
+
+
+\vspace{10pt}
+
+
+\begin{center}
+\begin{tabular}{lr}
+\begin{minipage}{0.5\textwidth}
+\raisebox{-1mm}[0pt][0pt]{\includegraphics[width=12mm]{by.eps}}
+
+%%%%%%%%%% COPYRIGHT
+
+{\small Copyright {% if report.anonymous %}anonymous{% else %}{{report.author.user.first_name}} {{report.author.user.last_name}}{% endif %}. \newline
+
+This work is licensed under the Creative Commons \newline
+\href{http://creativecommons.org/licenses/by/4.0/}{Attribution 4.0 International License}. \newline
+Published by the SciPost Foundation.
+}
+\end{minipage}
+&
+\begin{minipage}{0.5\textwidth}
+%%%%%%%%%% DATES
+{\small Received {{report.date_submitted|date:'d-m-Y'}}
+{% if report.doi_string %}
+    doi:\href{//dx.doi.org{{report.doi_string|safe_tex_url}} }{ {{report.doi_string|safe_tex_url}} }
+{% endif %}
+}
+\end{minipage}
+\end{tabular}
+\end{center}
+
+\vspace{10pt}
+\noindent\rule{\textwidth}{1pt}
+
+%%%%%%%% CONTENTS
+
+\section*{Ratings}
+\begin{center}
+\begin{tabular}{r p{0.15\columnwidth} r l}
+	{\bf Validity} & {{report.get_validity_display}} & {\bf Clarity} & {{report.get_clarity_display}} \\
+	{\bf Significance} & {{report.get_significance_display}} & {\bf Formatting} & {{report.get_formatting_display}} \\
+	{\bf Originality} & {{report.get_originality_display}} & {\bf Grammar} & {{report.get_grammar_display}}
+\end{tabular}
+\end{center}
+
+\section{Strengths}
+{{report.strengths|linebreaktex}}
+
+\section{Weaknesses}
+{{report.weaknesses|linebreaktex}}
+
+\section{Report}
+{{report.report|linebreaktex}}
+
+
+\section{Requested changes}
+{{report.requested_changes|linebreaktex}}
+
+
+\end{document}
diff --git a/submissions/templates/submissions/_single_public_report.html b/submissions/templates/submissions/_single_public_report.html
index a733936561c287c2c8b5ccf6f579efe52b20fd56..cc4b233b4540fd5b969181a41377ac181d727a70 100644
--- a/submissions/templates/submissions/_single_public_report.html
+++ b/submissions/templates/submissions/_single_public_report.html
@@ -1,8 +1,10 @@
 {% extends 'submissions/_single_public_report_without_comments.html' %}
 
 {% block single_report_footer %}
-    <hr class="small">
-    <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3>
+    {% if user.is_authenticated and perms.scipost.can_submit_comments %}
+        <hr class="small">
+        <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3>
+    {% endif %}
 
     {% for reply in report.comment_set.vetted %}
         {% include 'comments/_single_comment_with_link.html' with comment=reply perms=perms user=user %}
diff --git a/submissions/templates/submissions/_single_public_report_without_comments.html b/submissions/templates/submissions/_single_public_report_without_comments.html
index bad492424de08ddb7c528cca2a7d70e0eba1e438..2c5c69adc82528e3cc09108b9c08eadff738020b 100644
--- a/submissions/templates/submissions/_single_public_report_without_comments.html
+++ b/submissions/templates/submissions/_single_public_report_without_comments.html
@@ -3,13 +3,19 @@
 
 <div class="row">
     <div class="col-12">
-        <div class="report">
+        <div class="report" id="report_{{report.report_nr}}">
             {% if user.contributor == submission.editor_in_charge or user|is_in_group:'Editorial Administrators' and user|is_not_author_of_submission:submission.arxiv_identifier_w_vn_nr %}
 
                 <div class="reportid">
                     <h3>{% if report.anonymous %}(chose public anonymity) {% endif %}<a href="{% url 'scipost:contributor_info' report.author.id %}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a>
                         on {{ report.date_submitted|date:'Y-n-j' }}</h3>
                     </h3>
+                    {% if report.pdf_report %}
+                        <a href="{% url 'submissions:report_detail_pdf' report.submission.arxiv_identifier_w_vn_nr report.report_nr %}" target="_blank">Download as PDF</a>
+                    {% endif %}
+                    {% if perms.scipost.can_manage_reports %}
+                        {% if report.pdf_report %}&middot; {% endif %}<a href="{% url 'submissions:report_pdf_compile' report.id %}"{% if not report.pdf_report %}class="btn btn-warning btn-sm"{% endif %}>Update/Compile the Report pdf</a>
+                    {% endif %}
                 </div>
 
                 {% if report.flagged %}
@@ -28,9 +34,10 @@
                 <div class="row">
                     <div class="col-12">
                         <h3>Remarks for editors</h3>
-                        <div class="pl-md-4">{{ report.remarks_for_editors }}</div>
+                        <div class="pl-md-4">{{ report.remarks_for_editors|default:'-' }}</div>
                     </div>
                 </div>
+
                 <div class="row">
                     <div class="col-12">
                         <h3>Recommendation</h3>
@@ -39,9 +46,15 @@
                 </div>
             {% else %}
                 <div class="reportid">
-                    <h3 id="report_id{{report.id}}">{% if report.anonymous %}Anonymous Report {{report.id}}{% else %}<a href="{% url 'scipost:contributor_info' report.author.id %}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a>{% endif %}
+                    <h3>{% if report.anonymous %}Anonymous Report {{report.report_nr}}{% else %}<a href="{% url 'scipost:contributor_info' report.author.id %}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a>{% endif %}
                         on {{ report.date_submitted|date:'Y-n-j' }}</h3>
                     </h3>
+                    {% if report.pdf_report %}
+                        <a href="{% url 'submissions:report_detail_pdf' report.submission.arxiv_identifier_w_vn_nr report.report_nr %}" target="_blank">Download as PDF</a>
+                    {% endif %}
+                    {% if perms.scipost.can_manage_reports %}
+                        {% if report.pdf_report %}&middot; {% endif %}<a href="{% url 'submissions:report_pdf_compile' report.id %}"{% if not report.pdf_report %}class="btn btn-warning btn-sm"{% endif %}>Update/Compile the Report pdf</a>
+                    {% endif %}
                 </div>
 
                 {% include 'submissions/_single_report_content.html' with report=report %}
diff --git a/submissions/templates/submissions/_single_report_card_summary.html b/submissions/templates/submissions/_single_report_card_summary.html
new file mode 100644
index 0000000000000000000000000000000000000000..e0f9fb2fe14cf4714659a4fde5045bc15771d5eb
--- /dev/null
+++ b/submissions/templates/submissions/_single_report_card_summary.html
@@ -0,0 +1,5 @@
+<div class="card-block {% block cardblock_class_block %}{% endblock %}">
+    <h3>{{report.get_status_display}} Report {{report.report_nr}} by {% if report.anonymous %}<em>anonymous</em>{% else %}<a href="{{report.author.get_absolute_url}}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a>{% endif %}</h3>
+    <h4>Received: {{ report.date_submitted|date:'Y-n-j' }}</h4>
+    On Submission: <a href="{{report.submission.get_absolute_url}}">{{report.submission}}</a>
+</div>
diff --git a/submissions/templates/submissions/_single_report_content.html b/submissions/templates/submissions/_single_report_content.html
index 82e06f943f39743d148e56b154382759fe1b2fa8..3e1874d8a8f4d81b1b1550dfb0bca28d0b0ce4be 100644
--- a/submissions/templates/submissions/_single_report_content.html
+++ b/submissions/templates/submissions/_single_report_content.html
@@ -1,27 +1,36 @@
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Strengths</h3>
-        <div class="pl-md-4">{{ report.strengths|linebreaks }}</div>
+{% if report.strengths %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Strengths</h3>
+            <div class="pl-md-4">{{ report.strengths|linebreaks }}</div>
+        </div>
     </div>
-</div>
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Weaknesses</h3>
-        <div class="pl-md-4">{{ report.weaknesses|linebreaks }}</div>
+{% endif %}
+
+{% if report.weaknesses %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Weaknesses</h3>
+            <div class="pl-md-4">{{ report.weaknesses|linebreaks }}</div>
+        </div>
     </div>
-</div>
+{% endif %}
+
 <div class="row">
     <div class="col-12">
         <h3 class="highlight tight">Report</h3>
         <div class="pl-md-4">{{ report.report|linebreaks }}</div>
     </div>
 </div>
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Requested changes</h3>
-        <div class="pl-md-4">
-            <p>{{ report.requested_changes|linebreaks }}</p>
-            {% include 'submissions/_single_report_ratings.html' with report=report %}
-      </div>
-  </div>
-</div>
+
+{% if report.requested_changes %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Requested changes</h3>
+            <div class="pl-md-4">
+                <p>{{ report.requested_changes|linebreaksbr }}</p>
+                {% include 'submissions/_single_report_ratings.html' with report=report %}
+            </div>
+        </div>
+    </div>
+{% endif %}
diff --git a/submissions/templates/submissions/_submission_card_author_content.html b/submissions/templates/submissions/_submission_card_author_content.html
index 89a1ae41aa7b9982b41dcb8bf59095a0ee47da88..1dabd69564b13275a5cc7742cbf8f826e3baeb2f 100644
--- a/submissions/templates/submissions/_submission_card_author_content.html
+++ b/submissions/templates/submissions/_submission_card_author_content.html
@@ -8,8 +8,10 @@
     <p class="card-text">Status: {{submission.get_status_display}}</p>
 
     {% if current_user and current_user.contributor == submission.submitted_by %}
-        <p>
-            <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>
+        <p class="card-text">
+            {% if submission.editor_in_charge %}
+                <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>
+            {% endif %}
             {% if submission.status == 'revision_requested' %}
             &middot; <a href="{% url 'submissions:prefill_using_identifier' %}?identifier={{submission.arxiv_identifier_wo_vn_nr}}">Resubmit this manuscript</a>
             {% endif %}
diff --git a/submissions/templates/submissions/_submission_refereeing_status.html b/submissions/templates/submissions/_submission_refereeing_status.html
index 50066b96f9b564b3e9d18b1dc24d191c56e922f6..5d1ea7b1d2c3baea8d9b6efab91ba7bc895382c8 100644
--- a/submissions/templates/submissions/_submission_refereeing_status.html
+++ b/submissions/templates/submissions/_submission_refereeing_status.html
@@ -1,6 +1,6 @@
 {% if submission.refereeing_cycle != 'direct_rec' %}
     <div class="card-block">
         <p class="card-text">Nr referees invited: {{submission.referee_invitations.count}} <span>[{{submission.count_accepted_invitations}} acccepted / {{submission.count_declined_invitations}} declined / {{submission.count_pending_invitations}} response pending]</span></p>
-        <p class="card-text">Nr reports obtained: {{submission.count_obtained_reports}} [{{submission.count_invited_reports}} invited / {{submission.count_contrib_reports}} contributed], nr refused: {{submission.count_refused_reports}}, nr awaiting vetting: {{submission.count_awaiting_vetting}}</p>
+        <p class="card-text">Nr reports obtained: {{submission.count_obtained_reports}} [{{submission.count_invited_reports}} invited / {{submission.count_contrib_reports}} contributed], nr refused: {{submission.reports.rejected.count}}, nr awaiting vetting: {{submission.reports.awaiting_vetting.count}}</p>
     </div>
 {% endif %}
diff --git a/submissions/templates/submissions/_submission_summary.html b/submissions/templates/submissions/_submission_summary.html
index 334f2d67912757293c26183e4412ee0e8f6d1601..613cc023ff67d310dc160c307b72ce562be694b6 100644
--- a/submissions/templates/submissions/_submission_summary.html
+++ b/submissions/templates/submissions/_submission_summary.html
@@ -1,6 +1,11 @@
 {% extends 'submissions/_submission_summary_short.html' %}
 
 {% block submission_summary_footer %}
+    {% if submission.pdf_refereeing_pack %}
+        <p class="mt-3">
+            <a href="{% url 'submissions:refereeing_package_pdf' submission.arxiv_identifier_w_vn_nr %}" target="_blank" class="btn btn-outline-primary">Download Refereeing Package</a>
+        </p>
+    {% endif %}
     <h3 class="mt-3">Abstract</h3>
     <p>{{submission.abstract}}</p>
 {% endblock %}
diff --git a/submissions/templates/submissions/_submission_summary_short.html b/submissions/templates/submissions/_submission_summary_short.html
index bf6915e89f54fe758948d39f7ae3d7c438025498..a5e999c09085d7ff121f00ad501ae30edc04af47 100644
--- a/submissions/templates/submissions/_submission_summary_short.html
+++ b/submissions/templates/submissions/_submission_summary_short.html
@@ -19,7 +19,7 @@
     </tr>
 
     <tr>
-        <td>arxiv Link:</td>
+        <td>Arxiv Link:</td>
         <td>
             <a href="{{submission.arxiv_link}}" target="_blank">{{submission.arxiv_link}}</a>
         </td>
diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html
index c2a20c722a204e2b42e55e0f762038b6af899185..069d183b679e7f09def5b4bb8cf87e95253f314b 100644
--- a/submissions/templates/submissions/editorial_page.html
+++ b/submissions/templates/submissions/editorial_page.html
@@ -26,10 +26,10 @@
                 <p class="card-text">(go to the <a href="{% url 'submissions:submission' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Submissions Page</a> to view Reports and Comments)</h3>
             </div>
         </div>
-        {% if other_versions %}
+        {% if submission.other_versions %}
             <h3>Other versions of this Submission exist:</h3>
             <div class="pl-4">
-                {% for vn in other_versions %}
+                {% for vn in submission.other_versions %}
                     {% include 'submissions/_submission_version.html' with submission=vn %}
                 {% endfor %}
             </div>
@@ -71,24 +71,22 @@
     </div>
 </div>
 
-{% if recommendation %}
-    <div class="row">
-        <div class="col-12">
-            <div class="card card-outline-secondary">
-                {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %}
+{% with recommendation as submission.eicrecommendations.first %}
+    {% if recommendation %}
+        <div class="row">
+            <div class="col-12">
+                <div class="card card-outline-secondary">
+                    {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %}
+                </div>
             </div>
         </div>
-    </div>
-{% endif %}
+    {% endif %}
+{% endwith %}
 
-<div class="row">
-    <div class="col-12">
-        <div class="card card-grey">
-            <div class="card-block">
-                <h1 class="card-title">Editorial Workflow</h1>
-                <a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a>
-            </div>
-        </div>
+<div class="card card-grey my-4">
+    <div class="card-block">
+        <h2 class="card-title">Editorial Workflow</h2>
+        <a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a>
     </div>
 </div>
 
@@ -111,7 +109,6 @@
         </div>
     </div>
 {% else %}
-
     {% if submission.refereeing_cycle != 'direct_rec' %}
         <div class="row">
             <div class="col-12">
@@ -123,7 +120,7 @@
         <div class="row">
             <div class="col-12">
                 <h3 class="mb-2">Detail of refereeing invitations:</h3>
-                {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=ref_invitations %}
+                {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=submission.referee_invitations.all %}
             </div>
         </div>
     {% endif %}
@@ -148,7 +145,7 @@
 
     <div class="row">
         <div class="col-12">
-            <h3>Actions:</h3>
+            <h2 class="mt-3">Actions</h2>
                 <ul>
                     {% if submission.refereeing_cycle != 'direct_rec' %}
                         <li>
@@ -173,7 +170,7 @@
                                 </div>
                             </form>
                         </li>
-                        <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ nr_reports_to_vet }})</li>
+                        <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ submission.reports.awaiting_vetting.count }})</li>
                         {% if not submission.reporting_deadline_has_passed %}
                             <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> &nbsp;(deactivates submission of new Reports and Comments)</li>
                         {% endif %}
@@ -188,28 +185,29 @@
     </div>
 {% endif %}
 
-<div class="row">
-    <div class="col-12">
-        <h1 class="highlight">Communications</h1>
-        <ul>
-            <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li>
-            <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li>
-        </ul>
-    </div>
-</div>
+<h2 class="mt-3">Communications</h2>
+<ul>
+    <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li>
+    <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li>
+</ul>
 
 <div class="row">
     <div class="col-12">
-        <ul class="list-group list-group-flush">
-            {% for comm in communications %}
-                <li class="list-group-item">
-                    {% include 'submissions/_editorial_communication_content.html' with communication=comm %}
-                </li>
-            {% empty %}
-                <li class="list-group-item">There have been no communications for this Submission.</li>
-            {% endfor %}
-        </ul>
+            <ul class="list-group list-group-flush">
+                {% for comm in submission.editorial_communications.all %}
+                    <li class="list-group-item">
+                        {% include 'submissions/_editorial_communication_content.html' with communication=comm %}
+                    </li>
+                {% empty %}
+                    <li class="list-group-item">There have been no communications for this Submission.</li>
+                {% endfor %}
+            </ul>
     </div>
 </div>
 
+<h2 class="mt-3">Events</h2>
+{% include 'submissions/submission_event_list.html' with events=submission.events.for_eic %}
+
+
+<div class="mb-5"></div>
 {% endblock content %}
diff --git a/submissions/templates/submissions/reports_accepted_list.html b/submissions/templates/submissions/reports_accepted_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..b4a2ff77d264bdbcf7531ec7d39e47e39e15573b
--- /dev/null
+++ b/submissions/templates/submissions/reports_accepted_list.html
@@ -0,0 +1,54 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Accepted Reports</span>
+{% endblock %}
+
+{% load bootstrap %}
+
+{% block pagetitle %}: Accepted Reports{% endblock pagetitle %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Accepted Reports</h1>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        <table class="table">
+            <thead>
+                <tr>
+                    <th>Report nr. of Submission</th>
+                    <th>Submission</th>
+                    <th>Report author</th>
+                    <th>Has PDF</th>
+                    <th>Action</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for report in reports %}
+                    <tr{% if not report.pdf_report %} class="table-danger"{% endif %}>
+                        <td>{{report.report_nr}}</td>
+                        <td><a href="{{report.get_absolute_url}}">{{report.submission.arxiv_identifier_w_vn_nr}}</a></td>
+                        <td>{% if report.anonymous %}<em>Anonymous</em>{% else %}{{report.author}}{% endif %}</td>
+                        <td>
+                            {{report.pdf_report|yesno:"Yes,No"}}
+                            {% if report.pdf_report %}
+                                &middot; <a href="{% url 'submissions:report_detail_pdf' report.submission.arxiv_identifier_w_vn_nr report.report_nr %}" target="_blank">Download</a>
+                            {% endif %}
+                        </td>
+                        <td>
+                            <a href="{% url 'submissions:report_pdf_compile' report.id %}">Compile/upload report</a>
+                        </td>
+                    </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+
+{% endblock %}
diff --git a/submissions/templates/submissions/reports_pdf_compile.html b/submissions/templates/submissions/reports_pdf_compile.html
new file mode 100644
index 0000000000000000000000000000000000000000..bf46e0b6860c836b3d5a3c7d843508ea94253412
--- /dev/null
+++ b/submissions/templates/submissions/reports_pdf_compile.html
@@ -0,0 +1,74 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block pagetitle %}: Upload Report PDF{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <a href="{% url 'submissions:reports_accepted_list' %}" class="breadcrumb-item">Accepted Reports</a>
+    <span class="breadcrumb-item">Upload Report PDF</span>
+{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col-12">
+            <h1 class="highlight">Upload Report PDF</h1>
+            <div class="card">
+                {% include 'submissions/_single_report_card_summary.html' with submission=report %}
+            </div>
+        </div>
+    </div>
+
+    <div class="row">
+        <div class="col-12">
+            <h3>Please process this code in your Tex Compiler:</h3>
+            <p>To compile, one needs the SciPost Latex Package. Please <a href="mailto: info@scipost.org">contact SciPost</a> if you did not receive it.</p>
+            <pre class="clickfocus" style="max-height: 200px;"><code>{% include 'submissions/_report_tex_template.html' with report=report %}</code></pre>
+        </div>
+    </div>
+
+
+    <div class="row">
+        <div class="col-12">
+          <form method="post" enctype="multipart/form-data">
+            {% csrf_token %}
+            {{ form|bootstrap }}
+            <input class="btn btn-secondary" type="submit" value="Upload"/>
+          </form>
+        </div>
+    </div>
+
+<script>
+    jQuery.fn.selectText = function(){
+        this.find('input').each(function() {
+            if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) {
+                $('<p class="p_copy" style="position: absolute; z-index: -1;"></p>').insertBefore($(this));
+            }
+            $(this).prev().html($(this).val());
+        });
+        var doc = document;
+        var element = this[0];
+
+        if (doc.body.createTextRange) {
+            var range = document.body.createTextRange();
+            range.moveToElementText(element);
+            range.select();
+        } else if (window.getSelection) {
+            var selection = window.getSelection();
+            var range = document.createRange();
+            range.selectNodeContents(element);
+            selection.removeAllRanges();
+            selection.addRange(range);
+        }
+    };
+
+    $(function() {
+        $('.clickfocus').on('click', function() {
+            $(this).find('code').selectText();
+        });
+    });
+</script>
+
+{% endblock %}
diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html
index f255cf191d11632a6776dda1ba0baf10e76e4ffd..4e6188df9338e987679e3648cd003496bd609181 100644
--- a/submissions/templates/submissions/submission_detail.html
+++ b/submissions/templates/submissions/submission_detail.html
@@ -50,10 +50,10 @@
             </div>
         </div>
 
-        {% if other_versions %}
+        {% if submission.other_versions %}
             <h3>Other versions of this Submission (with Reports) exist:</h3>
             <div class="pl-4">
-                {% for vn in other_versions %}
+                {% for vn in submission.other_versions %}
                     {% include 'submissions/_submission_version.html' with submission=vn %}
                 {% endfor %}
             </div>
@@ -99,6 +99,14 @@
             </div>
         {% endif %}
     {% endif %}
+
+    <div class="mb-4">
+        <h2>Events</h2>
+        <a href="javascript:;" data-toggle="toggle" data-target="#eventslist">Show/hide events</a>
+        <div id="eventslist">
+            {% include 'submissions/submission_event_list.html' with events=submission.events.for_author %}
+        </div>
+    </div>
 {% endif %}
 
 
@@ -139,6 +147,14 @@
                 <li>Commenting on this Submission is closed.</li>
             {% endif %}
         </ul>
+        {% if perms.scipost.can_manage_reports %}
+            <h3>Admin Actions</h3>
+            <ul>
+                <li>
+                    <a href="{% url 'submissions:treated_submission_pdf_compile' submission.arxiv_identifier_w_vn_nr %}">Update the Refereeing Package pdf</a>
+                </li>
+            <ul>
+        {% endif %}
     </div>
 </div>
 {% endif %}
diff --git a/submissions/templates/submissions/submission_event_list.html b/submissions/templates/submissions/submission_event_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..01e3d1b2dad54dc98a151d7ca30b49035114e786
--- /dev/null
+++ b/submissions/templates/submissions/submission_event_list.html
@@ -0,0 +1,16 @@
+<div class="row">
+    <div class="col-12">
+            <ul class="list-group list-group-flush events-list">
+                {% for event in events %}
+                    <li class="list-group-item">
+                        <div>
+                            {{event.text}}<br>
+                            <span class="text-muted">{{event.created}}</span>
+                        </div>
+                    </li>
+                {% empty %}
+                    <li class="list-group-item">There have been no events for this Submission.</li>
+                {% endfor %}
+            </ul>
+    </div>
+</div>
diff --git a/submissions/templates/submissions/submit_report.html b/submissions/templates/submissions/submit_report.html
index 63f80e447b69a04de026d1a51db389b58df83e29..fb4029c449a0df7ba6ebd109247bdb01de5e6255 100644
--- a/submissions/templates/submissions/submit_report.html
+++ b/submissions/templates/submissions/submit_report.html
@@ -81,13 +81,20 @@
         <div class="col-12">
             <div class="card card-grey">
                 <div class="card-block">
-                    <h1>Your report:</h1>
-                    <p class="mb-0">A preview of text areas will appear below as you type (you can use LaTeX \$...\$ for in-text equations or \ [ ... \ ] for on-line equations).</p>
+                    <h1>Your {% if form.instance.is_followup_report %}followup {% endif %}report:</h1>
+                    <p>A preview of text areas will appear below as you type (you can use LaTeX \$...\$ for in-text equations or \ [ ... \ ] for on-line equations).</p>
+                    <p class="mb-0">Any fields with an asterisk (*) are required.</p>
+                    {% if form.instance.is_followup_report %}
+                        <p class="mb-0">
+                            Because you have already submitted a Report for this Submission series, not all fields are required.
+                        </p>
+                    {% endif %}
                 </div>
             </div>
             <form action="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post">
                 {% csrf_token %}
                 {{ form|bootstrap:'3,9' }}
+                <p>Any fields with an asterisk (*) are required.</p>
                 <input class="btn btn-primary" type="submit" name="save_submit" value="Submit your report"/>
                 <input class="btn btn-secondary ml-2" type="submit" name="save_draft" value="Save your report as draft"/>
                 <div class="my-4">
diff --git a/submissions/templates/submissions/treated_submission_pdf_compile.html b/submissions/templates/submissions/treated_submission_pdf_compile.html
new file mode 100644
index 0000000000000000000000000000000000000000..19e456fefbb06e35c872c25f1cc8c53e0020ea62
--- /dev/null
+++ b/submissions/templates/submissions/treated_submission_pdf_compile.html
@@ -0,0 +1,82 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block pagetitle %}: Upload Submission Refereeing PDF{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <a href="{% url 'submissions:treated_submissions_list' %}" class="breadcrumb-item">Treated Submissions</a>
+    <span class="breadcrumb-item">Upload Submission Refereeing PDF</span>
+{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col-12">
+            <h1 class="highlight">Upload Submission Refereeing PDF</h1>
+            {% include 'submissions/_submission_summary_short.html' with submission=submission %}
+            <p class="my-2"><a href="{{submission.get_absolute_url}}">Go to Submission page</a></p>
+        </div>
+    </div>
+    <hr>
+
+    <div class="row">
+        <div class="col-12">
+            <h3>Please process this code in your Tex Compiler</h3>
+            <p>
+                You may need to compile twice because of the Table of Content.<br>
+                To compile, one needs the SciPost Latex Package. Please <a href="mailto: info@scipost.org">contact SciPost</a> if you did not receive it.
+            </p>
+            <h3>Content of the Refereeing Package</h3>
+            <p>
+                Number of Reports: {{submission.reports.accepted.count}}<br>
+                Number of Comments <small>(nested comments not counted)</small>: {{submission.comments.vetted.count}}
+            </p>
+            <pre class="clickfocus" style="max-height: 200px;"><code>{% include 'submissions/_refereeing_pack_tex_template.html' with submission=submission %}</code></pre>
+        </div>
+    </div>
+
+
+    <div class="row">
+        <div class="col-12">
+          <form method="post" enctype="multipart/form-data">
+            {% csrf_token %}
+            {{ form|bootstrap }}
+            <input class="btn btn-secondary" type="submit" value="Upload"/>
+          </form>
+        </div>
+    </div>
+
+<script>
+    jQuery.fn.selectText = function(){
+        this.find('input').each(function() {
+            if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) {
+                $('<p class="p_copy" style="position: absolute; z-index: -1;"></p>').insertBefore($(this));
+            }
+            $(this).prev().html($(this).val());
+        });
+        var doc = document;
+        var element = this[0];
+
+        if (doc.body.createTextRange) {
+            var range = document.body.createTextRange();
+            range.moveToElementText(element);
+            range.select();
+        } else if (window.getSelection) {
+            var selection = window.getSelection();
+            var range = document.createRange();
+            range.selectNodeContents(element);
+            selection.removeAllRanges();
+            selection.addRange(range);
+        }
+    };
+
+    $(function() {
+        $('.clickfocus').on('click', function() {
+            $(this).find('code').selectText();
+        });
+    });
+</script>
+
+{% endblock %}
diff --git a/submissions/templates/submissions/treated_submissions_list.html b/submissions/templates/submissions/treated_submissions_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..c9b167bd9832f074302c794376cfd497b0413f2c
--- /dev/null
+++ b/submissions/templates/submissions/treated_submissions_list.html
@@ -0,0 +1,56 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Treated Submissions</span>
+{% endblock %}
+
+{% load bootstrap %}
+
+{% block pagetitle %}: Treated Submissions{% endblock pagetitle %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Treated Submissions</h1>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        <table class="table">
+            <thead>
+                <tr>
+                    <th>Submission</th>
+                    <th>Status</th>
+                    <th>Accepted</th>
+                    <th>Number of Reports</th>
+                    <th>Has PDF</th>
+                    <th>Action</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for submission in submissions %}
+                    <tr{% if not submission.pdf_refereeing_pack %} class="table-danger"{% endif %}>
+                        <td><a href="{{submission.get_absolute_url}}">{{submission.arxiv_identifier_w_vn_nr}}</a></td>
+                        <td>{{submission.get_status_display}}</td>
+                        <td>{{submission.acceptance_date|default_if_none:'Date unknown'}}</td>
+                        <td>{{submission.reports.accepted.count}}</td>
+                        <td>
+                            {{submission.pdf_refereeing_pack|yesno:"Yes,No"}}
+                            {% if submission.pdf_refereeing_pack %}
+                                &middot; <a href="{% url 'submissions:refereeing_package_pdf' submission.arxiv_identifier_w_vn_nr %}" target="_blank">Download</a>
+                            {% endif %}
+                        </td>
+                        <td>
+                            <a href="{% url 'submissions:treated_submission_pdf_compile' submission.arxiv_identifier_w_vn_nr %}">Compile/upload Refereeing Package</a>
+                        </td>
+                    </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+
+{% endblock %}
diff --git a/submissions/templatetags/lookup.py b/submissions/templatetags/lookup.py
index 803edd8acbd338d2202c2c1666955ac082787673..c2f7e549124208067d554ffd7ce304d5f8758ae2 100644
--- a/submissions/templatetags/lookup.py
+++ b/submissions/templatetags/lookup.py
@@ -8,7 +8,7 @@ class SubmissionLookup(LookupChannel):
 
     def get_query(self, q, request):
         return (self.model.objects
-                .public()
+                .public_unlisted()
                 .order_by('-submission_date')
                 .filter(title__icontains=q)
                 .prefetch_related('publication')[:10])
diff --git a/submissions/urls.py b/submissions/urls.py
index 6e776fcf71b60a8500c7f7fc8657ac7eb0f9e8e2..c4d8d4fc656accf12e14509b8e9386d804caa865 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -18,6 +18,13 @@ urlpatterns = [
         name='submission_wo_vn_nr'),
     url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/$',
         views.submission_detail, name='submission'),
+    url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/reports/(?P<report_nr>[0-9]+)/pdf$',
+        views.report_detail_pdf, name='report_detail_pdf'),
+    url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/reports/pdf$',
+        views.submission_refereeing_package_pdf, name='refereeing_package_pdf'),
+    url(r'^treated_submissions$', views.treated_submissions_list, name='treated_submissions_list'),
+    url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/reports/compile$',
+        views.treated_submission_pdf_compile, name='treated_submission_pdf_compile'),
     url(r'^submit_manuscript$', views.RequestSubmission.as_view(), name='submit_manuscript'),
     url(r'^submit_manuscript/prefill$', views.prefill_using_arxiv_identifier,
         name='prefill_using_identifier'),
@@ -26,6 +33,7 @@ urlpatterns = [
         views.submissions_by_status, name='submissions_by_status'),
     url(r'^add_remark/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})$',
         views.add_remark, name='add_remark'),
+
     # Assignment of Editor-in-charge
     url(r'^assign_submission/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})$',
         views.assign_submission, name='assign_submission'),
@@ -73,9 +81,13 @@ urlpatterns = [
     url(r'^cycle/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/submit$',
         views.cycle_form_submit, name='cycle_confirmation'),
     # Reports
-    url(r'^submit_report/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})$',
+    url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/reports/submit$',
         views.submit_report, name='submit_report'),
-    url(r'^vet_submitted_reports$', views.vet_submitted_reports, name='vet_submitted_reports'),
+    url(r'^reports/vet_submitted$', views.vet_submitted_reports, name='vet_submitted_reports'),
+    url(r'^reports/list$', views.reports_accepted_list, name='reports_accepted_list'),
+    url(r'^reports/(?P<report_id>[0-9]+)/compile$',
+        views.report_pdf_compile, name='report_pdf_compile'),
+
     # Voting
     url(r'^prepare_for_voting/(?P<rec_id>[0-9]+)$', views.prepare_for_voting, name='prepare_for_voting'),
     url(r'^vote_on_rec/(?P<rec_id>[0-9]+)$', views.vote_on_rec, name='vote_on_rec'),
diff --git a/submissions/utils.py b/submissions/utils.py
index 908f7f35c9a12bfd2a592b2a712b31952f468bce..385dbfc3402e25ff730686360b4f49f6561e8428 100644
--- a/submissions/utils.py
+++ b/submissions/utils.py
@@ -126,7 +126,6 @@ class BaseSubmissionCycle:
         self.submission.reporting_deadline = deadline
         self.submission.save()
 
-
     def get_required_actions(self):
         '''Return list of the submission its required actions'''
         if not self.updated_action:
diff --git a/submissions/views.py b/submissions/views.py
index dbe926c6d43fff757dc1943d7400f2fe395de3c6..7d54e68dd9ecff81d84478413d99eda70cad92af 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -6,11 +6,13 @@ from django.contrib.auth.decorators import login_required, permission_required
 from django.contrib.auth.models import Group
 from django.core.urlresolvers import reverse, reverse_lazy
 from django.db import transaction
-from django.http import Http404, HttpResponseRedirect
+from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.shortcuts import get_object_or_404, render, redirect
 from django.template import Template, Context
 from django.utils import timezone
 from django.utils.decorators import method_decorator
+from django.views.generic.edit import CreateView
+from django.views.generic.list import ListView
 
 from guardian.decorators import permission_required_or_403
 from guardian.shortcuts import assign_perm
@@ -25,7 +27,7 @@ from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSe
                    SetRefereeingDeadlineForm, RefereeSelectForm, RefereeRecruitmentForm,\
                    ConsiderRefereeInvitationForm, EditorialCommunicationForm,\
                    EICRecommendationForm, ReportForm, VetReportForm, VotingEligibilityForm,\
-                   SubmissionCycleChoiceForm
+                   SubmissionCycleChoiceForm, ReportPDFForm, SubmissionReportsForm
 from .utils import SubmissionUtils
 
 from scipost.forms import ModifyPersonalMessageForm, RemarkForm
@@ -35,9 +37,6 @@ from scipost.utils import Utils
 from comments.forms import CommentForm
 from production.models import ProductionStream
 
-from django.views.generic.edit import CreateView
-from django.views.generic.list import ListView
-
 import strings
 
 
@@ -63,6 +62,9 @@ class RequestSubmission(CreateView):
     @transaction.atomic
     def form_valid(self, form):
         submission = form.save()
+        submission.add_general_event('The manuscript has been submitted to %s.'
+                                     % submission.get_submitted_to_journal_display())
+
         text = ('<h3>Thank you for your Submission to SciPost</h3>'
                 'Your Submission will soon be handled by an Editor.')
         messages.success(self.request, text)
@@ -119,7 +121,7 @@ class SubmissionListView(ListView):
     paginate_by = 10
 
     def get_queryset(self):
-        queryset = Submission.objects.public_overcomplete()
+        queryset = Submission.objects.public_newest()
         self.form = self.form(self.request.GET)
         if 'to_journal' in self.kwargs:
             queryset = queryset.filter(
@@ -186,9 +188,6 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
                                                          'Editorial College']).exists()
             and not is_author):
         raise Http404
-    other_versions = Submission.objects.filter(
-        arxiv_identifier_wo_vn_nr=submission.arxiv_identifier_wo_vn_nr
-    ).exclude(pk=submission.id)
 
     form = CommentForm()
 
@@ -206,7 +205,6 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
         recommendation = None
 
     context = {'submission': submission,
-               'other_versions': other_versions,
                'recommendation': recommendation,
                'comments': comments,
                'invited_reports': invited_reports,
@@ -219,6 +217,91 @@ def submission_detail(request, arxiv_identifier_w_vn_nr):
     return render(request, 'submissions/submission_detail.html', context)
 
 
+def report_detail_pdf(request, arxiv_identifier_w_vn_nr, report_nr):
+    """
+    Download the PDF of a Report if available.
+    """
+    report = get_object_or_404(Report.objects.accepted(),
+                               submission__arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr,
+                               pdf_report__isnull=False, report_nr=report_nr)
+    response = HttpResponse(report.pdf_report.read(), content_type='application/pdf')
+    filename = '%s_report-%i.pdf' % (report.submission.arxiv_identifier_w_vn_nr, report.report_nr)
+    response['Content-Disposition'] = ('filename=' + filename)
+    return response
+
+
+def submission_refereeing_package_pdf(request, arxiv_identifier_w_vn_nr):
+    """
+    This view let's the user download all Report PDF's in a single merged PDF.
+    The merging takes places every time its downloaded to make sure all available report PDF's
+    are included and the EdColAdmin doesn't have to compile the package every time again.
+    """
+    submission = get_object_or_404(Submission.objects.public().exclude(pdf_refereeing_pack=''),
+                                   arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+    response = HttpResponse(submission.pdf_refereeing_pack.read(), content_type='application/pdf')
+    filename = '%s-refereeing-package.pdf' % submission.arxiv_identifier_w_vn_nr
+    response['Content-Disposition'] = ('filename=' + filename)
+    return response
+
+
+@permission_required('scipost.can_manage_reports', raise_exception=True)
+def reports_accepted_list(request):
+    """
+    This view lists all accepted Reports. This shows if Report needs a PDF update/compile
+    in a convenient way.
+    """
+    reports = (Report.objects.accepted()
+               .order_by('pdf_report', 'submission').prefetch_related('submission'))
+    context = {
+        'reports': reports
+    }
+    return render(request, 'submissions/reports_accepted_list.html', context)
+
+
+@permission_required('scipost.can_manage_reports', raise_exception=True)
+def report_pdf_compile(request, report_id):
+    report = get_object_or_404(Report.objects.accepted(), id=report_id)
+    form = ReportPDFForm(request.POST or None, request.FILES or None, instance=report)
+    if form.is_valid():
+        report = form.save()
+        messages.success(request, 'Upload complete.')
+        return redirect(reverse('submissions:reports_accepted_list'))
+    context = {
+        'report': report,
+        'form': form
+    }
+    return render(request, 'submissions/reports_pdf_compile.html', context)
+
+
+@permission_required('scipost.can_manage_reports', raise_exception=True)
+def treated_submissions_list(request):
+    """
+    This view lists all accepted Reports. This shows if Report needs a PDF update/compile
+    in a convenient way.
+    """
+    submissions = Submission.objects.treated().order_by('pdf_refereeing_pack', '-acceptance_date')
+    context = {
+        'submissions': submissions
+    }
+    return render(request, 'submissions/treated_submissions_list.html', context)
+
+
+@permission_required('scipost.can_manage_reports', raise_exception=True)
+def treated_submission_pdf_compile(request, arxiv_identifier_w_vn_nr):
+    submission = get_object_or_404(Submission.objects.treated(),
+                                   arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
+    form = SubmissionReportsForm(request.POST or None, request.FILES or None, instance=submission)
+    if form.is_valid():
+        form.save()
+        messages.success(request, 'Upload complete.')
+        return redirect(reverse('submissions:treated_submissions_list'))
+    context = {
+        'submission': submission,
+        'form': form
+    }
+    return render(request, 'submissions/treated_submission_pdf_compile.html', context)
+
+
 ######################
 # Editorial workflow #
 ######################
@@ -397,6 +480,9 @@ def accept_or_decline_assignment_ack(request, assignment_id):
                 assign_perm('can_take_editorial_actions', ed_admins, assignment.submission)
                 SubmissionUtils.send_EIC_appointment_email()
                 SubmissionUtils.send_author_prescreening_passed_email()
+
+                # Add SubmissionEvents
+                assignment.submission.add_general_event('The Editor-in-charge has been assigned.')
             else:
                 assignment.accepted = False
                 assignment.refusal_reason = form.cleaned_data['refusal_reason']
@@ -457,6 +543,9 @@ def volunteer_as_EIC(request, arxiv_identifier_w_vn_nr):
     SubmissionUtils.send_EIC_appointment_email()
     SubmissionUtils.send_author_prescreening_passed_email()
 
+    # Add SubmissionEvents
+    submission.add_general_event('The Editor-in-charge has been assigned.')
+
     messages.success(request, 'Thank you for becoming Editor-in-charge of this submission.')
     return redirect(reverse('submissions:editorial_page',
                             args=[submission.arxiv_identifier_w_vn_nr]))
@@ -526,30 +615,11 @@ def assignments(request):
 def editorial_page(request, arxiv_identifier_w_vn_nr):
     submission = get_object_or_404(Submission.objects.filter_editorial_page(request.user),
                                    arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr)
-    other_versions = (Submission.objects
-                      .filter(arxiv_identifier_wo_vn_nr=submission.arxiv_identifier_wo_vn_nr)
-                      .exclude(pk=submission.id))
-    ref_invitations = RefereeInvitation.objects.filter(submission=submission)
-    nr_reports_to_vet = (Report.objects.awaiting_vetting()
-                         .filter(submission=submission,
-                                 submission__editor_in_charge=request.user.contributor)
-                         .count())
-    communications = (EditorialCommunication.objects
-                      .filter(submission=submission).order_by('timestamp'))
-    try:
-        recommendation = (EICRecommendation.objects.get_for_user_in_pool(request.user)
-                          .get(submission=submission))
-    except EICRecommendation.DoesNotExist:
-        recommendation = None
+
     context = {
         'submission': submission,
-        'other_versions': other_versions,
-        'recommendation': recommendation,
         'set_deadline_form': SetRefereeingDeadlineForm(),
         'cycle_choice_form': SubmissionCycleChoiceForm(instance=submission),
-        'ref_invitations': ref_invitations,
-        'nr_reports_to_vet': nr_reports_to_vet,
-        'communications': communications
     }
     return render(request, 'submissions/editorial_page.html', context)
 
@@ -661,6 +731,9 @@ def recruit_referee(request, arxiv_identifier_w_vn_nr):
             reg_invitation.save()
             Utils.load({'invitation': reg_invitation})
             Utils.send_registration_invitation_email()
+            submission.add_event_for_author('A referee has been invited.')
+            submission.add_event_for_eic('%s has been recruited and invited as a referee.'
+                                         % ref_recruit_form.cleaned_data['last_name'])
             # Copy the key to the refereeing invitation:
             ref_invitation.invitation_key = reg_invitation.invitation_key
             ref_invitation.save()
@@ -700,6 +773,9 @@ def send_refereeing_invitation(request, arxiv_identifier_w_vn_nr, contributor_id
     invitation.save()
     SubmissionUtils.load({'invitation': invitation})
     SubmissionUtils.send_refereeing_invitation_email()
+    submission.add_event_for_author('A referee has been invited.')
+    submission.add_event_for_eic('Referee %s has been invited.' % contributor.user.last_name)
+    messages.success(request, 'Invitation sent')
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
@@ -753,14 +829,23 @@ def accept_or_decline_ref_invitation_ack(request, invitation_id):
         invitation.date_responded = timezone.now()
         if form.cleaned_data['accept'] == 'True':
             invitation.accepted = True
+            decision_string = 'accepted'
         else:
             invitation.accepted = False
+            decision_string = 'declined'
             invitation.refusal_reason = form.cleaned_data['refusal_reason']
         invitation.save()
         SubmissionUtils.load({'invitation': invitation}, request)
         SubmissionUtils.email_referee_response_to_EIC()
         SubmissionUtils.email_referee_in_response_to_decision()
 
+        # Add SubmissionEvents
+        invitation.submission.add_event_for_author('A referee has %s the refereeing invitation.'
+                                                   % decision_string)
+        invitation.submission.add_event_for_eic('Referee %s has %s the refereeing invitation.'
+                                                % (invitation.referee.user.last_name,
+                                                   decision_string))
+
     context = {'invitation': invitation}
     return render(request, 'submissions/accept_or_decline_ref_invitation_ack.html', context)
 
@@ -776,6 +861,13 @@ def decline_ref_invitation(request, invitation_key):
         invitation.save()
         SubmissionUtils.load({'invitation': invitation}, request)
         SubmissionUtils.email_referee_response_to_EIC()
+
+        # Add SubmissionEvents
+        invitation.submission.add_event_for_author('A referee has declined the'
+                                                   ' refereeing invitation.')
+        invitation.submission.add_event_for_eic('Referee %s has declined the refereeing '
+                                                'invitation.' % invitation.referee.user.last_name)
+
         messages.success(request, 'Thank you for informing us that you will not provide a Report.')
         return redirect(reverse('scipost:index'))
     context = {'invitation': invitation, 'form': form}
@@ -796,6 +888,12 @@ def cancel_ref_invitation(request, arxiv_identifier_w_vn_nr, invitation_id):
     invitation.save()
     SubmissionUtils.load({'invitation': invitation})
     SubmissionUtils.send_ref_cancellation_email()
+
+    # Add SubmissionEvents
+    invitation.submission.add_event_for_author('A referee invitation has been cancelled.')
+    invitation.submission.add_event_for_eic('Referee invitation for %s has been cancelled.'
+                                            % invitation.last_name)
+
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
@@ -812,6 +910,8 @@ def extend_refereeing_deadline(request, arxiv_identifier_w_vn_nr, days):
     submission.status = 'EICassigned'
     submission.latest_activity = timezone.now()
     submission.save()
+
+    submission.add_general_event('A new refereeing deadline is set.')
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
@@ -832,6 +932,7 @@ def set_refereeing_deadline(request, arxiv_identifier_w_vn_nr):
             submission.status = 'EICassigned'
             submission.latest_activity = timezone.now()
             submission.save()
+            submission.add_general_event('A new refereeing deadline is set.')
             context = {'ack_header': 'New reporting deadline set.',
                        'followup_message': 'Return to the ',
                        'followup_link': reverse('submissions:editorial_page',
@@ -866,6 +967,8 @@ def close_refereeing_round(request, arxiv_identifier_w_vn_nr):
     submission.reporting_deadline = timezone.now()
     submission.latest_activity = timezone.now()
     submission.save()
+    submission.add_general_event('Refereeing round has been closed.')
+
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
@@ -945,16 +1048,12 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
 
     form = EICRecommendationForm(request.POST or None)
     if form.is_valid():
-        recommendation = EICRecommendation(
-            submission=submission,
-            date_submitted=timezone.now(),
-            remarks_for_authors=form.cleaned_data['remarks_for_authors'],
-            requested_changes=form.cleaned_data['requested_changes'],
-            remarks_for_editorial_college=form.cleaned_data['remarks_for_editorial_college'],
-            recommendation=form.cleaned_data['recommendation'],
-            voting_deadline=timezone.now() + datetime.timedelta(days=7),
-        )
+        # Create new EICRecommendation
+        recommendation = form.save(commit=False)
+        recommendation.submission = submission
+        recommendation.voting_deadline = timezone.now() + datetime.timedelta(days=7)
         recommendation.save()
+
         # If recommendation is to accept or reject,
         # it is forwarded to the Editorial College for voting
         # If it is to carry out minor or major revisions,
@@ -964,12 +1063,21 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr):
                 recommendation.recommendation == 3 or
                 recommendation.recommendation == -3):
             submission.status = 'voting_in_preparation'
+
+            # Add SubmissionEvent for EIC
+            submission.add_event_for_eic('An Editorial Recommendation has been formulated: %s.'
+                                         % recommendation.get_recommendation_display())
+
         elif (recommendation.recommendation == -1 or
               recommendation.recommendation == -2):
             submission.status = 'revision_requested'
             SubmissionUtils.load({'submission': submission,
                                   'recommendation': recommendation})
             SubmissionUtils.send_author_revision_requested_email()
+
+            # Add SubmissionEvents
+            submission.add_general_event('An Editorial Recommendation has been formulated: %s.'
+                                         % recommendation.get_recommendation_display())
         submission.open_for_reporting = False
         submission.save()
 
@@ -1032,6 +1140,7 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
         errormessage = ('The system flagged you as a potential author of this Submission. '
                         'Please go to your personal page under the Submissions tab'
                         ' to clarify this.')
+
     if errormessage:
         messages.warning(request, errormessage)
         return redirect(reverse('scipost:personal_page'))
@@ -1040,12 +1149,12 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
     try:
         report_in_draft = submission.reports.in_draft().get(author=current_contributor)
     except Report.DoesNotExist:
-        report_in_draft = None
+        report_in_draft = Report(author=current_contributor, submission=submission)
     form = ReportForm(request.POST or None, instance=report_in_draft)
 
     # Check if data sent is valid
     if form.is_valid():
-        newreport = form.save(submission, current_contributor)
+        newreport = form.save(submission)
         if newreport.status == STATUS_DRAFT:
             messages.success(request, ('Your Report has been saved. '
                                        'You may carry on working on it,'
@@ -1058,6 +1167,10 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
         SubmissionUtils.email_EIC_report_delivered()
         SubmissionUtils.email_referee_report_delivered()
 
+        # Add SubmissionEvents for the EIC only, as it can also be rejected still
+        submission.add_event_for_eic('%s has submitted a new Report.'
+                                     % request.user.last_name)
+
         messages.success(request, 'Thank you for your Report')
         return redirect(reverse('scipost:personal_page'))
 
@@ -1069,16 +1182,17 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
 @permission_required('scipost.can_take_charge_of_submissions', raise_exception=True)
 def vet_submitted_reports(request):
     """
-    Reports with status `unvetted` will be shown one-by-one. A user may only
+    Reports with status `unvetted` will be shown one-by-one (oldest first). A user may only
     vet reports of submissions he/she is EIC of.
 
     After vetting an email is sent to the report author, bcc EIC. If report
     has not been refused, the submission author is also mailed.
     """
-    contributor = Contributor.objects.get(user=request.user)
+    contributor = request.user.contributor
     report_to_vet = (Report.objects.awaiting_vetting()
                      .select_related('submission')
-                     .filter(submission__editor_in_charge=contributor).first())
+                     .filter(submission__editor_in_charge=contributor)
+                     .order_by('date_submitted').first())
 
     form = VetReportForm(request.POST or None, initial={'report': report_to_vet})
     if form.is_valid():
@@ -1088,9 +1202,17 @@ def vet_submitted_reports(request):
         SubmissionUtils.load({'report': report,
                               'email_response': form.cleaned_data['email_response_field']})
         SubmissionUtils.acknowledge_report_email()  # email report author, bcc EIC
+
+        # 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()
 
+            # 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>.' % (
             reverse('submissions:editorial_page',
                     args=(report.submission.arxiv_identifier_w_vn_nr,)),
@@ -1125,6 +1247,11 @@ def prepare_for_voting(request, rec_id):
             recommendation.submission.status = 'put_to_EC_voting'
             recommendation.submission.save()
             messages.success(request, 'We have registered your selection.')
+
+            # Add SubmissionEvents
+            recommendation.submission.add_event_for_eic('The Editorial Recommendation has been '
+                                                        'put forward to the College for voting.')
+
             return redirect(reverse('submissions:editorial_page',
                                     args=[recommendation.submission.arxiv_identifier_w_vn_nr]))
     else:
@@ -1231,27 +1358,40 @@ def fix_College_decision(request, rec_id):
     """
     recommendation = get_object_or_404((EICRecommendation.objects
                                         .get_for_user_in_pool(request.user)), pk=rec_id)
+    submission = recommendation.submission
     if recommendation.recommendation in [1, 2, 3]:
         # Publish as Tier I, II or III
-        recommendation.submission.status = 'accepted'
-        recommendation.submission.acceptance_date = datetime.date.today()
+        submission.status = 'accepted'
+        submission.acceptance_date = datetime.date.today()
+
         # Create a ProductionStream object
-        prodstream = ProductionStream(submission=recommendation.submission)
+        prodstream = ProductionStream(submission=submission)
         prodstream.save()
+
+        # Add SubmissionEvent for authors
+        # Do not write a new event for minor/major modification: already done at moment of
+        # creation.
+        submission.add_event_for_author('An Editorial Recommendation has been formulated: %s.'
+                                        % recommendation.get_recommendation_display())
     elif recommendation.recommendation == -3:
-        # Reject
-        recommendation.submission.status = 'rejected'
-        previous_submissions = Submission.objects.filter(
-            arxiv_identifier_wo_vn_nr=recommendation.submission.arxiv_identifier_wo_vn_nr
-        ).exclude(pk=recommendation.submission.id)
-        for sub in previous_submissions:
+        # Reject + update-reject other versions of submission
+        submission.status = 'rejected'
+        for sub in submission.other_versions:
             sub.status = 'resubmitted_rejected'
             sub.save()
 
-    recommendation.submission.save()
-    SubmissionUtils.load({'submission': recommendation.submission,
-                          'recommendation': recommendation})
+        # Add SubmissionEvent for authors
+        # Do not write a new event for minor/major modification: already done at moment of
+        # creation.
+        submission.add_event_for_author('An Editorial Recommendation has been formulated: %s.'
+                                        % recommendation.get_recommendation_display())
+
+    # Add SubmissionEvent for EIC
+    submission.add_event_for_eic('The Editorial College\'s decision has been fixed: %s.'
+                                 % recommendation.get_recommendation_display())
+
+    submission.save()
+    SubmissionUtils.load({'submission': submission, 'recommendation': recommendation})
     SubmissionUtils.send_author_College_decision_email()
-    ack_message = 'The Editorial College\'s decision has been fixed.'
-    return render(request, 'scipost/acknowledgement.html',
-                  context={'ack_message': ack_message})
+    messages.success(request, 'The Editorial College\'s decision has been fixed.')
+    return redirect(reverse('submissions:pool'))