diff --git a/general.py b/general.py
deleted file mode 100644
index 5570b662718dd4458c5d43ddd33f02efb8df178d..0000000000000000000000000000000000000000
--- a/general.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from django.conf.urls import url
-from django.urls import reverse_lazy
-from django.views.generic import TemplateView, RedirectView
-
-from journals import views as journals_views
-
-urlpatterns = [
-    # Journals
-    url(r'^$', journals_views.journals, name='journals'),
-    url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page',
-                                                 args=['SciPostPhys']))),
-    url(r'^journals_terms_and_conditions$',
-        TemplateView.as_view(template_name='journals/journals_terms_and_conditions.html'),
-        name='journals_terms_and_conditions'),
-    url(r'^crossmark_policy$',
-        TemplateView.as_view(template_name='journals/crossmark_policy.html'),
-        name='crossmark_policy'),
-
-    # Editorial and Administrative Workflow
-    url(r'^initiate_publication$',
-        journals_views.initiate_publication,
-        name='initiate_publication'),
-    url(r'^validate_publication$',
-        journals_views.validate_publication,
-        name='validate_publication'),
-    url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$',
-        journals_views.mark_first_author,
-        name='mark_first_author'),
-    url(r'^mark_first_author_unregistered/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$',
-        journals_views.mark_first_author_unregistered,
-        name='mark_first_author_unregistered'),
-    url(r'^add_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$',
-        journals_views.add_author,
-        name='add_author'),
-    url(r'^add_author/(?P<publication_id>[0-9]+)$',
-        journals_views.add_author,
-        name='add_author'),
-    url(r'^add_unregistered_author/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$',
-        journals_views.add_unregistered_author,
-        name='add_unregistered_author'),
-    url(r'^add_new_unreg_author/(?P<publication_id>[0-9]+)$',
-        journals_views.add_new_unreg_author,
-        name='add_new_unreg_author'),
-    url(r'^manage_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.manage_metadata,
-        name='manage_metadata'),
-    url(r'^manage_metadata/(?P<issue_doi_label>[a-zA-Z]+.[0-9]+.[0-9]+)$',
-        journals_views.manage_metadata,
-        name='manage_metadata'),
-    url(r'^manage_metadata/$',
-        journals_views.manage_metadata,
-        name='manage_metadata'),
-    url(r'^create_citation_list_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.create_citation_list_metadata,
-        name='create_citation_list_metadata'),
-    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'^add_generic_funder/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.add_generic_funder,
-        name='add_generic_funder'),
-    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'),
-    url(r'^metadata_xml_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/(?P<option>[a-z]+)$',
-        journals_views.metadata_xml_deposit,
-        name='metadata_xml_deposit'),
-    url(r'^mark_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$',
-        journals_views.mark_deposit_success,
-        name='mark_deposit_success'),
-    url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.produce_metadata_DOAJ,
-        name='produce_metadata_DOAJ'),
-    url(r'^metadata_DOAJ_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.metadata_DOAJ_deposit,
-        name='metadata_DOAJ_deposit'),
-    url(r'^mark_doaj_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$',
-        journals_views.mark_doaj_deposit_success,
-        name='mark_doaj_deposit_success'),
-    url(r'^harvest_citedby_list/$',
-        journals_views.harvest_citedby_list,
-        name='harvest_citedby_list'),
-    url(r'^harvest_citedby_links/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
-        journals_views.harvest_citedby_links,
-        name='harvest_citedby_links'),
-    url(r'^sign_existing_report/(?P<report_id>[0-9]+)$',
-        journals_views.sign_existing_report,
-        name='sign_existing_report'),
-    url(r'^manage_report_metadata/$',
-        journals_views.manage_report_metadata,
-        name='manage_report_metadata'),
-    url(r'^manage_comment_metadata/$',
-        journals_views.manage_comment_metadata,
-        name='manage_comment_metadata'),
-    url(r'^mark_report_doi_needed/(?P<report_id>[0-9]+)/(?P<needed>[0-1])$',
-        journals_views.mark_report_doi_needed,
-        name='mark_report_doi_needed'),
-    url(r'^mark_comment_doi_needed/(?P<comment_id>[0-9]+)/(?P<needed>[0-1])$',
-        journals_views.mark_comment_doi_needed,
-        name='mark_comment_doi_needed'),
-    url(r'^generic_metadata_xml_deposit/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)$',
-        journals_views.generic_metadata_xml_deposit,
-        name='generic_metadata_xml_deposit'),
-    url(r'^mark_generic_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$',
-        journals_views.mark_generic_deposit_success,
-        name='mark_generic_deposit_success'),
-]
diff --git a/journals/admin.py b/journals/admin.py
index 5aff8e167e095df8f086ba9002fc7eaa29a3e80f..18468831ac764f2d2ff54862f5052828fb56044f 100644
--- a/journals/admin.py
+++ b/journals/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin, messages
 from django import forms
 
 from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, \
-    Deposit, DOAJDeposit, GenericDOIDeposit, Reference
+    Deposit, DOAJDeposit, GenericDOIDeposit, Reference, PublicationAuthorsTable
 
 from scipost.models import Contributor
 from submissions.models import Submission
@@ -59,16 +59,21 @@ class ReferenceInline(admin.TabularInline):
     model = Reference
 
 
+class AuthorsInline(admin.TabularInline):
+    model = PublicationAuthorsTable
+    extra = 0
+
+
 class PublicationAdmin(admin.ModelAdmin):
     search_fields = ['title', 'author_list']
     list_display = ['title', 'author_list', 'in_issue', 'doi_string', 'publication_date']
     date_hierarchy = 'publication_date'
     list_filter = ['in_issue']
-    inlines = [ReferenceInline]
+    inlines = [AuthorsInline, ReferenceInline]
     form = PublicationAdminForm
 
-admin.site.register(Publication, PublicationAdmin)
 
+admin.site.register(Publication, PublicationAdmin)
 
 
 class DepositAdmin(admin.ModelAdmin):
