diff --git a/submissions/forms.py b/submissions/forms.py
index 210a0adcb339cca19e8a4aa0c37eeab21a3c6d89..e299e58cd601c661b44c9bcd3adb8148729ed554 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -1,4 +1,5 @@
 from django import forms
+from django.core.validators import RegexValidator
 #from django.contrib.auth.models import User, Group
 
 from .models import *
@@ -20,10 +21,22 @@ class SubmissionSearchForm(forms.Form):
 ###############################
 
 class SubmissionIdentifierForm(forms.Form):
-    identifier = forms.CharField(widget=forms.TextInput(
-        {'label': 'arXiv identifier',
-         'placeholder': 'new style (with version nr) ####.####(#)v#(#)',
-         'cols': 20}))
+    identifier = forms.CharField(
+        widget=forms.TextInput(
+            {'label': 'arXiv identifier',
+             'placeholder': 'new style (with version nr) ####.####(#)v#(#)',
+             'cols': 20}
+        ),
+        validators=[
+            RegexValidator(
+                regex="^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$",
+                message='The identifier you entered is improperly formatted '
+                        '(did you forget the version number?)',
+                code='invalid_identifier'
+            ),
+        ])
+
+
 
 class SubmissionForm(forms.ModelForm):
     class Meta:
diff --git a/submissions/models.py b/submissions/models.py
index ae7648b5b84926795a557f723aa99621ec117cf0..68a3d1e867b2720f97fd109dee8cd1d8a18d681a 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -57,18 +57,6 @@ SUBMISSION_STATUS_PUBLICLY_UNLISTED = [
     'withdrawn',
 ]
 
-# SUBMISSION_ACTION_REQUIRED = (
-#     ('assign_EIC', 'Editor-in-charge to be assigned'),
-# #    ('Fellow_accepts_or_refuse_assignment', 'Fellow must accept or refuse assignment'),
-#     ('EIC_runs_refereeing_round', 'Editor-in-charge to run refereeing round (inviting referees)'),
-#     ('EIC_closes_refereeing_round', 'Editor-in-charge to close refereeing round'),
-#     ('EIC_invites_author_response', 'Editor-in-charge invites authors to complete their replies'),
-#     ('EIC_formulates_editorial_recommendation',
-#      'Editor-in-charge to formulate editorial recommendation'),
-#     ('EC_ratification', 'Editorial College ratifies editorial recommendation'),
-#     ('Decision_to_authors', 'Editor-in-charge forwards decision to authors'),
-#     )
-
 SUBMISSION_TYPE = (
     ('Letter', 'Letter (broad-interest breakthrough results)'),
     ('Article', 'Article (in-depth reports on specialized research)'),
@@ -78,6 +66,7 @@ submission_type_dict = dict(SUBMISSION_TYPE)
 
 
 class Submission(models.Model):
+    # Main submission fields
     is_current = models.BooleanField(default=True)
     is_resubmission = models.BooleanField(default=False)
     submitted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
@@ -89,13 +78,12 @@ class Submission(models.Model):
                                        blank=True, null=True, default=None)
     discipline = models.CharField(max_length=20, choices=SCIPOST_DISCIPLINES, default='physics')
     domain = models.CharField(max_length=3, choices=SCIPOST_JOURNALS_DOMAINS)
-#    specialization = models.CharField(max_length=1, choices=SCIPOST_JOURNALS_SPECIALIZATIONS)
     subject_area = models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS,
                                     verbose_name='Primary subject area', default='Phys:QP')
     secondary_areas = ChoiceArrayField(
         models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS),
         blank=True, null=True)
-    status = models.CharField(max_length=30, choices=SUBMISSION_STATUS) # set by Editors
+    status = models.CharField(max_length=30, choices=SUBMISSION_STATUS)  # set by Editors
     author_comments = models.TextField(blank=True, null=True)
     list_of_changes = models.TextField(blank=True, null=True)
     remarks_for_editors = models.TextField(blank=True, null=True)
