diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
index 819a8a25ed762d1782e9a434b629f414e727d742..16eef90707c65e80f5a37a9a43e0a54d1e40fe29 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 2.2.12 on 2020-05-27 09:15
+# Generated by Django 2.2.12 on 2020-06-15 13:58
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -244,7 +244,7 @@ class Migration(migrations.Migration):
             },
         ),
         migrations.CreateModel(
-            name='DefaultTaskTemplate',
+            name='DefaultTaskRelationSelectionTemplate',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
@@ -257,7 +257,7 @@ class Migration(migrations.Migration):
             },
         ),
         migrations.CreateModel(
-            name='DefaultTaskRelationSelectionTemplate',
+            name='DefaultTaskTemplate',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
@@ -562,7 +562,7 @@ class Migration(migrations.Migration):
             },
         ),
         migrations.CreateModel(
-            name='TaskConnector',
+            name='TaskConnectorType',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
@@ -615,7 +615,7 @@ class Migration(migrations.Migration):
             },
         ),
         migrations.CreateModel(
-            name='TaskTemplate',
+            name='TaskRelationSelectionTemplate',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
@@ -625,11 +625,10 @@ class Migration(migrations.Migration):
                 ('description', models.CharField(help_text='A longer description of this object.', max_length=255)),
                 ('version', models.CharField(help_text='Version of this template (with respect to other templates of the same name).', max_length=128)),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
-                ('validation_code_js', models.CharField(help_text='JavaScript code for additional (complex) validation.', max_length=128)),
             ],
         ),
         migrations.CreateModel(
-            name='TaskRelationSelectionTemplate',
+            name='TaskTemplate',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
@@ -639,20 +638,21 @@ class Migration(migrations.Migration):
                 ('description', models.CharField(help_text='A longer description of this object.', max_length=255)),
                 ('version', models.CharField(help_text='Version of this template (with respect to other templates of the same name).', max_length=128)),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
+                ('validation_code_js', models.CharField(help_text='JavaScript code for additional (complex) validation.', max_length=128)),
             ],
         ),
-        migrations.AddConstraint(
-            model_name='taskrelationselectiontemplate',
-            constraint=models.UniqueConstraint(fields=('name', 'version'), name='TaskRelationSelectionTemplate_unique_name_version'),
-        ),
         migrations.AddConstraint(
             model_name='tasktemplate',
             constraint=models.UniqueConstraint(fields=('name', 'version'), name='TaskTemplate_unique_name_version'),
         ),