diff --git a/journals/forms.py b/journals/forms.py
index bcbf9ce526eed8f1877e32df781652cd0744e4f1..44462b752ef726690395007f2765d454a0e597fa 100644
--- a/journals/forms.py
+++ b/journals/forms.py
@@ -6,7 +6,7 @@ from django import forms
 from django.forms import BaseModelFormSet, modelformset_factory
 from django.utils import timezone
 
-from .models import UnregisteredAuthor, Issue, Publication, Reference
+from .models import Issue, Publication, Reference, UnregisteredAuthor
 
 from scipost.services import DOICaller
 from submissions.models import Submission
@@ -32,7 +32,7 @@ class ValidatePublicationForm(forms.ModelForm):
 class UnregisteredAuthorForm(forms.ModelForm):
     class Meta:
         model = UnregisteredAuthor
-        fields = ['first_name', 'last_name']
+        fields = ('first_name', 'last_name')
 
 
 class CitationListBibitemsForm(forms.Form):
diff --git a/journals/migrations/0009_auto_20180212_1947.py b/journals/migrations/0009_auto_20180212_1947.py
new file mode 100644
index 0000000000000000000000000000000000000000..3b45ebe54173af16e913f2dc9bbae27edffeec70
--- /dev/null
+++ b/journals/migrations/0009_auto_20180212_1947.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-12 18:47
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0008_auto_20180203_1229'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='publication',
+            old_name='authors',
+            new_name='authors_old',
+        ),
+        migrations.RenameField(
+            model_name='publication',
+            old_name='authors_unregistered',
+            new_name='authors_unregistered_old',
+        ),
+    ]
diff --git a/journals/migrations/0010_auto_20180212_1947.py b/journals/migrations/0010_auto_20180212_1947.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b60b98e106555c74c4a014fb5363a68dc642a8d
--- /dev/null
+++ b/journals/migrations/0010_auto_20180212_1947.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-12 18:47
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0009_auto_20180212_1947'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='publication',
+            name='authors_old',
+            field=models.ManyToManyField(blank=True, related_name='publications_old', to='scipost.Contributor'),
+        ),
+        migrations.AlterField(
+            model_name='publication',
+            name='authors_unregistered_old',
+            field=models.ManyToManyField(blank=True, related_name='publications_old', to='journals.UnregisteredAuthor'),
+        ),
+    ]
diff --git a/journals/migrations/0011_auto_20180212_1950.py b/journals/migrations/0011_auto_20180212_1950.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6003ecac3699d13d09452f5c629a5f212f3c487
--- /dev/null
+++ b/journals/migrations/0011_auto_20180212_1950.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-12 18:50
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('scipost', '0004_auto_20180212_1932'),
+        ('journals', '0010_auto_20180212_1947'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='PublicationAuthorsTable',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('order', models.PositiveSmallIntegerField()),
+                ('contributor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='scipost.Contributor')),
+                ('publication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='authors', to='journals.Publication')),
+                ('unregistered_author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='journals.UnregisteredAuthor')),
+            ],
+            options={
+                'ordering': ('order',),
+            },
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='authors_registered',
+            field=models.ManyToManyField(blank=True, related_name='publications', through='journals.PublicationAuthorsTable', to='scipost.Contributor'),
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='authors_unregistered',
+            field=models.ManyToManyField(blank=True, related_name='publications', through='journals.PublicationAuthorsTable', to='journals.UnregisteredAuthor'),
+        ),
+    ]
diff --git a/journals/migrations/0012_auto_20180212_1950.py b/journals/migrations/0012_auto_20180212_1950.py
new file mode 100644
index 0000000000000000000000000000000000000000..69128e76f801ab5d082083e6c4405eb244bc5042
--- /dev/null
+++ b/journals/migrations/0012_auto_20180212_1950.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-12 18:50
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def transfer_publication_authors_to_separate_table(apps, schema_editor):
+    Contributor = apps.get_model('scipost', 'Contributor')
+    Publication = apps.get_model('journals', 'Publication')
+    UnregisteredAuthor = apps.get_model('journals', 'UnregisteredAuthor')
+    PublicationAuthorsTable = apps.get_model('journals', 'PublicationAuthorsTable')
+
+    for publication in Publication.objects.all():
+        registered_authors = Contributor.objects.filter(publications_old__id=publication.id)
+        unregistered_authors = UnregisteredAuthor.objects.filter(publications_old__id=publication.id)
+
+        count = 1
+        for author in registered_authors:
+            PublicationAuthorsTable.objects.create(
+                publication=publication,
+                contributor=author,
+                order=count,
+            )
+            count += 1
+
+        for author in unregistered_authors:
+            PublicationAuthorsTable.objects.create(
+                publication=publication,
+                unregistered_author=author,
+                order=count,
+            )
+            count += 1
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0011_auto_20180212_1950'),
+    ]
+
+    operations = [
+        migrations.RunPython(transfer_publication_authors_to_separate_table)
+    ]
diff --git a/journals/models.py b/journals/models.py
index c583a4c5221d25c8d9f2f6cc0b95493b0e06a683..41cd2052cc1ad1bdaba0b9852ff8219190edc51e 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -30,6 +30,46 @@ class UnregisteredAuthor(models.Model):
         return self.last_name + ', ' + self.first_name
 
 
+class PublicationAuthorsTable(models.Model):
+    publication = models.ForeignKey('journals.Publication', related_name='authors')
+    unregistered_author = models.ForeignKey('journals.UnregisteredAuthor', null=True, blank=True,
+                                            related_name='+')
+    contributor = models.ForeignKey('scipost.Contributor', null=True, blank=True, related_name='+')
+    order = models.PositiveSmallIntegerField()
+
+    class Meta:
+        ordering = ('order',)
+
+    def __str__(self):
+        if self.contributor:
+            return str(self.contributor)
+        elif self.unregistered_author:
+            return str(self.unregistered_author)
+
+    def save(self, *args, **kwargs):
+        if not self.order:
+            self.order = self.publication.authors.count() + 1
+        return super().save(*args, **kwargs)
+
+    @property
+    def is_registered(self):
+        return self.contributor is not None
+
+    @property
+    def first_name(self):
+        if self.contributor:
+            return self.contributor.user.first_name
+        if self.unregistered_author:
+            return self.unregistered_author.first_name
+
+    @property
+    def last_name(self):
+        if self.contributor:
+            return self.contributor.user.last_name
+        if self.unregistered_author:
+            return self.unregistered_author.last_name
+
+
 class Journal(models.Model):
     name = models.CharField(max_length=100, choices=SCIPOST_JOURNALS, unique=True)
     doi_label = models.CharField(max_length=200, unique=True, db_index=True,
@@ -240,9 +280,15 @@ class Publication(models.Model):
         models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS), blank=True, null=True)
 
     # Authors
