diff --git a/notifications/migrations/0002_notification_url_code.py b/notifications/migrations/0002_notification_url_code.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8922d06cd68ebd87772913a30232203c46fe343
--- /dev/null
+++ b/notifications/migrations/0002_notification_url_code.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('notifications', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='notification',
+            name='url_code',
+            field=models.CharField(blank=True, max_length=255),
+        ),
+    ]
diff --git a/notifications/models.py b/notifications/models.py
index 3f0d1dd553cfac820324b9030c688b2d5558b251..eb0947cf320bfb04f7ddb13a5b8b84a2697251f3 100644
--- a/notifications/models.py
+++ b/notifications/models.py
@@ -71,6 +71,8 @@ class Notification(models.Model):
     # of notifications.
     internal_type = models.CharField(max_length=255, blank=True, choices=NOTIFICATION_TYPES)
 
+    url_code = models.CharField(max_length=255, blank=True)
+
     objects = NotificationQuerySet.as_manager()
 
     class Meta:
diff --git a/preprints/helpers.py b/preprints/helpers.py
index d5437b287c6539ca03ce34265425af7b6438b19c..1af7fba21670c593835cbbb0a1f1a3a6360490d8 100644
--- a/preprints/helpers.py
+++ b/preprints/helpers.py
@@ -5,24 +5,40 @@ __license__ = "AGPL v3"
 from django.db.models import Max
 from django.utils import timezone
 
+from submissions.models import Submission
+
 from .models import Preprint
 
 
-def generate_new_scipost_identifier():
-    """Return an identifier for a new SciPost preprint series without version number."""
+def generate_new_scipost_identifier(old_preprint=None):
+    """
+    Return an identifier for a new SciPost preprint series without version number.
+
+    TODO: This method will explode as soon as it will be used similtaneously by two or more people.
+    """
     now = timezone.now()
-    existing_identifier = Preprint.objects.filter(
-        created__year=now.year, created__month=now.month).aggregate(
-        identifier=Max('scipost_preprint_identifier'))['identifier']
-    if not existing_identifier:
-        existing_identifier = '1'
-    else:
-        existing_identifier = str(existing_identifier + 1)
-    return '{year}{month}_{identifier}'.format(
-        year=now.year, month=str(now.month).rjust(2, '0'),
-        identifier=existing_identifier.rjust(5, '0')), int(existing_identifier)
 
+    if isinstance(old_preprint, Submission):
+        old_preprint = old_preprint.preprint
+
+    if old_preprint:
+        # Generate new version number of existing series.
+        preprint_series = Preprint.objects.filter(
+            scipost_preprint_identifier=old_preprint.scipost_preprint_identifier).values_list(
+            'vn_nr', flat=True)
+        identifier = '{}v{}'.format(old_preprint.identifier_wo_vn_nr, max(preprint_series) + 1)
+        return identifier, old_preprint.scipost_preprint_identifier
+    else:
+        # New series of Preprints.
+        existing_identifier = Preprint.objects.filter(
+            created__year=now.year, created__month=now.month).aggregate(
+            identifier=Max('scipost_preprint_identifier'))['identifier']
+        if not existing_identifier:
+            existing_identifier = '1'
+        else:
+            existing_identifier = str(existing_identifier + 1)
 