+        migrations.AddConstraint(
+            model_name='taskrelationselectiontemplate',
+            constraint=models.UniqueConstraint(fields=('name', 'version'), name='TaskRelationSelectionTemplate_unique_name_version'),
+        ),
         migrations.AddField(
             model_name='taskrelationdraft',
             name='consumer',
-            field=models.ForeignKey(help_text='Task Draft that has the input connector.', on_delete=django.db.models.deletion.CASCADE, related_name='consumed_by', to='tmssapp.TaskDraft'),
+            field=models.ForeignKey(help_text='Task Draft that has the input connector.', on_delete=django.db.models.deletion.CASCADE, related_name='produced_by', to='tmssapp.TaskDraft'),
         ),
         migrations.AddField(
             model_name='taskrelationdraft',
@@ -661,18 +661,18 @@ class Migration(migrations.Migration):
         ),
         migrations.AddField(
             model_name='taskrelationdraft',
-            name='input',
-            field=models.ForeignKey(help_text='Input connector of consumer.', on_delete=django.db.models.deletion.CASCADE, related_name='inputs_task_relation_draft', to='tmssapp.TaskConnector'),
+            name='input_role',
+            field=models.ForeignKey(help_text='Input connector type (what kind of data can be taken as input).', on_delete=django.db.models.deletion.CASCADE, related_name='taskrelationdraft_input_roles', to='tmssapp.TaskConnectorType'),
         ),
         migrations.AddField(
             model_name='taskrelationdraft',
-            name='output',
-            field=models.ForeignKey(help_text='Output connector of producer.', on_delete=django.db.models.deletion.CASCADE, related_name='outputs_task_relation_draft', to='tmssapp.TaskConnector'),
+            name='output_role',
+            field=models.ForeignKey(help_text='Output connector type (what kind of data can be created as output).', on_delete=django.db.models.deletion.CASCADE, related_name='taskrelationdraft_output_roles', to='tmssapp.TaskConnectorType'),
         ),
         migrations.AddField(
             model_name='taskrelationdraft',
             name='producer',
-            field=models.ForeignKey(help_text='Task Draft that has the output connector. NOTE: The producer does typically, but not necessarily, belong to the same Scheduling Unit (or even the same Project) as the consumer.', on_delete=django.db.models.deletion.CASCADE, related_name='produced_by', to='tmssapp.TaskDraft'),
+            field=models.ForeignKey(help_text='Task Draft that has the output connector. NOTE: The producer does typically, but not necessarily, belong to the same Scheduling Unit (or even the same Project) as the consumer.', on_delete=django.db.models.deletion.CASCADE, related_name='consumed_by', to='tmssapp.TaskDraft'),
         ),
         migrations.AddField(
             model_name='taskrelationdraft',
@@ -682,7 +682,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taskrelationblueprint',
             name='consumer',
-            field=models.ForeignKey(help_text='Task Blueprint that has the input connector.', on_delete=django.db.models.deletion.CASCADE, related_name='consumed_by', to='tmssapp.TaskBlueprint'),
+            field=models.ForeignKey(help_text='Task Blueprint that has the input connector.', on_delete=django.db.models.deletion.CASCADE, related_name='produced_by', to='tmssapp.TaskBlueprint'),
         ),
         migrations.AddField(
             model_name='taskrelationblueprint',
@@ -696,18 +696,18 @@ class Migration(migrations.Migration):
         ),
         migrations.AddField(
             model_name='taskrelationblueprint',
-            name='input',
-            field=models.ForeignKey(help_text='Input connector of consumer.', on_delete=django.db.models.deletion.CASCADE, related_name='inputs_task_relation_blueprint', to='tmssapp.TaskConnector'),
+            name='input_role',
+            field=models.ForeignKey(help_text='Input connector type (what kind of data can be taken as input).', on_delete=django.db.models.deletion.CASCADE, related_name='taskrelationblueprint_input_roles', to='tmssapp.TaskConnectorType'),
         ),
         migrations.AddField(
             model_name='taskrelationblueprint',
-            name='output',
-            field=models.ForeignKey(help_text='Output connector of producer.', on_delete=django.db.models.deletion.CASCADE, related_name='outputs_task_relation_blueprint', to='tmssapp.TaskConnector'),
+            name='output_role',
+            field=models.ForeignKey(help_text='Output connector type (what kind of data can be created as output).', on_delete=django.db.models.deletion.CASCADE, related_name='taskrelationblueprint_output_roles', to='tmssapp.TaskConnectorType'),
         ),
         migrations.AddField(
             model_name='taskrelationblueprint',
             name='producer',
-            field=models.ForeignKey(help_text='Task Blueprint that has the output connector.', on_delete=django.db.models.deletion.CASCADE, related_name='produced_by', to='tmssapp.TaskBlueprint'),
+            field=models.ForeignKey(help_text='Task Blueprint that has the output connector.', on_delete=django.db.models.deletion.CASCADE, related_name='consumed_by', to='tmssapp.TaskBlueprint'),
         ),
         migrations.AddField(
             model_name='taskrelationblueprint',
@@ -735,27 +735,27 @@ class Migration(migrations.Migration):
             field=models.ForeignKey(help_text='Schema used for requirements_doc.', on_delete=django.db.models.deletion.CASCADE, to='tmssapp.TaskTemplate'),
         ),
         migrations.AddField(
-            model_name='taskconnector',
+            model_name='taskconnectortype',
             name='dataformats',
             field=models.ManyToManyField(blank=True, to='tmssapp.Dataformat'),
         ),
         migrations.AddField(
-            model_name='taskconnector',
+            model_name='taskconnectortype',
             name='datatype',
             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Datatype'),
         ),
         migrations.AddField(
-            model_name='taskconnector',
+            model_name='taskconnectortype',
             name='input_of',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inputs', to='tmssapp.TaskTemplate'),
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inpput_connector_types', to='tmssapp.TaskTemplate'),
         ),
         migrations.AddField(
-            model_name='taskconnector',
+            model_name='taskconnectortype',
             name='output_of',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='outputs', to='tmssapp.TaskTemplate'),
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='output_connector_types', to='tmssapp.TaskTemplate'),
         ),
         migrations.AddField(
-            model_name='taskconnector',
+            model_name='taskconnectortype',
             name='role',
             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Role'),
         ),