-    authors = models.ManyToManyField('scipost.Contributor', blank=True,
-                                     related_name='publications')
+    authors_registered = models.ManyToManyField('scipost.Contributor', blank=True,
+                                                through='PublicationAuthorsTable',
+                                                through_fields=('publication', 'contributor'),
+                                                related_name='publications')
     authors_unregistered = models.ManyToManyField('journals.UnregisteredAuthor', blank=True,
+                                                  through='PublicationAuthorsTable',
+                                                  through_fields=(
+                                                    'publication',
+                                                    'unregistered_author'),
                                                   related_name='publications')
     first_author = models.ForeignKey('scipost.Contributor', blank=True, null=True,
                                      on_delete=models.CASCADE,
@@ -282,6 +328,12 @@ class Publication(models.Model):
     latest_metadata_update = models.DateTimeField(blank=True, null=True)
     latest_activity = models.DateTimeField(default=timezone.now)
 
+    # Deprecated fields. About to be removed after successful database migration on production.
+    authors_old = models.ManyToManyField('scipost.Contributor', blank=True,
+                                         related_name='publications_old')
+    authors_unregistered_old = models.ManyToManyField('journals.UnregisteredAuthor', blank=True,
+                                                      related_name='publications_old')
+
     objects = PublicationQuerySet.as_manager()
 
     def __str__(self):
diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html
index ab992648f64fb3493cddf54a540158efd4478983..b49a3a0408821feaf3c8ddcc5ca28cb7e9dc1e94 100644
--- a/journals/templates/journals/add_author.html
+++ b/journals/templates/journals/add_author.html
@@ -29,18 +29,16 @@
 
 <div class="row">
     <div class="col-12">
-      <h3>Current list of authors as contributors:</h3>
+      <h3>Current list of authors</h3>
       <ul>
         {% for author in publication.authors.all %}
-            <li><a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a></li>
-        {% empty %}
-            <li>No unregistered authors known.</li>
-        {% endfor %}
-      </ul>
-      <h3>Current list of additional authors (unregistered):</h3>
-      <ul>
-        {% for author in publication.authors_unregistered.all %}
-            <li>{{ author }}</li>
+            <li>
+                {% if author.is_registered %}
+                    <a href="{{ author.contributor.get_absolute_url }}">{{ author.contributor }}</a>
+                {% else %}
+                    {{ author.unregistered_author }}
+                {% endif %}
+            </li>
         {% empty %}
             <li>No unregistered authors known.</li>
         {% endfor %}
@@ -49,54 +47,38 @@
       <br>
       <h2 class="highlight">Add an (unregistered) author</h2>
 
-      <h3>Search for missing author:</h3>
-      <form action="{% url 'journals:add_author' publication.id %}" method="post">
-            {% csrf_token %}
-            {{form|bootstrap}}
+      <h3>Search for missing author</h3>
+      <form method="get">
+            {{ form|bootstrap }}
             <input class="btn btn-primary" type="submit" value="Search">
       </form>
 
       {% if form.has_changed %}
-            <br>
-            <h3 class="mt-2">Identified as contributor:</h3>
-            <ul class="list-group">
+          <br>
+            <h3>Identified as Contributor:</h3>
+            <ul>
               {% for contributor in contributors_found %}
-                  <li class="list-group-item p-2">
-                    <div class="d-block w-100 font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div>
-                    <a class="d-block" href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a>
+                  <li>
+                    <div class="font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div>
+                    <a href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a>
                   </li>
               {% empty %}
-                  <span class="text-danger">No Contributor with this name could be identified.</span>
+                  <li><span class="text-danger">No Contributor with this name could be identified.</span></li>
               {% endfor %}
             </ul>
 
-            <h3 class="mt-2">Identified as existing unregistered author:</h3>
-            <ul class="list-group">
-              {% for unreg_auth in unregistered_authors_found %}
-                <li class="list-group-item">
-                    <div class="d-block w-100 font-weight-bold">{{ unreg_auth }}
-                    <a class="d-block" href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a>
-                </li>
-                {% empty %}
-                    <span class="text-danger">No UnregisteredAuthor with this name could be found in the database.</span>
-                {% endfor %}
-            </ul>
-
-            <h3 class="mt-3">You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3>
-            <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post">
+            <h3>You can otherwise add the author manually and link it to the publication</h3>
+            <form action="{% url 'journals:add_author' publication_id=publication.id %}" method="post">
                 {% csrf_token %}
-                {{ new_unreg_author_form|bootstrap }}
+                {{ form|bootstrap }}
                 <input class="btn btn-primary" type="submit" value="Add">
             </form>
-
+        <br>
       {% endif %}
-
-      <br>
-      <h3>
-          <a href="{{publication.get_absolute_url}}">Return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>.
-      </h3>
     </div>
 </div>
 
+<p>Return to the <a href="{{publication.get_absolute_url}}">publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>.</p>
+
 
 {% endblock content %}
diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html
index 56f960111f3f71caae0111c8e6ca43e3a8150e75..0b0547b47c5be8f52046bbf7b3036ac80089d857 100644
--- a/journals/templates/journals/manage_metadata.html
+++ b/journals/templates/journals/manage_metadata.html
@@ -74,20 +74,11 @@ event: "focusin"
 	<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>
+              <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %})
+                <ul class="list-unstyled pl-4">
                   {% for author in publication.authors.all %}
                   <li>
