diff --git a/src/main/java/de/hftstuttgart/dtabackend/models/Result.java b/src/main/java/de/hftstuttgart/dtabackend/models/Result.java
index 8d0fefc6be22fba9419c40a49d5960de77f6cd50..4af7920b465b6be06222e2b1cea0fc48f1a2a7bd 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/models/Result.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/models/Result.java
@@ -2,7 +2,9 @@ package de.hftstuttgart.dtabackend.models;
 
 public class Result
 {
-    public String name;
+	public String packageName;
+	public String className;
+	public String name;
     public int state;
 
     public String failureType;
diff --git a/src/main/java/de/hftstuttgart/dtabackend/models/ResultSummary.java b/src/main/java/de/hftstuttgart/dtabackend/models/ResultSummary.java
index 97b61bb0605a14de7349c8d4749f154ce2c28556..b9a11ef87bfb3ddc55cff095ade84f9a278dbca0 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/models/ResultSummary.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/models/ResultSummary.java
@@ -7,5 +7,7 @@ public class ResultSummary
 {
     public long timestamp               = System.currentTimeMillis() / 1000;
     public String globalStacktrace      = null;
+    public String successfulTestCompetencyProfile;
+    public String overallTestCompetencyProfile;
     public Set<Result> results   = new HashSet<>();
 }
diff --git a/src/main/java/de/hftstuttgart/dtabackend/models/TestCompetencyProfile.java b/src/main/java/de/hftstuttgart/dtabackend/models/TestCompetencyProfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6a5e3ab506b7328d140597c46da2dd8d490ceaa
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/dtabackend/models/TestCompetencyProfile.java
@@ -0,0 +1,49 @@
+package de.hftstuttgart.dtabackend.models;
+
+public class TestCompetencyProfile {
+	public static final int MAX_COMPETENCY_DIMENSIONS = 16;
+	
+	public static final String COMPETENCY_SEPARATOR=";";
+	
+	public String testPackageName;
+	public String testClassName;
+	public String testName;
+	
+	public float[] competencyAssessments=new float[MAX_COMPETENCY_DIMENSIONS]; 
+	
+	public static float[] competencyProjection(float[] cp, float[] cp2) {
+	    float z[] = new float[MAX_COMPETENCY_DIMENSIONS];
+
+	    for (int i = 0; i < MAX_COMPETENCY_DIMENSIONS; i++) {
+	        z[i] = cp[i] * cp2[i];
+	    }
+	   return z;
+	}
+	
+	public static float[] competencyShare(float[] cp, float[] cpTotal) {
+	    float z[] = new float[MAX_COMPETENCY_DIMENSIONS];
+
+	    for (int i = 0; i < MAX_COMPETENCY_DIMENSIONS; i++) {
+	        z[i] = cp[i] / cpTotal[i];
+	    }
+	   return z;
+	}
+
+	public static float[] competencySum(float[] cp, float[] cp2) {
+	    float z[] = new float[MAX_COMPETENCY_DIMENSIONS];
+
+	    for (int i = 0; i < MAX_COMPETENCY_DIMENSIONS; i++) {
+	        z[i] = cp[i] + cp2[i];
+	    }
+	   return z;
+	}
+	
+	@Override
+	public boolean equals(Object other) {
+		return other instanceof TestCompetencyProfile && 
+				testPackageName.equals(((TestCompetencyProfile)other).testPackageName) &&
+				testClassName.equals(((TestCompetencyProfile)other).testClassName) &&
+				testName.equals(((TestCompetencyProfile)other).testName);
+	}
+
+}
diff --git a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
index 9f06d329f32421ec8756af2f8968b3faf9e01d61..4c4e520d8241e0082b272c0dc8e377da81be4d25 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
@@ -88,6 +88,8 @@ public class TaskUpload {
             LOG.info("check for provided Ticketsystem information");
             UnifiedTicketingUtil.reportResults(taskFileRef.getInputStream(), resultSummary);
         }
+        
+        taskFileRef.getInputStream().close();
 
         LOG.info("submission tested successfully");
         return resultSummary;
diff --git a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
index 3621b151d7491dd2f3c9c8764333d58011a3633a..310b8b4c7becba60156339eab5690137d6fcda03 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
@@ -65,7 +65,7 @@ public class UnitTestUpload {
         unitTestFileRef.transferTo(file);
         LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath()));
 