@@ -767,7 +767,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taskblueprint',
             name='scheduling_unit_blueprint',
-            field=models.ForeignKey(help_text='Scheduling Unit Blueprint to which this task belongs.', on_delete=django.db.models.deletion.CASCADE, to='tmssapp.SchedulingUnitBlueprint'),
+            field=models.ForeignKey(help_text='Scheduling Unit Blueprint to which this task belongs.', on_delete=django.db.models.deletion.CASCADE, related_name='task_blueprints', to='tmssapp.SchedulingUnitBlueprint'),
         ),
         migrations.AddField(
             model_name='taskblueprint',
@@ -942,14 +942,14 @@ class Migration(migrations.Migration):
             field=models.ForeignKey(help_text='Cluster hosting this filesystem.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Cluster'),
         ),
         migrations.AddField(
-            model_name='defaulttaskrelationselectiontemplate',
+            model_name='defaulttasktemplate',
             name='template',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.TaskRelationSelectionTemplate'),
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.TaskTemplate'),
         ),
         migrations.AddField(
-            model_name='defaulttasktemplate',
+            model_name='defaulttaskrelationselectiontemplate',
             name='template',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.TaskTemplate'),
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.TaskRelationSelectionTemplate'),
         ),
         migrations.AddField(
             model_name='defaultsubtasktemplate',
@@ -1038,8 +1038,8 @@ class Migration(migrations.Migration):
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_tas_tags_256437_gin'),
         ),
         migrations.AddIndex(
-            model_name='taskconnector',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_tas_tags_a12728_gin'),
+            model_name='taskconnectortype',
+            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_tas_tags_19ff09_gin'),
         ),
         migrations.AddConstraint(
             model_name='subtasktemplate',
@@ -1061,14 +1061,14 @@ class Migration(migrations.Migration):
             model_name='subtask',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_sub_tags_d2fc43_gin'),
         ),
-        migrations.AddIndex(
-            model_name='defaulttaskrelationselectiontemplate',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_def_tags_b652d9_gin'),
-        ),
         migrations.AddIndex(
             model_name='defaulttasktemplate',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_def_tags_c88200_gin'),
         ),