-                    <a href="{% url 'journals:mark_first_author' publication_id=publication.id contributor_id=author.id %}">{{ author }}</a>
-                  </li>
-                  {% endfor %}
-                </ul>
-                <p>unregistered authors:</p>
-                <ul>
-                  {% for author_unreg in publication.authors_unregistered.all %}
-                  <li>
-                    <a href="{% url 'journals:mark_first_author_unregistered' publication_id=publication.id unregistered_author_id=author_unreg.id %}">{{ author_unreg }}</a>
+                    {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a>
                   </li>
                   {% endfor %}
                 </ul>
diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html
index 56ed342a757de2b909f8ebac9ccf157cb6ee8e7f..358a8bbca484f3651103a84b22d9df4e010f28b9 100644
--- a/journals/templates/journals/publication_detail.html
+++ b/journals/templates/journals/publication_detail.html
@@ -20,10 +20,11 @@
 
     <meta name="citation_title" content="{{ publication.title }}"/>
     {% for author in publication.authors.all %}
-    <meta name="citation_author" content="{{ author.user.last_name }}, {{ author.user.first_name }}"/>
-    {% endfor %}
-    {% for author in publication.authors_unregistered.all %}
-    <meta name="citation_author" content="{{ author.last_name }}, {{ author.first_name }}"/>
+        {% if author.contributor %}
+            <meta name="citation_author" content="{{ author.contributor.user.last_name }}, {{ author.contributor.user.first_name }}"/>
+        {% elif author.unregistered_author %}
+            <meta name="citation_author" content="{{ author.unregistered_author.last_name }}, {{ author.unregistered_author.first_name }}"/>
+        {% endif %}
     {% endfor %}
     <meta name="citation_doi" content="{{ publication.doi_string }}"/>
     <meta name="citation_publication_date" content="{{ publication.publication_date|date:'Y/m/d' }}"/>
@@ -83,10 +84,11 @@
             <h3>Authors</h3>
             <ul>
                 {% for author in publication.authors.all %}
-                      <li><a href="{{author.get_absolute_url}}">{{ author }}</a></li>
-                {% endfor %}
-                {% for author in publication.authors_unregistered.all %}
-                      <li>{{ author }}</li>
+                    {% if author.is_registered %}
+                        <li><a href="{{ author.contributor.get_absolute_url }}">{{ author.contributor }}</a></li>
+                    {% else %}
+                        <li>{{ author.unregistered_author }}</li>
+                    {% endif %}
                 {% endfor %}
             </ul>
 
@@ -96,7 +98,7 @@
                 {# This function is not available for public yet! #}
                 <em>The following is not available for the public yet:</em>
                 {% include 'partials/journals/references.html' with publication=publication %}
-                
+
                 {% if publication.funders_generic.exists %}
                     <h3>Funder{{ publication.funders_generic.count|pluralize }} for this publication:</h3>
                     <ul>
@@ -118,7 +120,7 @@
         </div>
     </div>
 
-    {% if request.user and request.user.contributor in publication.authors.all %}
+    {% if request.user and request.user.contributor in publication.registered_authors.all %}
         <h3>Author actions</h3>
         <ul>
             <li><a href="{% url 'commentaries:comment_on_publication' publication.doi_label %}">Place a comment on this publication</a></li>
@@ -131,29 +133,15 @@
         <div class="col-12">
             <h3>Editorial Administration tools: </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">
-                      <p>registered authors:</p>
-                      <ul>
-                        {% for author in publication.authors.all %}
-                          <li>
-                            <a href="{% url 'journals:mark_first_author' publication_id=publication.id contributor_id=author.id %}">{{ author }}</a>
-                          </li>
-                        {% endfor %}
-                      </ul>
-                    </div>
-                    <div class="col-md-5">
-                      <p>unregistered authors:</p>
-                      <ul>
-                        {% for author_unreg in publication.authors_unregistered.all %}
-                          <li>
-                            <a href="{% url 'journals:mark_first_author_unregistered' publication_id=publication.id unregistered_author_id=author_unreg.id %}">{{ author_unreg }}</a>
-                          </li>
-                        {% endfor %}
-                      </ul>
-                    </div>
-                </div>
+              <li>
+                  Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %})
+                  <ul class="list-unstyled pl-4">
+                    {% for author in publication.authors.all %}
+                      <li>
+                        {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a>
+                      </li>
+                    {% endfor %}
+                  </ul>
               </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>
diff --git a/journals/urls/general.py b/journals/urls/general.py
index dd9cfea9eab02f3c9e99417c5d25887fd7b75956..c57c961fd9e4985efee6e2e2b7fc310190e2547c 100644
--- a/journals/urls/general.py
+++ b/journals/urls/general.py
@@ -23,24 +23,15 @@ urlpatterns = [
     url(r'^validate_publication$',
         journals_views.validate_publication,
         name='validate_publication'),
-    url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$',
+    url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<author_object_id>[0-9]+)$',
         journals_views.mark_first_author,
         name='mark_first_author'),
-    url(r'^mark_first_author_unregistered/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$',
-        journals_views.mark_first_author_unregistered,
-        name='mark_first_author_unregistered'),
     url(r'^add_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$',
         journals_views.add_author,
         name='add_author'),
     url(r'^add_author/(?P<publication_id>[0-9]+)$',
         journals_views.add_author,
         name='add_author'),
-    url(r'^add_unregistered_author/(?P<publication_id>[0-9]+)/(?P<unregistered_author_id>[0-9]+)$',
-        journals_views.add_unregistered_author,
-        name='add_unregistered_author'),
-    url(r'^add_new_unreg_author/(?P<publication_id>[0-9]+)$',
-        journals_views.add_new_unreg_author,
-        name='add_new_unreg_author'),
     url(r'^manage_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
         journals_views.manage_metadata,
         name='manage_metadata'),
diff --git a/journals/views.py b/journals/views.py
index 54ffe22a2c4f8cf5ee6e4e344f574192db084b2d..2456765e8afcf0601a8725e8b6efbec92db10d3d 100644
--- a/journals/views.py
+++ b/journals/views.py
@@ -21,8 +21,8 @@ from django.shortcuts import get_object_or_404, render, redirect
 
 from .exceptions import PaperNumberingError
 from .helpers import paper_nr_string, issue_doi_label_from_doi_label