-        Pattern pattern = Pattern.compile(this.TESTCONFIGREGEX);
+        Pattern pattern = Pattern.compile(TESTCONFIGREGEX);
         Matcher config = null;
 
         LOG.debug("reading test configuration file");
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/CompetencyAssessmentUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/CompetencyAssessmentUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..4df652152d3d6a4776bcfdf8abe1095d0207e4c0
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/CompetencyAssessmentUtil.java
@@ -0,0 +1,88 @@
+package de.hftstuttgart.dtabackend.utils;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import de.hftstuttgart.dtabackend.models.Result;
+import de.hftstuttgart.dtabackend.models.ResultSummary;
+import de.hftstuttgart.dtabackend.models.TestCompetencyProfile;
+
+import java.io.FileNotFoundException;
+
+public class CompetencyAssessmentUtil {
+	private static final Logger LOG = LogManager.getLogger(CompetencyAssessmentUtil.class);
+			
+	public static String TEST_COMPETENCY_MANIFEST_FILE_NAME="competency-tests.mft";
+	
+/*	public static void main(String[] args) throws StreamReadException, DatabindException, MalformedURLException, IOException {
+		List<TestCompetencyProfile> testCompetencyProfiles=readTestCompetencyProfiles(Path.of(args[0]), args[1]);
+		sumTestCompetencyProfiles(testCompetencyProfiles);
+		ObjectMapper objectMapper = new ObjectMapper();
+        ResultSummary resultSummary = objectMapper.readValue(
+            new File(Path.of(args[0]).toFile(), args[2]).toURI().toURL(),
+            ResultSummary.class);
+		sumSuccessfulCompetencyProfiles(testCompetencyProfiles, resultSummary);
+	}
+*/	
+	public static float[] sumTestCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles) {
+		float[] tcpTotalProfile=new float[TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
+		for(TestCompetencyProfile currentProfile: testCompetencyProfiles) {
+			tcpTotalProfile=TestCompetencyProfile.competencySum(tcpTotalProfile, currentProfile.competencyAssessments);
+		}
+		return tcpTotalProfile;
+	}
+	
+	public static float[] sumSuccessfulCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles, ResultSummary resultSummary) {
+		float[] sumSuccessful=new float[TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
+		for(Result currentResult: resultSummary.results) {
+			if(currentResult.state==Result.State.SUCCESS.ordinal()) {
+				TestCompetencyProfile currentProfile=new TestCompetencyProfile();
+				currentProfile.testPackageName=currentResult.packageName;
+				currentProfile.testClassName=currentResult.className;
+				currentProfile.testName=currentResult.name;
+				int testIndex=testCompetencyProfiles.indexOf(currentProfile);
+				sumSuccessful=TestCompetencyProfile.competencySum(sumSuccessful, testCompetencyProfiles.get(testIndex).competencyAssessments);
+			}
+		}
+		return sumSuccessful;
+	}
+	
+	public static List<TestCompetencyProfile> readTestCompetencyProfiles(Path testPath, String fileName) {
+		List<TestCompetencyProfile> testCompetencyProfiles=new ArrayList<TestCompetencyProfile>();
+		try {
+			BufferedReader testCompetencyManifest=new BufferedReader(new FileReader(new File(testPath.toFile(), fileName)));
+			String testEntry=testCompetencyManifest.readLine();
+			while(testEntry!=null)
+			{
+				String[] testEntyComponents=testEntry.split(TestCompetencyProfile.COMPETENCY_SEPARATOR);
+				TestCompetencyProfile currentProfile=new TestCompetencyProfile();
+				currentProfile.testPackageName=testEntyComponents[0];
+				currentProfile.testClassName=testEntyComponents[1];
+				currentProfile.testName=testEntyComponents[2];
+				for(int competencyIndex=0; competencyIndex<TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS; competencyIndex++) {
+					currentProfile.competencyAssessments[competencyIndex]=Float.valueOf(testEntyComponents[competencyIndex+3]);
+				}
+				testCompetencyProfiles.add(currentProfile);
+				testEntry=testCompetencyManifest.readLine();
+			}
+			testCompetencyManifest.close();
+			LOG.info("Added "+testCompetencyProfiles.size()+" test competency profiles from test competency manifest. Optional agent functionality enabled.");
+		} catch (FileNotFoundException e) {
+			LOG.info("Test competency manifest file for agent feedback not found. Skipping optional functionality.");
+			testCompetencyProfiles=null;
+		} catch (IOException e) {
+			LOG.info("Test competency manifest file for agent feedback unreadable. Skipping optional functionality.");
+			testCompetencyProfiles=null;
+		} 
+		return testCompetencyProfiles;
+	}
+
+}
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
index 68f4e941a54c96a7055b48996ee913c1b72cd91d..bf2d5982dbe26ee7dc2dba92ca5b9765c139cf8a 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
@@ -8,7 +8,6 @@ import com.github.dockerjava.api.model.HostConfig;
 import com.github.dockerjava.core.DefaultDockerClientConfig;
 import com.github.dockerjava.core.DockerClientConfig;
 import com.github.dockerjava.core.DockerClientImpl;