+        migrations.AddIndex(
+            model_name='defaulttaskrelationselectiontemplate',
+            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_def_tags_3bee7d_gin'),
+        ),
         migrations.AddIndex(
             model_name='defaultsubtasktemplate',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_def_tags_e9c73d_gin'),
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
index f67a46eef6c84937207e7005ebec7145d1ce3eff..0a0607d514b73c5f92fa2324084cac5bde2da77b 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
@@ -207,7 +207,7 @@ class Subtask(BasicCommon):
 
         if self.state.value == SubtaskState.Choices.SCHEDULED.value and self.__original_state.value == SubtaskState.Choices.SCHEDULING.value:
             if self.start_time is None:
-                if self.predecessors.all().count() is 0:
+                if self.predecessors.all().count() == 0:
                     raise SubtaskSchedulingException("Cannot schedule subtask id=%s when start time is 'None'." % (self.pk, ))
                 else:
                     self.start_time = datetime.utcnow()
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 9e49ea172ef87ef7dac9ad730a07a20320eba95a..7b3329f3f8de955f55f5517a992a63794087b1e9 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -90,7 +90,7 @@ class AbstractChoice(Model):
 
 
 class Role(AbstractChoice):
-    """Defines the model and predefined list of possible Role's for TaskConnector.
+    """Defines the model and predefined list of possible Role's for TaskConnectorType.
     The items in the Choises class below are automagically populated into the database via a data migration."""
     class Choices(Enum):
         CORRELATOR = "correlator"
@@ -103,7 +103,7 @@ class Role(AbstractChoice):
 
 
 class Datatype(AbstractChoice):
-    """Defines the model and predefined list of possible Datatype's for TaskConnector.
+    """Defines the model and predefined list of possible Datatype's for TaskConnectorType.
     The items in the Choises class below are automagically populated into the database via a data migration."""
     class Choices(Enum):
         VISIBILITIES = "visibilities"
@@ -133,12 +133,12 @@ class CopyReason(AbstractChoice):
 
 # concrete models
 
-class TaskConnector(BasicCommon):
+class TaskConnectorType(BasicCommon):
     role = ForeignKey('Role', null=False, on_delete=PROTECT)
     datatype = ForeignKey('Datatype', null=False, on_delete=PROTECT)
     dataformats = ManyToManyField('Dataformat', blank=True)
-    output_of = ForeignKey("TaskTemplate", related_name='outputs', on_delete=CASCADE)
-    input_of = ForeignKey("TaskTemplate", related_name='inputs', on_delete=CASCADE)
+    output_of = ForeignKey("TaskTemplate", related_name='output_connector_types', on_delete=CASCADE)
+    input_of = ForeignKey("TaskTemplate", related_name='inpput_connector_types', on_delete=CASCADE)
 
 
 #
@@ -352,6 +352,7 @@ class TaskBlueprint(NamedCommon):
 
 class TaskRelationDraft(BasicCommon):
     selection_doc = JSONField(help_text='Filter for selecting dataproducts from the output role.')
+    selection_template = ForeignKey('TaskRelationSelectionTemplate', on_delete=CASCADE, help_text='Schema used for selection_doc.') # todo: 'schema'?
     dataformat = ForeignKey('Dataformat', null=False, on_delete=PROTECT, help_text='Selected data format to use. One of (MS, HDF5).')
 
     # caveat: it might look like producer has an incorrect related_name='consumed_by'. But it really is correct, denends on the way you look at it
@@ -359,9 +360,8 @@ class TaskRelationDraft(BasicCommon):
     # caveat: it might look like consumer has an incorrect related_name='produced_by'. But it really is correct, denends on the way you look at it
     consumer = ForeignKey('TaskDraft', related_name='produced_by', on_delete=CASCADE, help_text='Task Draft that has the input connector.')
 
-    input = ForeignKey('TaskConnector', related_name='inputs_task_relation_draft', on_delete=CASCADE, help_text='Input connector of consumer.')
-    output = ForeignKey('TaskConnector', related_name='outputs_task_relation_draft', on_delete=CASCADE, help_text='Output connector of producer.')
-    selection_template = ForeignKey('TaskRelationSelectionTemplate', on_delete=CASCADE, help_text='Schema used for selection_doc.') # todo: 'schema'?
+    input_role = ForeignKey('TaskConnectorType', related_name='taskrelationdraft_input_roles', on_delete=CASCADE, help_text='Input connector type (what kind of data can be taken as input).')
+    output_role = ForeignKey('TaskConnectorType', related_name='taskrelationdraft_output_roles', on_delete=CASCADE, help_text='Output connector type (what kind of data can be created as output).')
 
     def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
         if self.selection_doc and self.selection_template_id and self.selection_template.schema:
@@ -379,8 +379,8 @@ class TaskRelationBlueprint(BasicCommon):
     # caveat: it might look like consumer has an incorrect related_name='produced_by'. But it really is correct, denends on the way you look at it
     consumer = ForeignKey('TaskBlueprint', related_name='produced_by', on_delete=CASCADE, help_text='Task Blueprint that has the input connector.')
 
-    input = ForeignKey('TaskConnector', related_name='inputs_task_relation_blueprint', on_delete=CASCADE, help_text='Input connector of consumer.')
-    output = ForeignKey('TaskConnector', related_name='outputs_task_relation_blueprint', on_delete=CASCADE, help_text='Output connector of producer.')
+    input_role = ForeignKey('TaskConnectorType', related_name='taskrelationblueprint_input_roles', on_delete=CASCADE, help_text='Input connector type (what kind of data can be taken as input).')
+    output_role = ForeignKey('TaskConnectorType', related_name='taskrelationblueprint_output_roles', on_delete=CASCADE, help_text='Output connector type (what kind of data can be created as output).')
     draft = ForeignKey('TaskRelationDraft', on_delete=CASCADE, related_name='related_task_relation_blueprint', help_text='Task Relation Draft which this work request instantiates.')
     selection_template = ForeignKey('TaskRelationSelectionTemplate', on_delete=CASCADE, help_text='Schema used for selection_doc.')  # todo: 'schema'?
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/populate.py b/SAS/TMSS/src/tmss/tmssapp/populate.py
index 31b8c5923fce6868720c5ba9359c08c042cac53a..991150faa93e0505872139c716fa286647bf0310 100644
--- a/SAS/TMSS/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/populate.py
@@ -76,14 +76,14 @@ def _populate_task_draft_example():
             pipeline_task_draft = models.TaskDraft.objects.create(**task_draft_data)
 
             # connect them
-            connector = models.TaskConnector.objects.first() # TODO: get the correct connector instead of the first
+            connector_type = models.TaskConnectorType.objects.first() # TODO: get the correct connector instead of the first
             task_relation_data = {"tags": [],
                                   "selection_doc": {},
                                   "dataformat": models.Dataformat.objects.get(value='MeasurementSet'),
                                   "producer": obs_task_draft,
                                   "consumer": pipeline_task_draft,
-                                  "input": connector,
-                                  "output": connector,
+                                  "input_role": connector_type,
+                                  "output_role": connector_type,
                                   "selection_template": models.TaskRelationSelectionTemplate.objects.get(name="All")}
             models.TaskRelationDraft.objects.create(**task_relation_data)
 
@@ -1366,14 +1366,14 @@ def _populate_pipelinecontrol_schema():
 
 
 def _populate_connectors():
-    # the TaskConnector's define how the Task[Draft/Blueprint] *can* be connected.
-    TaskConnector.objects.create(role=Role.objects.get(value=Role.Choices.CALIBRATOR.value),
-                                 datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
-                                 output_of=TaskTemplate.objects.get(name='correlator schema'),
-                                 input_of=TaskTemplate.objects.get(name='preprocessing schema'))
-
-    TaskConnector.objects.create(role=Role.objects.get(value=Role.Choices.TARGET.value),
-                                 datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
-                                 output_of=TaskTemplate.objects.get(name='correlator schema'),
-                                 input_of=TaskTemplate.objects.get(name='preprocessing schema'))
+    # the TaskConnectorType's define how the Task[Draft/Blueprint] *can* be connected.
+    TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.CALIBRATOR.value),
+                                     datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
+                                     output_of=TaskTemplate.objects.get(name='correlator schema'),
+                                     input_of=TaskTemplate.objects.get(name='preprocessing schema'))
+
+    TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.TARGET.value),
+                                     datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
+                                     output_of=TaskTemplate.objects.get(name='correlator schema'),
+                                     input_of=TaskTemplate.objects.get(name='preprocessing schema'))
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
index 4d1ae4d3b271419fcddc417a1025045c6afca4c4..a860e368eaaf64928b155a5e83a2f1e8fc759be6 100644
--- a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
@@ -163,9 +163,9 @@ class CopyReasonSerializer(serializers.ModelSerializer):
         fields = '__all__'
 
 