-from .models import Journal, Issue, Publication, UnregisteredAuthor, Deposit, DOAJDeposit,\
-                    GenericDOIDeposit
+from .models import Journal, Issue, Publication, Deposit, DOAJDeposit,\
+                    GenericDOIDeposit, PublicationAuthorsTable
 from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\
                    UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm,\
                    ReferenceFormSet
@@ -246,18 +246,22 @@ def validate_publication(request):
     if validate_publication_form.is_valid():
         publication = validate_publication_form.save()
 
-        # Fill in remaining data
+        # Fill remaining data
         submission = publication.accepted_submission
-        publication.authors.add(*submission.authors.all())
-        if publication.first_author:
-            publication.authors.add(publication.first_author)
         if publication.first_author_unregistered:
-            publication.authors_unregistered.add(publication.first_author_unregistered)
+            PublicationAuthorsTable.objects.create(
+                order=1,
+                publication=publication,
+                unregistered_author=publication.first_author_unregistered)
+
+        for submission_author in submission.authors.all():
+            PublicationAuthorsTable.objects.create(
+                publication=publication, contributor=submission_author)
         publication.authors_claims.add(*submission.authors_claims.all())
         publication.authors_false_claims.add(*submission.authors_false_claims.all())
 
         # Add Institutions to the publication
-        for author in publication.authors.all():
+        for author in publication.authors_registered.all():
             for current_affiliation in author.affiliations.active():
                 publication.institutions.add(current_affiliation.institution)
 
@@ -334,25 +338,29 @@ def manage_metadata(request, issue_doi_label=None, doi_label=None):
 
 
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
-@transaction.atomic
-def mark_first_author(request, publication_id, contributor_id):
+def mark_first_author(request, publication_id, author_object_id):
     publication = get_object_or_404(Publication, id=publication_id)
-    contributor = get_object_or_404(Contributor, id=contributor_id)
-    publication.first_author = contributor
-    publication.first_author_unregistered = None
-    publication.save()
-    return redirect(reverse('journals:manage_metadata',
-                            kwargs={'doi_label': publication.doi_label}))
-
+    author_object = get_object_or_404(publication.authors, id=author_object_id)
 
-@permission_required('scipost.can_publish_accepted_submission', return_403=True)
-@transaction.atomic
-def mark_first_author_unregistered(request, publication_id, unregistered_author_id):
-    publication = get_object_or_404(Publication, id=publication_id)
-    unregistered_author = get_object_or_404(UnregisteredAuthor, id=unregistered_author_id)
-    publication.first_author = None
-    publication.first_author_unregistered = unregistered_author
+    # Save explicit relation
+    if author_object.is_registered:
+        publication.first_author = author_object.contributor
+        publication.first_author_unregistered = None
+    else:
+        publication.first_author = None
+        publication.first_author_unregistered = author_object.unregistered_author
     publication.save()
+
+    # Redo ordering
+    author_object.order = 1
+    author_object.save()
+    author_objects = publication.authors.exclude(id=author_object.id)
+    count = 2
+    for author in author_objects:
+        author.order = count
+        author.save()
+        count += 1
+    messages.success(request, 'Marked {} first author'.format(author_object))
     return redirect(reverse('journals:manage_metadata',
                             kwargs={'doi_label': publication.doi_label}))
 
