diff --git a/.gitignore b/.gitignore
index 0eeb06ba57fd256d5cd7eab1ba083b5be4f0cc83..63c279548e44fe2f5fc42adada3d549cd9f72055 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@ __pycache__
 
 *~
 
+.DS_STORE
+
 # Package managers
 /venv*
 /node_modules/
diff --git a/README.md b/README.md
index da09e066c26eea7bc0ad388464ef197014d84910..0a4608961069118a9a1404f4966efe48fdb0e225 100644
--- a/README.md
+++ b/README.md
@@ -158,8 +158,16 @@ To build the documentation, run:
 After this, generated documentation should be available in `docs/_build/html`.
 
 ## Writing tests
-It is recommended, when writing tests, to use the `ContributorFactory` located in `scipost.factories`. This will automatically generate a related user with Registered Contributor membership. You may probably need to use the fixture list `["permissions", "groups"]` in your tests make sure the permissions groups are working properly.
-It is recommended, when writing tests for new models, to make use of ModelFactories instead of fixtures to prevent issues with altering fields in the model later on.
+It is recommended, when writing tests, to use the `ContributorFactory` located in `scipost.factories`. This will
+automatically generate a related user with Registered Contributor membership. Using the `Contributor` model in tests
+requires loading the permissions and groups. Previously, this was done by including `fixtures = ["permissions",
+"groups"]` at the top of the `TestCase`, but since these fixtures behave unpredictable and are a nuisance to keep up to
+date with the actual groups and permissions, it is much better to call `add_groups_and_permissions`, located in
+`common.helpers.test`, in a function named `setUp`, which runs before each test. `add_groups_and_permissions` wraps the
+management command of the same name.
+
+It is recommended, when writing tests for new models, to make use of `ModelFactory` instead of fixtures
+for the same reason.
 
 A basic example of a test might look like:
 ```shell
@@ -167,12 +175,12 @@ from django.contrib.auth.models import Group
 from django.test import TestCase
 
 from scipost.factories import ContributorFactory
+from common.helpers.test import add_groups_and_permissions
 
 
 class VetCommentaryRequestsTest(TestCase):
-    fixtures = ['groups', 'permissions']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.contributor = ContributorFactory(user__password='test123')  # The default password is `adm1n`
 
     def test_example_test(self):
diff --git a/commentaries/test_forms.py b/commentaries/test_forms.py
index cec31d3071f2944cc61a8c0cebb785adb186f27f..8733064ae2267d07111ed7c9fe0c1662cc85fb3f 100644
--- a/commentaries/test_forms.py
+++ b/commentaries/test_forms.py
@@ -6,12 +6,12 @@ from scipost.factories import UserFactory
 from .factories import VettedCommentaryFactory, UnvettedCommentaryFactory
 from .forms import RequestCommentaryForm, VetCommentaryForm
 from .models import Commentary
+from common.helpers.test import add_groups_and_permissions
 
 
 class TestVetCommentaryForm(TestCase):
-    fixtures = ['permissions', 'groups']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.commentary = UnvettedCommentaryFactory.create()
         self.user = UserFactory()
         self.form_data = {
@@ -71,9 +71,8 @@ class TestVetCommentaryForm(TestCase):
 
 
 class TestRequestCommentaryForm(TestCase):
-    fixtures = ['permissions', 'groups']
-
     def setUp(self):
+        add_groups_and_permissions()
         factory_instance = VettedCommentaryFactory.build()
         self.user = UserFactory()
         self.valid_form_data = model_form_data(factory_instance, RequestCommentaryForm)
diff --git a/commentaries/test_views.py b/commentaries/test_views.py
index 50d6850fd46c2b7166370a078492a227e04dcda5..17ea43b4c1d38d48a40b41d0e9edddd86930d61a 100644
--- a/commentaries/test_views.py
+++ b/commentaries/test_views.py
@@ -1,46 +1,45 @@
 from django.core.urlresolvers import reverse
 from django.contrib.auth.models import Group
-from django.test import TestCase, Client
+from django.test import TestCase, Client, RequestFactory
 
-from scipost.factories import ContributorFactory
+from scipost.factories import ContributorFactory, UserFactory
 
 from .factories import UnvettedCommentaryFactory, VettedCommentaryFactory, UnpublishedVettedCommentaryFactory
 from .forms import CommentarySearchForm
 from .models import Commentary
+from .views import RequestCommentary
+from common.helpers.test import add_groups_and_permissions
 
 
 class RequestCommentaryTest(TestCase):
     """Test cases for `request_commentary` view method"""
-    fixtures = ['permissions', 'groups', 'contributors']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.view_url = reverse('commentaries:request_commentary')
         self.login_url = reverse('scipost:login')
         self.redirected_login_url = '%s?next=%s' % (self.login_url, self.view_url)
 
-    def test_get_requests(self):
-        """Test different GET requests on view"""
-        # Anoymous user should redirect to login page
+    def test_redirects_if_not_logged_in(self):
         request = self.client.get(self.view_url)
         self.assertRedirects(request, self.redirected_login_url)
 
-        # Registered Contributor should get 200
-        self.client.login(username="Test", password="testpw")
-        request = self.client.get(self.view_url)
-        self.assertEquals(request.status_code, 200)
+    def test_valid_response_if_logged_in(self):
+        """Test different GET requests on view"""
+        request = RequestFactory().get(self.view_url)
+        request.user = UserFactory()
+        response = RequestCommentary.as_view()(request)
+        self.assertEqual(response.status_code, 200)
 
     def test_post_invalid_forms(self):
         """Test different kind of invalid RequestCommentaryForm submits"""
-        self.client.login(username="Test", password="testpw")
-        request = self.client.post(self.view_url)
-        self.assertEquals(request.status_code, 200)
+        raise NotImplementedError
 
 
 class VetCommentaryRequestsTest(TestCase):
     """Test cases for `vet_commentary_requests` view method"""
-    fixtures = ['groups', 'permissions']
 
     def setUp(self):
+        add_groups_and_permissions()
         self.view_url = reverse('commentaries:vet_commentary_requests')
         self.login_url = reverse('scipost:login')
         self.password = 'test123'
@@ -90,9 +89,9 @@ class VetCommentaryRequestsTest(TestCase):
 
 class BrowseCommentariesTest(TestCase):
     """Test cases for `browse` view."""
-    fixtures = ['groups', 'permissions']
 
     def setUp(self):
+        add_groups_and_permissions()
         VettedCommentaryFactory(discipline='physics')
         self.view_url = reverse('commentaries:browse', kwargs={
             'discipline': 'physics',
@@ -111,9 +110,8 @@ class BrowseCommentariesTest(TestCase):
 
 
 class CommentaryDetailTest(TestCase):
-    fixtures = ['permissions', 'groups']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.client = Client()
         self.commentary = UnpublishedVettedCommentaryFactory()
         self.target = reverse(
diff --git a/comments/test_views.py b/comments/test_views.py
index e1824139a5c2dd7def2f41ae2f6c6fd742914e41..d80fea2bd5e779336dc0d3ce31a6e77f9ae23a91 100644
--- a/comments/test_views.py
+++ b/comments/test_views.py
@@ -13,12 +13,13 @@ from .factories import CommentFactory
 from .forms import CommentForm
 from .models import Comment
 from .views import new_comment
-
 from common.helpers import model_form_data
+from common.helpers.test import add_groups_and_permissions
 
 
 class TestNewComment(TestCase):
-    fixtures = ['groups', 'permissions']
+    def setUp(self):
+        add_groups_and_permissions()
 
     def install_messages_middleware(self, request):
         # I don't know what the following three lines do, but they help make a RequestFactory
diff --git a/common/helpers/__init__.py b/common/helpers/__init__.py
index 5bab1621fd150b0eaa7904b18cbf5e41cc82f628..78f99d9b8e50de1c0ce2fc15ae82ddf0eb23ef85 100644
--- a/common/helpers/__init__.py
+++ b/common/helpers/__init__.py
@@ -29,7 +29,6 @@ def model_form_data(model, form_class, form_kwargs={}):
     form_fields = list(form_class(**form_kwargs).fields.keys())
     return filter_keys(model_data, form_fields)
 
-
 def random_arxiv_identifier_with_version_number():
     return random_arxiv_identifier_without_version_number() + "v0"
 
diff --git a/common/helpers/test.py b/common/helpers/test.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c0d7c96d9724179fc73d98a7a14709ba2d35fbb
--- /dev/null
+++ b/common/helpers/test.py
@@ -0,0 +1,4 @@
+import scipost.management.commands.add_groups_and_permissions
+
+def add_groups_and_permissions():
+    scipost.management.commands.add_groups_and_permissions.Command().handle(verbose=False)
diff --git a/scipost/management/commands/add_groups_and_permissions.py b/scipost/management/commands/add_groups_and_permissions.py
index 8ca05f6dffe5bc6f5a6c728945ee903f6d019731..b661bab5b80ec3002a089da3bdd0639e4484c571 100644
--- a/scipost/management/commands/add_groups_and_permissions.py
+++ b/scipost/management/commands/add_groups_and_permissions.py
@@ -9,7 +9,7 @@ from scipost.models import Contributor
 class Command(BaseCommand):
     help = 'Defines groups and permissions'
 
-    def handle(self, *args, **options):
+    def handle(self, *args, verbose=True, **options):
         """Append all user Groups and setup a Contributor roles to user."""
 
         # Create Groups
@@ -229,4 +229,6 @@ class Command(BaseCommand):
             can_view_docs_scipost,
         )
 
-        self.stdout.write(self.style.SUCCESS('Successfully created groups and permissions.'))
+
+        if verbose:
+            self.stdout.write(self.style.SUCCESS('Successfully created groups and permissions.'))
diff --git a/scipost/services.py b/scipost/services.py
index 957bb7603e66f5980f8d1568fcd29508427b5b8c..395e61e7ea5859a147a2170994c84e43ab6c16c3 100644
--- a/scipost/services.py
+++ b/scipost/services.py
@@ -166,7 +166,7 @@ class DOICaller(BaseCaller):
 class ArxivCaller(BaseCaller):
     """ Performs an Arxiv article lookup for given identifier """
 
-    # # State of the caller
+    # State of the caller
     resubmission = False
     previous_submissions = []
     errormessages = arxiv_caller_errormessages
diff --git a/scipost/test_views.py b/scipost/test_views.py
index 5b764927f0baa855389a30b22dafd751cfaa6a2a..22291f792c19630af0cc6b5192667fb3b4c4d8b4 100644
--- a/scipost/test_views.py
+++ b/scipost/test_views.py
@@ -8,8 +8,8 @@ from commentaries.forms import CommentarySearchForm
 from commentaries.models import Commentary
 
 from .factories import ContributorFactory,\
-                       EditorialCollegeFellowFactory, EditorialCollegeFactory
-from .models import EditorialCollege, EditorialCollegeFellow
+                       EditorialCollegeFellowshipFactory, EditorialCollegeFactory
+from .models import EditorialCollege, EditorialCollegeFellowship
 
 
 class RequestCommentaryTest(TestCase):
@@ -137,7 +137,7 @@ class AboutViewTest(TestCase):
 
         # Create College with 10 members
         self.college = EditorialCollegeFactory()
-        EditorialCollegeFellowFactory.create_batch(10)
+        EditorialCollegeFellowshipFactory.create_batch(10)
 
     def test_status_code_200_including_members(self):
         response = self.client.get(self.target)
@@ -151,4 +151,4 @@ class AboutViewTest(TestCase):
         # Members exist in college
         self.assertTrue(college.member.count() >= 10)
         last_member = college.member.last()
-        self.assertTrue(isinstance(last_member, EditorialCollegeFellow))
+        self.assertTrue(isinstance(last_member, EditorialCollegeFellowship))
diff --git a/scipost/utils.py b/scipost/utils.py
index 07da56a2a7a0f5c5eb0f312a2a4156112bade871..4e8236490f9f1dad43085a23b5d069b389b000f6 100644
--- a/scipost/utils.py
+++ b/scipost/utils.py
@@ -217,7 +217,7 @@ class Utils(BaseMailUtil):
         email_text_html += ',<br/>'
         if len(cls.invitation.personal_message) > 3:
             email_text += cls.invitation.personal_message + '\n\n'
-            email_text_html += '\n<i>{{ personal_message|linebreaks }}</i><br/>\n'
+            email_text_html += '\n{{ personal_message|linebreaks }}<br/>\n'
             email_context['personal_message'] = cls.invitation.personal_message
 
         # This text to be put in C, ci invitations
@@ -304,6 +304,14 @@ class Utils(BaseMailUtil):
                 'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n'
                 'after which your registration will be activated, allowing you to contribute, '
                 'in particular by providing referee reports.\n\n'
+                'To ensure timely processing of the submission (out of respect for the authors), '
+                'we would appreciate a quick accept/decline '
+                'response from you, ideally within the next 2 days.\n\n'
+                'If you are not able to provide a Report, you can let us know by simply '
+                'navigating to \n\nhttps://scipost.org/submissions/decline_ref_invitation/'
+                + cls.invitation.invitation_key + '\n\n'
+                'If you are able to provide a Report, you can confirm this after registering '
+                'and logging in (you will automatically be prompted for a confirmation).\n\n'
                 'We very much hope that we can count on your expertise,\n\n'
                 'Many thanks in advance,\n\nThe SciPost Team')
             email_text_html += (
@@ -315,6 +323,15 @@ class Utils(BaseMailUtil):
                 '<a href="https://scipost.org/invitation/{{ invitation_key }}">registration form</a> '
                 'for you. After activation of your registration, you will be allowed to contribute, '
                 'in particular by providing referee reports.</p>'
+                '<p>To ensure timely processing of the submission (out of respect for the authors), '
+                'we would appreciate a quick accept/decline '
+                'response from you, ideally within the next 2 days.</p>'
+                '<p>If you are <strong>not</strong> able to provide a Report, '
+                'you can let us know by simply '
+                '<a href="https://scipost.org/submissions/decline_ref_invitation/{{ invitation_key }}>'
+                'clicking here</a>.</p>'
+                '<p>If you are able to provide a Report, you can confirm this after registering '
+                'and logging in (you will automatically be prompted for a confirmation).</p>'
                 '<p>We very much hope that we can count on your expertise,</p>'
                 '<p>Many thanks in advance,</p>'
                 '<p>The SciPost Team</p>')
diff --git a/submissions/templates/submissions/decline_ref_invitation.html b/submissions/templates/submissions/decline_ref_invitation.html
new file mode 100644
index 0000000000000000000000000000000000000000..9efedb177f5058eb3fbe73a51397de573d09391d
--- /dev/null
+++ b/submissions/templates/submissions/decline_ref_invitation.html
@@ -0,0 +1,41 @@
+{% extends 'scipost/base.html' %}
+
+{% block pagetitle %}: decline refereeing invitation{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block content %}
+
+<script>
+$(document).ready(function(){
+
+  $('[name="accept"]').on('change', function() {
+      if($('[name="accept"]:checked').val() == 'False') {
+          $('#id_refusal_reason').parents('.form-group').show();
+      }
+      else {
+          $('#id_refusal_reason').parents('.form-group').hide();
+      }
+    }).trigger('change');
+  });
+</script>
+
+
+<div class="row">
+  <div class="col-12">
+    <h1 class="highlight">SciPost Submission which you have been asked to Referee:</h1>
+    {% include 'submissions/_submission_summary.html' with submission=invitation.submission %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-12">
+    <h3 class="highlight">You are choosing to decline this Refereeing Invitation</h3>
+    <form action="{% url 'submissions:decline_ref_invitation' invitation_key=invitation.invitation_key %}" method="post">
+      {% csrf_token %}
+      {{ form|bootstrap }}
+      <input type="submit" class="btn btn-secondary" value="Submit" />
+    </form>
+  </div>
+</div>
+
+{% endblock content %}
diff --git a/submissions/templates/submissions/refereeing_overview.html b/submissions/templates/submissions/refereeing_overview.html
index bda7f5c3502d94e203179d0e8399c05cc5e93019..a7e09c540820a90a020a229f3f8bad204736186a 100644
--- a/submissions/templates/submissions/refereeing_overview.html
+++ b/submissions/templates/submissions/refereeing_overview.html
@@ -35,7 +35,7 @@
 	<h4>Refereeing status summary:</h4>
 	{% include 'submissions/_submission_refereeing_status.html' with submission=submission %}
 	<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 %}
 	<a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a>
       </div>
     </div>
diff --git a/submissions/urls.py b/submissions/urls.py
index 48e208052b98fc264fd01f9c991d80325bd5a886..8465d4f9c7b572bed6e6e1437a7f904c1d377132 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -54,6 +54,8 @@ urlpatterns = [
         views.accept_or_decline_ref_invitations, name='accept_or_decline_ref_invitations'),
     url(r'^accept_or_decline_ref_invitation/(?P<invitation_id>[0-9]+)$',
         views.accept_or_decline_ref_invitation_ack, name='accept_or_decline_ref_invitation_ack'),
+    url(r'^decline_ref_invitation/(?P<invitation_key>.+)$',
+        views.decline_ref_invitation, name='decline_ref_invitation'),
     url(r'^ref_invitation_reminder/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/(?P<invitation_id>[0-9]+)$', views.ref_invitation_reminder, name='ref_invitation_reminder'),
     url(r'^cancel_ref_invitation/(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/(?P<invitation_id>[0-9]+)$',
         views.cancel_ref_invitation, name='cancel_ref_invitation'),
diff --git a/submissions/utils.py b/submissions/utils.py
index fb2039cc6df596f19c5dbce7b37985c794f9ee11..df19145f93f6a1e2db97d190fdb2e5a59d658fd0 100644
--- a/submissions/utils.py
+++ b/submissions/utils.py
@@ -616,6 +616,7 @@ class SubmissionUtils(BaseMailUtil):
         emailmessage.attach_alternative(html_version, 'text/html')
         emailmessage.send(fail_silently=False)
 
+
     @classmethod
     def send_refereeing_invitation_email(cls):
         """
@@ -701,66 +702,162 @@ class SubmissionUtils(BaseMailUtil):
         emailmessage.attach_alternative(html_version, 'text/html')
         emailmessage.send(fail_silently=False)
 
+    @classmethod
+    def send_unreg_ref_reminder_email(cls):
+        """
+        This method is used to remind a referee who has not yet responded.
+        It is used for unregistered referees only.
+        It is called from the ref_invitation_reminder method in submissions/views.py.
+        """
+        email_text = (
+            'Dear ' + cls.invitation.title + ' '
+            + cls.invitation.last_name + ',\n\n'
+            'On behalf of the Editor-in-charge '
+            + cls.invitation.submission.editor_in_charge.get_title_display() + ' '
+            + cls.invitation.submission.editor_in_charge.user.last_name
+            + ', we would like to cordially remind you of our recent request to referee\n\n'
+            + cls.invitation.submission.title + ' by '
+            + cls.invitation.submission.author_list + '.')
+        email_text_html = (
+            '<p>Dear {{ title }} {{ last_name }},</p>'
+            '<p>On behalf of the Editor-in-charge {{ EIC_title }} {{ EIC_last_name }}, '
+            'we would like to cordially remind you of our recent request to referee</p>'
+            '<p>{{ sub_title }}</p>'
+            '\n<p>by {{ author_list }}.</p>')
+        email_text += (
+            '\n\nWe would also like to renew '
+            'our invitation to become a Contributor on SciPost '
+            '(our records show that you are not yet registered); '
+            'your partially pre-filled registration form is still available at\n\n'
+            'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n'
+            'after which your registration will be activated, giving you full access to '
+            'the portal\'s facilities (in particular allowing you to '
+            'provide referee reports).\n\n'
+            'To ensure timely processing of the submission (out of respect for the authors), '
+            'we would appreciate a quick accept/decline response from you, '
+            'ideally within the next 2 days.\n\n'
+            'If you are not able to provide a Report, you can quickly let us know by simply '
+            'navigating to \n\nhttps://scipost.org/decline_ref_invitation/'
+            + cls.invitation.invitation_key + '\n\n'
+            'If you are able to provide a Report, you can confirm this after registering '
+            'and logging in (you will automatically be prompted for a confirmation). '
+            'Your report can thereafter be submitted by simply clicking on '
+            'the "Contribute a Report" link at '
+            'https://scipost.org/submission/'
+            + cls.invitation.submission.arxiv_identifier_w_vn_nr
+            + ' before the reporting deadline (currently set at '
+            + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d")
+            + '; your report will be automatically recognized as an invited report). '
+            'You might want to make sure you are familiar with our refereeing code of conduct '
+            'https://scipost.org/journals/journals_terms_and_conditions and with the '
+            'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.'
+            '\n\nWe very much hope we can count on your expertise,'
+            '\n\nMany thanks in advance,\n\nThe SciPost Team'
+        )
+        email_text_html += (
+            '\n<p>We would also like to renew '
+            'our invitation to become a Contributor on SciPost '
+            '(our records show that you are not yet registered); '
+            'your partially pre-filled '
+            '<a href="https://scipost.org/invitation/{{ invitation_key }}">'
+            'registration form</a> is still available, '
+            'after which your registration will be activated, giving you full access to '
+            'the portal\'s facilities (in particular allowing you to provide referee reports).</p>'
+            '<p>To ensure timely processing of the submission (out of respect for the authors), '
+            'we would appreciate a quick accept/decline response from you, '
+            'ideally within the next 2 days.</p>'
+            '<p>If you are <strong>not</strong> able to provide a Report, '
+            'you can quickly let us know by simply '
+            '<a href="https://scipost.org/decline_ref_invitation/{{ invitation_key }}>'
+            'clicking here</a>.</p>'
+            '<p>If you are able to provide a Report, you can confirm this after registering '
+            'and logging in (you will automatically be prompted for a confirmation). '
+            'Your report can thereafter be submitted by simply clicking on '
+            'the "Contribute a Report" link at '
+            'the <a href="https://scipost.org/submission/{{ arxiv_identifier_w_vn_nr }}">'
+            'Submission\'s page</a> before the reporting deadline (currently set at '
+            '{{ deadline }}; your report will be automatically recognized as an invited report).</p>'
+            '\n<p>You might want to make sure you are familiar with our '
+            '<a href="https://scipost.org/journals/journals_terms_and_conditions">'
+            'refereeing code of conduct</a> and with the '
+            '<a href="https://scipost.org/submissions/sub_and_ref_procedure">'
+            'refereeing procedure</a>.</p>'
+            '<p>We very much hope we can count on your expertise,</p>'
+            '<p>Many thanks in advance,</p>'
+            '<p>The SciPost Team</p>')
+        email_context = Context({
+            'title': cls.invitation.title,
+            'last_name': cls.invitation.last_name,
+            'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(),
+            'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name,
+            'sub_title': cls.invitation.submission.title,
+            'author_list': cls.invitation.submission.author_list,
+            'arxiv_identifier_w_vn_nr': cls.invitation.submission.arxiv_identifier_w_vn_nr,
+            'deadline': datetime.datetime.strftime(cls.invitation.submission.reporting_deadline,
+                                                   "%Y-%m-%d"),
+            'invitation_key': cls.invitation.invitation_key,
+        })
+        email_text_html += '<br/>' + EMAIL_FOOTER
+        html_template = Template(email_text_html)
+        html_version = html_template.render(email_context)
+        emailmessage = EmailMultiAlternatives(
+            'SciPost: reminder (refereeing request and registration invitation)', email_text,
+            'SciPost Submissions <submissions@scipost.org>',
+            [cls.invitation.email_address],
+            bcc=[cls.invitation.submission.editor_in_charge.user.email,
+                 'submissions@scipost.org'],
+            reply_to=['submissions@scipost.org'])
+        emailmessage.attach_alternative(html_version, 'text/html')
+        emailmessage.send(fail_silently=False)
+
+
     @classmethod
     def send_ref_reminder_email(cls):
         """
-        This method is used to remind a referee who is not registered as a Contributor.
+        This method is used to remind a referee who has not yet responded.
+        It is used for registered Contributors only.
         It is called from the ref_invitation_reminder method in submissions/views.py.
         """
-        email_text = ('Dear ' + cls.invitation.get_title_display() + ' '
-                      + cls.invitation.last_name + ',\n\n'
-                      'On behalf of the Editor-in-charge '
-                      + cls.invitation.submission.editor_in_charge.get_title_display() + ' '
-                      + cls.invitation.submission.editor_in_charge.user.last_name
-                      + ', we would like to cordially remind you of our recent request to referee\n\n'
-                      + cls.invitation.submission.title + ' by '
-                      + cls.invitation.submission.author_list + '.')
+        email_text = (
+            'Dear ' + cls.invitation.get_title_display() + ' '
+            + cls.invitation.last_name + ',\n\n'
+            'On behalf of the Editor-in-charge '
+            + cls.invitation.submission.editor_in_charge.get_title_display() + ' '
+            + cls.invitation.submission.editor_in_charge.user.last_name
+            + ', we would like to cordially remind you of our recent request to referee\n\n'
+            + cls.invitation.submission.title + ' by '
+            + cls.invitation.submission.author_list + '.')
         email_text_html = (
             '<p>Dear {{ title }} {{ last_name }},</p>'
             '<p>On behalf of the Editor-in-charge {{ EIC_title }} {{ EIC_last_name }}, '
             'we would like to cordially remind you of our recent request to referee</p>'
             '<p>{{ sub_title }}</p>'
             '\n<p>by {{ author_list }}.</p>')
-        if cls.invitation.referee is None:
-            email_text += ('\n\nWe would also like to renew '
-                           'our invitation to become a Contributor on SciPost '
-                           '(our records show that you are not yet registered); '
-                           'your partially pre-filled registration form is still available at\n\n'
-                           'https://scipost.org/invitation/' + cls.invitation.invitation_key + '\n\n'
-                           'after which your registration will be activated, giving you full access to '
-                           'the portal\'s facilities (in particular allowing you to provide referee reports).')
-            email_text_html += (
-                '\n<p>We would also like to renew '
-                'our invitation to become a Contributor on SciPost '
-                '(our records show that you are not yet registered); '
-                'your partially pre-filled '
-                '<a href="https://scipost.org/invitation/{{ invitation_key }}">'
-                'registration form</a> is still available, '
-                'after which your registration will be activated, giving you full access to '
-                'the portal\'s facilities (in particular allowing you to provide referee reports).</p>')
         if cls.invitation.accepted is None:
-            email_text += ('\n\nPlease visit '
-                           'https://scipost.org/submissions/accept_or_decline_ref_invitations '
-                           '(login required) as soon as possible (ideally within the next 2 days) '
-                           'in order to accept or decline this invitation.')
+            email_text += (
+                '\n\nPlease visit '
+                'https://scipost.org/submissions/accept_or_decline_ref_invitations '
+                '(login required) as soon as possible (ideally within the next 2 days) '
+                'in order to accept or decline this invitation.')
             email_text_html += (
                 '\n<p>Please '
                 '<a href="https://scipost.org/submissions/accept_or_decline_ref_invitations">'
                 'accept or decline the invitation</a> '
                 '(login required) as soon as possible (ideally within the next 2 days) '
                 'in order to ensure rapid processing of the submission.')
-        email_text += ('\n\nYour report can be submitted by simply clicking on '
-                       'the "Contribute a Report" link at '
-                       'https://scipost.org/submission/'
-                       + cls.invitation.submission.arxiv_identifier_w_vn_nr
-                       + ' before the reporting deadline (currently set at '
-                       + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d")
-                       + '; your report will be automatically recognized as an invited report). '
-                       'You might want to make sure you are familiar with our refereeing code of conduct '
-                       'https://scipost.org/journals/journals_terms_and_conditions and with the '
-                       'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.'
-                       '\n\nWe very much hope we can count on your expertise,'
-                       '\n\nMany thanks in advance,\n\nThe SciPost Team')
+        email_text += (
+            '\n\nYour report can be submitted by simply clicking on '
+            'the "Contribute a Report" link at '
+            'https://scipost.org/submission/'
+            + cls.invitation.submission.arxiv_identifier_w_vn_nr
+            + ' before the reporting deadline (currently set at '
+            + datetime.datetime.strftime(cls.invitation.submission.reporting_deadline, "%Y-%m-%d")
+            + '; your report will be automatically recognized as an invited report). '
+            'You might want to make sure you are familiar with our refereeing code of conduct '
+            'https://scipost.org/journals/journals_terms_and_conditions and with the '
+            'refereeing procedure https://scipost.org/submissions/sub_and_ref_procedure.'
+            '\n\nWe very much hope we can count on your expertise,'
+            '\n\nMany thanks in advance,\n\nThe SciPost Team')
         email_text_html += (
             '\n<p>Your report can be submitted by simply clicking on '
             'the "Contribute a Report" link at '
@@ -800,6 +897,7 @@ class SubmissionUtils(BaseMailUtil):
         emailmessage.attach_alternative(html_version, 'text/html')
         emailmessage.send(fail_silently=False)
 
+
     @classmethod
     def send_ref_cancellation_email(cls):
         """
diff --git a/submissions/views.py b/submissions/views.py
index 81375ff8b1198c191c9a0000b1e3d64687bcdc62..387ac0debb92a8bfbbf80734ef0d87d1e22dd4e3 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -800,7 +800,10 @@ def ref_invitation_reminder(request, arxiv_identifier_w_vn_nr, invitation_id):
     invitation.date_last_reminded = timezone.now()
     invitation.save()
     SubmissionUtils.load({'invitation': invitation})
-    SubmissionUtils.send_ref_reminder_email()
+    if invitation.referee is not None:
+        SubmissionUtils.send_ref_reminder_email()
+    else:
+        SubmissionUtils.send_unreg_ref_reminder_email()
     return redirect(reverse('submissions:editorial_page',
                             kwargs={'arxiv_identifier_w_vn_nr': arxiv_identifier_w_vn_nr}))
 
@@ -842,6 +845,24 @@ def accept_or_decline_ref_invitation_ack(request, invitation_id):
     return render(request, 'submissions/accept_or_decline_ref_invitation_ack.html', context)
 
 
+def decline_ref_invitation(request, invitation_key):
+    invitation = get_object_or_404(RefereeInvitation, invitation_key=invitation_key)
+    if request.method == 'POST':
+        form = ConsiderRefereeInvitationForm(request.POST)
+        if form.is_valid():
+            invitation.accepted = False
+            invitation.refusal_reason = form.cleaned_data['refusal_reason']
+            invitation.save()
+            SubmissionUtils.load({'invitation': invitation}, request)
+            SubmissionUtils.email_referee_response_to_EIC()
+            messages.success(request, 'Thank you for informing us that you will not provide a Report.')
+            return redirect(reverse('scipost:index'))
+    else:
+        form = ConsiderRefereeInvitationForm(initial={'accept': False})
+    context = {'invitation': invitation, 'form': form}
+    return render(request, 'submissions/decline_ref_invitation.html', context)
+
+
 @login_required
 @permission_required_or_403('can_take_editorial_actions',
                             (Submission, 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_w_vn_nr'))
diff --git a/templates/email/referee_in_response_to_decision.html b/templates/email/referee_in_response_to_decision.html
index 563f0956c294831980e22356293ffa4d6432d5f2..4e3b8502223fa7402894ea9aa1f935c1923eeae8 100644
--- a/templates/email/referee_in_response_to_decision.html
+++ b/templates/email/referee_in_response_to_decision.html
@@ -5,6 +5,7 @@ We hereby confirm your choice to {% if invitation.accepted %}accept{% else %}dec
 {{invitation.submission.title}} by {{invitation.submission.author_list}}\n\n
 
 {% if invitation.accepted %}
+We will look forward to receiving your Report by the reporting deadline {{ invitation.submission.reporting_deadline|date:'Y-m-d' }}.\n\n
 Many thanks for your collaboration,\n
 {% else %}
 Nonetheless, we thank you very much for considering this refereeing invitation,\n
diff --git a/templates/email/referee_in_response_to_decision_html.html b/templates/email/referee_in_response_to_decision_html.html
index cb418b3609f26d5462ca664a661f3ad19d012a1e..a512ce69174076cdf2bbcebbdb6cce239af332f8 100644
--- a/templates/email/referee_in_response_to_decision_html.html
+++ b/templates/email/referee_in_response_to_decision_html.html
@@ -9,6 +9,7 @@
 
 <p>
     {% if invitation.accepted %}
+    We will look forward to receiving your Report by the reporting deadline {{ invitation.submission.reporting_deadline|date:'Y-m-d' }}.
     Many thanks for your collaboration,
     {% else %}
     Nonetheless, we thank you very much for considering this refereeing invitation,
diff --git a/templates/email/referee_response_to_EIC.html b/templates/email/referee_response_to_EIC.html
index c3e7b18856e90284714941a74d3a529b134c5c5b..e73f226ccf6c68346f1d879ba008e59d5d828fcf 100644
--- a/templates/email/referee_response_to_EIC.html
+++ b/templates/email/referee_response_to_EIC.html
@@ -1,6 +1,6 @@
 Dear {{invitation.submission.editor_in_charge.get_title_display}} {{invitation.submission.editor_in_charge.user.last_name}},\n\n
 
-Referee {{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission\n\n
+Referee {% if invitation.referee %}{{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}}{% else %}{{ invitation.title }} {{ invitation.first_name }} {{ invitation.last_name }}{% endif %} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission\n\n
 
 {{invitation.submission.title}} by {{invitation.submission.author_list}}\n\n
 
diff --git a/templates/email/referee_response_to_EIC_html.html b/templates/email/referee_response_to_EIC_html.html
index 0cdce8b6dc46e3f57acd13a47a2877e95d43b3cb..529b34c5f923afb7cecefaa688e8c96c4ec31ae2 100644
--- a/templates/email/referee_response_to_EIC_html.html
+++ b/templates/email/referee_response_to_EIC_html.html
@@ -1,7 +1,7 @@
 <p>Dear {{invitation.submission.editor_in_charge.get_title_display}} {{invitation.submission.editor_in_charge.user.last_name}},</p>
 
 <p>
-    Referee {{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission
+    Referee {% if invitation.referee %}{{invitation.referee.get_title_display}} {{invitation.referee.user.last_name}}{% else %}{{ invitation.title }} {{ invitation.first_name }} {{ invitation.last_name }}{% endif %} has {% if invitation.accepted %}accepted{% else %}declined (due to reason: {{invitation.get_refusal_reason_display}}){% endif %} to referee Submission
 </p>
 <p>
     "{{invitation.submission.title}} by {{invitation.submission.author_list}}".
diff --git a/theses/factories.py b/theses/factories.py
index bf4a32440a8b5ddbbe1932c0bb2a27feaca7a464..fe9091788560fdc69f34f7b65519f0d0772157b9 100644
--- a/theses/factories.py
+++ b/theses/factories.py
@@ -5,6 +5,7 @@ from scipost.factories import ContributorFactory
 
 from .models import ThesisLink
 from .forms import VetThesisLinkForm
+from .constants import MASTER_THESIS
 
 
 class ThesisLinkFactory(factory.django.DjangoModelFactory):
@@ -12,7 +13,7 @@ class ThesisLinkFactory(factory.django.DjangoModelFactory):
         model = ThesisLink
 
     requested_by = factory.SubFactory(ContributorFactory)
-    type = ThesisLink.MASTER_THESIS
+    type = MASTER_THESIS
     title = factory.Faker('bs')
     pub_link = factory.Faker('uri')
     author = factory.Faker('name')
diff --git a/theses/test_forms.py b/theses/test_forms.py
index dd649cedb0fecb2ead03e333ea6e280e3f658df9..e43421af0883d236ceaf90809572d91d06a1e792 100644
--- a/theses/test_forms.py
+++ b/theses/test_forms.py
@@ -6,12 +6,12 @@ from scipost.factories import ContributorFactory
 from .factories import ThesisLinkFactory, VetThesisLinkFormFactory
 from .forms import RequestThesisLinkForm, VetThesisLinkForm
 from common.helpers import model_form_data
+from common.helpers.test import add_groups_and_permissions
 
 
 class TestRequestThesisLink(TestCase):
-    fixtures = ['permissions', 'groups']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.contributor = ContributorFactory()
         self.user = self.contributor.user
         self.request = RequestFactory()
diff --git a/theses/test_models.py b/theses/test_models.py
index 9cda6172906f7feeb4a8789f014fb4a09f5f7bf9..c878df0efa98a652ee2799dc19b40a82511e354e 100644
--- a/theses/test_models.py
+++ b/theses/test_models.py
@@ -5,10 +5,12 @@ from django.core.exceptions import ValidationError
 
 from .models import ThesisLink
 from .factories import ThesisLinkFactory
+from common.helpers.test import add_groups_and_permissions
 
 
 class ThesisLinkTestCase(TestCase):
-    fixtures = ['permissions', 'groups']
+    def setUp(self):
+        add_groups_and_permissions()
 
     def test_domain_cannot_be_blank(self):
         thesis_link = ThesisLinkFactory()
diff --git a/theses/test_views.py b/theses/test_views.py
index 6db7757f05dd44f226adc606d42ca37d227641f5..91e37fc3c6b157d72e479765f8dc7d3c5ba6344e 100644
--- a/theses/test_views.py
+++ b/theses/test_views.py
@@ -17,10 +17,11 @@ from .factories import ThesisLinkFactory, VettedThesisLinkFactory, VetThesisLink
 from .models import ThesisLink
 from .forms import VetThesisLinkForm
 from common.helpers import model_form_data
-
+from common.helpers.test import add_groups_and_permissions
 
 class TestThesisDetail(TestCase):
-    fixtures = ['groups', 'permissions']
+    def setUp(self):
+        add_groups_and_permissions()
 
     def test_visits_valid_thesis_detail(self):
         """ A visitor does not have to be logged in to view a thesis link. """
@@ -32,9 +33,8 @@ class TestThesisDetail(TestCase):
 
 
 class TestRequestThesisLink(TestCase):
-    fixtures = ['groups', 'permissions']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.client = Client()
         self.target = reverse('theses:request_thesislink')
 
@@ -51,9 +51,8 @@ class TestRequestThesisLink(TestCase):
 
 
 class TestVetThesisLinkRequests(TestCase):
-    fixtures = ['groups', 'permissions']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.client = Client()
         self.thesislink = ThesisLinkFactory()
         self.target = reverse('theses:vet_thesislink', kwargs={'pk': self.thesislink.id})
@@ -158,24 +157,23 @@ class TestVetThesisLinkRequests(TestCase):
 
 
 class TestTheses(TestCase):
-    fixtures = ['groups', 'permissions']
-
     def setUp(self):
+        add_groups_and_permissions()
         self.client = Client()
         self.target = reverse('theses:theses')
 
     def test_empty_search_query(self):
         thesislink = VettedThesisLinkFactory()
         response = self.client.get(self.target)
-        search_results = response.context["search_results"]
-        recent_theses = response.context["recent_theses"]
-        self.assertEqual(search_results, [])
-        self.assertEqual(recent_theses.exists(), True)
+        search_results = response.context["object_list"]
+        self.assertTrue(thesislink in search_results)
 
     def test_search_query_on_author(self):
         thesislink = VettedThesisLinkFactory()
+        other_thesislink = VettedThesisLinkFactory()
         form_data = {'author': thesislink.author}
         response = self.client.get(self.target, form_data)
-        search_results = response.context['search_results']
+        search_results = response.context['object_list']
         self.assertTrue(thesislink in search_results)
+        self.assertTrue(other_thesislink not in search_results)
         self.assertEqual(len(search_results), 1)
diff --git a/theses/views.py b/theses/views.py
index d299924c227b8a73722d50867017b1a80711b07c..72856c885224b4f0c2534714e737e208ed9b8fbb 100644
--- a/theses/views.py
+++ b/theses/views.py
@@ -80,7 +80,6 @@ class VetThesisLink(UpdateView):
 class ThesisListView(ListView):
     model = ThesisLink
     form = ThesisLinkSearchForm
-    thesis_search_list = []
     paginate_by = 10
 
     def get_queryset(self):