-class TaskConnectorSerializer(RelationalHyperlinkedModelSerializer):
+class TaskConnectorTypeSerializer(RelationalHyperlinkedModelSerializer):
     class Meta:
-        model = models.TaskConnector
+        model = models.TaskConnectorType
         fields = '__all__'
 
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/tasks.py b/SAS/TMSS/src/tmss/tmssapp/tasks.py
index d905e7774b12a1ac56977c5e72f6412aee455535..6e69a877e05873b48fd146466678637bdbe76373 100644
--- a/SAS/TMSS/src/tmss/tmssapp/tasks.py
+++ b/SAS/TMSS/src/tmss/tmssapp/tasks.py
@@ -61,32 +61,25 @@ def create_task_blueprint_from_task_draft(task_draft: models.TaskDraft) -> model
     # so, when converting two TaskDrafts (for example an observation and a pipeline), then for the conversion
     # of the first TaskDraft->TaskBlueprint no relation is setup,
     # and for the second TaskDraft->TaskBlueprint conversion we have both endpoints available, so we can connect them.
-    for consumer in task_draft.consumed_by.all():
-        producing_task_blueprint = consumer.producer.task_blueprints.first()
-        if producing_task_blueprint is not None:
-            relation = models.TaskRelationBlueprint.objects.create(draft=consumer,
-                                                                   input=consumer.input,
-                                                                   output=consumer.output,
-                                                                   producer=task_blueprint,
-                                                                   consumer=producing_task_blueprint,
-                                                                   selection_doc=consumer.selection_doc,
-                                                                   selection_template=consumer.selection_template,
-                                                                   dataformat=consumer.dataformat)
-            logger.info("create_task_blueprint_from_task_draft(task_draft.id=%s) connected task_blueprint id=%s to task_blueprint id=%s via task_relation_blueprint id=%s",
-                        task_draft.pk, task_blueprint.pk, producing_task_blueprint.pk, relation.pk)
-    for producer in task_draft.produced_by.all():
-        consuming_task_blueprint = producer.consumer.task_blueprints.first()
-        if consuming_task_blueprint is not None:
-            relation = models.TaskRelationBlueprint.objects.create(draft=producer,
-                                                                   input=producer.input,
-                                                                   output=producer.output,
-                                                                   producer=consuming_task_blueprint,
-                                                                   consumer=task_blueprint,
-                                                                   selection_doc=producer.selection_doc,
-                                                                   selection_template=producer.selection_template,
-                                                                   dataformat=producer.dataformat)
-            logger.info("create_task_blueprint_from_task_draft(task_draft.id=%s) connected task_blueprint id=%s to task_blueprint id=%s via task_relation_blueprint id=%s",
-                        task_draft.pk, consuming_task_blueprint.pk, task_blueprint.pk, relation.pk)
+    task_draft_relations = list(task_draft.consumed_by.all()) + list(task_draft.produced_by.all())
+    for task_relation_draft in task_draft_relations:
+        for producing_task_blueprint in task_relation_draft.producer.task_blueprints.all():
+            for consuming_task_blueprint in task_relation_draft.consumer.task_blueprints.all():
+                try:
+                    # do nothing if task_relation_blueprint already exists...
+                    models.TaskRelationBlueprint.objects.get(producer_id=producing_task_blueprint.id, consumer_id=consuming_task_blueprint.id)
+                except models.TaskRelationBlueprint.DoesNotExist:
+                    # ...'else' create it.
+                    task_relation_blueprint = models.TaskRelationBlueprint.objects.create(draft=task_relation_draft,
+                                                                                          input_role=task_relation_draft.input_role,
+                                                                                          output_role=task_relation_draft.output_role,
+                                                                                          producer=producing_task_blueprint,
+                                                                                          consumer=consuming_task_blueprint,
+                                                                                          selection_doc=task_relation_draft.selection_doc,
+                                                                                          selection_template=task_relation_draft.selection_template,
+                                                                                          dataformat=task_relation_draft.dataformat)
+                    logger.info("create_task_blueprint_from_task_draft(task_draft.id=%s) connected task_blueprint id=%s to task_blueprint id=%s via task_relation_blueprint id=%s",
+                                task_draft.pk, task_blueprint.pk, producing_task_blueprint.pk, task_relation_blueprint.pk)
 
     return task_blueprint
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
index 4516d434acbf9e031a0c6daad5d01a019668cea2..a5e519730502a9d7687adf4ed3774fa976c3b365 100644
--- a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
@@ -120,9 +120,9 @@ class ResourceUnitViewSet(LOFARViewSet):
     queryset = models.ResourceUnit.objects.all()
     serializer_class = serializers.ResourceUnitSerializer
     