@@ -369,62 +377,37 @@ def add_author(request, publication_id, contributor_id=None, unregistered_author
     publication = get_object_or_404(Publication, id=publication_id)
     if contributor_id:
         contributor = get_object_or_404(Contributor, id=contributor_id)
-        publication.authors.add(contributor)
+        PublicationAuthorsTable.objects.create(contributor=contributor, publication=publication)
         publication.save()
+        messages.success(request, 'Added {} as an author.'.format(contributor))
         return redirect(reverse('journals:manage_metadata',
                                 kwargs={'doi_label': publication.doi_label}))
 
-    if request.method == 'POST':
-        form = UnregisteredAuthorForm(request.POST)
-        if form.is_valid():
-            contributors_found = Contributor.objects.filter(
-                user__last_name__icontains=form.cleaned_data['last_name'])
-            unregistered_authors_found = UnregisteredAuthor.objects.filter(
-                last_name__icontains=form.cleaned_data['last_name'])
-            new_unreg_author_form = UnregisteredAuthorForm(
-                initial={'first_name': form.cleaned_data['first_name'],
-                         'last_name': form.cleaned_data['last_name'], })
-        else:
-            errormessage = 'Please fill in the form properly'
-            return render(request, 'scipost/error.html', context={'errormessage': errormessage})
-    else:
-        form = UnregisteredAuthorForm()
-        contributors_found = None
-        unregistered_authors_found = None
-        new_unreg_author_form = UnregisteredAuthorForm()
-    context = {'publication': publication,
-               'contributors_found': contributors_found,
-               'unregistered_authors_found': unregistered_authors_found,
-               'form': form,
-               'new_unreg_author_form': new_unreg_author_form, }
+    contributors_found = None
+    form = UnregisteredAuthorForm(request.POST or request.GET or None)
+
+    if request.POST and form.is_valid():
+        unregistered_author = form.save()
+        PublicationAuthorsTable.objects.create(
+            publication=publication,
+            unregistered_author=unregistered_author)
+        messages.success(request, 'Added {} as an unregistered author.'.format(
+            unregistered_author
+        ))
+        return redirect(reverse('journals:manage_metadata',
+                                kwargs={'doi_label': publication.doi_label}))
+    elif form.is_valid():
+        contributors_found = Contributor.objects.filter(
+            # user__first_name__icontains=form.cleaned_data['first_name'],
+            user__last_name__icontains=form.cleaned_data['last_name'])
+    context = {
+        'publication': publication,
+        'contributors_found': contributors_found,
+        'form': form,
+    }
     return render(request, 'journals/add_author.html', context)
 
 
-@permission_required('scipost.can_publish_accepted_submission', return_403=True)
-@transaction.atomic
-def add_unregistered_author(request, publication_id, unregistered_author_id):
-    publication = get_object_or_404(Publication, id=publication_id)
-    unregistered_author = get_object_or_404(UnregisteredAuthor, id=unregistered_author_id)
-    publication.authors_unregistered.add(unregistered_author)
-    publication.save()
-    return redirect(reverse('journals:manage_metadata',
-                            kwargs={'doi_label': publication.doi_label}))
-
-
-@permission_required('scipost.can_publish_accepted_submission', return_403=True)
-@transaction.atomic
-def add_new_unreg_author(request, publication_id):
-    publication = get_object_or_404(Publication, id=publication_id)
-    if request.method == 'POST':
-        new_unreg_author_form = UnregisteredAuthorForm(request.POST)
-        if new_unreg_author_form.is_valid():
-            new_unreg_author = new_unreg_author_form.save()
-            publication.authors_unregistered.add(new_unreg_author)
-            return redirect(reverse('journals:manage_metadata',
-                                    kwargs={'doi_label': publication.doi_label}))
-    raise Http404
-
-
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
 @transaction.atomic
 def create_citation_list_metadata(request, doi_label):
@@ -611,40 +594,27 @@ def create_metadata_xml(request, doi_label):
         '</journal_issue>\n'
         '<journal_article publication_type=\'full_text\'>\n'
         '<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():
-        if author == publication.first_author:
+    initial['metadata_xml'] += '<contributors>\n'
+    for author_object in publication.authors.all():
+        if author_object.order == 1:
             initial['metadata_xml'] += (
                 '<person_name sequence=\'first\' contributor_role=\'author\'> '
-                '<given_name>' + author.user.first_name + '</given_name> '
-                '<surname>' + author.user.last_name + '</surname> '
+                '<given_name>' + author_object.first_name + '</given_name> '
+                '<surname>' + author_object.last_name + '</surname> '
             )
         else:
             initial['metadata_xml'] += (
                 '<person_name sequence=\'additional\' contributor_role=\'author\'> '
-                '<given_name>' + author.user.first_name + '</given_name> '
-                '<surname>' + author.user.last_name + '</surname> '
-            )
-        if author.orcid_id:
-            initial['metadata_xml'] += '<ORCID>http://orcid.org/' + author.orcid_id + '</ORCID>'
-        initial['metadata_xml'] += '</person_name>\n'
-
-    for author_unreg in publication.authors_unregistered.all():
-        if author_unreg == publication.first_author_unregistered:
-            initial['metadata_xml'] += (
-                '<person_name sequence=\'first\' contributor_role=\'author\'> '
-                '<given_name>' + author_unreg.first_name + '</given_name> '
-                '<surname>' + author_unreg.last_name + '</surname> '
+                '<given_name>' + author_object.first_name + '</given_name> '
+                '<surname>' + author_object.last_name + '</surname> '
             )
-        else:
+        if author_object.contributor and author_object.contributor.orcid_id:
             initial['metadata_xml'] += (
-                '<person_name sequence=\'additional\' contributor_role=\'author\'> '
-                '<given_name>' + author_unreg.first_name + '</given_name> '
-                '<surname>' + author_unreg.last_name + '</surname> '
+                '<ORCID>http://orcid.org/' + author_object.contributor.orcid_id + '</ORCID>'
             )
         initial['metadata_xml'] += '</person_name>\n'
     initial['metadata_xml'] += '</contributors>\n'
diff --git a/scipost/forms.py b/scipost/forms.py
index a1a08bda2e0d99bb84cc688d700543c0327ff12b..60c748382e617c1bc3a971b3caefdddb3ebb3f63 100644
--- a/scipost/forms.py
+++ b/scipost/forms.py
@@ -121,7 +121,7 @@ class RegistrationForm(forms.Form):
             country=self.cleaned_data['country_of_employment'],
             name=self.cleaned_data['affiliation'],
         )