-def format_scipost_identifier(identifier, version=1):
-    return 'scipost_{identifier}v{version}'.format(
-        identifier=identifier, version=version)
+        identifier = 'scipost_{year}{month}_{identifier}v1'.format(
+            year=now.year, month=str(now.month).rjust(2, '0'),
+            identifier=existing_identifier.rjust(5, '0'))
+        return identifier, int(existing_identifier)
diff --git a/submissions/admin.py b/submissions/admin.py
index 7e02b3362b0bd7fd1cb3ca0f49d5e5b76538d1c5..78df5387cad6306dcc075d99576e120b1f57b910 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -65,8 +65,10 @@ class SubmissionAdmin(GuardedModelAdmin):
         }),
         ('Versioning', {
             'fields': (
+                'thread_hash',
                 'is_current',
-                'is_resubmission',
+                '_is_resubmission',
+                'is_resubmission_of',
                 'list_of_changes'),
         }),
         ('Submission details', {
diff --git a/submissions/constants.py b/submissions/constants.py
index d32c9d654fc4079dac178a3d6c4ca503c04f69b2..a10841d53e78759400bd4d21928c8ae90648a9f4 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -46,6 +46,7 @@ NO_REQUIRED_ACTION_STATUSES = [
 ]
 
 SUBMISSION_TYPE = (
+    # ('', None),
     ('Letter', 'Letter (broad-interest breakthrough results)'),
     ('Article', 'Article (in-depth reports on specialized research)'),
     ('Review', 'Review (candid snapshot of current research in a given area)'),
diff --git a/submissions/forms.py b/submissions/forms.py
index 8709a00de4f9191f40ebc0e73c238a105324ebd0..af9e2eecb349d165df82c2aa579deea86f8e2d33 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -31,7 +31,7 @@ from colleges.models import Fellowship
 from journals.models import Journal
 from journals.constants import SCIPOST_JOURNAL_PHYSICS_PROC, SCIPOST_JOURNAL_PHYSICS
 from mails.utils import DirectMailUtil
-from preprints.helpers import generate_new_scipost_identifier, format_scipost_identifier
+from preprints.helpers import generate_new_scipost_identifier
 from preprints.models import Preprint
 from production.utils import get_or_create_production_stream
 from scipost.constants import SCIPOST_SUBJECT_AREAS
@@ -95,180 +95,237 @@ class SubmissionPoolFilterForm(forms.Form):
 # Submission and resubmission #
 ###############################
 
-class SubmissionChecks:
-    """Mixin with checks run at least the Submission creation form."""
+class SubmissionService:
+    """
+    Object to run checks for prefiller and submit manuscript forms.
+    """
 
-    use_arxiv_preprint = True
-    arxiv_data = {}
-    is_resubmission = False
-    last_submission = None
+    metadata = {}
 
-    def __init__(self, *args, **kwargs):
-        self.requested_by = kwargs.pop('requested_by', None)
-        super().__init__(*args, **kwargs)
-        # Prefill `is_resubmission` property if data is coming from initial data
-        if kwargs.get('initial', None):
-            if kwargs['initial'].get('is_resubmission', None):
-                self.is_resubmission = kwargs['initial']['is_resubmission'] in ('True', True)
-
-        # `is_resubmission` property if data is coming from (POST) request
-        if kwargs.get('data', None):
-            if kwargs['data'].get('is_resubmission', None):
-                self.is_resubmission = kwargs['data']['is_resubmission'] in ('True', True)
-
-    def _submission_already_exists(self, identifier):
-        if Submission.objects.filter(preprint__identifier_w_vn_nr=identifier).exists():
-            error_message = 'This preprint version has already been submitted to SciPost.'
-            raise forms.ValidationError(error_message, code='duplicate')
+    def __init__(self, requested_by, preprint_server, identifier=None, resubmission_of_id=None):
+        self.requested_by = requested_by
+        self.preprint_server = preprint_server
+        self.identifier = identifier
+        self.resubmission_of_id = resubmission_of_id
+        self._arxiv_data = None
+
+    @property
+    def latest_submission(self):
+        """
+        Return latest version of preprint series or None.
+        """
+        if hasattr(self, '_latest_submission'):
+            return self._latest_submission
+
+        if self.identifier:
+            # Check if is resubmission when identifier data is submitted.
+            identifier = self.identifier.rpartition('v')[0]
+            self._latest_submission = Submission.objects.filter(
+                preprint__identifier_wo_vn_nr=identifier).order_by(
+                '-preprint__vn_nr').first()
+        elif self.resubmission_of_id:
+            # Resubmission (submission id) is selected by user.
+            try:
+                self._latest_submission = Submission.objects.filter(
+                    id=int(self.resubmission_of_id)).order_by('-preprint__vn_nr').first()
+            except ValueError:
+                self._latest_submission = None
+        return self._latest_submission
+
+    @property
+    def arxiv_data(self):
+        if self._arxiv_data is None:
+            self._call_arxiv()
+        return self._arxiv_data
+
+    def run_checks(self):
+        """
+        Do several pre-checks (using the arXiv API if needed).
+
+        This is needed for both the prefill and submission forms.
+        """
+        self._submission_already_exists()
+        self._submission_previous_version_is_valid_for_submission()
+
+        if self.preprint_server == 'arxiv':
+            self._submission_is_already_published()
+
+    def _call_arxiv(self):
+        """
+        Retrieve all data from the ArXiv database for `identifier`.
+        """
+        if self.preprint_server != 'arxiv':
+            # Do the call here to prevent multiple calls to the arXiv API in one request.
+            self._arxiv_data = {}
+            return
+        if not self.identifier:
+            print('crap', self.identifier)
+            return
+
+        caller = ArxivCaller(self.identifier)
 
-    def _call_arxiv(self, identifier):
-        caller = ArxivCaller(identifier)
         if caller.is_valid:
-            self.arxiv_data = caller.data
+            self._arxiv_data = caller.data
             self.metadata = caller.metadata
         else:
             error_message = 'A preprint associated to this identifier does not exist.'
             raise forms.ValidationError(error_message)
 
-    def _submission_is_already_published(self, identifier):
-        published_id = None
-        if 'arxiv_doi' in self.arxiv_data:
-            published_id = self.arxiv_data['arxiv_doi']
-        elif 'arxiv_journal_ref' in self.arxiv_data:
-            published_id = self.arxiv_data['arxiv_journal_ref']
+    def get_latest_submission_data(self):
+        """
+        Return initial form data originating from earlier Submission.
+        """
+        if self.is_resubmission():
+            return {
+                'title': self.latest_submission.title,
+                'abstract': self.latest_submission.abstract,
+                'author_list': self.latest_submission.author_list,
+                'discipline': self.latest_submission.discipline,
+                'domain': self.latest_submission.domain,
+                'referees_flagged': self.latest_submission.referees_flagged,
+                'referees_suggested': self.latest_submission.referees_suggested,
+                'secondary_areas': self.latest_submission.secondary_areas,
+                'subject_area': self.latest_submission.subject_area,
+                'submitted_to': self.latest_submission.submitted_to,
+                'submission_type': self.latest_submission.submission_type,
+            }
+        return {}
 
-        if published_id:
-            error_message = ('This paper has been published under DOI %(published_id)s'
-                             '. Please comment on the published version.'),
-            raise forms.ValidationError(error_message, code='published',
-                                        params={'published_id': published_id})
+    def is_resubmission(self):
+        """
+        Check if Submission is a SciPost or arXiv resubmission.
+        """
+        return self.latest_submission is not None
 
-    def _submission_previous_version_is_valid_for_submission(self, identifier):
-        """Check if previous submitted versions have the appropriate status."""
-        identifiers = self.identifier_into_parts(identifier)
-        submission = (Submission.objects
-                      .filter(preprint__identifier_wo_vn_nr=identifiers['identifier_wo_vn_nr'])
-                      .order_by('preprint__vn_nr').last())
-
-        # If submissions are found; check their statuses
-        if submission:
-            self.last_submission = submission
-            if submission.open_for_resubmission:
-                self.is_resubmission = True
-                if self.requested_by.contributor not in submission.authors.all():
-                    error_message = ('There exists a preprint with this arXiv identifier '
-                                     'but an earlier version number. Resubmission is only possible'
-                                     ' if you are a registered author of this manuscript.')
-                    raise forms.ValidationError(error_message)
-            elif submission.status == STATUS_REJECTED:
-                error_message = ('This arXiv preprint has previously undergone refereeing '
-                                 'and has been rejected. Resubmission is only possible '
-                                 'if the manuscript has been substantially reworked into '
-                                 'a new arXiv submission with distinct identifier.')
-                raise forms.ValidationError(error_message)
-            else:
-                error_message = ('There exists a preprint with this arXiv identifier '
-                                 'but an earlier version number, which is still undergoing '
-                                 'peer refereeing. '
-                                 'A resubmission can only be performed after request '
-                                 'from the Editor-in-charge. Please wait until the '
-                                 'closing of the previous refereeing round and '
-                                 'formulation of the Editorial Recommendation '
-                                 'before proceeding with a resubmission.')
-                raise forms.ValidationError(error_message)
+    def identifier_matches_regex(self, journal_code):
+        """
+        Check if identifier is valid for the Journal submitting to.
+        """
+        if self.preprint_server != 'arxiv':
+            # Only check arXiv identifiers
+            return
 
-    def identifier_matches_regex(self, identifier, journal_code):
-        """Check if arXiv identifier is valid for the Journal submitting to."""
         if journal_code in EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS.keys():
             regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS[journal_code]
         else:
             regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS['default']
 
         pattern = re.compile(regex)
-        if not pattern.match(identifier):
+        if not pattern.match(self.identifier):
             # No match object returned, identifier is invalid
             error_message = ('The journal you want to submit to does not allow for this'
-                             ' arXiv identifier. Please contact SciPost if you have'
+                             ' identifier. Please contact SciPost if you have'
                              ' any further questions.')
             raise forms.ValidationError(error_message, code='submitted_to')
 
-    def submission_is_resubmission(self):
-        """Check if the Submission is a resubmission."""
-        return self.is_resubmission
+    def process_resubmission_procedure(self, submission):
+        """
+        Update all fields for new and old Submission and EditorialAssignments to comply with
+        the resubmission procedures.
 
-    def identifier_into_parts(self, identifier):
-        """Split the preprint identifier into parts."""
-        data = {
-            'identifier_w_vn_nr': identifier,
-            'identifier_wo_vn_nr': identifier.rpartition('v')[0],
-            'vn_nr': int(identifier.rpartition('v')[2])
-        }
-        return data
+        -- submission: the new version of the Submission series.
+        """
+        if not self.latest_submission:
+            raise Submission.DoesNotExist
 
-    def do_pre_checks(self, identifier):
-        """Group call of different checks."""
-        self._submission_already_exists(identifier)
-        if self.use_arxiv_preprint:
-            self._call_arxiv(identifier)
-        self._submission_is_already_published(identifier)
-        self._submission_previous_version_is_valid_for_submission(identifier)
+        # Close last submission
+        Submission.objects.filter(id=self.latest_submission.id).update(
+            is_current=False, open_for_reporting=False, status=STATUS_RESUBMITTED)
 
+        # Copy Topics
+        submission.topics.add(*self.latest_submission.topics.all())
 
-class SubmissionIdentifierForm(SubmissionChecks, forms.Form):
-    """Prefill SubmissionForm using this form that takes an arXiv ID only."""
+        # Open for comment and reporting and copy EIC info
+        Submission.objects.filter(id=submission.id).update(
+            open_for_reporting=True,
+            open_for_commenting=True,
+            is_resubmission_of=self.latest_submission,
+            visible_pool=True,
+            refereeing_cycle=CYCLE_UNDETERMINED,
+            editor_in_charge=self.latest_submission.editor_in_charge,
+            status=STATUS_EIC_ASSIGNED,
+            thread_hash=self.latest_submission.thread_hash)
 
-    IDENTIFIER_PLACEHOLDER = 'new style (with version nr) ####.####(#)v#(#)'
+        # Add author(s) (claim) fields
+        submission.authors.add(*self.latest_submission.authors.all())
+        submission.authors_claims.add(*self.latest_submission.authors_claims.all())
+        submission.authors_false_claims.add(*self.latest_submission.authors_false_claims.all())
 
-    identifier_w_vn_nr = forms.RegexField(
-        regex=IDENTIFIER_PATTERN_NEW, strip=True,
-        error_messages={'invalid': strings.arxiv_query_invalid},
-        widget=forms.TextInput({'placeholder': IDENTIFIER_PLACEHOLDER}))
+        # Create new EditorialAssigment for the current Editor-in-Charge
+        EditorialAssignment.objects.create(
+            submission=submission,
+            to=self.latest_submission.editor_in_charge,
+            status=STATUS_ACCEPTED)
 
-    def clean_identifier_w_vn_nr(self):
-        """Do basic prechecks based on the arXiv ID only."""
-        identifier = self.cleaned_data['identifier_w_vn_nr']
-        self.do_pre_checks(identifier)
-        return identifier
+    def _submission_already_exists(self):
+        """
+        Check if preprint has already been submitted before.
+        """
+        if Submission.objects.filter(preprint__identifier_w_vn_nr=self.identifier).exists():
+            error_message = 'This preprint version has already been submitted to SciPost.'
+            raise forms.ValidationError(error_message, code='duplicate')
 
-    def _gather_data_from_last_submission(self):
-        """Return dictionary with data coming from previous submission version."""
-        if self.submission_is_resubmission():
-            data = {
-                'is_resubmission': True,
-                'discipline': self.last_submission.discipline,
-                'domain': self.last_submission.domain,
-                'referees_flagged': self.last_submission.referees_flagged,
-                'referees_suggested': self.last_submission.referees_suggested,
-                'secondary_areas': self.last_submission.secondary_areas,
-                'subject_area': self.last_submission.subject_area,
-                'submitted_to': self.last_submission.submitted_to,
-                'submission_type': self.last_submission.submission_type,
-            }
-        return data or {}
+    def _submission_previous_version_is_valid_for_submission(self):
+        """
+        Check if previous submitted versions have the appropriate status.
+        """
 
-    def request_arxiv_preprint_form_prefill_data(self):
-        """Return dictionary to prefill `RequestSubmissionForm`."""
-        form_data = self.arxiv_data
-        form_data['identifier_w_vn_nr'] = self.cleaned_data['identifier_w_vn_nr']
-        if self.submission_is_resubmission():
-            form_data.update(self._gather_data_from_last_submission())
-        return form_data
+        if self.latest_submission:
+            if self.latest_submission.status == STATUS_REJECTED:
+                # Explicitly give rejected status warning.
+                error_message = ('This preprint has previously undergone refereeing '
+                                 'and has been rejected. Resubmission is only possible '
+                                 'if the manuscript has been substantially reworked into '
+                                 'a new submission with distinct identifier.')
+                raise forms.ValidationError(error_message)
+            elif self.latest_submission.open_for_resubmission:
+                # Check if verified author list contains current user.
+                if self.requested_by.contributor not in self.latest_submission.authors.all():
+                    error_message = ('There exists a preprint with this identifier '
+                                     'but an earlier version number. Resubmission is only possible'
+                                     ' if you are a registered author of this manuscript.')
+                    raise forms.ValidationError(error_message)
+            else:
+                # Submission has not an appropriate status for resubmission.
+                error_message = ('There exists a preprint with this identifier '
+                                 'but an earlier version number, which is still undergoing '
+                                 'peer refereeing. '
+                                 'A resubmission can only be performed after request '
+                                 'from the Editor-in-charge. Please wait until the '
+                                 'closing of the previous refereeing round and '
+                                 'formulation of the Editorial Recommendation '
+                                 'before proceeding with a resubmission.')
+                raise forms.ValidationError(error_message)
 
+    def _submission_is_already_published(self):
+        """
+        Check if preprint number is already registered with a DOI in the *ArXiv* database.
+        """
+        published_id = None
+        if 'arxiv_doi' in self.arxiv_data:
+            published_id = self.arxiv_data['arxiv_doi']
+        elif 'arxiv_journal_ref' in self.arxiv_data:
+            published_id = self.arxiv_data['arxiv_journal_ref']
+
+        if published_id:
+            error_message = ('This paper has been published under DOI %(published_id)s'
+                             '. Please comment on the published version.'),
+            raise forms.ValidationError(error_message, code='published',
+                                        params={'published_id': published_id})
 
-class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
-    """Form to submit a new Submission."""
 
-    scipost_identifier = None
+class SubmissionForm(forms.ModelForm):
+    """
+    Form to submit a new (re)Submission.
+    """
 
     identifier_w_vn_nr = forms.CharField(widget=forms.HiddenInput())
-    arxiv_link = forms.URLField(
-        widget=forms.TextInput(attrs={'placeholder': 'ex.:  arxiv.org/abs/1234.56789v1'}))
     preprint_file = forms.FileField()
 
     class Meta:
         model = Submission
         fields = [
-            'is_resubmission',
+            'is_resubmission_of',
             'discipline',
             'submitted_to',
             'proceedings',
@@ -283,43 +340,72 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
             'list_of_changes',
             'remarks_for_editors',
             'referees_suggested',
-            'referees_flagged'
+            'referees_flagged',
+            'arxiv_link',
         ]
         widgets = {
-            'is_resubmission': forms.HiddenInput(),
+            'is_resubmission_of': forms.HiddenInput(),
             'secondary_areas': forms.SelectMultiple(choices=SCIPOST_SUBJECT_AREAS),
-            'remarks_for_editors': forms.TextInput(
-                attrs={'placeholder': 'Any private remarks (for the editors only)', 'rows': 3}),
-            'referees_suggested': forms.TextInput(
-                attrs={'placeholder': 'Optional: names of suggested referees', 'rows': 3}),
-            'referees_flagged': forms.TextInput(
-                attrs={'placeholder': 'Optional: names of referees whose reports should be treated with caution (+ short reason)', 'rows': 3}),
+            'arxiv_link': forms.TextInput(
+                attrs={'placeholder': 'ex.:  arxiv.org/abs/1234.56789v1'}),
+            'remarks_for_editors': forms.Textarea(
+                attrs={'placeholder': 'Any private remarks (for the editors only)', 'rows': 5}),
+            'referees_suggested': forms.Textarea(
+                attrs={'placeholder': 'Optional: names of suggested referees', 'rows': 5}),
+            'referees_flagged': forms.Textarea(
+                attrs={
+                    'placeholder': 'Optional: names of referees whose reports should be treated with caution (+ short reason)',
+                    'rows': 5
+                }),
+            'author_comments': forms.Textarea(
+                attrs={'placeholder': 'Your resubmission letter (will be viewable online)'}),
+            'list_of_changes': forms.Textarea(
+                attrs={'placeholder': 'Give a point-by-point list of changes (will be viewable online)'}),
         }
 
     def __init__(self, *args, **kwargs):
-        self.use_arxiv_preprint = kwargs.pop('use_arxiv_preprint', True)
+        self.requested_by = kwargs.pop('requested_by')
+        self.preprint_server = kwargs.pop('preprint_server', 'arxiv')
+        self.resubmission_preprint = kwargs['initial'].get('resubmission', False)
+
+        data = args[0] if len(args) > 1 else kwargs.get('data', {})
+        identifier = kwargs['initial'].get('identifier_w_vn_nr', None) or data.get('identifier_w_vn_nr')
+
+        self.service = SubmissionService(
+            self.requested_by, self.preprint_server,
+            identifier=identifier,
+            resubmission_of_id=self.resubmission_preprint)
+        if self.preprint_server == 'scipost':
+            kwargs['initial'] = self.service.get_latest_submission_data()
 
         super().__init__(*args, **kwargs)
 
-        # Alter resubmission-dependent fields
-        if not self.submission_is_resubmission():
-            # These fields are only available for resubmissions
+        if not self.preprint_server == 'arxiv':
+            # No arXiv-specific data required.
+            del self.fields['identifier_w_vn_nr']
+            del self.fields['arxiv_link']
+        elif not self.preprint_server == 'scipost':
+            # No need for a file upload if user is not using the SciPost preprint server.
+            del self.fields['preprint_file']
+
+        # Find all submission allowed to be resubmitted by current user.
+        self.fields['is_resubmission_of'].queryset = Submission.objects.candidate_for_resubmission(
+            self.requested_by)
+
+        # Fill resubmission-dependent fields
+        if self.is_resubmission():
+            self.fields['is_resubmission_of'].initial = self.service.latest_submission
+        else:
+            # These fields are only available for resubmissions.
             del self.fields['author_comments']
             del self.fields['list_of_changes']
-        else:
-            self.fields['author_comments'].widget.attrs.update({
-                'placeholder': 'Your resubmission letter (will be viewable online)', })
-            self.fields['list_of_changes'].widget.attrs.update({
-                'placeholder': 'Give a point-by-point list of changes (will be viewable online)'})
 
-        # ArXiv or SciPost preprint fields
-        if self.use_arxiv_preprint:
-            del self.fields['preprint_file']
-        else:
-            del self.fields['arxiv_link']
-            del self.fields['identifier_w_vn_nr']
+        if not self.fields['is_resubmission_of'].initial:
+            # No intial nor submitted data found.
+            del self.fields['is_resubmission_of']
 
-        self.fields['submitted_to'].queryset = Journal.objects.filter(active=True)
+        # Select Journal instances.
+        self.fields['submitted_to'].queryset = Journal.objects.active()
         self.fields['submitted_to'].label = 'Journal: submit to'
 
         # Proceedings submission fields
@@ -332,20 +418,27 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
                 doi_label=SCIPOST_JOURNAL_PHYSICS_PROC)
             del self.fields['proceedings']
 
-        # Submission type is optional
-        self.fields['submission_type'].required = False
+    def is_resubmission(self):
+        return self.service.is_resubmission()
 
     def clean(self, *args, **kwargs):
-        """Do all prechecks which are also done in the prefiller."""
+        """
+        Do all general checks for Submission.
+        """
         cleaned_data = super().clean(*args, **kwargs)
+
+        # SciPost preprints are auto-generated here.
+        self.scipost_identifier = None
         if 'identifier_w_vn_nr' not in cleaned_data:
-            # New series of SciPost preprints
-            identifier_str, self.scipost_identifier = generate_new_scipost_identifier()
-            cleaned_data['identifier_w_vn_nr'] = format_scipost_identifier(identifier_str)
+            self.service.identifier, self.scipost_identifier = generate_new_scipost_identifier(
+                cleaned_data.get('is_resubmission_of', None))
+            # Also copy to the form data
+            self.cleaned_data['identifier_w_vn_nr'] = self.service.identifier
 
-        self.do_pre_checks(cleaned_data['identifier_w_vn_nr'])
-        self.identifier_matches_regex(
-            cleaned_data['identifier_w_vn_nr'], cleaned_data['submitted_to'].doi_label)
+        # Run checks again to clean any possible human intervention and run checks again
+        # with possibly newly generated identifier.
+        self.service.run_checks()
+        self.service.identifier_matches_regex(cleaned_data['submitted_to'].doi_label)
 
         if self.cleaned_data['submitted_to'].doi_label != SCIPOST_JOURNAL_PHYSICS_PROC:
             try:
@@ -353,31 +446,22 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
             except KeyError:
                 # No proceedings returned to data
                 return cleaned_data
-
         return cleaned_data
 
     def clean_author_list(self):
-        """Check if author list matches the Contributor submitting.
-
-        The submitting user must be an author of the submission.
-        Also possibly may be extended to check permissions and give ultimate submission
-        power to certain user groups.
+        """
+        Check if author list matches the Contributor submitting.
         """
         author_list = self.cleaned_data['author_list']
-        if not self.use_arxiv_preprint:
-            # Using SciPost preprints, there is nothing to check with.
-            return author_list
-
         if not self.requested_by.last_name.lower() in author_list.lower():
             error_message = ('Your name does not match that of any of the authors. '
                              'You are not authorized to submit this preprint.')
-            raise forms.ValidationError(error_message, code='not_an_author')
+            self.add_error('author_list', error_message)
         return author_list
 
     def clean_submission_type(self):
-        """Validate Submission type.
-
-        The SciPost Physics journal requires a Submission type to be specified.
+        """
+        Validate Submission type for the SciPost Physics journal.
         """
         submission_type = self.cleaned_data['submission_type']
         journal_doi_label = self.cleaned_data['submitted_to'].doi_label
@@ -385,39 +469,10 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
             self.add_error('submission_type', 'Please specify the submission type.')
         return submission_type
 
-    @transaction.atomic
-    def copy_and_save_data_from_resubmission(self, submission):
-        """Fill given Submission with data coming from last_submission."""
-        if not self.last_submission:
-            raise Submission.DoesNotExist
-
-        # Close last submission
-        Submission.objects.filter(id=self.last_submission.id).update(
-            is_current=False, open_for_reporting=False, status=STATUS_RESUBMITTED)
-
-        # Copy Topics
-        submission.topics.add(*self.last_submission.topics.all())
-
-        # Open for comment and reporting and copy EIC info
-        Submission.objects.filter(id=submission.id).update(
-            open_for_reporting=True,
-            open_for_commenting=True,
-            is_resubmission=True,
-            visible_pool=True,
-            editor_in_charge=self.last_submission.editor_in_charge,
-            status=STATUS_EIC_ASSIGNED)
-
-        # Add author(s) (claim) fields
-        submission.authors.add(*self.last_submission.authors.all())
-        submission.authors_claims.add(*self.last_submission.authors_claims.all())
-        submission.authors_false_claims.add(*self.last_submission.authors_false_claims.all())
-
-        # Create new EditorialAssigment for the current Editor-in-Charge
-        EditorialAssignment.objects.create(
-            submission=submission, to=self.last_submission.editor_in_charge, status=STATUS_ACCEPTED)
-
     def set_pool(self, submission):
-        """Set the default set of (guest) Fellows for this Submission."""
+        """
+        Set the default set of (guest) Fellows for this Submission.
+        """
         qs = Fellowship.objects.active()
         fellows = qs.regular().filter(
             contributor__discipline=submission.discipline).return_active_for_submission(submission)
@@ -431,46 +486,85 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
 
     @transaction.atomic
     def save(self):
-        """Fill, create and transfer data to the new Submission.
-
-        Prefill instance before save.
-        Because of the ManyToManyField on `authors`, commit=False for this form
-        is disabled. Saving the form without the database call may loose `authors`
-        data without notice.
+        """
+        Create the new Submission and Preprint instances.
         """
         submission = super().save(commit=False)
         submission.submitted_by = self.requested_by.contributor
 
         # Save identifiers
-        identifiers = self.identifier_into_parts(self.cleaned_data['identifier_w_vn_nr'])
+        identifiers = self.cleaned_data['identifier_w_vn_nr'].rpartition('v')
         preprint, __ = Preprint.objects.get_or_create(
-            identifier_w_vn_nr=identifiers['identifier_w_vn_nr'],
-            identifier_wo_vn_nr=identifiers['identifier_wo_vn_nr'],
-            vn_nr=identifiers['vn_nr'],
+            identifier_w_vn_nr=self.cleaned_data['identifier_w_vn_nr'],
+            identifier_wo_vn_nr=identifiers[0],
+            vn_nr=identifiers[2],
             url=self.cleaned_data.get('arxiv_link', ''),
             scipost_preprint_identifier=self.scipost_identifier,
             _file=self.cleaned_data.get('preprint_file', None), )
 
         # Save metadata directly from ArXiv call without possible user interception
-        submission.metadata = self.metadata if hasattr(self, 'metadata') else {}
+        submission.metadata = self.service.metadata
         submission.preprint = preprint
 
-        if self.submission_is_resubmission():
-            # Reset Refereeing Cycle. EIC needs to pick a cycle on resubmission.
-            submission.refereeing_cycle = CYCLE_UNDETERMINED
-            submission.save()  # Save before filling from old Submission.
-
-            self.copy_and_save_data_from_resubmission(submission)
-        else:
-            # Save!
-            submission.save()
+        submission.save()
+        if self.is_resubmission():
+            self.service.process_resubmission_procedure(submission)
 
         # Gather first known author and Fellows.
         submission.authors.add(self.requested_by.contributor)
         self.set_pool(submission)
 
         # Return latest version of the Submission. It could be outdated by now.
-        return Submission.objects.get(id=submission.id)
+        submission.refresh_from_db()
+        return submission
+
+
+class SubmissionIdentifierForm(forms.Form):
+    """
+    Prefill SubmissionForm using this form that takes an arXiv ID only.
+    """
+
+    IDENTIFIER_PLACEHOLDER = 'new style (with version nr) ####.####(#)v#(#)'
+
+    identifier_w_vn_nr = forms.RegexField(
+        label='arXiv identifier with version number',
+        regex=IDENTIFIER_PATTERN_NEW, strip=True,
+        error_messages={'invalid': strings.arxiv_query_invalid},
+        widget=forms.TextInput({'placeholder': IDENTIFIER_PLACEHOLDER}))
+
+    def __init__(self, *args, **kwargs):
+        self.requested_by = kwargs.pop('requested_by')
+        return super().__init__(*args, **kwargs)
+
+
+    def clean_identifier_w_vn_nr(self):
+        """
+        Do basic prechecks based on the arXiv ID only.
+        """
+        identifier = self.cleaned_data.get('identifier_w_vn_nr', None)
+
+        self.service = SubmissionService(self.requested_by, 'arxiv', identifier=identifier)
+        self.service.run_checks()
+        return identifier
+
+    def get_initial_submission_data(self):
+        """
+        Return dictionary to prefill `SubmissionForm`.
+        """
+        form_data = self.service.arxiv_data
+        form_data['identifier_w_vn_nr'] = self.cleaned_data['identifier_w_vn_nr']
+        if self.service.is_resubmission():
+            form_data.update({
+                'discipline': self.service.latest_submission.discipline,
+                'domain': self.service.latest_submission.domain,
+                'referees_flagged': self.service.latest_submission.referees_flagged,
+                'referees_suggested': self.service.latest_submission.referees_suggested,
+                'secondary_areas': self.service.latest_submission.secondary_areas,
+                'subject_area': self.service.latest_submission.subject_area,
+                'submitted_to': self.service.latest_submission.submitted_to,
+                'submission_type': self.service.latest_submission.submission_type,
+            })
+        return form_data
 
 
 class SubmissionReportsForm(forms.ModelForm):
diff --git a/submissions/managers.py b/submissions/managers.py
index edb98934913597f183e1c515ae3d331bbcb0f8cf..dc73320955c2e4f1e1cc2c8578c6c7e0fd7f1a9a 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -17,6 +17,8 @@ now = timezone.now()
 class SubmissionQuerySet(models.QuerySet):
     def _newest_version_only(self, queryset):
         """
+        TODO: Make more efficient... with agregation or whatever.
+
         The current Queryset should return only the latest version
         of the Arxiv submissions known to SciPost.
 
@@ -157,7 +159,7 @@ class SubmissionQuerySet(models.QuerySet):
         (including subsequent resubmissions, even if those came in later).
         """
         identifiers = []
-        for sub in self.filter(is_resubmission=False,
+        for sub in self.filter(is_resubmission_of__isnull=True,
                                submission_date__range=(from_date, until_date)):
             identifiers.append(sub.preprint.identifier_wo_vn_nr)
         return self.filter(preprint__identifier_wo_vn_nr__in=identifiers)
@@ -209,6 +211,19 @@ class SubmissionQuerySet(models.QuerySet):
         """Return Submissions that have EditorialAssignments that still need to be sent."""
         return self.filter(editorial_assignments__status=constants.STATUS_PREASSIGNED)
 
+    def candidate_for_resubmission(self, user):
+        """
+        Return all Submissions that are open for resubmission specialised for a certain User.
+        """
+        if not hasattr(user, 'contributor'):
+            return self.none()
+
+        return self.filter(is_current=True, status__in=[
+            constants.STATUS_INCOMING,
+            constants.STATUS_UNASSIGNED,
+            constants.STATUS_EIC_ASSIGNED,
+            ], submitted_by=user.contributor)
+
 
 class SubmissionEventQuerySet(models.QuerySet):
     def for_author(self):
diff --git a/submissions/migrations/0045_submission_is_resubmission_of.py b/submissions/migrations/0045_submission_is_resubmission_of.py
new file mode 100644
index 0000000000000000000000000000000000000000..a0ea4d2ebea14f5bcd7a740717c053fc4624bb36
--- /dev/null
+++ b/submissions/migrations/0045_submission_is_resubmission_of.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-11-30 09:13
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0044_auto_20181115_1009'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='submission',
+            name='is_resubmission_of',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='successor', to='submissions.Submission'),
+        ),
+    ]
diff --git a/submissions/migrations/0046_auto_20181130_1013.py b/submissions/migrations/0046_auto_20181130_1013.py
new file mode 100644
index 0000000000000000000000000000000000000000..41769a5dbba9f9eb31028ebaa50a8379bfe39623
--- /dev/null
+++ b/submissions/migrations/0046_auto_20181130_1013.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-11-30 09:13
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def populate_explicit_resubmission_links(apps, schema_editor):
+    Submission = apps.get_model('submissions', 'Submission')
+
+    for resubmission in Submission.objects.filter(preprint__vn_nr__gt=1):
+        resub_of = Submission.objects.filter(
+            preprint__identifier_wo_vn_nr=resubmission.preprint.identifier_wo_vn_nr).order_by(
+            '-preprint__vn_nr').exclude(id=resubmission.id).first()
+        Submission.objects.filter(id=resubmission.id).update(is_resubmission_of=resub_of)
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0045_submission_is_resubmission_of'),
+    ]
+
+    operations = [
+        migrations.RunPython(populate_explicit_resubmission_links, reverse_code=migrations.RunPython.noop),
+    ]
diff --git a/submissions/migrations/0047_auto_20181204_2011.py b/submissions/migrations/0047_auto_20181204_2011.py
new file mode 100644
index 0000000000000000000000000000000000000000..15fe0d2cb0de419eb07beb1d6f8954efdf8a3bfc
--- /dev/null
+++ b/submissions/migrations/0047_auto_20181204_2011.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0046_auto_20181130_1013'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='submission',
+            old_name='is_resubmission',
+            new_name='_is_resubmission',
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='submission_type',
+            field=models.CharField(blank=True, choices=[('Letter', 'Letter (broad-interest breakthrough results)'), ('Article', 'Article (in-depth reports on specialized research)'), ('Review', 'Review (candid snapshot of current research in a given area)')], max_length=10),
+        ),
+    ]
diff --git a/submissions/migrations/0048_submission_thread_hash.py b/submissions/migrations/0048_submission_thread_hash.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddf50c99d378afb379eedca6278da7bf875a29b6
--- /dev/null
+++ b/submissions/migrations/0048_submission_thread_hash.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:37
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_auto_20181204_2011'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='submission',
+            name='thread_hash',
+            field=models.UUIDField(default=uuid.uuid4),
+        ),
+    ]
diff --git a/submissions/migrations/0049_auto_20181204_2040.py b/submissions/migrations/0049_auto_20181204_2040.py
new file mode 100644
index 0000000000000000000000000000000000000000..bbcd903d8ecd1538e68965795fcfce6a74be4305
--- /dev/null
+++ b/submissions/migrations/0049_auto_20181204_2040.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:40
+from __future__ import unicode_literals
+
+import uuid
+
+from django.db import migrations
+
+
+def get_thread_ids(parent, submissions_list=[]):
+    successor = parent.successor.first()
+    if not successor:
+        return submissions_list
+
+    submissions_list.append(successor.id)
+    return get_thread_ids(successor, submissions_list)
+
+
+def populate_thread_hashes(apps, schema_editor):
+    Submission = apps.get_model('submissions', 'Submission')
+
+    for original_submission in Submission.objects.filter(is_resubmission_of__isnull=True):
+        children_ids = get_thread_ids(original_submission, [original_submission.id])
+        Submission.objects.filter(id__in=children_ids).update(thread_hash=uuid.uuid4())
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0048_submission_thread_hash'),
+    ]
+
+    operations = [
+        migrations.RunPython(populate_thread_hashes, reverse_code=migrations.RunPython.noop),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 58acca54932f2fceb81313a167eb661b54918470..f7348cfb610ade1639421d2518b357eb5885d74e 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -4,6 +4,7 @@ __license__ = "AGPL v3"
 
 import datetime
 import feedparser
+import uuid
 
 from django.contrib.postgres.fields import JSONField
 from django.contrib.contenttypes.fields import GenericRelation
@@ -75,7 +76,10 @@ class Submission(models.Model):
     is_current = models.BooleanField(default=True)
     visible_public = models.BooleanField("Is publicly visible", default=False)
     visible_pool = models.BooleanField("Is visible in the Pool", default=False)
-    is_resubmission = models.BooleanField(default=False)
+    is_resubmission_of = models.ForeignKey(
+        'self', blank=True, null=True, related_name='successor')
+    thread_hash = models.UUIDField(default=uuid.uuid4)
+    _is_resubmission = models.BooleanField(default=False)
     refereeing_cycle = models.CharField(
         max_length=30, choices=SUBMISSION_CYCLES, default=CYCLE_DEFAULT, blank=True)
 
@@ -84,7 +88,7 @@ class Submission(models.Model):
 
     subject_area = models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS,
                                     verbose_name='Primary subject area', default='Phys:QP')
-    submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE)
+    submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE, blank=True)
     submitted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
                                      related_name='submitted_submissions')
     voting_fellows = models.ManyToManyField('colleges.Fellowship', blank=True,
@@ -194,6 +198,10 @@ class Submission(models.Model):
         """Return url of the Submission detail page."""
         return reverse('submissions:submission', args=(self.preprint.identifier_w_vn_nr,))
 
+    @property
+    def is_resubmission(self):
+        return self.is_resubmission_of is not None
+
     @property
     def notification_name(self):
         """Return string representation of this Submission as shown in Notifications."""
@@ -230,13 +238,12 @@ class Submission(models.Model):
     def original_submission_date(self):
         """Return the submission_date of the first Submission in the thread."""
         return Submission.objects.filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).first().submission_date
+            thread_hash=self.thread_hash, is_resubmission_of__isnull=True).first().submission_date
 
     @property
     def thread(self):
         """Return all (public) Submissions in the database in this ArXiv identifier series."""
-        return Submission.objects.public().filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).order_by(
+        return Submission.objects.public().filter(thread_hash=self.thread_hash).order_by(
                 '-preprint__vn_nr')
 
     @cached_property
@@ -251,8 +258,7 @@ class Submission(models.Model):
 
     def get_other_versions(self):
         """Return queryset of other Submissions with this ArXiv identifier series."""
-        return Submission.objects.filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).exclude(pk=self.id)
+        return Submission.objects.filter(thread_hash=self.thread_hash).exclude(pk=self.id)
 
     def count_accepted_invitations(self):
         """Count number of accepted RefereeInvitations for this Submission."""
diff --git a/submissions/templates/submissions/submission_form.html b/submissions/templates/submissions/submission_form.html
index 1e314ea136b45e02b96556a9fe77cba68bee94b4..433ff7ed59cb0ccf78b218259a9b3eded44f7e89 100644
--- a/submissions/templates/submissions/submission_form.html
+++ b/submissions/templates/submissions/submission_form.html
@@ -48,6 +48,24 @@
         <p>
             Please prepare your manuscript according to the <a href="{% url 'submissions:author_guidelines' %}">author guidelines</a>.
         </p>
+
+
+        {% if form.is_resubmission %}
+            <hr>
+            <p class="mb-1">You are submitting a new version of your manuscript:</p>
+            <h3><a href="{{ form.fields.is_resubmission_of.initial.get_absolute_url }}" target="_blank">{{ form.fields.is_resubmission_of.initial.title }}</a></h3>
+            <p>
+                by {{ form.fields.is_resubmission_of.initial.author_list }}
+                <br>
+                Preprint number: {{ form.fields.is_resubmission_of.initial.preprint.identifier_w_vn_nr }}
+            </p>
+        {% endif %}
+
+        {% comment %}
+        {% if not form.form_complete %}
+            <h3 class="text-danger">Please check the preprint identifier used for resubmission. Current identifier {{ form.resubmission_preprint }} is not valid.</h3>
+        {% endif %}
+        {% endcomment %}
     </div>
 </div>
 
diff --git a/submissions/templates/submissions/submission_prefill_form.html b/submissions/templates/submissions/submission_prefill_form.html
index 0b9cdb911805cff65781fe9c9b3d0c56e5b3573d..9a4e96e80ede61ecd90371fcd627eed1037514da 100644
--- a/submissions/templates/submissions/submission_prefill_form.html
+++ b/submissions/templates/submissions/submission_prefill_form.html
@@ -35,7 +35,8 @@
             <div class='card-body'>
                 <h3>Please provide the arXiv identifier for your Submission</h3>
                 <p><em>(give the identifier without prefix but with version number, as per the placeholder)</em></p>
-                <form action="{% url 'submissions:submit_manuscript_arxiv' %}" method="get">
+                <form action="{% url 'submissions:prefill_using_identifier' %}" method="post">
+                  {% csrf_token %}
                   {{ form|bootstrap }}
                   <input type="submit" class="btn btn-outline-secondary" value="Query arXiv"/>
                       <br>
diff --git a/submissions/templates/submissions/submission_resubmission_candidates.html b/submissions/templates/submissions/submission_resubmission_candidates.html
new file mode 100644
index 0000000000000000000000000000000000000000..0a26172c5ff5943c7571244b373f03f51e7cd184
--- /dev/null
+++ b/submissions/templates/submissions/submission_resubmission_candidates.html
@@ -0,0 +1,39 @@
+{% extends 'scipost/base.html' %}
+
+{% load bootstrap %}
+
+{% block pagetitle %}: submit manuscript{% endblock pagetitle %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <form method="post">
+            {% csrf_token %}
+            <h1 class="highlight">Possible Resubmissions</h1>
+            <p>The system has found {{ submissions|length|pluralize:'a Submission,Submissions' }} for which you are a verified author. If you wish to submit a new version for {{ submissions|length|pluralize:'this Submission,one of these Submissions' }}, please use the "Resubmit this Submission" buttton below.</p>
+            <ul>
+                {% for submission in submissions %}
+                    <li class="py-2">
+                        <strong>{{ submission.title }}</strong>
+                        <br>
+                        {{ submission.author_list }}
+                        <br>
+                        Preprint number: {{ submission.preprint.identifier_w_vn_nr }}
+                        <br>
+                        {% if not submission.open_for_resubmission %}
+                            <strong class="text-danger">This submission is still undergoing peer refereeing. A resubmission can only be performed after request from the Editor-in-charge. Please wait until the closing of the previous refereeing round and formulation of the Editorial Recommendation before proceeding with a resubmission.</strong>
+                        {% else %}
+                            <button type="submit" name="submission" value="{{ submission.id }}"class="btn btn-primary py-1 mt-1">Resubmit this Submission</button>
+                        {% endif %}
+                    </li>
+                {% endfor %}
+            </ul>
+            <p>
+                If you wish to submit a new Submission, please <button type="submit" name="submission" value="new" class="btn btn-primary py-1 mr-1">submit a new Submission here</button>.
+            </p>
+        </form>
+    </div>
+</div>
+
+{% endblock content %}
diff --git a/submissions/test_views.py b/submissions/test_views.py
index 6f4b9fbdf9d9cc43b6c27a32b4db70bb9efa1fad..c2bf1dba5b4cb2cc410c96699a10c3925e4a2f40 100644
--- a/submissions/test_views.py
+++ b/submissions/test_views.py
@@ -15,7 +15,7 @@ from .factories import UnassignedSubmissionFactory, EICassignedSubmissionFactory
                        ResubmittedSubmissionFactory, ResubmissionFactory,\
                        PublishedSubmissionFactory, DraftReportFactory,\
                        AcceptedRefereeInvitationFactory
-from .forms import RequestSubmissionForm, SubmissionIdentifierForm, ReportForm
+from .forms import SubmissionIdentifierForm, ReportForm. SubmissionForm
 from .models import Submission, Report, RefereeInvitation
 
 from journals.models import Journal
@@ -96,7 +96,7 @@ class PrefillUsingIdentifierTest(BaseContributorTestCase):
                                     {'identifier':
                                         TEST_SUBMISSION['identifier_w_vn_nr']})
         self.assertEqual(response.status_code, 200)
-        self.assertIsInstance(response.context['form'], RequestSubmissionForm)
+        # self.assertIsInstance(response.context['form'], SubmissionForm)
 
         # Explicitly compare fields instead of assertDictEqual as metadata field may be outdated
         # self.assertEqual(TEST_SUBMISSION['is_resubmission'],
@@ -189,7 +189,7 @@ class SubmitManuscriptTest(BaseContributorTestCase):
         # Submit new Submission form
         response = client.post(reverse('submissions:submit_manuscript'), params)
         self.assertEqual(response.status_code, 200)
-        self.assertIsInstance(response.context['form'], RequestSubmissionForm)
+        self.assertIsInstance(response.context['form'], SubmissionForm)
         self.assertFalse(response.context['form'].is_valid())
         self.assertIn('author_list', response.context['form'].errors.keys())
 
diff --git a/submissions/urls.py b/submissions/urls.py
index 9b2f9985cbf8c22e4f8c9bd2600efb1c94925991..5591c3ff0cb1661be5172ecc0563d6057c21da2e 100644
--- a/submissions/urls.py
+++ b/submissions/urls.py
@@ -68,6 +68,7 @@ urlpatterns = [
     url(r'^admin/reports/(?P<report_id>[0-9]+)/compile$',
         views.report_pdf_compile, name='report_pdf_compile'),
 
+    url(r'^resubmit_manuscript$', views.resubmit_manuscript, name='resubmit_manuscript'),
     url(r'^submit_manuscript$', views.prefill_using_arxiv_identifier, name='submit_manuscript'),
     url(r'^submit_manuscript/scipost$',
         views.RequestSubmissionUsingSciPostView.as_view(), name='submit_manuscript_scipost'),
diff --git a/submissions/views.py b/submissions/views.py
index 51e476f0b54edde37a25674c51d4bf5ec3d77366..3ae50a5702a8882bbcf74922559395f21f415c3a 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -1,10 +1,8 @@
 __copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
-
 import datetime
 import feedparser
-import json
 import strings
 
 from django.contrib import messages
@@ -32,7 +30,7 @@ from .models import (
     Submission, EICRecommendation, EditorialAssignment, RefereeInvitation, Report, SubmissionEvent)
 from .mixins import SubmissionAdminViewMixin
 from .forms import (
-    SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSearchForm, RecommendationVoteForm,
+    SubmissionIdentifierForm, SubmissionForm, SubmissionSearchForm, RecommendationVoteForm,
     ConsiderAssignmentForm, InviteEditorialAssignmentForm, EditorialAssignmentForm, VetReportForm,
     SetRefereeingDeadlineForm, RefereeSearchForm, #RefereeSelectForm,
     iThenticateReportForm, VotingEligibilityForm,
@@ -57,24 +55,56 @@ from production.forms import ProofsDecisionForm
 from profiles.models import Profile
 from profiles.forms import SimpleProfileForm, ProfileEmailForm
 from scipost.constants import INVITATION_REFEREEING
+from scipost.decorators import is_contributor_user
 from scipost.forms import RemarkForm
 from scipost.mixins import PaginationMixin
 from scipost.models import Contributor, Remark
-from submissions.models import RefereeInvitation
-
-# from notifications.views import is_test_user  # Temporarily until release
 
 
 ###############
 # SUBMISSIONS:
 ###############
+@login_required
+@is_contributor_user()
+def resubmit_manuscript(request):
+    """
+    Choose which Submission to resubmit if Submission is available.
+
+    On POST, redirect to submit page.
+    """
+    submissions = get_list_or_404(
+        Submission.objects.candidate_for_resubmission(request.user))
+    if request.POST and request.POST.get('submission'):
+        if request.POST['submission'] == 'new':
+            return redirect(reverse('submissions:submit_manuscript_scipost') + '?resubmission=false')
+
+        last_submission = Submission.objects.candidate_for_resubmission(request.user).filter(
+            id=request.POST['submission']).first()
+
+        if last_submission:
+            if last_submission.preprint.scipost_preprint_identifier:
+                # Determine right preprint-view.
+                extra_param = '?resubmission={}'.format(request.POST['submission'])
+                return redirect(reverse('submissions:submit_manuscript_scipost') + extra_param)
+            else:
+                extra_param = '?identifier_w_vn_nr={}'.format(
+                    last_submission.preprint.identifier_w_vn_nr)
+                return redirect(reverse('submissions:submit_manuscript') + extra_param)
+        else:
+            # POST request invalid. Try again with GET request.
+            return redirect('submissions:resubmit_manuscript')
+    context = {
+        'submissions': submissions,
+    }
+    return render(request, 'submissions/submission_resubmission_candidates.html', context)
+
 
 class RequestSubmissionView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
     """Formview to submit a new manuscript (Submission)."""
 
     permission_required = 'scipost.can_submit_manuscript'
     success_url = reverse_lazy('scipost:personal_page')
-    form_class = RequestSubmissionForm
+    form_class = SubmissionForm
     template_name = 'submissions/submission_form.html'
 
     def get_context_data(self, *args, **kwargs):
@@ -87,8 +117,8 @@ class RequestSubmissionView(LoginRequiredMixin, PermissionRequiredMixin, CreateV
         """Form requires extra kwargs."""
         kwargs = super().get_form_kwargs()
         kwargs['requested_by'] = self.request.user
-        if hasattr(self, 'initial_data'):
-            kwargs['initial'] = self.initial_data
+        kwargs['initial'] = getattr(self, 'initial_data', {})
+        kwargs['initial']['resubmission'] = self.request.GET.get('resubmission')
         return kwargs
 
     @transaction.atomic
@@ -102,7 +132,7 @@ class RequestSubmissionView(LoginRequiredMixin, PermissionRequiredMixin, CreateV
                 'Your Submission will soon be handled by an Editor.')
         messages.success(self.request, text)
 
-        if form.submission_is_resubmission():
+        if form.is_resubmission():
             # Send emails
             SubmissionUtils.load({'submission': submission}, self.request)
             SubmissionUtils.send_authors_resubmission_ack_email()
@@ -124,35 +154,41 @@ class RequestSubmissionUsingArXivView(RequestSubmissionView):
     """Formview to submit a new Submission using arXiv."""
 
     def get(self, request):
-        """Redirect to the arXiv prefill form if arXiv ID is not known."""
+        """
+        Redirect to the arXiv prefill form if arXiv ID is not known.
+        """
         form = SubmissionIdentifierForm(request.GET or None, requested_by=self.request.user)
         if form.is_valid():
             # Gather data from ArXiv API if prefill form is valid
-            self.initial_data = form.request_arxiv_preprint_form_prefill_data()
+            self.initial_data = form.get_initial_submission_data()
             return super().get(request)
         else:
+            for code, err in form.errors.items():
+                messages.warning(request, err[0])
             return redirect('submissions:prefill_using_identifier')
 
     def get_form_kwargs(self):
         """Form requires extra kwargs."""
         kwargs = super().get_form_kwargs()
-        kwargs['use_arxiv_preprint'] = True
+        kwargs['preprint_server'] = 'arxiv'
         return kwargs
 
 
 class RequestSubmissionUsingSciPostView(RequestSubmissionView):
     """Formview to submit a new Submission using SciPost's preprint server."""
 
-    def dispatch(self, request, *args, **kwargs):
-        """TEMPORARY: Not accessible unless in test group."""
-        # if not is_test_user(request.user):
-        #     raise Http404
-        return super().dispatch(request, *args, **kwargs)
+    def get(self, request):
+        """Check for possible Resubmissions before dispatching."""
+        if Submission.objects.candidate_for_resubmission(request.user).exists():
+            if not request.GET.get('resubmission'):
+                return redirect('submissions:resubmit_manuscript')
+        return super().get(request)
 
     def get_form_kwargs(self):
         """Form requires extra kwargs."""
         kwargs = super().get_form_kwargs()
-        kwargs['use_arxiv_preprint'] = False
+        # kwargs['use_arxiv_preprint'] = False
+        kwargs['preprint_server'] = 'scipost'
         return kwargs
 
 
@@ -162,13 +198,10 @@ def prefill_using_arxiv_identifier(request):
     """Form view asking for the arXiv ID related to the new Submission to submit."""
     query_form = SubmissionIdentifierForm(request.POST or None, initial=request.GET or None,
                                           requested_by=request.user)
-    if query_form.is_valid():
-        prefill_data = query_form.request_arxiv_preprint_form_prefill_data()
-        form = RequestSubmissionForm(
-            initial=prefill_data, requested_by=request.user, use_arxiv_preprint=True)
 
+    if query_form.is_valid():
         # Submit message to user
-        if query_form.submission_is_resubmission():
+        if query_form.service.is_resubmission():
             resubmessage = ('There already exists a preprint with this arXiv identifier '
                             'but a different version number. \nYour Submission will be '
                             'handled as a resubmission.')
@@ -176,14 +209,10 @@ def prefill_using_arxiv_identifier(request):
         else:
             messages.success(request, strings.acknowledge_arxiv_query, fail_silently=True)
 
-        context = {
-            'form': form,
-        }
         response = redirect('submissions:submit_manuscript_arxiv')
         response['location'] += '?identifier_w_vn_nr={}'.format(
             query_form.cleaned_data['identifier_w_vn_nr'])
-        # return render(request, 'submissions/submission_form.html', context)
-        return reponse
+        return response
 
     context = {
         'form': query_form,