@@ -106,17 +94,22 @@ class Submission(models.Model):
     open_for_commenting = models.BooleanField(default=False)
     title = models.CharField(max_length=300)
     author_list = models.CharField(max_length=1000, verbose_name="author list")
+
     # Authors which have been mapped to contributors:
-    authors = models.ManyToManyField (Contributor, blank=True, related_name='authors_sub')
-    authors_claims = models.ManyToManyField (Contributor, blank=True,
-                                             related_name='authors_sub_claims')
-    authors_false_claims = models.ManyToManyField (Contributor, blank=True,
-                                                   related_name='authors_sub_false_claims')
+    authors = models.ManyToManyField(Contributor, blank=True, related_name='authors_sub')
+    authors_claims = models.ManyToManyField(Contributor, blank=True,
+                                            related_name='authors_sub_claims')
+    authors_false_claims = models.ManyToManyField(Contributor, blank=True,
+                                                  related_name='authors_sub_false_claims')
     abstract = models.TextField()
+
+    # Arxiv identifiers with/without version number
     arxiv_identifier_w_vn_nr = models.CharField(max_length=15, default='0000.00000v0')
     arxiv_identifier_wo_vn_nr = models.CharField(max_length=10, default='0000.00000')
     arxiv_vn_nr = models.PositiveSmallIntegerField(default=1)
     arxiv_link = models.URLField(verbose_name='arXiv link (including version nr)')
+
+    # Metadata
     metadata = JSONField(default={}, blank=True, null=True)
     submission_date = models.DateField(verbose_name='submission date')
     latest_activity = models.DateTimeField(default=timezone.now)
@@ -126,7 +119,7 @@ class Submission(models.Model):
             ('can_take_editorial_actions', 'Can take editorial actions'),
             )
 
-    def __str__ (self):
+    def __str__(self):
         header = (self.arxiv_identifier_w_vn_nr + ', '
                   + self.title[:30] + ' by ' + self.author_list[:30])
         if self.is_current:
diff --git a/submissions/services.py b/submissions/services.py
new file mode 100644
index 0000000000000000000000000000000000000000..bd16fb2ae70960507034ca3e46f8b6780a85fe87
--- /dev/null
+++ b/submissions/services.py
@@ -0,0 +1,86 @@
+# Module for making external api calls as needed in the submissions cycle
+import feedparser
+
+from .models import *
+
+
+class ArxivCaller():
+    def lookup_article(identifier):
+        # Pre-checks
+        if same_version_exists(identifier)
+            return False, "This preprint version has already been submitted to SciPost."
+
+        # Split the given identifier in an article identifier and version number
+        identifier_without_vn_nr = identifier.rpartition('v')[0]
+        arxiv_vn_nr = int(identifier.rpartition('v')[2])
+
+        resubmission = False
+        if previous_submission_undergoing_refereeing(identifier):
+            errormessage = '<p>There exists a preprint with this arXiv identifier '
+                            'but an earlier version number, which is still undergoing '
+                            'peer refereeing.</p>'
+                            '<p>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.</p>'
+            return False, errormessage
+
+        # Arxiv query
+        queryurl = ('http://export.arxiv.org/api/query?id_list=%s'
+                    % identifier)
+        arxiv_response = feedparser.parse(queryurl)
+
+        # Check if response has at least one entry
+        if not 'entries' in arxiv_response
+            errormessage = 'Bad response from Arxiv.'
+            return False, errormessage
+
+        # Check if preprint exists
+        if not preprint_exists(arxiv_response)
+            errormessage = 'A preprint associated to this identifier does not exist.'
+            return False, errormessage
+
+        # Check via journal ref if already published
+        arxiv_journal_ref = published_journal_ref
+        if arxiv_journal_ref
+            errormessage = 'This paper has been published as ' + arxiv_journal_ref +
+                            '. You cannot submit it to SciPost anymore.'
+            return False, resubmission
+
+        # Check via DOI if already published
+        arxiv_doi = published_journal_ref
+        if arxiv_doi
+            errormessage = 'This paper has been published under DOI ' + arxiv_doi
+                            + '. You cannot submit it to SciPost anymore.'
+            return False, errormessage
+
+        return arxiv_response, ""
+
+
+    def same_version_exists(identifier):
+        return Submission.objects.filter(arxiv_identifier_w_vn_nr=identifier).exists()
+
+    def previous_submission_undergoing_refereeing(identifier):
+        previous_submissions = Submission.objects.filter(
+            arxiv_identifier_wo_vn_nr=identifier).order_by('-arxiv_vn_nr')
+
+        if previous_submissions:
+            return not previous_submissions[0].status == 'revision_requested'
+        else:
+            return False
+
+    def preprint_exists(arxiv_response):
+        return 'title' in arxiv_response['entries'][0]
+
+    def published_journal_ref(arxiv_response):
+        if 'arxiv_journal_ref' in arxiv_response['entries'][0]
+            return arxiv_response['entries'][0]['arxiv_journal_ref']
+        else:
+            return False
+
+    def published_DOI(arxiv_response):
+        if 'arxiv_doi' in arxiv_response['entries'][0]
+            return arxiv_response['entries'][0]['arxiv_doi']
+        else:
+            return False
diff --git a/submissions/tests.py b/submissions/tests/test_models.py
similarity index 55%
rename from submissions/tests.py
rename to submissions/tests/test_models.py
index 7ce503c2dd97ba78597f6ff6e4393132753573f6..2e9cb5f6ba351402af656aec1be5d9ac257bc5c0 100644
--- a/submissions/tests.py
+++ b/submissions/tests/test_models.py
@@ -1,3 +1 @@
 from django.test import TestCase
-
-# Create your tests here.
diff --git a/submissions/tests/test_views.py b/submissions/tests/test_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..f35d237bde6def6e0755612febe441d1d10d6d63
--- /dev/null
+++ b/submissions/tests/test_views.py
@@ -0,0 +1,27 @@
+from django.test import TestCase
+from django.test import Client
+
+from submissions.views import *
+
+
+
+class PrefillUsingIdentifierTest(TestCase):
+    fixtures = ['permissions', 'groups', 'contributors']
+
+    def test_retrieving_existing_arxiv_paper(self):
+        client = Client()
+        client.login(username="Test", password="testpw")
+
+        response = client.post('/submissions/prefill_using_identifier',
+                               {'identifier': '1512.00030v1'})
+
+        self.assertEqual(response.status_code, 200)
+
+    def test_still_200_ok_if_identifier_is_wrong(self):
+        client = Client()
+        client.login(username="Test", password="testpw")
+
+        response = client.post('/submissions/prefill_using_identifier',
+                               {'identifier': '1512.00030'})
+
+        self.assertEqual(response.status_code, 200)
diff --git a/submissions/views.py b/submissions/views.py
index d3e7718ce4628b68cd323ac4758a668fecf86c91..f7a4ac054a33887fecb3f5c76662125ea437275f 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -44,25 +44,15 @@ def prefill_using_identifier(request):
     if request.method == "POST":
         identifierform = SubmissionIdentifierForm(request.POST)
         if identifierform.is_valid():
-            # we allow 1 or 2 digits for version
-            identifierpattern = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$")
-            errormessage = ''
-            if not identifierpattern.match(identifierform.cleaned_data['identifier']):
-                errormessage = ('The identifier you entered is improperly formatted '
-                                '(did you forget the version number?)')
-            elif (Submission.objects
-                  #.filter(arxiv_link__contains=identifierform.cleaned_data['identifier'])
-                  .filter(arxiv_identifier_w_vn_nr=identifierform.cleaned_data['identifier'])
-                  .exists()):
-                errormessage = 'This preprint version has already been submitted to SciPost.'
-            if errormessage != '':
+            # Perform Arxiv query and check if results are OK for submission
+            metadata, errormessage = lookup_article(identifierform.cleaned_data['identifier'])
+
+            if not metadata:
                 form = SubmissionForm()
                 return render(request, 'submissions/submit_manuscript.html',
                               {'identifierform': identifierform, 'form': form,
                                'errormessage': errormessage})