-        contributor, new = Contributor.objects.get_or_create(**{
+        contributor, __ = Contributor.objects.get_or_create(**{
             'user': user,
             'invitation_key': self.cleaned_data.get('invitation_key', ''),
             'title': self.cleaned_data['title'],
@@ -133,10 +133,6 @@ class RegistrationForm(forms.Form):
             contributor=contributor,
             institution=institution,
         )
-
-        if contributor.activation_key == '':
-            # Seems redundant?
-            contributor.generate_key()
         contributor.save()
         return contributor
 
@@ -190,20 +186,27 @@ class DraftInvitationForm(forms.ModelForm):
 
 class ContributorsFilterForm(forms.Form):
     names = forms.CharField(widget=forms.Textarea())
+    include_invitations = forms.BooleanField(required=False, initial=True,
+                                             label='Include invitations in the filter.')
 
     def filter(self):
         names_found = []
         names_not_found = []
+        invitations_found = []
         r = self.cleaned_data['names'].replace('\r', '\n').split('\n')
+        include_invitations = self.cleaned_data.get('include_invitations', False)
         for name in r:
             last_name = name.split(',')[0]
             if not last_name:
                 continue
             if Contributor.objects.filter(user__last_name__istartswith=last_name).exists():
                 names_found.append(name)
+            elif include_invitations and RegistrationInvitation.objects.pending_response().filter(
+              last_name__istartswith=last_name).exists():
+                invitations_found.append(name)
             else:
                 names_not_found.append(name)
-        return names_found, names_not_found
+        return names_found, names_not_found, invitations_found
 
 
 class RegistrationInvitationForm(forms.ModelForm):
@@ -317,7 +320,7 @@ class UpdatePersonalDataForm(forms.ModelForm):
         and changes the orcid_id. It marks all Publications, Reports and Comments
         authors by this Contributor with a deposit_requires_update == True.
         """
-        publications = Publication.objects.filter(authors=self.instance)
+        publications = Publication.objects.filter(authors_registered=self.instance)
         for publication in publications:
             publication.doideposit_needs_updating = True
             publication.save()
diff --git a/scipost/managers.py b/scipost/managers.py
index fcb78b3d9878180c70042b4b90f19e7a29206966..db457fd9bd20d2ea05fafc34f92021b5f50d5740 100644
--- a/scipost/managers.py
+++ b/scipost/managers.py
@@ -49,6 +49,9 @@ class RegistrationInvitationManager(models.Manager):
     def declined(self):
         return self.filter(responded=True, declined=True)
 
+    def pending_response(self):
+        return self.filter(responded=False)
+
     def declined_or_without_response(self):
         return self.filter(Q(responded=True, declined=True) | Q(responded=False))
 
diff --git a/scipost/migrations/0003_auto_20180206_1940.py b/scipost/migrations/0003_auto_20180206_1940.py
new file mode 100644
index 0000000000000000000000000000000000000000..49b00fcebc59e03bb54e71967c6c4965b2fa43d5
--- /dev/null
+++ b/scipost/migrations/0003_auto_20180206_1940.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-06 18:40
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('scipost', '0002_auto_20171229_1435'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contributor',
+            name='user',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/scipost/migrations/0004_auto_20180212_1932.py b/scipost/migrations/0004_auto_20180212_1932.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7e69e16c0bd73c4f52dec139d09ff200360a64a
--- /dev/null
+++ b/scipost/migrations/0004_auto_20180212_1932.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-02-12 18:32
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('scipost', '0003_auto_20180206_1940'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contributor',
+            name='user',
+            field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/scipost/models.py b/scipost/models.py
index 03121a51bf68120856deb74203694cd5482c2fd3..b217d78e78b1c207bbb7cb6aab19ae709dc0438d 100644
--- a/scipost/models.py
+++ b/scipost/models.py
@@ -4,7 +4,8 @@ import random
 import string
 
 from django.core.urlresolvers import reverse
-from django.contrib.auth.models import User
+from django.conf import settings
+from django.contrib.auth import get_user_model
 from django.contrib.postgres.fields import ArrayField
 from django.db import models
 from django.utils import timezone
@@ -14,7 +15,8 @@ from .constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\
                        subject_areas_dict, CONTRIBUTOR_STATUS, TITLE_CHOICES,\
                        INVITATION_STYLE, INVITATION_TYPE,\
                        INVITATION_CONTRIBUTOR, INVITATION_FORMAL,\
-                       AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS
+                       AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS,\
+                       CONTRIBUTOR_NEWLY_REGISTERED
 from .fields import ChoiceArrayField
 from .managers import FellowManager, ContributorQuerySet, RegistrationInvitationManager,\
                       UnavailabilityPeriodManager, AuthorshipClaimQuerySet
@@ -28,7 +30,7 @@ def get_sentinel_user():
     status: "deactivated" and anonymized.
     Fallback user for models relying on Contributor that is being deleted.
     '''
-    user, new = User.objects.get_or_create(username='deleted')
+    user, __ = get_user_model().objects.get_or_create(username='deleted')
     return Contributor.objects.get_or_create(status=-4, user=user)[0]
 
 
@@ -37,11 +39,12 @@ class Contributor(models.Model):
     All *science* users of SciPost are Contributors.
     username, password, email, first_name and last_name are inherited from User.
     """
-    user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True)
+    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, unique=True)
     invitation_key = models.CharField(max_length=40, blank=True)
     activation_key = models.CharField(max_length=40, blank=True)
     key_expires = models.DateTimeField(default=timezone.now)
-    status = models.SmallIntegerField(default=0, choices=CONTRIBUTOR_STATUS)
+    status = models.SmallIntegerField(default=CONTRIBUTOR_NEWLY_REGISTERED,
+                                      choices=CONTRIBUTOR_STATUS)
     title = models.CharField(max_length=4, choices=TITLE_CHOICES)
     discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES,
                                   default='physics', verbose_name='Main discipline')
@@ -69,7 +72,7 @@ class Contributor(models.Model):
     def save(self, *args, **kwargs):
         if not self.activation_key:
             self.generate_key()
-        super().save(*args, **kwargs)
+        return super().save(*args, **kwargs)
 
     def get_absolute_url(self):
         return reverse('scipost:contributor_info', args=(self.id,))
diff --git a/scipost/templates/scipost/contributors_filter.html b/scipost/templates/scipost/contributors_filter.html
index eedc758ad56422aea9a9aeee8717b017e1f594f9..12418bd8a252a1be98829df8c4ee790cd806ce2a 100644
--- a/scipost/templates/scipost/contributors_filter.html
+++ b/scipost/templates/scipost/contributors_filter.html
@@ -33,13 +33,17 @@
     <h2>Filter result</h2>
     {% if names_not_found %}
         <h3>New names</h3>
