We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
The Phase (algorithm) input and output selects are annoying to use in the admin
A select 2 widget would be better.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `app/grandchallenge/evaluation/admin.py`
Content:
```
1 from django.contrib import admin
2 from django.core.exceptions import ObjectDoesNotExist, ValidationError
3 from django.forms import ModelForm
4 
5 from grandchallenge.challenges.models import ChallengeRequest
6 from grandchallenge.components.admin import (
7     ComponentImageAdmin,
8     cancel_jobs,
9     deprovision_jobs,
10     requeue_jobs,
11 )
12 from grandchallenge.core.admin import (
13     GroupObjectPermissionAdmin,
14     UserObjectPermissionAdmin,
15 )
16 from grandchallenge.core.templatetags.remove_whitespace import oxford_comma
17 from grandchallenge.evaluation.models import (
18     Evaluation,
19     EvaluationGroupObjectPermission,
20     EvaluationUserObjectPermission,
21     Method,
22     MethodGroupObjectPermission,
23     MethodUserObjectPermission,
24     Phase,
25     PhaseGroupObjectPermission,
26     PhaseUserObjectPermission,
27     Submission,
28     SubmissionGroupObjectPermission,
29     SubmissionUserObjectPermission,
30 )
31 from grandchallenge.evaluation.tasks import create_evaluation
32 from grandchallenge.evaluation.utils import SubmissionKindChoices
33 
34 
35 class PhaseAdminForm(ModelForm):
36     class Meta:
37         model = Phase
38         fields = "__all__"
39 
40     def clean(self):
41         cleaned_data = super().clean()
42 
43         duplicate_interfaces = {
44             *cleaned_data.get("algorithm_inputs", [])
45         }.intersection({*cleaned_data.get("algorithm_outputs", [])})
46 
47         if duplicate_interfaces:
48             raise ValidationError(
49                 f"The sets of Algorithm Inputs and Algorithm Outputs must be unique: "
50                 f"{oxford_comma(duplicate_interfaces)} present in both"
51             )
52 
53         submission_kind = cleaned_data["submission_kind"]
54         total_number_of_submissions_allowed = cleaned_data[
55             "total_number_of_submissions_allowed"
56         ]
57 
58         if (
59             submission_kind == SubmissionKindChoices.ALGORITHM
60             and not total_number_of_submissions_allowed
61         ):
62             try:
63                 request = ChallengeRequest.objects.get(
64                     short_name=self.instance.challenge.short_name
65                 )
66                 error_addition = f"The corresponding challenge request lists the following limits: Preliminary phase: {request.phase_1_number_of_submissions_per_team * request.expected_number_of_teams} Final test phase: {request.phase_2_number_of_submissions_per_team * request.expected_number_of_teams}. Set the limits according to the phase type. "
67             except ObjectDoesNotExist:
68                 error_addition = "There is no corresponding challenge request."
69             raise ValidationError(
70                 "For phases that take an algorithm as submission input, "
71                 "the total_number_of_submissions_allowed needs to be set. "
72                 + error_addition
73             )
74 
75         return cleaned_data
76 
77 
78 @admin.register(Phase)
79 class PhaseAdmin(admin.ModelAdmin):
80     ordering = ("challenge",)
81     list_display = (
82         "slug",
83         "title",
84         "challenge",
85         "submission_kind",
86         "open_for_submissions",
87         "submissions_open_at",
88         "submissions_close_at",
89         "submissions_limit_per_user_per_period",
90     )
91     search_fields = ("pk", "title", "slug", "challenge__short_name")
92     list_filter = (
93         "submission_kind",
94         "challenge__short_name",
95     )
96     form = PhaseAdminForm
97 
98     @admin.display(boolean=True)
99     def open_for_submissions(self, instance):
100         return instance.open_for_submissions
101 
102 
103 @admin.action(
104     description="Reevaluate selected submissions",
105     permissions=("change",),
106 )
107 def reevaluate_submissions(modeladmin, request, queryset):
108     """Creates a new evaluation for an existing submission"""
109     for submission in queryset:
110         create_evaluation.apply_async(
111             kwargs={"submission_pk": str(submission.pk)}
112         )
113 
114 
115 @admin.register(Submission)
116 class SubmissionAdmin(admin.ModelAdmin):
117     ordering = ("-created",)
118     list_display = ("pk", "created", "phase", "creator")
119     list_filter = ("phase__challenge__short_name",)
120     search_fields = ("pk", "creator__username", "phase__slug")
121     readonly_fields = (
122         "creator",
123         "phase",
124         "predictions_file",
125         "algorithm_image",
126     )
127     actions = (reevaluate_submissions,)
128 
129 
130 @admin.register(Evaluation)
131 class EvaluationAdmin(admin.ModelAdmin):
132     ordering = ("-created",)
133     list_display = ("pk", "created", "submission", "status", "error_message")
134     list_filter = ("submission__phase__challenge__short_name", "status")
135     list_select_related = (
136         "submission__phase__challenge",
137         "submission__creator",
138     )
139     search_fields = (
140         "pk",
141         "submission__pk",
142         "submission__phase__challenge__short_name",
143         "submission__creator__username",
144     )
145     readonly_fields = (
146         "status",
147         "submission",
148         "method",
149         "inputs",
150         "outputs",
151         "attempt",
152         "stdout",
153         "stderr",
154         "error_message",
155         "input_prefixes",
156         "task_on_success",
157         "task_on_failure",
158         "runtime_metrics",
159     )
160     actions = (requeue_jobs, cancel_jobs, deprovision_jobs)
161 
162 
163 admin.site.register(PhaseUserObjectPermission, UserObjectPermissionAdmin)
164 admin.site.register(PhaseGroupObjectPermission, GroupObjectPermissionAdmin)
165 admin.site.register(Method, ComponentImageAdmin)
166 admin.site.register(MethodUserObjectPermission, UserObjectPermissionAdmin)
167 admin.site.register(MethodGroupObjectPermission, GroupObjectPermissionAdmin)
168 admin.site.register(SubmissionUserObjectPermission, UserObjectPermissionAdmin)
169 admin.site.register(
170     SubmissionGroupObjectPermission, GroupObjectPermissionAdmin
171 )
172 admin.site.register(EvaluationUserObjectPermission, UserObjectPermissionAdmin)
173 admin.site.register(
174     EvaluationGroupObjectPermission, GroupObjectPermissionAdmin
175 )
176
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/app/grandchallenge/evaluation/admin.py b/app/grandchallenge/evaluation/admin.py
--- a/app/grandchallenge/evaluation/admin.py
+++ b/app/grandchallenge/evaluation/admin.py
@@ -93,6 +93,13 @@
         "submission_kind",
         "challenge__short_name",
     )
+    autocomplete_fields = (
+        "inputs",
+        "outputs",
+        "algorithm_inputs",
+        "algorithm_outputs",
+        "archive",
+    )
     form = PhaseAdminForm
 
     @admin.display(boolean=True)

{"golden_diff": "diff --git a/app/grandchallenge/evaluation/admin.py b/app/grandchallenge/evaluation/admin.py\n--- a/app/grandchallenge/evaluation/admin.py\n+++ b/app/grandchallenge/evaluation/admin.py\n@@ -93,6 +93,13 @@\n         \"submission_kind\",\n         \"challenge__short_name\",\n     )\n+    autocomplete_fields = (\n+        \"inputs\",\n+        \"outputs\",\n+        \"algorithm_inputs\",\n+        \"algorithm_outputs\",\n+        \"archive\",\n+    )\n     form = PhaseAdminForm\n \n     @admin.display(boolean=True)\n", "issue": "The Phase (algorithm) input and output selects are annoying to use in the admin\nA select 2 widget would be better.\n", "before_files": [{"content": "from django.contrib import admin\nfrom django.core.exceptions import ObjectDoesNotExist, ValidationError\nfrom django.forms import ModelForm\n\nfrom grandchallenge.challenges.models import ChallengeRequest\nfrom grandchallenge.components.admin import (\n    ComponentImageAdmin,\n    cancel_jobs,\n    deprovision_jobs,\n    requeue_jobs,\n)\nfrom grandchallenge.core.admin import (\n    GroupObjectPermissionAdmin,\n    UserObjectPermissionAdmin,\n)\nfrom grandchallenge.core.templatetags.remove_whitespace import oxford_comma\nfrom grandchallenge.evaluation.models import (\n    Evaluation,\n    EvaluationGroupObjectPermission,\n    EvaluationUserObjectPermission,\n    Method,\n    MethodGroupObjectPermission,\n    MethodUserObjectPermission,\n    Phase,\n    PhaseGroupObjectPermission,\n    PhaseUserObjectPermission,\n    Submission,\n    SubmissionGroupObjectPermission,\n    SubmissionUserObjectPermission,\n)\nfrom grandchallenge.evaluation.tasks import create_evaluation\nfrom grandchallenge.evaluation.utils import SubmissionKindChoices\n\n\nclass PhaseAdminForm(ModelForm):\n    class Meta:\n        model = Phase\n        fields = \"__all__\"\n\n    def clean(self):\n        cleaned_data = super().clean()\n\n        duplicate_interfaces = {\n            *cleaned_data.get(\"algorithm_inputs\", [])\n        }.intersection({*cleaned_data.get(\"algorithm_outputs\", [])})\n\n        if duplicate_interfaces:\n            raise ValidationError(\n                f\"The sets of Algorithm Inputs and Algorithm Outputs must be unique: \"\n                f\"{oxford_comma(duplicate_interfaces)} present in both\"\n            )\n\n        submission_kind = cleaned_data[\"submission_kind\"]\n        total_number_of_submissions_allowed = cleaned_data[\n            \"total_number_of_submissions_allowed\"\n        ]\n\n        if (\n            submission_kind == SubmissionKindChoices.ALGORITHM\n            and not total_number_of_submissions_allowed\n        ):\n            try:\n                request = ChallengeRequest.objects.get(\n                    short_name=self.instance.challenge.short_name\n                )\n                error_addition = f\"The corresponding challenge request lists the following limits: Preliminary phase: {request.phase_1_number_of_submissions_per_team * request.expected_number_of_teams} Final test phase: {request.phase_2_number_of_submissions_per_team * request.expected_number_of_teams}. Set the limits according to the phase type. \"\n            except ObjectDoesNotExist:\n                error_addition = \"There is no corresponding challenge request.\"\n            raise ValidationError(\n                \"For phases that take an algorithm as submission input, \"\n                \"the total_number_of_submissions_allowed needs to be set. \"\n                + error_addition\n            )\n\n        return cleaned_data\n\n\n@admin.register(Phase)\nclass PhaseAdmin(admin.ModelAdmin):\n    ordering = (\"challenge\",)\n    list_display = (\n        \"slug\",\n        \"title\",\n        \"challenge\",\n        \"submission_kind\",\n        \"open_for_submissions\",\n        \"submissions_open_at\",\n        \"submissions_close_at\",\n        \"submissions_limit_per_user_per_period\",\n    )\n    search_fields = (\"pk\", \"title\", \"slug\", \"challenge__short_name\")\n    list_filter = (\n        \"submission_kind\",\n        \"challenge__short_name\",\n    )\n    form = PhaseAdminForm\n\n    @admin.display(boolean=True)\n    def open_for_submissions(self, instance):\n        return instance.open_for_submissions\n\n\n@admin.action(\n    description=\"Reevaluate selected submissions\",\n    permissions=(\"change\",),\n)\ndef reevaluate_submissions(modeladmin, request, queryset):\n    \"\"\"Creates a new evaluation for an existing submission\"\"\"\n    for submission in queryset:\n        create_evaluation.apply_async(\n            kwargs={\"submission_pk\": str(submission.pk)}\n        )\n\n\n@admin.register(Submission)\nclass SubmissionAdmin(admin.ModelAdmin):\n    ordering = (\"-created\",)\n    list_display = (\"pk\", \"created\", \"phase\", \"creator\")\n    list_filter = (\"phase__challenge__short_name\",)\n    search_fields = (\"pk\", \"creator__username\", \"phase__slug\")\n    readonly_fields = (\n        \"creator\",\n        \"phase\",\n        \"predictions_file\",\n        \"algorithm_image\",\n    )\n    actions = (reevaluate_submissions,)\n\n\n@admin.register(Evaluation)\nclass EvaluationAdmin(admin.ModelAdmin):\n    ordering = (\"-created\",)\n    list_display = (\"pk\", \"created\", \"submission\", \"status\", \"error_message\")\n    list_filter = (\"submission__phase__challenge__short_name\", \"status\")\n    list_select_related = (\n        \"submission__phase__challenge\",\n        \"submission__creator\",\n    )\n    search_fields = (\n        \"pk\",\n        \"submission__pk\",\n        \"submission__phase__challenge__short_name\",\n        \"submission__creator__username\",\n    )\n    readonly_fields = (\n        \"status\",\n        \"submission\",\n        \"method\",\n        \"inputs\",\n        \"outputs\",\n        \"attempt\",\n        \"stdout\",\n        \"stderr\",\n        \"error_message\",\n        \"input_prefixes\",\n        \"task_on_success\",\n        \"task_on_failure\",\n        \"runtime_metrics\",\n    )\n    actions = (requeue_jobs, cancel_jobs, deprovision_jobs)\n\n\nadmin.site.register(PhaseUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(PhaseGroupObjectPermission, GroupObjectPermissionAdmin)\nadmin.site.register(Method, ComponentImageAdmin)\nadmin.site.register(MethodUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(MethodGroupObjectPermission, GroupObjectPermissionAdmin)\nadmin.site.register(SubmissionUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(\n    SubmissionGroupObjectPermission, GroupObjectPermissionAdmin\n)\nadmin.site.register(EvaluationUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(\n    EvaluationGroupObjectPermission, GroupObjectPermissionAdmin\n)\n", "path": "app/grandchallenge/evaluation/admin.py"}], "after_files": [{"content": "from django.contrib import admin\nfrom django.core.exceptions import ObjectDoesNotExist, ValidationError\nfrom django.forms import ModelForm\n\nfrom grandchallenge.challenges.models import ChallengeRequest\nfrom grandchallenge.components.admin import (\n    ComponentImageAdmin,\n    cancel_jobs,\n    deprovision_jobs,\n    requeue_jobs,\n)\nfrom grandchallenge.core.admin import (\n    GroupObjectPermissionAdmin,\n    UserObjectPermissionAdmin,\n)\nfrom grandchallenge.core.templatetags.remove_whitespace import oxford_comma\nfrom grandchallenge.evaluation.models import (\n    Evaluation,\n    EvaluationGroupObjectPermission,\n    EvaluationUserObjectPermission,\n    Method,\n    MethodGroupObjectPermission,\n    MethodUserObjectPermission,\n    Phase,\n    PhaseGroupObjectPermission,\n    PhaseUserObjectPermission,\n    Submission,\n    SubmissionGroupObjectPermission,\n    SubmissionUserObjectPermission,\n)\nfrom grandchallenge.evaluation.tasks import create_evaluation\nfrom grandchallenge.evaluation.utils import SubmissionKindChoices\n\n\nclass PhaseAdminForm(ModelForm):\n    class Meta:\n        model = Phase\n        fields = \"__all__\"\n\n    def clean(self):\n        cleaned_data = super().clean()\n\n        duplicate_interfaces = {\n            *cleaned_data.get(\"algorithm_inputs\", [])\n        }.intersection({*cleaned_data.get(\"algorithm_outputs\", [])})\n\n        if duplicate_interfaces:\n            raise ValidationError(\n                f\"The sets of Algorithm Inputs and Algorithm Outputs must be unique: \"\n                f\"{oxford_comma(duplicate_interfaces)} present in both\"\n            )\n\n        submission_kind = cleaned_data[\"submission_kind\"]\n        total_number_of_submissions_allowed = cleaned_data[\n            \"total_number_of_submissions_allowed\"\n        ]\n\n        if (\n            submission_kind == SubmissionKindChoices.ALGORITHM\n            and not total_number_of_submissions_allowed\n        ):\n            try:\n                request = ChallengeRequest.objects.get(\n                    short_name=self.instance.challenge.short_name\n                )\n                error_addition = f\"The corresponding challenge request lists the following limits: Preliminary phase: {request.phase_1_number_of_submissions_per_team * request.expected_number_of_teams} Final test phase: {request.phase_2_number_of_submissions_per_team * request.expected_number_of_teams}. Set the limits according to the phase type. \"\n            except ObjectDoesNotExist:\n                error_addition = \"There is no corresponding challenge request.\"\n            raise ValidationError(\n                \"For phases that take an algorithm as submission input, \"\n                \"the total_number_of_submissions_allowed needs to be set. \"\n                + error_addition\n            )\n\n        return cleaned_data\n\n\n@admin.register(Phase)\nclass PhaseAdmin(admin.ModelAdmin):\n    ordering = (\"challenge\",)\n    list_display = (\n        \"slug\",\n        \"title\",\n        \"challenge\",\n        \"submission_kind\",\n        \"open_for_submissions\",\n        \"submissions_open_at\",\n        \"submissions_close_at\",\n        \"submissions_limit_per_user_per_period\",\n    )\n    search_fields = (\"pk\", \"title\", \"slug\", \"challenge__short_name\")\n    list_filter = (\n        \"submission_kind\",\n        \"challenge__short_name\",\n    )\n    autocomplete_fields = (\n        \"inputs\",\n        \"outputs\",\n        \"algorithm_inputs\",\n        \"algorithm_outputs\",\n        \"archive\",\n    )\n    form = PhaseAdminForm\n\n    @admin.display(boolean=True)\n    def open_for_submissions(self, instance):\n        return instance.open_for_submissions\n\n\n@admin.action(\n    description=\"Reevaluate selected submissions\",\n    permissions=(\"change\",),\n)\ndef reevaluate_submissions(modeladmin, request, queryset):\n    \"\"\"Creates a new evaluation for an existing submission\"\"\"\n    for submission in queryset:\n        create_evaluation.apply_async(\n            kwargs={\"submission_pk\": str(submission.pk)}\n        )\n\n\n@admin.register(Submission)\nclass SubmissionAdmin(admin.ModelAdmin):\n    ordering = (\"-created\",)\n    list_display = (\"pk\", \"created\", \"phase\", \"creator\")\n    list_filter = (\"phase__challenge__short_name\",)\n    search_fields = (\"pk\", \"creator__username\", \"phase__slug\")\n    readonly_fields = (\n        \"creator\",\n        \"phase\",\n        \"predictions_file\",\n        \"algorithm_image\",\n    )\n    actions = (reevaluate_submissions,)\n\n\n@admin.register(Evaluation)\nclass EvaluationAdmin(admin.ModelAdmin):\n    ordering = (\"-created\",)\n    list_display = (\"pk\", \"created\", \"submission\", \"status\", \"error_message\")\n    list_filter = (\"submission__phase__challenge__short_name\", \"status\")\n    list_select_related = (\n        \"submission__phase__challenge\",\n        \"submission__creator\",\n    )\n    search_fields = (\n        \"pk\",\n        \"submission__pk\",\n        \"submission__phase__challenge__short_name\",\n        \"submission__creator__username\",\n    )\n    readonly_fields = (\n        \"status\",\n        \"submission\",\n        \"method\",\n        \"inputs\",\n        \"outputs\",\n        \"attempt\",\n        \"stdout\",\n        \"stderr\",\n        \"error_message\",\n        \"input_prefixes\",\n        \"task_on_success\",\n        \"task_on_failure\",\n        \"runtime_metrics\",\n    )\n    actions = (requeue_jobs, cancel_jobs, deprovision_jobs)\n\n\nadmin.site.register(PhaseUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(PhaseGroupObjectPermission, GroupObjectPermissionAdmin)\nadmin.site.register(Method, ComponentImageAdmin)\nadmin.site.register(MethodUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(MethodGroupObjectPermission, GroupObjectPermissionAdmin)\nadmin.site.register(SubmissionUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(\n    SubmissionGroupObjectPermission, GroupObjectPermissionAdmin\n)\nadmin.site.register(EvaluationUserObjectPermission, UserObjectPermissionAdmin)\nadmin.site.register(\n    EvaluationGroupObjectPermission, GroupObjectPermissionAdmin\n)\n", "path": "app/grandchallenge/evaluation/admin.py"}]}