-            # Otherwise we query arXiv for the information:
-            identifier_without_vn_nr = identifierform.cleaned_data['identifier'].rpartition('v')[0]
-            arxiv_vn_nr = int(identifierform.cleaned_data['identifier'].rpartition('v')[2])
+
             is_resubmission = False
             resubmessage = ''
             previous_submissions = Submission.objects.filter(
@@ -95,6 +85,7 @@ def prefill_using_identifier(request):
                     errormessage = 'A preprint associated to this identifier does not exist.'
                 except:
                     pass
+
                 # If paper has been published, should comment on published version
                 try:
                     arxiv_journal_ref = arxivquery['entries'][0]['arxiv_journal_ref']
@@ -113,22 +104,7 @@ def prefill_using_identifier(request):
                     context = {'identifierform': identifierform, 'form': form,
                                'errormessage': errormessage}
                     return render(request, 'submissions/submit_manuscript.html', context)
-                # otherwise prefill the form:
-                # metadata = arxivquery
-                # title = arxivquery['entries'][0]['title']
-                # authorlist = arxivquery['entries'][0]['authors'][0]['name']
-                # for author in arxivquery['entries'][0]['authors'][1:]:
-                #     authorlist += ', ' + author['name']
-                # arxiv_link = arxivquery['entries'][0]['id']
-                # abstract = arxivquery['entries'][0]['summary']
-                # form = SubmissionForm(
-                #     initial={'is_resubmission': is_resubmission,
-                #              'metadata': metadata,
-                #              'title': title, 'author_list': authorlist,
-                #              'arxiv_identifier_w_vn_nr': identifierform.cleaned_data['identifier'],
-                #              'arxiv_identifier_wo_vn_nr': identifier_without_vn_nr,
-                #              'arxiv_vn_nr': arxiv_vn_nr,
-                #              'arxiv_link': arxiv_link, 'abstract': abstract})
+
                 metadata = arxivquery
                 title = arxivquery['entries'][0]['title']
                 authorlist = arxivquery['entries'][0]['authors'][0]['name']
@@ -148,7 +124,6 @@ def prefill_using_identifier(request):
                     initialdata['submission_type'] = previous_submissions[0].submission_type
                     initialdata['discipline'] = previous_submissions[0].discipline
                     initialdata['domain'] = previous_submissions[0].domain
-#                    initialdata['specialization'] = previous_submissions[0].specialization
                     initialdata['subject_area'] = previous_submissions[0].subject_area
                     initialdata['secondary_areas'] = previous_submissions[0].secondary_areas
                     initialdata['referees_suggested'] = previous_submissions[0].referees_suggested
@@ -165,7 +140,9 @@ def prefill_using_identifier(request):
                            'errormessage': errormessage,}
                 return render(request, 'submissions/submit_manuscript.html', context)
         else:
-            pass
+            form = SubmissionForm()
+            return render(request, 'submissions/submit_manuscript.html',
+                          {'identifierform': identifierform, 'form': form})
     return redirect(reverse('submissions:submit_manuscript'))
 
 
@@ -185,7 +162,7 @@ def submit_manuscript(request):
                 return render(request, 'submissions/submit_manuscript.html',
                               {'identifierform': identifierform, 'form': form,
                                'errormessage': errormessage})
-            submission = Submission (
+            submission = Submission(
                 is_current = True,
                 is_resubmission = form.cleaned_data['is_resubmission'],
                 submitted_by = submitted_by,