-        <pre><code>{% for name in names_not_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre>
+        <pre class="mb-3"><code>{% for name in names_not_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre>
     {% endif %}
-    <br>
+
     {% if names_found %}
         <h3>Names found in the system</h3>
-        <pre><code>{% for name in names_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre>
+        <pre class="mb-3"><code>{% for name in names_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre>
+    {% endif %}
 
+    {% if invitations_found %}
+        <h3>Invitations (pending response) found in database</h3>
+        <pre class="mb-3"><code>{% for name in invitations_found %}{{ name }}{% if not forloop.last %}<br>{% endif %}{% endfor %}</code></pre>
     {% endif %}
 {% endif %}
 
diff --git a/scipost/views.py b/scipost/views.py
index 64fd94a5749dd079d2f9ddcc32b412d874ad075c..b9d8656f910498ac50b5d7993d097c7f8b7eb00b 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -44,7 +44,7 @@ from affiliations.forms import AffiliationsFormset
 from colleges.permissions import fellowship_or_admin_required
 from commentaries.models import Commentary
 from comments.models import Comment
-from journals.models import Publication, Journal
+from journals.models import Publication, Journal, PublicationAuthorsTable
 from mails.views import MailEditingSubView
 from news.models import NewsItem
 from submissions.models import Submission, RefereeInvitation,\
@@ -386,17 +386,16 @@ def contributors_filter(request):
     view returns all entries of those lists with users that are certainly not registered
     or invitated.
     """
-    names_found = names_not_found = None
+    names_found = names_not_found = invitations_found = None
     form = ContributorsFilterForm(request.POST or None)
     if form.is_valid():
-        names_found, names_not_found = form.filter()
-        # messages.success(request, 'Draft invitation saved.')
-        # return redirect(reverse('scipost:draft_registration_invitation'))
+        names_found, names_not_found, invitations_found = form.filter()
 
     context = {
         'form': form,
         'names_found': names_found,
         'names_not_found': names_not_found,
+        'invitations_found': invitations_found,
     }
     return render(request, 'scipost/contributors_filter.html', context)
 
@@ -798,7 +797,7 @@ def _personal_page_publications(request):
     }
     context['nr_publication_authorships_to_claim'] = Publication.objects.filter(
         author_list__contains=request.user.last_name).exclude(
-        authors=contributor).exclude(
+        authors_registered=contributor).exclude(
         authors_claims=contributor).exclude(
         authors_false_claims=contributor).count()
     return render(request, 'partials/scipost/personal_page/publications.html', context)
@@ -1026,28 +1025,28 @@ def claim_authorships(request):
     contributor = Contributor.objects.get(user=request.user)
 
     publication_authorships_to_claim = (Publication.objects
-                                       .filter(author_list__contains=contributor.user.last_name)
-                                       .exclude(authors__in=[contributor])
-                                       .exclude(authors_claims__in=[contributor])
-                                       .exclude(authors_false_claims__in=[contributor]))
+                                        .filter(author_list__contains=contributor.user.last_name)
+                                        .exclude(authors_registered=contributor)
+                                        .exclude(authors_claims=contributor)
+                                        .exclude(authors_false_claims=contributor))
     pub_auth_claim_form = AuthorshipClaimForm()
     submission_authorships_to_claim = (Submission.objects
                                        .filter(author_list__contains=contributor.user.last_name)
-                                       .exclude(authors__in=[contributor])
-                                       .exclude(authors_claims__in=[contributor])
-                                       .exclude(authors_false_claims__in=[contributor]))
+                                       .exclude(authors=contributor)
+                                       .exclude(authors_claims=contributor)
+                                       .exclude(authors_false_claims=contributor))
     sub_auth_claim_form = AuthorshipClaimForm()
     commentary_authorships_to_claim = (Commentary.objects
                                        .filter(author_list__contains=contributor.user.last_name)
-                                       .exclude(authors__in=[contributor])
-                                       .exclude(authors_claims__in=[contributor])
-                                       .exclude(authors_false_claims__in=[contributor]))
+                                       .exclude(authors=contributor)
+                                       .exclude(authors_claims=contributor)
+                                       .exclude(authors_false_claims=contributor))
     com_auth_claim_form = AuthorshipClaimForm()
     thesis_authorships_to_claim = (ThesisLink.objects
                                    .filter(author__contains=contributor.user.last_name)
-                                   .exclude(author_as_cont__in=[contributor])
-                                   .exclude(author_claims__in=[contributor])
-                                   .exclude(author_false_claims__in=[contributor]))
+                                   .exclude(author_as_cont=contributor)
+                                   .exclude(author_claims=contributor)
+                                   .exclude(author_false_claims=contributor))
     thesis_auth_claim_form = AuthorshipClaimForm()
 
     context = {
@@ -1140,16 +1139,17 @@ def vet_authorship_claim(request, claim_id, claim):
         vetting_contributor = Contributor.objects.get(user=request.user)
         claim_to_vet = AuthorshipClaim.objects.get(pk=claim_id)
 
-        if claim_to_vet.publication is not None:
+        if claim_to_vet.publication:
             claim_to_vet.publication.authors_claims.remove(claim_to_vet.claimant)
             if claim == '1':
-                claim_to_vet.publication.authors.add(claim_to_vet.claimant)
+                PublicationAuthorsTable.objects.create(
+                    publication=claim_to_vet.publication, contributor=claim_to_vet.claimant)
                 claim_to_vet.status = '1'
             elif claim == '0':
                 claim_to_vet.publication.authors_false_claims.add(claim_to_vet.claimant)
                 claim_to_vet.status = '-1'
             claim_to_vet.publication.save()
-        if claim_to_vet.submission is not None:
+        if claim_to_vet.submission:
             claim_to_vet.submission.authors_claims.remove(claim_to_vet.claimant)
             if claim == '1':
                 claim_to_vet.submission.authors.add(claim_to_vet.claimant)
@@ -1158,7 +1158,7 @@ def vet_authorship_claim(request, claim_id, claim):
                 claim_to_vet.submission.authors_false_claims.add(claim_to_vet.claimant)
                 claim_to_vet.status = '-1'
             claim_to_vet.submission.save()
-        if claim_to_vet.commentary is not None:
+        if claim_to_vet.commentary:
             claim_to_vet.commentary.authors_claims.remove(claim_to_vet.claimant)
             if claim == '1':
                 claim_to_vet.commentary.authors.add(claim_to_vet.claimant)
@@ -1167,7 +1167,7 @@ def vet_authorship_claim(request, claim_id, claim):
                 claim_to_vet.commentary.authors_false_claims.add(claim_to_vet.claimant)
                 claim_to_vet.status = '-1'
             claim_to_vet.commentary.save()
-        if claim_to_vet.thesislink is not None:
+        if claim_to_vet.thesislink:
             claim_to_vet.thesislink.author_claims.remove(claim_to_vet.claimant)
             if claim == '1':
                 claim_to_vet.thesislink.author_as_cont.add(claim_to_vet.claimant)
@@ -1189,7 +1189,7 @@ def contributor_info(request, contributor_id):
     on the relevant name (in listing headers of Submissions, ...).
     """
     contributor = get_object_or_404(Contributor, pk=contributor_id)
-    contributor_publications = Publication.objects.published().filter(authors=contributor)
+    contributor_publications = Publication.objects.published().filter(authors_registered=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)