-import com.github.dockerjava.transport.DockerHttpClient;
 import com.github.dockerjava.zerodep.ZerodepDockerHttpClient;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
index 83dd92436818586170b204eba5864aa3dee971f9..1e496cfac644dff14df71865f3d04dbb86841442 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
@@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.dockerjava.api.model.Bind;
 import com.github.dockerjava.api.model.Volume;
 import de.hftstuttgart.dtabackend.models.ResultSummary;
+import de.hftstuttgart.dtabackend.models.TestCompetencyProfile;
+
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.springframework.core.env.Environment;
@@ -13,7 +15,10 @@ import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.List;
 import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 @Component
 public class ExecuteTestUtil  {
@@ -109,7 +114,7 @@ public class ExecuteTestUtil  {
 
         // check if result file is there
         if (!resultFile.exists() || !resultFile.isFile()) {
-            LOG.error(String.format("couln't find result file in %s", resultFile.getAbsolutePath()));
+            LOG.error(String.format("Could not find result file in %s", resultFile.getAbsolutePath()));
             throw new RuntimeException("no resultfile found");
         }
 
@@ -118,7 +123,21 @@ public class ExecuteTestUtil  {
         ResultSummary resultSummary = objectMapper.readValue(
             resultFile.toURI().toURL(),
             ResultSummary.class);
-
+        
+        LOG.info("Checking for optional test competency profile information for paedagogical agent functionality...");
+        List<TestCompetencyProfile> testCompetencyProfiles=CompetencyAssessmentUtil.readTestCompetencyProfiles(testPathHost, CompetencyAssessmentUtil.TEST_COMPETENCY_MANIFEST_FILE_NAME);
+        if(testCompetencyProfiles!=null) {
+        	LOG.info("Found optional test competency profiles, generating agent profile data...");
+        	resultSummary.overallTestCompetencyProfile=packFloats(CompetencyAssessmentUtil.sumTestCompetencyProfiles(testCompetencyProfiles));
+        	resultSummary.successfulTestCompetencyProfile=packFloats(CompetencyAssessmentUtil.sumSuccessfulCompetencyProfiles(testCompetencyProfiles, resultSummary));
+        }
+        
         return resultSummary;
     }
+    
+    private static String packFloats(float[] array) {
+    	return IntStream.range(0, array.length)
+                .mapToObj(i -> String.valueOf(array[i]))
+                .collect(Collectors.joining(";"));
+    }
 }
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/RegexUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/RegexUtil.java
index c0692d715d9da189f1bc976a20d4fd91f0c3e723..64227dd6124510a98b8e2df56dec666ce1060f5f 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/RegexUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/RegexUtil.java
@@ -15,7 +15,7 @@ import java.util.regex.Pattern;
 public class RegexUtil {
 
     public enum ConfigType {
-        PROFESSOR,
+        TEACHER,
         STUDENT,
     }
 
@@ -26,13 +26,13 @@ public class RegexUtil {
     }
 
     public static Matcher findProfessorConfig(InputStream is) {
-        return findConfig(is, ConfigType.PROFESSOR);
+        return findConfig(is, ConfigType.TEACHER);
     }
 
     public static Matcher findConfig(InputStream is, ConfigType configType) {
         Pattern pattern;
         switch (configType) {
-            case PROFESSOR:
+            case TEACHER:
                 pattern = Pattern.compile(UnitTestUpload.TESTCONFIGREGEX);
                 break;