-class TaskConnectorViewSet(LOFARViewSet):
-    queryset = models.TaskConnector.objects.all()
-    serializer_class = serializers.TaskConnectorSerializer
+class TaskConnectorTypeViewSet(LOFARViewSet):
+    queryset = models.TaskConnectorType.objects.all()
+    serializer_class = serializers.TaskConnectorTypeSerializer
 
 
 @permission_classes((DjangoModelPermissions,))   # example override of default permissions per viewset | todo: review for production
diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py
index d63bd5467b95e70743af60527169c458d92fe8e7..feb1c41cb6035b490f8db9090ba593e22013ee11 100644
--- a/SAS/TMSS/src/tmss/urls.py
+++ b/SAS/TMSS/src/tmss/urls.py
@@ -91,7 +91,7 @@ router.register(r'generator_template', viewsets.GeneratorTemplateViewSet)
 router.register(r'scheduling_unit_template', viewsets.SchedulingUnitTemplateViewSet)
 router.register(r'task_template', viewsets.TaskTemplateViewSet)
 router.register(r'task_relation_selection_template', viewsets.TaskRelationSelectionTemplateViewSet)
-router.register(r'task_connector', viewsets.TaskConnectorViewSet)
+router.register(r'task_connector_type', viewsets.TaskConnectorTypeViewSet)
 router.register(r'default_generator_template', viewsets.DefaultGeneratorTemplateViewSet)
 router.register(r'default_scheduling_unit_template', viewsets.DefaultSchedulingUnitTemplateViewSet)
 router.register(r'default_task_template', viewsets.DefaultTaskTemplateViewSet)