diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IAnnotation.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IAnnotation.java
index d8957a0d393696650cc86ad0216d05ea68bcfa65..0378153de66a916d195a5b498f4654a88d49d671 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IAnnotation.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IAnnotation.java
@@ -3,6 +3,7 @@ package unipotsdam.gf.interfaces;
 import unipotsdam.gf.modules.annotation.model.Annotation;
 import unipotsdam.gf.modules.annotation.model.AnnotationPatchRequest;
 import unipotsdam.gf.modules.annotation.model.AnnotationPostRequest;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
 
 import java.util.ArrayList;
 
@@ -44,12 +45,13 @@ public interface IAnnotation {
     Annotation getAnnotation(String annotationId);
 
     /**
-     * Returns all annotations from a target
+     * Returns all annotations for a specific target id and category
      *
-     * @param targetId the target id
-     * @return Returns all annotations
+     * @param targetId The if of the target
+     * @param targetCategory The category of the target
+     * @return Returns all annotations for a target
      */
-    ArrayList<Annotation> getAnnotations(int targetId);
+    ArrayList<Annotation> getAnnotations(String targetId, Category targetCategory);
 
     /**
      * Checks if an annotation id already exists in the database
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ISubmission.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ISubmission.java
new file mode 100644
index 0000000000000000000000000000000000000000..01a450025cfcf1e1cddf4b6b8bc059ffb29da3a0
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ISubmission.java
@@ -0,0 +1,80 @@
+package unipotsdam.gf.interfaces;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+import unipotsdam.gf.modules.submission.model.*;
+
+import java.util.ArrayList;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public interface ISubmission {
+
+    /**
+     * Store the full submission text in the database
+     *
+     * @param request The full submission post request
+     * @return The new full submission
+     */
+    FullSubmission addFullSubmission(FullSubmissionPostRequest request);
+
+    /**
+     * Get the entire submission from the databse
+     *
+     * @param fullSubmissionId The id of the submission
+     * @return The full submission
+     */
+    FullSubmission getFullSubmission(String fullSubmissionId);
+
+    /**
+     * Checks if a full submission id already exists in the database
+     *
+     * @param fullSubmissionId The id of the full submission
+     * @return Returns true if the id exists
+     */
+    boolean existsFullSubmissionId(String fullSubmissionId);
+
+    /**
+     * Store the submission part text in the database
+     *
+     * @param submissionPartPostRequest The submission part post request
+     * @return The new submission part
+     */
+    SubmissionPart addSubmissionPart(SubmissionPartPostRequest submissionPartPostRequest);
+
+    /**
+     * Get the entire submission part from database
+     *
+     * @param fullSubmissionId The id of the full submission
+     * @param category The category of the submission
+     * @return The returned submission part
+     */
+    SubmissionPart getSubmissionPart(String fullSubmissionId, Category category);
+
+    /**
+     * Get all submission parts based on an id
+     *
+     * @param fullSubmissionId The id of a full submission
+     * @return An ArrayList holding the submission parts
+     */
+    ArrayList<SubmissionPart> getAllSubmissionParts(String fullSubmissionId);
+
+    /**
+     * Get all project representations of submission part for a given project id
+     *
+     * @param projectId The given project id
+     * @return An ArrayList of submission project representations
+     */
+    ArrayList<SubmissionProjectRepresentation> getSubmissionPartsByProjectId(String projectId);
+
+    /**
+     * Checks if a submission part already exists in the database
+     *
+     * @param fullSubmissionId The id of the full submission
+     * @param category The category of the submission
+     * @return Returns true if the submission part exists
+     */
+    boolean existsSubmissionPart(String fullSubmissionId, Category category);
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/controller/AnnotationController.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/controller/AnnotationController.java
index ce29362c3f10354b41d3802bd945d638e62b52c9..394ccf69df9e554a136704c2221a0f4e1b3a4bfe 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/controller/AnnotationController.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/controller/AnnotationController.java
@@ -7,6 +7,7 @@ import unipotsdam.gf.modules.annotation.model.Annotation;
 import unipotsdam.gf.modules.annotation.model.AnnotationBody;
 import unipotsdam.gf.modules.annotation.model.AnnotationPatchRequest;
 import unipotsdam.gf.modules.annotation.model.AnnotationPostRequest;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
 
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
@@ -27,8 +28,8 @@ public class AnnotationController implements IAnnotation {
         connection.connect();
 
         // build and execute request
-        String request = "INSERT INTO annotations (`id`, `userToken`, `targetId`, `title`, `comment`, `startCharacter`, `endCharacter`) VALUES (?,?,?,?,?,?,?);";
-        connection.issueInsertOrDeleteStatement(request, uuid, annotationPostRequest.getUserToken(), annotationPostRequest.getTargetId(), annotationPostRequest.getBody().getTitle(), annotationPostRequest.getBody().getComment(),annotationPostRequest.getBody().getStartCharacter(), annotationPostRequest.getBody().getEndCharacter());
+        String request = "INSERT INTO annotations (`id`, `userToken`, `targetId`, `targetCategory`, `title`, `comment`, `startCharacter`, `endCharacter`) VALUES (?,?,?,?,?,?,?,?);";
+        connection.issueInsertOrDeleteStatement(request, uuid, annotationPostRequest.getUserToken(), annotationPostRequest.getTargetId(), annotationPostRequest.getTargetCategory().toString().toUpperCase(), annotationPostRequest.getBody().getTitle(), annotationPostRequest.getBody().getComment(),annotationPostRequest.getBody().getStartCharacter(), annotationPostRequest.getBody().getEndCharacter());
 
         // close connection
         connection.close();
@@ -104,7 +105,7 @@ public class AnnotationController implements IAnnotation {
     }
 
     @Override
-    public ArrayList<Annotation> getAnnotations(int targetId) {
+    public ArrayList<Annotation> getAnnotations(String targetId, Category category) {
 
         // declare annotation ArrayList
         ArrayList<Annotation> annotations = new ArrayList<>();
@@ -114,8 +115,8 @@ public class AnnotationController implements IAnnotation {
         connection.connect();
 
         // build and execute request
-        String request = "SELECT * FROM annotations WHERE targetId = ?;";
-        VereinfachtesResultSet rs = connection.issueSelectStatement(request, targetId);
+        String request = "SELECT * FROM annotations WHERE targetId = ? AND targetCategory = ?;";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, targetId, category.toString().toUpperCase());
 
         while (rs.next()) {
             annotations.add(getAnnotationFromResultSet(rs));
@@ -171,7 +172,8 @@ public class AnnotationController implements IAnnotation {
         String id = rs.getString("id");
         long timestamp = rs.getTimestamp(2).getTime();
         String userToken = rs.getString("userToken");
-        int targetId = rs.getInt("targetId");
+        String targetId = rs.getString("targetId");
+        Category targetCategory = Category.valueOf(rs.getString("targetCategory"));
 
         // initialize new annotation body
         String title = rs.getString("title");
@@ -180,7 +182,7 @@ public class AnnotationController implements IAnnotation {
         int endCharacter = rs.getInt("endCharacter");
         AnnotationBody body = new AnnotationBody(title, comment, startCharacter, endCharacter);
 
-        return new Annotation(id, timestamp, userToken, targetId, body);
+        return new Annotation(id, timestamp, userToken, targetId, targetCategory, body);
 
     }
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/Annotation.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/Annotation.java
index 699ec3eda8ad469fda08b6688311fabb9a17bc5b..950959d31d5820e480aeefb57852c9dbecb4cfa4 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/Annotation.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/Annotation.java
@@ -1,5 +1,7 @@
 package unipotsdam.gf.modules.annotation.model;
 
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
 /**
  * @author Sven Kästle
  * skaestle@uni-potsdam.de
@@ -10,15 +12,17 @@ public class Annotation {
     private String id;
     private long timestamp;
     private String userToken;
-    private int targetId;
+    private String targetId;
+    private Category targetCategory;
     private AnnotationBody body;
 
     // constructor
-    public Annotation(String id, long timestamp, String userToken, int targetId, AnnotationBody body) {
+    public Annotation(String id, long timestamp, String userToken, String targetId, Category targetCategory, AnnotationBody body) {
         this.id = id;
         this.timestamp = timestamp;
         this.userToken = userToken;
         this.targetId = targetId;
+        this.targetCategory = targetCategory;
         this.body = body;
     }
 
@@ -47,14 +51,22 @@ public class Annotation {
         this.userToken = userToken;
     }
 
-    public int getTargetId() {
+    public String getTargetId() {
         return targetId;
     }
 
-    public void setTargetId(int targetId) {
+    public void setTargetId(String targetId) {
         this.targetId = targetId;
     }
 
+    public Category getTargetCategory() {
+        return targetCategory;
+    }
+
+    public void setTargetCategory(Category targetCategory) {
+        this.targetCategory = targetCategory;
+    }
+
     public AnnotationBody getBody() {
         return body;
     }
@@ -70,6 +82,7 @@ public class Annotation {
                 ", timestamp=" + timestamp +
                 ", userToken='" + userToken + '\'' +
                 ", targetId=" + targetId +
+                ", targetCategory=" + targetCategory +
                 ", body=" + body +
                 '}';
     }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java
index 60d895b66b293668f4b505684a46d75ebea88dbe..f8e3f913afcdae8ec44cfe720eb26165bcd296f4 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationMessage.java
@@ -1,9 +1,12 @@
 package unipotsdam.gf.modules.annotation.model;
 
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
 public class AnnotationMessage {
     // variables
     private String from;
     private String targetId;
+    private Category targetCategory;
     private AnnotationMessageType type;
     private String annotationId;
 
@@ -30,6 +33,14 @@ public class AnnotationMessage {
         this.targetId = targetId;
     }
 
+    public Category getTargetCategory() {
+        return targetCategory;
+    }
+
+    public void setTargetCategory(Category targetCategory) {
+        this.targetCategory = targetCategory;
+    }
+
     public AnnotationMessageType getType() {
         return type;
     }
@@ -51,8 +62,10 @@ public class AnnotationMessage {
         return "AnnotationMessage{" +
                 "from='" + from + '\'' +
                 ", targetId='" + targetId + '\'' +
+                ", targetCategory=" + targetCategory +
                 ", type=" + type +
                 ", annotationId='" + annotationId + '\'' +
                 '}';
     }
+
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationPostRequest.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationPostRequest.java
index 5dfe6e206f1f014eb3ce88fbc22e401323b2c422..1ae3c2b6b5137b7877367c3342b1f2eaab7584f4 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationPostRequest.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/model/AnnotationPostRequest.java
@@ -1,5 +1,7 @@
 package unipotsdam.gf.modules.annotation.model;
 
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
 /**
  * @author Sven Kästle
  * skaestle@uni-potsdam.de
@@ -8,13 +10,15 @@ public class AnnotationPostRequest {
 
     // variables
     private String userToken;
-    private int targetId;
+    private String targetId;
+    private Category targetCategory;
     private AnnotationBody body;
 
     // constructors
-    public AnnotationPostRequest(String userToken, int targetId, AnnotationBody body) {
+    public AnnotationPostRequest(String userToken, String targetId, Category targetCategory, AnnotationBody body) {
         this.userToken = userToken;
         this.targetId = targetId;
+        this.targetCategory = targetCategory;
         this.body = body;
     }
 
@@ -30,14 +34,22 @@ public class AnnotationPostRequest {
         this.userToken = userToken;
     }
 
-    public int getTargetId() {
+    public String getTargetId() {
         return targetId;
     }
 
-    public void setTargetId(int targetId) {
+    public void setTargetId(String targetId) {
         this.targetId = targetId;
     }
 
+    public Category getTargetCategory() {
+        return targetCategory;
+    }
+
+    public void setTargetCategory(Category targetCategory) {
+        this.targetCategory = targetCategory;
+    }
+
     public AnnotationBody getBody() {
         return body;
     }
@@ -51,8 +63,9 @@ public class AnnotationPostRequest {
         return "AnnotationPostRequest{" +
                 "userToken='" + userToken + '\'' +
                 ", targetId=" + targetId +
-                ", body=" + body.toString() +
+                ", targetCategory=" + targetCategory +
+                ", body=" + body +
                 '}';
     }
-
+    
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/view/AnnotationService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/view/AnnotationService.java
index 1072cd55891857bc8fa1d2d9ece561f5b105da81..9a4656e6dc7098c0c7563a57a162ef5d3bc782ae 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/view/AnnotationService.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/view/AnnotationService.java
@@ -6,6 +6,7 @@ import unipotsdam.gf.modules.annotation.model.Annotation;
 import unipotsdam.gf.modules.annotation.model.AnnotationPatchRequest;
 import unipotsdam.gf.modules.annotation.model.AnnotationPostRequest;
 import unipotsdam.gf.modules.annotation.model.AnnotationResponse;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
@@ -108,12 +109,12 @@ public class AnnotationService {
     }
 
     @GET
-    @Path("/target/{id}")
-    public Response getAnnotations(@PathParam("id") int targetId) {
+    @Path("/targetid/{id}/targetcategory/{category}")
+    public Response getAnnotations(@PathParam("id") String targetId, @PathParam("category") String category) {
 
         // receive the annotation
         AnnotationController controller = new AnnotationController();
-        ArrayList<Annotation> annotations = controller.getAnnotations(targetId);
+        ArrayList<Annotation> annotations = controller.getAnnotations(targetId, Category.valueOf(category.toUpperCase()));
 
         if (!annotations.isEmpty()) {
             return Response.ok(annotations).build();
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWSTarget.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWSTarget.java
new file mode 100644
index 0000000000000000000000000000000000000000..09409309c304231d50a4e472cba639dd60d5dd6a
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWSTarget.java
@@ -0,0 +1,46 @@
+package unipotsdam.gf.modules.annotation.websocket;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class AnnotationWSTarget {
+
+    // variables
+    String targetId;
+    Category targetCategory;
+
+    // constructor
+    public AnnotationWSTarget(String targetId, Category targetCategory) {
+        this.targetId = targetId;
+        this.targetCategory = targetCategory;
+    }
+
+    // methods
+    public String getTargetId() {
+        return targetId;
+    }
+
+    public void setTargetId(String targetId) {
+        this.targetId = targetId;
+    }
+
+    public Category getTargetCategory() {
+        return targetCategory;
+    }
+
+    public void setTargetCategory(Category targetCategory) {
+        this.targetCategory = targetCategory;
+    }
+
+    @Override
+    public String toString() {
+        return "AnnotationWSTarget{" +
+                "targetId='" + targetId + '\'' +
+                ", targetCategory=" + targetCategory.toString() +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java
index 29c2d3f61ebc6da8e99be59dfdff206c8e1810b0..b30743913672d6770337c6d4b5ca5dcebfeda1a5 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/annotation/websocket/AnnotationWebSocketEndpoint.java
@@ -1,6 +1,7 @@
 package unipotsdam.gf.modules.annotation.websocket;
 
 import unipotsdam.gf.modules.annotation.model.AnnotationMessage;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
 
 import javax.websocket.*;
 import javax.websocket.server.PathParam;
@@ -10,26 +11,27 @@ import java.util.HashMap;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 
-@ServerEndpoint(value = "/ws/annotation/{targetId}", decoders = AnnotationMessageDecoder.class, encoders = AnnotationMessageEncoder.class)
+@ServerEndpoint(value = "/ws/annotation/{targetId}/{targetCategory}", decoders = AnnotationMessageDecoder.class, encoders = AnnotationMessageEncoder.class)
 public class AnnotationWebSocketEndpoint {
 
     private Session session;
     private static final Set<AnnotationWebSocketEndpoint> endpoints = new CopyOnWriteArraySet<>();
-    private static HashMap<String, String> targets = new HashMap<>();
+    private static HashMap<String, AnnotationWSTarget> targets = new HashMap<>();
 
     @OnOpen
-    public void onOpen(Session session, @PathParam("targetId") String targetId) throws IOException {
+    public void onOpen(Session session, @PathParam("targetId") String targetId, @PathParam("targetCategory") String targetCategory) throws IOException {
         // initialize session
         this.session = session;
         // save endpoint in set of endpoints
         endpoints.add(this);
-        // save mapping of session and target id
-        targets.put(session.getId(), targetId);
+        // save mapping of session and target (id + category)
+        targets.put(session.getId(), new AnnotationWSTarget(targetId, Category.valueOf(targetCategory.toUpperCase())));
     }
 
     @OnMessage
     public void onMessage(Session session, AnnotationMessage annotationMessage) throws IOException, EncodeException {
-        annotationMessage.setTargetId(targets.get(session.getId()));
+        annotationMessage.setTargetId(targets.get(session.getId()).getTargetId());
+        annotationMessage.setTargetCategory(targets.get(session.getId()).getTargetCategory());
         annotationMessage.setFrom(session.getId());
         broadcast(annotationMessage);
 
@@ -49,7 +51,8 @@ public class AnnotationWebSocketEndpoint {
         endpoints.forEach(endpoint -> {
             synchronized (endpoint) {
                 try {
-                    if (targets.get(endpoint.session.getId()).equals(annotationMessage.getTargetId())
+                    if (targets.get(endpoint.session.getId()).getTargetId().equals(annotationMessage.getTargetId())
+                            && targets.get(endpoint.session.getId()).getTargetCategory() == annotationMessage.getTargetCategory()
                             && !endpoint.session.getId().equals(annotationMessage.getFrom())) {
                         System.out.println("Send message to session" + endpoint.session.getId() + " from session " + annotationMessage.getFrom());
                         endpoint.session.getBasicRemote().sendObject(annotationMessage);
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f5b6a30279d55b5157c0b31ee285e68c077f528
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java
@@ -0,0 +1,568 @@
+package unipotsdam.gf.modules.submission.controller;
+
+import com.google.common.base.Strings;
+import unipotsdam.gf.core.database.mysql.MysqlConnect;
+import unipotsdam.gf.core.database.mysql.VereinfachtesResultSet;
+import unipotsdam.gf.interfaces.ISubmission;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+import unipotsdam.gf.modules.submission.model.*;
+
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import java.util.UUID;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class SubmissionController implements ISubmission {
+    @Override
+    public FullSubmission addFullSubmission(FullSubmissionPostRequest fullSubmissionPostRequest) {
+
+        // create a new id if we found no id.
+        String uuid = UUID.randomUUID().toString();
+        while (existsFullSubmissionId(uuid)) {
+            uuid = UUID.randomUUID().toString();
+        }
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "INSERT INTO fullsubmissions (`id`, `user`, `text`, `projectId`) VALUES (?,?,?,?);";
+        connection.issueInsertOrDeleteStatement(request, uuid, fullSubmissionPostRequest.getUser(), fullSubmissionPostRequest.getText(), fullSubmissionPostRequest.getProjectId());
+
+        // get the new submission from database
+        FullSubmission fullSubmission = getFullSubmission(uuid);
+
+        // close connection
+        connection.close();
+
+        return fullSubmission;
+
+    }
+
+    @Override
+    public FullSubmission getFullSubmission(String fullSubmissionId) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "SELECT * FROM fullsubmissions WHERE id = ?;";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId);
+
+        if (rs.next()) {
+            // save submission
+            FullSubmission fullSubmission = getFullSubmissionFromResultSet(rs);
+
+            // close connection
+            connection.close();
+
+            return fullSubmission;
+        }
+        else {
+
+            // close connection
+            connection.close();
+
+            return null;
+        }
+
+    }
+
+    @Override
+    public boolean existsFullSubmissionId(String id) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "SELECT COUNT(*) > 0 AS `exists` FROM fullsubmissions WHERE id = ?;";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, id);
+
+        if (rs.next()) {
+            // save the response
+            int count = rs.getInt("exists");
+
+            // close connection
+            connection.close();
+
+            // return true if we found the id
+            if (count < 1) {
+                return false;
+            }
+            else {
+                return true;
+            }
+        }
+
+        // something happened
+        return true;
+
+    }
+
+    @Override
+    public SubmissionPart addSubmissionPart(SubmissionPartPostRequest submissionPartPostRequest) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "INSERT IGNORE INTO submissionparts (`userId`, `fullSubmissionId`, `category`) VALUES (?,?,?);";
+        connection.issueInsertOrDeleteStatement(request, submissionPartPostRequest.getUserId(), submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory().toString().toUpperCase());
+
+        // declare request string
+        String requestElement;
+        for (SubmissionPartBodyElement element : submissionPartPostRequest.getBody()) {
+
+            // calculate how many similar elements are next to the new element
+            int similarElements = numOfSimilarBodyElements(submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getStartCharacter(), element.getEndCharacter());
+
+            switch (similarElements) {
+                // similar element on the left side
+                case -1:
+                    requestElement = "UPDATE submissionpartbodyelements SET endCharacter = ? WHERE fullSubmissionId = ? AND category = ? AND endCharacter = ?;";
+                    connection.issueUpdateStatement(requestElement, element.getEndCharacter(), submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getStartCharacter());
+                    break;
+                // no similar element
+                case 0:
+                    if (!hasOverlappingBoundaries(submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element)) {
+                        requestElement = "INSERT IGNORE INTO submissionpartbodyelements (`fullSubmissionId`, `category`, `startCharacter`, `endCharacter`) VALUES (?,?,?,?);";
+                        connection.issueInsertOrDeleteStatement(requestElement, submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory().toString().toUpperCase(), element.getStartCharacter(), element.getEndCharacter());
+                    }
+                    break;
+                // similar element on the right side
+                case 1:
+                    requestElement = "UPDATE submissionpartbodyelements SET startCharacter = ? WHERE fullSubmissionId = ? AND category = ? AND startCharacter = ?;";
+                    connection.issueUpdateStatement(requestElement, element.getStartCharacter(), submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getEndCharacter());
+                    break;
+                // similar elements on both sides
+                case 2:
+                    // fetch end character from right element
+                    requestElement = "SELECT endCharacter FROM submissionpartbodyelements WHERE fullSubmissionId = ? AND category = ? AND startCharacter = ?;";
+                    VereinfachtesResultSet rs = connection.issueSelectStatement(requestElement, submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getEndCharacter());
+
+                    // delete right element
+                    String deleteElement = "DELETE FROM submissionpartbodyelements WHERE fullSubmissionId = ? AND category = ? AND startCharacter = ?;";
+                    connection.issueInsertOrDeleteStatement(deleteElement, submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getEndCharacter());
+
+                    if (rs.next()) {
+                        int end = rs.getInt("endCharacter");
+
+                        // update left element
+                        String updateElement = "UPDATE submissionpartbodyelements SET endCharacter = ? WHERE fullSubmissionId = ? AND category = ? AND endCharacter = ?;";
+                        connection.issueUpdateStatement(updateElement, end, submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory(), element.getStartCharacter());
+
+                    }
+
+            }
+
+        }
+
+        // get the new submission from database
+        SubmissionPart submissionPart = getSubmissionPart(submissionPartPostRequest.getFullSubmissionId(), submissionPartPostRequest.getCategory());
+
+        // close connection
+        connection.close();
+
+        return submissionPart;
+
+    }
+
+    @Override
+    public SubmissionPart getSubmissionPart(String fullSubmissionId, Category category) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // declare text
+        String text;
+
+        // build and execute request to receive text
+        String requestText = "SELECT text " +
+                "FROM fullsubmissions " +
+                "WHERE id = ?";
+        VereinfachtesResultSet rsText = connection.issueSelectStatement(requestText, fullSubmissionId);
+
+        if (rsText.next()) {
+            // save text
+            text = rsText.getString("text");
+
+            // build and execute request
+            String request = "SELECT * FROM submissionparts s " +
+                    "LEFT JOIN submissionpartbodyelements b " +
+                    "ON s.fullSubmissionId = b.fullSubmissionId " +
+                    "AND s.category = b.category " +
+                    "WHERE s.fullSubmissionId = ? " +
+                    "AND s.category = ?;";
+            VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId, category);
+
+            if (rs.next()) {
+                // save submission
+                SubmissionPart submissionPart = getSubmissionPartFromResultSet(rs, text);
+
+                // close connection
+                connection.close();
+
+                return submissionPart;
+            }
+            else {
+                // close connection
+                connection.close();
+
+                return null;
+            }
+        }
+
+        return null;
+
+    }
+
+    @Override
+    public ArrayList<SubmissionPart> getAllSubmissionParts(String fullSubmissionId) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // declare text
+        String text;
+
+        // build and execute request to receive text
+        String requestText = "SELECT text " +
+                "FROM fullsubmissions " +
+                "WHERE id = ?";
+        VereinfachtesResultSet rsText = connection.issueSelectStatement(requestText, fullSubmissionId);
+
+        if (rsText.next()) {
+            // save text
+            text = rsText.getString("text");
+
+            // build and execute request
+            String request = "SELECT * " +
+                    "FROM submissionparts sp " +
+                    "LEFT JOIN submissionpartbodyelements  spbe " +
+                    "ON sp.fullSubmissionId = spbe.fullSubmissionId " +
+                    "AND sp.category = spbe.category " +
+                    "WHERE sp.fullSubmissionId = ? " +
+                    "ORDER BY sp.timestamp;";
+            VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId);
+
+            ArrayList<SubmissionPart> submissionParts = new ArrayList<>();
+
+            if (rs.next()) {
+                // save submission
+                submissionParts = getAllSubmissionPartsFromResultSet(rs, text);
+            }
+
+            // close connection
+            connection.close();
+
+            return submissionParts;
+        }
+
+        // close connection
+        connection.close();
+
+        return null;
+
+    }
+
+    @Override
+    public ArrayList<SubmissionProjectRepresentation> getSubmissionPartsByProjectId(String projectId) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "SELECT s.userId, s.category, s.fullSubmissionId " +
+                "FROM fullsubmissions f " +
+                "LEFT JOIN submissionparts s " +
+                "ON f.id = s.fullSubmissionId " +
+                "WHERE f.projectId = ?";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, projectId);
+
+        ArrayList<SubmissionProjectRepresentation> representations;
+
+        // save submission
+        representations = getAllSubmissionProjectRepresentationsFromResultSet(rs);
+
+        // close connection
+        connection.close();
+
+        return representations;
+
+    }
+
+    @Override
+    public boolean existsSubmissionPart(String fullSubmissionId, Category category) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "SELECT COUNT(*) > 0 AS `exists` FROM submissionparts WHERE fullSubmissionId = ? AND category = ?;";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId, category);
+
+        if (rs.next()) {
+            // save the response
+            int count = rs.getInt("exists");
+
+            // close connection
+            connection.close();
+
+            // return true if we found the id
+            if (count < 1) {
+                return false;
+            }
+            else {
+                return true;
+            }
+        }
+
+        // something happened
+        return true;
+
+    }
+
+    /**
+     * Build a full submission object from a given result set
+     *
+     * @param rs The result set from a database query
+     * @return A new full submission object
+     */
+    private FullSubmission getFullSubmissionFromResultSet(VereinfachtesResultSet rs) {
+
+        String id = rs.getString("id");
+        long timestamp = rs.getTimestamp("timestamp").getTime();
+        String user = rs.getString("user");
+        String text = rs.getString("text");
+        String projectId = rs.getString("projectId");
+
+        return new FullSubmission(id, timestamp, user, text, projectId);
+
+    }
+
+    /**
+     * Build a submission part object from a given result set
+     *
+     * @param rs The result set from the database query
+     * @return A new submission part object
+     */
+    private SubmissionPart getSubmissionPartFromResultSet(VereinfachtesResultSet rs, String text) {
+
+        // declare variables
+        int start, end;
+        String textPart;
+
+        // initialize variables
+        long timestamp = rs.getTimestamp("timestamp").getTime();
+        String userId = rs.getString("userId");
+        String fullSubmissionId = rs.getString("fullSubmissionId");
+        Category category = Category.valueOf(rs.getString("category").toUpperCase());
+
+        // build body and iterate over result set
+        ArrayList<SubmissionPartBodyElement> body = new ArrayList<>();
+
+        do {
+            // initialize body variables
+            start = rs.getInt("startCharacter");
+            end = rs.getInt("endCharacter");
+            textPart = text.substring(start, end);
+
+            // build element
+            SubmissionPartBodyElement element = new SubmissionPartBodyElement(textPart, start, end);
+
+            body.add(element);
+        } while (rs.next());
+
+        return new SubmissionPart(timestamp, userId, fullSubmissionId, category, body);
+    }
+
+    /**
+     * Build an array of submission part objects from a given result set
+     *
+     * @param rs The result set from the database query, holding different submission parts
+     * @return An array of submission parts
+     */
+    private ArrayList<SubmissionPart> getAllSubmissionPartsFromResultSet(VereinfachtesResultSet rs, String text) {
+
+        // declare variables
+        int start, end;
+        String textPart;
+
+        ArrayList<SubmissionPart> submissionParts = new ArrayList<>();
+        // tmp part
+        SubmissionPart tmpPart = null;
+        // tmp body element
+        SubmissionPartBodyElement tmpElement;
+        // tmp category
+        String tmpCategory = "";
+        do {
+
+            if (!tmpCategory.equals(rs.getString("category").toUpperCase())) {
+                // current tmp category
+                tmpCategory = rs.getString("category").toUpperCase();
+
+                // add last submission part
+                if (tmpPart != null) {
+                    submissionParts.add(tmpPart);
+                }
+
+                // build submission part with empty body
+                tmpPart = new SubmissionPart(
+                    rs.getTimestamp("timestamp").getTime(),
+                    rs.getString("userId"),
+                    rs.getString("fullSubmissionId"),
+                    Category.valueOf(tmpCategory),
+                    new ArrayList<SubmissionPartBodyElement>()
+                );
+            }
+
+            // initialize body variables
+            start = rs.getInt("startCharacter");
+            end = rs.getInt("endCharacter");
+            textPart = text.substring(start, end);
+
+            tmpElement = new SubmissionPartBodyElement(textPart, start, end);
+
+            tmpPart.getBody().add(tmpElement);
+
+        } while (rs.next());
+
+        // add last part
+        submissionParts.add(tmpPart);
+
+        return submissionParts;
+    }
+
+    private ArrayList<SubmissionProjectRepresentation> getAllSubmissionProjectRepresentationsFromResultSet(VereinfachtesResultSet rs) {
+
+        ArrayList<SubmissionProjectRepresentation> representations = new ArrayList<>();
+
+        while (rs.next()) {
+            if (!Strings.isNullOrEmpty(rs.getString("category"))) {
+                representations.add(new SubmissionProjectRepresentation(
+                        rs.getString("userId"),
+                        Category.valueOf(rs.getString("category").toUpperCase()),
+                        rs.getString("fullSubmissionId")
+                ));
+            }
+        }
+
+        return representations;
+
+    }
+
+    /**
+     * Calculates how many similar body elements (based on start and end character) can be found in the database
+     *
+     * @param fullSubmissionId The id of the full submission
+     * @param category The category of the submission part
+     * @param startCharacter The start character of the new element
+     * @param endCharacter The end character of the old element
+     * @return Return 0 if there are no similar elements, 2 if we found two similar elements (right and left side),
+     * 1 if we found a similar element on the right side and -1 if we found a similar element on the left side.
+     */
+    private int numOfSimilarBodyElements(String fullSubmissionId, Category category, int startCharacter, int endCharacter) {
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // build and execute request
+        String request = "SELECT COUNT(*) AS `count` FROM submissionpartbodyelements WHERE fullSubmissionId = ? AND category = ? AND (endCharacter = ? OR startCharacter = ?);";
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId, category.toString().toUpperCase(), startCharacter, endCharacter);
+
+        if (rs.next()) {
+            // save the response
+            int count = rs.getInt("count");
+
+            // found one element; left or right side
+            if (count == 1) {
+
+                // build and execute request to find out on which side we found a similar body element
+                String requestSide = "SELECT COUNT(*) AS `side` FROM submissionpartbodyelements WHERE fullSubmissionId = ? AND category = ? AND endCharacter = ?;";
+                VereinfachtesResultSet rsSide = connection.issueSelectStatement(requestSide, fullSubmissionId, category.toString().toUpperCase(), startCharacter);
+
+                if (rsSide.next()) {
+                    // save the response
+                    int side = rsSide.getInt("side");
+
+                    // close connection
+                    connection.close();
+
+                    if (side == 1) {
+                        return -1;
+                    }
+                    else {
+                        return 1;
+                    }
+
+                }
+            }
+            else {
+                // close connection
+                connection.close();
+
+                return count;
+            }
+        }
+
+        return 0;
+
+    }
+
+    /**
+     * Checks if a new body element has overlapping boundaries with an already existing element
+     *
+     * @param fullSubmissionId The id of the full submission
+     * @param category The category
+     * @param element The new element
+     * @return Returns true if overlapping boundaries have been found
+     */
+    private boolean hasOverlappingBoundaries(String fullSubmissionId, Category category, SubmissionPartBodyElement element) {
+
+        // establish connection
+        MysqlConnect connection = new MysqlConnect();
+        connection.connect();
+
+        // initialize start and end character
+        int start = element.getStartCharacter();
+        int end = element.getEndCharacter();
+
+        // build and execute request
+        String request = "SELECT COUNT(*) > 0 AS `exists` FROM submissionpartbodyelements WHERE fullSubmissionId = ? AND category = ? AND (" +
+                "(startCharacter <= ? AND ? <= endCharacter) OR " + // start character overlapping
+                "(startCharacter <= ? AND ? <= endCharacter));"; // end character overlapping
+        VereinfachtesResultSet rs = connection.issueSelectStatement(request, fullSubmissionId, category.toString(), start, start, end, end);
+
+        if (rs.next()) {
+            // save the response
+            int count = rs.getInt("exists");
+
+            // close connection
+            connection.close();
+
+            // return true if we found the id
+            if (count < 1) {
+                return false;
+            }
+            else {
+                return true;
+            }
+        }
+
+        // something happened
+        return true;
+
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmission.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmission.java
new file mode 100644
index 0000000000000000000000000000000000000000..37b35c9fb9809ee409548f374c3623d73e204170
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmission.java
@@ -0,0 +1,77 @@
+package unipotsdam.gf.modules.submission.model;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class FullSubmission {
+
+    // variables
+    private String id;
+    private long timestamp;
+    private String user;
+    private String text;
+    private String projectId;
+
+    // constructor
+    public FullSubmission(String id, long timestamp, String user, String text, String projectId) {
+        this.id = id;
+        this.timestamp = timestamp;
+        this.user = user;
+        this.text = text;
+        this.projectId = projectId;
+    }
+
+    // methods
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public String toString() {
+        return "FullSubmission{" +
+                "id='" + id + '\'' +
+                ", timestamp=" + timestamp +
+                ", user='" + user + '\'' +
+                ", text='" + text + '\'' +
+                ", projectId='" + projectId + '\'' +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmissionPostRequest.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmissionPostRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..48a2dfe748498fcd1f672ac5eb6ed2bc126af227
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/FullSubmissionPostRequest.java
@@ -0,0 +1,57 @@
+package unipotsdam.gf.modules.submission.model;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class FullSubmissionPostRequest {
+
+    // variables
+    private String user;
+    private String text;
+    private String projectId;
+
+    // constructors
+    public FullSubmissionPostRequest(String user, String text, String projectId) {
+        this.user = user;
+        this.text = text;
+        this.projectId = projectId;
+    }
+
+    public FullSubmissionPostRequest() {}
+
+    // methods
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public String toString() {
+        return "FullSubmissionPostRequest{" +
+                "user='" + user + '\'' +
+                ", text='" + text + '\'' +
+                ", projectId='" + projectId + '\'' +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPart.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPart.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a0b7644d1f69f2c5490f1bc7ac9ab6111eb6daa
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPart.java
@@ -0,0 +1,83 @@
+package unipotsdam.gf.modules.submission.model;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
+import java.util.ArrayList;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class SubmissionPart {
+
+    // variables
+    private long timestamp;
+    private String userId;
+    private String fullSubmissionId;
+    private Category category;
+    private ArrayList<SubmissionPartBodyElement> body;
+
+    // constructor
+    public SubmissionPart(long timestamp, String userId, String fullSubmissionId, Category category, ArrayList<SubmissionPartBodyElement> body) {
+        this.timestamp = timestamp;
+        this.userId = userId;
+        this.fullSubmissionId = fullSubmissionId;
+        this.category = category;
+        this.body = body;
+    }
+
+    public SubmissionPart(){}
+
+    // methods
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getFullSubmissionId() {
+        return fullSubmissionId;
+    }
+
+    public void setFullSubmissionId(String fullSubmissionId) {
+        this.fullSubmissionId = fullSubmissionId;
+    }
+
+    public Category getCategory() {
+        return category;
+    }
+
+    public void setCategory(Category category) {
+        this.category = category;
+    }
+
+    public ArrayList<SubmissionPartBodyElement> getBody() {
+        return body;
+    }
+
+    public void setBody(ArrayList<SubmissionPartBodyElement> body) {
+        this.body = body;
+    }
+
+    @Override
+    public String toString() {
+        return "SubmissionPart{" +
+                "timestamp=" + timestamp +
+                ", userId='" + userId + '\'' +
+                ", fullSubmissionId='" + fullSubmissionId + '\'' +
+                ", category=" + category +
+                ", body=" + body +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartBodyElement.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartBodyElement.java
new file mode 100644
index 0000000000000000000000000000000000000000..7448d70ab6c9704057c71b257482bf904c74ee0a
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartBodyElement.java
@@ -0,0 +1,57 @@
+package unipotsdam.gf.modules.submission.model;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class SubmissionPartBodyElement {
+
+    // variables
+    private String text;
+    private int startCharacter;
+    private int endCharacter;
+
+    // constructors
+    public SubmissionPartBodyElement(String text, int startCharacter, int endCharacter) {
+        this.text = text;
+        this.startCharacter = startCharacter;
+        this.endCharacter = endCharacter;
+    }
+
+    public SubmissionPartBodyElement() {}
+
+    // methods
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public int getStartCharacter() {
+        return startCharacter;
+    }
+
+    public void setStartCharacter(int startCharacter) {
+        this.startCharacter = startCharacter;
+    }
+
+    public int getEndCharacter() {
+        return endCharacter;
+    }
+
+    public void setEndCharacter(int endCharacter) {
+        this.endCharacter = endCharacter;
+    }
+
+    @Override
+    public String toString() {
+        return "SubmissionPartBodyElement{" +
+                ", text='" + text + '\'' +
+                ", startCharacter=" + startCharacter +
+                ", endCharacter=" + endCharacter +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartPostRequest.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartPostRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..07ac839bb6ca8927c00e5b766d05e1f4a50e6763
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionPartPostRequest.java
@@ -0,0 +1,72 @@
+package unipotsdam.gf.modules.submission.model;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
+import java.util.ArrayList;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class SubmissionPartPostRequest {
+
+    // variables
+    private String userId;
+    private String fullSubmissionId;
+    private Category category;
+    private ArrayList<SubmissionPartBodyElement> body;
+
+    // constructors
+    public SubmissionPartPostRequest(String userId, String fullSubmissionId, Category category, ArrayList<SubmissionPartBodyElement> body) {
+        this.userId = userId;
+        this.fullSubmissionId = fullSubmissionId;
+        this.category = category;
+        this.body = body;
+    }
+
+    public SubmissionPartPostRequest(){}
+
+    // methods
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getFullSubmissionId() {
+        return fullSubmissionId;
+    }
+
+    public void setFullSubmissionId(String fullSubmissionId) {
+        this.fullSubmissionId = fullSubmissionId;
+    }
+
+    public Category getCategory() {
+        return category;
+    }
+
+    public void setCategory(Category category) {
+        this.category = category;
+    }
+
+    public ArrayList<SubmissionPartBodyElement> getBody() {
+        return body;
+    }
+
+    public void setBody(ArrayList<SubmissionPartBodyElement> body) {
+        this.body = body;
+    }
+
+    @Override
+    public String toString() {
+        return "SubmissionPartPostRequest{" +
+                "userId='" + userId + '\'' +
+                ", fullSubmissionId='" + fullSubmissionId + '\'' +
+                ", category=" + category +
+                ", body=" + body +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionProjectRepresentation.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionProjectRepresentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..998bc1fb6c567e7d30fa0fa06cd91f3808afcdf6
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionProjectRepresentation.java
@@ -0,0 +1,55 @@
+package unipotsdam.gf.modules.submission.model;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+
+public class SubmissionProjectRepresentation {
+
+    // variables
+    private String user;
+    private Category category;
+    private String fullSubmissionId;
+
+    // constructor
+    public SubmissionProjectRepresentation(String user, Category category, String fullSubmissionId) {
+        this.user = user;
+        this.category = category;
+        this.fullSubmissionId = fullSubmissionId;
+    }
+
+    public SubmissionProjectRepresentation(){}
+
+    // methods
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public Category getCategory() {
+        return category;
+    }
+
+    public void setCategory(Category category) {
+        this.category = category;
+    }
+
+    public String getFullSubmissionId() {
+        return fullSubmissionId;
+    }
+
+    public void setFullSubmissionId(String fullSubmissionId) {
+        this.fullSubmissionId = fullSubmissionId;
+    }
+
+    @Override
+    public String toString() {
+        return "SubmissionProjectRepresentation{" +
+                "user='" + user + '\'' +
+                ", category=" + category +
+                ", fullSubmissionId='" + fullSubmissionId + '\'' +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionResponse.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..51990953829fab6fde864683722c758e9e5a7d98
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/model/SubmissionResponse.java
@@ -0,0 +1,35 @@
+package unipotsdam.gf.modules.submission.model;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+public class SubmissionResponse {
+
+    // variables
+    String message;
+
+    // constructors
+    public SubmissionResponse(String message) {
+        this.message = message;
+    }
+
+    public SubmissionResponse(){}
+
+    // methods
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        return "SubmissionResponse{" +
+                "message='" + message + '\'' +
+                '}';
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/view/SubmissionService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/view/SubmissionService.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b6bfd25b9aa141526009e46153c799c87b0acea
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/view/SubmissionService.java
@@ -0,0 +1,117 @@
+package unipotsdam.gf.modules.submission.view;
+
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
+import unipotsdam.gf.modules.submission.controller.SubmissionController;
+import unipotsdam.gf.modules.submission.model.*;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+
+/**
+ * @author Sven Kästle
+ * skaestle@uni-potsdam.de
+ */
+
+@Path("/submissions")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class SubmissionService {
+
+    @POST
+    @Path("/full")
+    public Response addFullSubmission(FullSubmissionPostRequest fullSubmissionPostRequest) {
+        // save full submission request in database and return the new full submission
+        SubmissionController controller = new SubmissionController();
+        FullSubmission fullSubmission = controller.addFullSubmission(fullSubmissionPostRequest);
+
+        return Response.ok(fullSubmission).build();
+    }
+
+    @GET
+    @Path("/full/{id}")
+    public Response getFullSubmission(@PathParam("id") String fullSubmissionId) {
+
+        // get full submission from database based by id
+        SubmissionController controller = new SubmissionController();
+        FullSubmission fullSubmission = controller.getFullSubmission(fullSubmissionId);
+
+        if (fullSubmission != null) {
+            return Response.ok(fullSubmission).build();
+        }
+        else {
+            // declare response
+            SubmissionResponse response = new SubmissionResponse();
+            response.setMessage("Submission with the id '" + fullSubmissionId + "' can't be found");
+
+            return Response.status(Response.Status.NOT_FOUND).entity(response).build();
+        }
+
+    }
+
+    @POST
+    @Path("/part")
+    public Response addSubmissionPart(SubmissionPartPostRequest submissionPartPostRequest) {
+        // save submission part request in the database and return the new submission part
+        SubmissionController controller = new SubmissionController();
+        SubmissionPart submissionPart = controller.addSubmissionPart(submissionPartPostRequest);
+
+        return Response.ok(submissionPart).build();
+    }
+
+    @GET
+    @Path("/full/{id}/category/{category}")
+    public Response getSubmissionPart(@PathParam("id") String fullSubmissionId, @PathParam("category") String category) {
+        // get submission part from database based by id
+        SubmissionController controller = new SubmissionController();
+        SubmissionPart submissionPart = controller.getSubmissionPart(fullSubmissionId, Category.valueOf(category.toUpperCase()));
+
+        if (submissionPart != null) {
+            return  Response.ok(submissionPart).build();
+        }
+        else {
+            // declare response
+            SubmissionResponse response = new SubmissionResponse();
+            response.setMessage("Submission part with the full submission id '" + fullSubmissionId + "' and the category '" + category.toUpperCase() + "' can't be found");
+
+            return Response.status(Response.Status.NOT_FOUND).entity(response).build();
+        }
+    }
+
+    @GET
+    @Path("/full/{id}/parts")
+    public Response getAllSubmissionParts(@PathParam("id") String fullSubmissionId) {
+        // get submission parts from database based by id
+        SubmissionController controller = new SubmissionController();
+        ArrayList<SubmissionPart> parts = controller.getAllSubmissionParts(fullSubmissionId);
+
+        if (parts.size() > 0) {
+            return Response.ok(parts).build();
+        }
+        else {
+            SubmissionResponse response = new SubmissionResponse();
+            response.setMessage("No submission parts found for submission with the id '" + fullSubmissionId + "'");
+
+            return Response.status(Response.Status.NOT_FOUND).entity(response).build();
+        }
+    }
+
+    @GET
+    @Path("/project/{id}")
+    public Response getSubmissionPartsByProjectId(@PathParam("id") String projectId) {
+        // get submission project representation from database based by project id
+        SubmissionController controller = new SubmissionController();
+        ArrayList<SubmissionProjectRepresentation> representations = controller.getSubmissionPartsByProjectId(projectId);
+
+        if (representations.size() > 0) {
+            return Response.ok(representations).build();
+        }
+        else {
+            SubmissionResponse response = new SubmissionResponse();
+            response.setMessage("No submission parts found for project id '" + projectId + "'");
+
+            return Response.status(Response.Status.NOT_FOUND).entity(response).build();
+        }
+    }
+}
diff --git a/gemeinsamforschen/src/main/webapp/assets/css/annotationStyle.css b/gemeinsamforschen/src/main/webapp/assets/css/annotationStyle.css
index 0dbf610d881507005fe7c9e4ff0bf8475356f093..a9ed0b540fd86a20c6375dfd3e602bd0d0f8a35b 100644
--- a/gemeinsamforschen/src/main/webapp/assets/css/annotationStyle.css
+++ b/gemeinsamforschen/src/main/webapp/assets/css/annotationStyle.css
@@ -148,10 +148,20 @@ ol {
     float: right;
     margin: 20px;
 }
+.leftcontent-buttons-back {
+    float: left;
+    margin: 20px;
+}
 .leftcontent-text {
     overflow: scroll;
+    white-space: pre-line;
+    color: lightgrey;
 }
 .resize-vertical {
     resize: vertical;
 }
+.categoryText {
+    color: black;
+    font-weight: bold;
+}
 
diff --git a/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css
new file mode 100644
index 0000000000000000000000000000000000000000..53ad932cba2ed091225f101c0e1a72c5be1dbc18
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css
@@ -0,0 +1,165 @@
+body, html {
+    height: 100vh;
+    width: 100vw;
+}
+.content-mainpage {
+    display: flex;
+    box-sizing: border-box;
+    font-family: Arial;
+    height: 100%;
+    overflow-y: hidden;
+}
+.rightcolumn {
+    float: right;
+    width: 25%;
+    height: 100%;
+    padding: 10px;
+    display: inline-block;
+    overflow: scroll;
+}
+.leftcolumn {
+    padding: 10px;
+    float: left;
+    width: 75%;
+    display: inline-block;
+    /* background-color: yellow; */
+}
+.rightcontent {
+    height: 100%;
+}
+.rightcontent ol {
+    padding: 0px;
+    margin: 0px;
+    list-style-type: none;
+    height: 100%;
+}
+.rightcontent li {
+    height: calc((100% - 70px) / 8);
+    min-height: 40px;
+}
+.leftcontent {
+    max-height: 100%;
+    display: flex;
+    flex-flow: column;
+    /* background-color: white; */
+}
+.spacing {
+    margin-bottom: 10px;
+    /* background-color: orange; */
+}
+.container-fluid-content {
+    display: flex;
+    flex-flow: column;
+    height: 100%;
+}
+.flex {
+    display: flex;
+}
+.flex .container-fluid{
+    flex: 1;
+}
+.full-height {
+    height: 100%;
+}
+.leftcontent-buttons-save {
+    float: right;
+    margin: 20px;
+}
+.leftcontent-text {
+    overflow: scroll;
+    white-space: pre-line;
+}
+.category-card {
+    min-height: 30px;
+    height: 100%;
+    width: 100%;
+    border-radius: 5px;
+    font-weight: bold;
+    font-size: large;
+    overflow: hidden;
+}
+.category-card p {
+    position: relative;
+    float: left;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    max-width: 100%;
+}
+.not-added{
+    border-style: dashed;
+    border-color: lightgray;
+    color: lightgray;
+}
+
+.titel {
+    background-color: #ba68c8;
+}
+.added-titel {
+    border-style: solid;
+    border-color: #ba68c8;
+    color: #ba68c8;
+}
+
+.recherche {
+    background-color: #7986cb;
+}
+.added-recherche {
+    border-style: solid;
+    border-color: #7986cb;
+    color: #7986cb;
+}
+
+.literaturverzeichnis {
+    background-color: #4dd0e1;
+}
+.added-literaturverzeichnis {
+    border-style: solid;
+    border-color: #4dd0e1;
+    color: #4dd0e1;
+}
+
+.forschungsfrage {
+    background-color: #81c784;
+}
+.added-forschungsfrage {
+    border-style: solid;
+    border-color: #81c784;
+    color: #81c784;
+}
+
+.untersuchungskonzept {
+    background-color: #dce775;
+}
+.added-untersuchungskonzept {
+    border-style: solid;
+    border-color: #dce775;
+    color: #dce775;
+}
+
+.methodik {
+    background-color: #ffd54f;
+}
+.added-methodik {
+    border-style: solid;
+    border-color: #ffd54f;
+    color: #ffd54f;
+}
+
+.durchfuehrung {
+    background-color: #ff8a65;
+}
+.added-durchfuehrung {
+    border-style: solid;
+    border-color: #ff8a65;
+    color: #ff8a65;
+}
+
+.auswertung {
+    background-color: #a1887f;
+}
+.added-auswertung {
+    border-style: solid;
+    border-color: #a1887f;
+    color: #a1887f;
+}
\ No newline at end of file
diff --git a/gemeinsamforschen/src/main/webapp/assets/css/unstructured-upload.css b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-upload.css
new file mode 100644
index 0000000000000000000000000000000000000000..9b1c11047b5335b7f030735c5730f38debfc1afb
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-upload.css
@@ -0,0 +1,58 @@
+body, html {
+    height: 100vh;
+    width: 100vw;
+}
+.content-mainpage {
+    display: flex;
+    box-sizing: border-box;
+    font-family: Arial;
+    height: 100%;
+    overflow-y: scroll;
+    flex-flow: column nowrap;
+}
+.container-fluid-content {
+    display: flex;
+    flex-flow: column;
+    height: 100%;
+}
+.full-height {
+    height: 100%;
+}
+.flex {
+    display: flex;
+}
+.document-text-buttons {
+    margin-bottom: 15px;
+    margin-top: 15px;
+    display: inline;
+}
+.document-text-buttons-back {
+    float: left;
+}
+.document-text-buttons-next {
+    float: right;
+}
+.file-upload-area {
+    height: 20%;
+}
+
+.upload-text {
+    display: flex;
+    flex-flow: column;
+    height: 100%;
+}
+.upload-text-textarea {
+    resize: none;
+    flex: 1;
+}
+#upload-textarea-form {
+    height: 100%;
+    margin-bottom: 15px;
+}
+label.error {
+    color: red;
+}
+.flex .container-fluid{
+    flex: 1;
+}
+
diff --git a/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css b/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css
deleted file mode 100644
index 16ff7e4ce9ecbb4d462b22445ac2bbe064279705..0000000000000000000000000000000000000000
--- a/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css
+++ /dev/null
@@ -1,143 +0,0 @@
-ol {
-    padding: 0px;
-    margin: 0px;
-    list-style-type: none;
-}
-.mainpage {
-    display: flex;
-    box-sizing: border-box;
-    font-family: Arial;
-    height: 100%;
-}
-.rightcolumn {
-    float: right;
-    width: 25%;
-    display: inline-block;
-    /* background-color: blue; */
-}
-.leftcolumn {
-    float: left;
-    width: 75%;
-    display: inline-block;
-    /* background-color: yellow; */
-}
-.rightcontent {
-    margin: 10px;
-}
-.leftcontent {
-    margin: 10px;
-    /* background-color: white; */
-}
-.spacing {
-    height: 10px;
-    /* background-color: orange; */
-}
-
-.annotation-card {
-    width: 100%;
-    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
-    transition: 0.3s;
-    border-radius: 5px;
-    display: inline-block;
-    background-color: white;
-}
-.annotation-card:hover {
-    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
-}
-.annotation-header {
-    padding: 5px;
-    display: flex;
-    flex-wrap: wrap;
-    align-items: center;
-    border-top-right-radius: 5px;
-    border-top-left-radius: 5px;
-    color: white;			}
-.annotation-header i {
-    font-size: 11px;
-}
-.annotation-header span {
-    font-size: 11px;
-    margin-left: 5px;
-    margin-right: 5px;
-}
-.annotation-header a:link {
-    color: white;
-    text-decoration: none;
-}
-.annotation-header a:visited {
-    color: white;
-    text-decoration: none;
-}
-.annotation-header a:active {
-    color: white;
-    text-decoration: none;
-}
-.annotation-header a:hover {
-    color: #e6e6e6;
-    text-decoration: none;
-}
-.annotation-header-title {
-    display: flex;
-    flex-flow: column;
-    width: calc(100% - 40px);
-}
-.annotation-header-toggle {
-    height: 40px;
-    width: 40px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-}
-.annotation-body {
-    padding: 8px;
-    border-bottom-right-radius: 5px;
-    border-bottom-left-radius: 5px;
-}
-.annotation-body p {
-    margin: 0px;
-    font-size: 13px;
-}
-.overflow-hidden {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-.annotation-footer {
-    padding: 5px;
-    padding-top: 0px;
-    text-align: right;
-    font-size: 9px;
-    color: lightgrey;
-    display: flex;
-}
-.annotation-footer span {
-    margin-left: 5px;
-}
-.annotation-footer-delete {
-    margin-right: 5px;
-    cursor: pointer;
-}
-.annotation-footer-date {
-    flex: 1
-}
-
-
-
-.unstructured-textarea {
-    resize: none;
-}
-.document-text-buttons {
-    margin-top: 10px;
-    display: inline;
-}
-.document-text-buttons-lock {
-    float: left;
-}
-.document-text-buttons-back {
-    float: left;
-}
-.document-text-buttons-save {
-    float: right;
-}
-
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/annotationRest.js b/gemeinsamforschen/src/main/webapp/assets/js/annotationRest.js
index 787ccd96b74c391cd417e4733b5281611012720b..76fd89c8f25a0d29e923f2e03d617e50890707df 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/annotationRest.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/annotationRest.js
@@ -81,10 +81,11 @@ function getAnnotation(id, responseHandler) {
  * GET: Get all annotations from database for a specific target
  *
  * @param targetId The target id
+ * @param targetCategory The category of the target
  * @param responseHandler The response handler
  */
-function getAnnotations(targetId, responseHandler) {
-    var url = "../rest/annotations/target/" + targetId;
+function getAnnotations(targetId, targetCategory, responseHandler) {
+    var url = "../rest/annotations/targetid/" + targetId + "/targetcategory/" + targetCategory;
     $.ajax({
         url: url,
         type: "GET",
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js b/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js
index 5150c1f92e7e23ebe6045b9df333dce7667093a9..b6f25d8c8adba325836a6a282a147429b155dd34 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/annotationScript.js
@@ -1,19 +1,52 @@
-// initialize userToken, userColors and targetId
-var userToken = getUserTokenFromUrl();
+// initialize userToken, userColors
 var userColors = new Map();
 var userColorsDark = new Map();
-var targetId = 200;
 
 // declare document text, start and end character
-var documentText, startCharacter, endCharacter;
+var startCharacter, endCharacter;
 
 /**
  * This function will fire when the DOM is ready
  */
 $(document).ready(function() {
+    let fullSubmissionId = getQueryVariable("fullSubmissionId");
+    let category = getQueryVariable("category");
+
+    // fetch full submission from database
+    getFullSubmission(getQueryVariable("fullSubmissionId"), function (response) {
+
+        // set text
+        $('#documentText').html(response.text);
+
+        // fetch submission parts
+        getSubmissionPart(fullSubmissionId, category, function (response) {
+
+            let body = response.body;
+            // save body
+            $('#documentText').data("body", body);
+            let offset = 0;
+            for (let i = 0; i < body.length; i++) {
+                addHighlightedSubmissionPart(body[i].startCharacter, body[i].endCharacter, offset);
+                // add char count of '<span class="categoryText"></span>'
+                offset += 34;
+            }
+
+            // scroll document text to first span element
+            let documentText = $('#documentText');
+            let span = $('#documentText span').first();
+            documentText.scrollTo(span);
+
+
+        }, function () {
+            // error
+        })
+
+    }, function () {
+        // error
+    });
 
     // connect to websocket on page ready
-    connect(targetId);
+    connect(fullSubmissionId, category);
 
     /**
      * Context menu handler
@@ -22,17 +55,8 @@ $(document).ready(function() {
         selector: '.context-menu-one',
         callback: function(key, options) {
 
-            // action for 'annotation' click
-            if (key == 'annotation') {
-                // show modal if something is selected
-                if (getSelectedText().length > 0) {
-                    startCharacter = window.getSelection().getRangeAt(0).startOffset;
-                    endCharacter = window.getSelection().getRangeAt(0).endOffset;
-
-                    // display annotation create modal
-                    $('#annotation-create-modal').modal("show");
-                }
-            }
+            // handle annotation context click
+            handleAnnotationClick()
 
         },
         items: {
@@ -47,6 +71,13 @@ $(document).ready(function() {
         location.href="givefeedback.jsp?token=" + getUserTokenFromUrl();
     });
 
+    /**
+     * back button
+     */
+    $('#btnBack').click(function () {
+        location.href="project-student.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getQueryVariable("projectId");
+    });
+
     /**
      * validation of annotation create form inside the modal
      */
@@ -201,10 +232,8 @@ $(document).ready(function() {
         $('#annotation-edit-form-comment').val('')
     });
 
-    documentText = $('#documentText').html();
-
     // fetch annotations from server on page start
-    getAnnotations(targetId, function (response) {
+    getAnnotations(fullSubmissionId, category, function (response) {
         // iterate over annotations and display each
         $.each(response, function (i, annotation) {
             displayAnnotation(annotation);
@@ -305,7 +334,7 @@ function displayAnnotation(annotation) {
                             .append(
                                 // edit
                                 function () {
-                                    if (userToken == annotation.userToken) {
+                                    if (getUserTokenFromUrl() === annotation.userToken) {
                                         return $('<div>').attr('class', 'annotation-footer-edit')
                                             .append(
                                                 $('<i>').attr('class', editIcon)
@@ -332,7 +361,12 @@ function displayAnnotation(annotation) {
             )
             .data('annotation', annotation)
             .mouseenter(function () {
-                addHighlightedText(annotation.body.startCharacter, annotation.body.endCharacter, annotation.userToken);
+                addHighlightedAnnotation(annotation.body.startCharacter, annotation.body.endCharacter, annotation.userToken);
+
+                // scroll document text to anchor element
+                let documentText = $('#documentText');
+                let anchor = $('#anchor');
+                documentText.scrollTo(anchor);
             })
             .mouseleave(function () {
                 deleteHighlightedText();
@@ -352,25 +386,84 @@ function displayAnnotation(annotation) {
  * @param endCharacter The offset of the end character
  * @param userToken The user token
  */
-function addHighlightedText(startCharacter, endCharacter, userToken) {
+function addHighlightedAnnotation(startCharacter, endCharacter, userToken) {
+    let offset = calculateExtraOffset(startCharacter);
+
+    // initialize variables
+    let documentText = $('#documentText').text();
+    let documentHtml = $('#documentText').html();
+
     // create <span> tag with the annotated text
-    var replacement = $('<span></span>').css('background-color', getUserColor(userToken)).html(documentText.slice(startCharacter, endCharacter));
+    var replacement = $('<span></span>').attr('id', 'anchor').css('background-color', getUserColor(userToken)).html(documentText.slice(startCharacter, endCharacter));
 
     // wrap an <p> tag around the replacement, get its parent (the <p>) and ask for the html
     var replacementHtml = replacement.wrap('<p/>').parent().html();
 
     // insert the replacementHtml
-    var newDocument = documentText.slice(0, startCharacter) + replacementHtml + documentText.slice(endCharacter);
+    var newDocument = documentHtml.slice(0, startCharacter + offset) + replacementHtml + documentHtml.slice(endCharacter + offset);
 
     // set new document text
     $('#documentText').html(newDocument);
 }
 
+/**
+ * Add a highlighted text at specific position
+ *
+ * @param startCharacter The offset of the start character
+ * @param endCharacter The offset of the end character
+ * @param offset The calculated extra offset depending on already highlighted text
+ */
+function addHighlightedSubmissionPart(startCharacter, endCharacter, offset) {
+
+    var documentText = $('#documentText').text();
+    var documentHtml = $('#documentText').html();
+
+    // create <span> tag with the annotated text
+    var replacement = $('<span></span>').attr('class', 'categoryText').html(documentText.slice(startCharacter, endCharacter));
+
+    // wrap an <p> tag around the replacement, get its parent (the <p>) and ask for the html
+    var replacementHtml = replacement.wrap('<p/>').parent().html();
+
+    // insert the replacementHtml
+    var newDocument = documentHtml.slice(0, startCharacter + offset) + replacementHtml + documentHtml.slice(endCharacter + offset);
+
+    // set new document text
+    $('#documentText').html(newDocument);
+}
+
+/**
+ * Iterate over all data arrays and calculate the offset for a given start character
+ *
+ * @param startCharacter The given start character
+ * @returns {number} The offset
+ */
+function calculateExtraOffset(startCharacter) {
+    // get submission part body
+    let body = $('#documentText').data("body");
+    let extraOffset = 0;
+
+    for (let i = 0; i < body.length; i++) {
+        if (body[i].startCharacter <= startCharacter) {
+            extraOffset += 27;
+        }
+        if (body[i].endCharacter <= startCharacter) {
+            extraOffset += 7;
+        }
+    }
+
+    return extraOffset;
+}
+
 /**
  * Restore the base text
  */
 function deleteHighlightedText() {
-    $('#documentText').html(documentText);
+
+    let documentText = $('#documentText');
+    let highlight = documentText.find('#anchor');
+    let text = highlight.text();
+    highlight.replaceWith(text);
+
 }
 
 /**
@@ -522,10 +615,17 @@ function toggleButtonHandler(id) {
  * @param endCharacter The endCharacter based on the annotated text
  */
 function saveNewAnnotation(title, comment, startCharacter, endCharacter) {
+
+    // initialize target
+    let targetId = getQueryVariable("fullSubmissionId");
+    let targetCategory = getQueryVariable("category");
+    let userToken = getUserTokenFromUrl();
+
     // build annotationPostRequest
     var annotationPostRequest = {
         userToken: userToken,
         targetId: targetId,
+        targetCategory: targetCategory,
         body: {
             title: title,
             comment: comment,
@@ -640,3 +740,54 @@ function showAndHideToggleButtonById(id) {
         annotationElement.find('.annotation-header-data').css('width', '100%');
     }
 }
+
+/**
+ * Handle the annotation click and show the modal
+ *
+ */
+function handleAnnotationClick() {
+
+    // if saved selection's range count is > 0
+    let sel = rangy.getSelection();
+    if (sel.rangeCount > 0) {
+        // calculate character range offset from range
+        let range = sel.getRangeAt(0);
+        let offsets = range.toCharacterRange($('#documentText')[0]);
+
+        // if selected text's length is > 0
+        let selectedText = getSelectedText();
+        if (selectedText.length > 0) {
+            // save start and end character and handle the selection
+            startCharacter = offsets.start;
+            endCharacter = offsets.end;
+
+            if (isAnnotationInRange(startCharacter, endCharacter)) {
+                // display annotation create modal
+                $('#annotation-create-modal').modal("show");
+            }
+            else {
+                window.alert("Annotationen sind nur in vorgehobenen Bereichen möglich")
+            }
+
+
+        }
+    }
+
+}
+
+/**
+ * Checks if user selected area is inside submission part range
+ *
+ * @param start The start character of the selection
+ * @param end The end character of the selection
+ * @returns {boolean} Returns true if the selection is in range
+ */
+function isAnnotationInRange(start, end) {
+    let body = $('#documentText').data("body");
+    for (let i = 0; i < body.length; i++) {
+        if (body[i].startCharacter <= start && end <= body[i].endCharacter) {
+            return true;
+        }
+    }
+    return false;
+}
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js b/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js
index 62bbd2f33c69daada2c18e08614c9ab718ad6c00..5c3ced1b8d2017cf5e7365a17306d90c6ba37d49 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/annotationWebsocket.js
@@ -1,10 +1,10 @@
 var ws;
 
-function connect(targetId) {
+function connect(targetId, targetCategory) {
     var host = document.location.host;
     var pathname = document.location.pathname;
 
-    ws = new WebSocket("ws://" + host  + "/ws/annotation/" + targetId);
+    ws = new WebSocket("ws://" + host  + "/ws/annotation/" + targetId + "/" + targetCategory);
 
     ws.onmessage = function (e) {
         var message = JSON.parse(e.data);
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/project-student.js b/gemeinsamforschen/src/main/webapp/assets/js/project-student.js
index ffc7facbdd443de53ce28d7faeb0cefd84298e7a..520600a93a3444968585c2d382cd2497acb5c0b5 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/project-student.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/project-student.js
@@ -1,4 +1,27 @@
 $(document).ready(function(){
+    // fetch all submission part project representations from database
+    getSubmissionPartsByProjectId(getQueryVariable("projectId"), function (response) {
+        
+        // iterate over response and display each element
+        for (let i = 0; i < response.length; i++) {
+            displaySubmission(response[i].user, response[i].category, response[i].fullSubmissionId);
+        }
+
+        // add click listener to feedback buttons
+        $('.annotationview').click(function () {
+            let fullSubmissionId = $(this).closest("li").data("fullSubmissionId");
+            let category = $(this).closest("li").data("category");
+            location.href="annotation-document.jsp?token=" + getUserTokenFromUrl() +
+                "&projectId=" + getQueryVariable("projectId") +
+                "&fullSubmissionId=" + fullSubmissionId +
+                "&category=" + category;
+        });
+        
+    }, function () {
+        // display empty view
+        displayEmptyView()
+    });
+
     /*
     var memberTable = $('#myGroupMembers');
     memberTable.hide();
@@ -13,11 +36,67 @@ $(document).ready(function(){
         location.href="viewfeedback.jsp?token="+getUserTokenFromUrl();
     });
 
-    $('.annotationview').click(function () {
-        location.href="annotation-document.jsp?token="+getUserTokenFromUrl();
-    });
-
     $('#btnUnstructuredUpload').click(function () {
-        location.href="upload-unstructured.jsp?token="+getUserTokenFromUrl();
+        location.href="unstructured-upload.jsp?token="+getUserTokenFromUrl() + "&projectId=" + getQueryVariable("projectId");
+    })
+});
+
+/**
+ * Display category of submission part in list
+ *
+ * @param user The user of the submission part
+ * @param category The category of the submission part
+ * @param fullSubmissionId The id of the full submission the submission part belongs to
+ */
+function displaySubmission(user, category, fullSubmissionId) {
+    // build link
+    $('#submissionUpload').append(
+        $('<li>')
+            .append($('<span>').append(category.toUpperCase() + " eingereicht"))
+            .append($('<a>').attr("class", "annotationview").attr("role", "button")
+                    .append($('<label>').css("font-size", "10px")
+                        .append($('<i>').attr("class", "far fa-comments").css("font-size", "15px"))
+                        .append("feedback")
+                    )
+            )
+            // add data to link
+            .data("fullSubmissionId", fullSubmissionId)
+            .data("category", category)
+    );
+
+}
+
+/**
+ * Display a not found message if there are no submission parts in the database (or on error)
+ */
+function displayEmptyView() {
+    // build link
+    $('#submissionUpload').append(
+        $('<li>')
+            .append($('<span>').append("keine Daten gefunden"))
+    );
+}
+
+/**
+ * GET: Get all representations of a submission part for a given project id
+ *
+ * @param projectId The id of the project
+ * @param responseHandler The response handler
+ * @param errorHandler The error handler
+ */
+function getSubmissionPartsByProjectId(projectId, responseHandler, errorHandler) {
+    var url = "../rest/submissions/project/" + projectId;
+    $.ajax({
+        url: url,
+        type: "GET",
+        dataType: "json",
+        success: function (response) {
+            // handle the response
+            responseHandler(response);
+        },
+        error: function () {
+            // handle the error
+            errorHandler();
+        }
     })
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/unstructuredAnnotation.js b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredAnnotation.js
new file mode 100644
index 0000000000000000000000000000000000000000..f420bbbd12047f018cbba3c6c4d306e03b3cf3e3
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredAnnotation.js
@@ -0,0 +1,320 @@
+/**
+ * This function will fire when the DOM is ready
+ */
+$(document).ready(function() {
+
+    // fetch the document text of the given id
+    getFullSubmission(getSubmissionIdFromUrl(), function (response) {
+        // set text in div
+        $('#documentText').html(response.text);
+
+        // get submissions parts from database
+        getAllSubmissionParts(getSubmissionIdFromUrl(), function (response) {
+
+            // iterate over response
+            for (let i = 0; i < response.length; i++) {
+                // save current category and body
+                let category = response[i].category;
+                let body = response[i].body;
+                // iterate over body and handle every selection
+                for (let j = 0; j < body.length; j++) {
+                    handleCategorySelection(category.toLowerCase(), body[j].startCharacter, body[j].endCharacter);
+                }
+            }
+
+        });
+
+    }, function () {
+        // jump to upload page on error
+        location.href="unstructured-upload.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getQueryVariable("projectId");
+    });
+
+    // set click listener to save button
+    $('#btnSave').click(function () {
+        saveButtonHandler();
+    });
+    
+    /**
+     * Context menu handler
+     */
+    $.contextMenu({
+        selector: '.context-menu-one',
+        callback: function(key, options) {
+
+            // handle the category click
+            handleCategoryClick(key);
+
+        },
+        items: {
+            "annotation": {
+                name: "Annotation",
+                icon: "edit",
+                items: {
+                    "titel": {name: "Titel"},
+                    "recherche": {name: "Recherche"},
+                    "literaturverzeichnis": {name: "Literaturverzeichnis"},
+                    "forschungsfrage": {name: "Forschungsfrage"},
+                    "untersuchungskonzept": {name: "Untersuchungskonzept"},
+                    "methodik": {name: "Methodik"},
+                    "durchfuehrung": {name: "Durchführung"},
+                    "auswertung": {name: "Auswertung"}
+                }
+            }
+
+        }
+    });
+
+});
+
+/**
+ * Get the id of a full submission from url
+ *
+ * @returns The id of the full submission
+ */
+function getSubmissionIdFromUrl() {
+    var parts = window.location.search.substr(1).split("&");
+    var $_GET = {};
+    for (var i = 0; i < parts.length; i++) {
+        var temp = parts[i].split("=");
+        $_GET[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
+    }
+    return $_GET['submission'];
+
+}
+
+/**
+ * Handel the category selection
+ *
+ * @param category The chosen category
+ * @param startCharacter The start character of the selected range
+ * @param endCharacter The end character of the selected range
+ */
+function handleCategorySelection(category, startCharacter, endCharacter) {
+
+    // if highlighting is possible
+    if (!isAlreadyHighlighted(startCharacter, endCharacter)) {
+
+        // check if element has 'not-added' class
+        var elem = $('#' + category);
+        if (elem.hasClass("not-added")) {
+            elem.toggleClass("not-added added-" + category);
+        }
+
+        // add highlighted text based on selected text
+        addHighlightedText(startCharacter, endCharacter, category, calculateExtraOffset(startCharacter));
+
+        // update data from category list
+        addSelectionDataToList(startCharacter, endCharacter, category);
+    }
+    else {
+        // show error message to user
+        window.alert("Dieser Bereich wurde bereits zugeordnet.")
+    }
+
+}
+
+/**
+ * Get the text value of the selected text
+ *
+ * @returns {string} The text
+ */
+function getSelectedText() {
+    if(window.getSelection){
+        return window.getSelection().toString();
+    }
+    else if(document.getSelection){
+        return document.getSelection();
+    }
+    else if(document.selection){
+        return document.selection.createRange().text;
+    }
+}
+
+/**
+ * Add a highlighted text at specific position
+ *
+ * @param startCharacter The offset of the start character
+ * @param endCharacter The offset of the end character
+ * @param category The category selected by user
+ * @param offset The calculated extra offset depending on already highlighted text
+ */
+function addHighlightedText(startCharacter, endCharacter, category, offset) {
+
+    var documentText = $('#documentText').text();
+    var documentHtml = $('#documentText').html();
+
+    // create <span> tag with the annotated text
+    var replacement = $('<span></span>').attr('class', category).html(documentText.slice(startCharacter, endCharacter));
+
+    // wrap an <p> tag around the replacement, get its parent (the <p>) and ask for the html
+    var replacementHtml = replacement.wrap('<p/>').parent().html();
+
+    // insert the replacementHtml
+    var newDocument = documentHtml.slice(0, startCharacter + offset) + replacementHtml + documentHtml.slice(endCharacter + offset);
+
+    // set new document text
+    $('#documentText').html(newDocument);
+}
+
+/**
+ * Check if the selected range is already highlighted
+ *
+ * @param startCharacter The start character of the range
+ * @param endCharacter The end character of the range
+ * @returns {boolean} Returns true if the selected range ist already highlighted
+ */
+function isAlreadyHighlighted(startCharacter, endCharacter) {
+    let isHighlighted = false;
+    $('#annotations').find('.category-card').each(function () {
+        let array = $(this).data('array');
+        if (array != null) {
+            for (let i = 0; i < array.length; i++) {
+                if ((array[i].start <= startCharacter && startCharacter <= array[i].end - 1) || // startCharacter inside highlighted range
+                    (array[i].start <= endCharacter - 1 && endCharacter - 1 <= array[i].end - 1) || // endCharacter inside highlighted range
+                    (startCharacter <= array[i].start && array[i].end - 1 <= endCharacter - 1)) { // new range overlaps hightlighted range
+                    isHighlighted = true;
+                }
+            }
+        }
+    });
+    return isHighlighted;
+}
+
+/**
+ * Iterate over all data arrays and calculate the offset for a given start character
+ *
+ * @param startCharacter The given start character
+ * @returns {number} The offset
+ */
+function calculateExtraOffset(startCharacter) {
+    let extraOffset = 0;
+    $('#annotations').find('.category-card').each(function () {
+        let array = $(this).data('array');
+        if (array != null) {
+            for (let i = 0; i < array.length; i++) {
+                if (array[i].end <= startCharacter) {
+                    extraOffset += 22 + $(this).attr('id').length;
+                }
+            }
+        }
+    });
+    return extraOffset;
+}
+
+/**
+ * Save start and end character to the data array of a category
+ *
+ * @param startCharacter The start character of the body element
+ * @param endCharacter The end character of the body element
+ * @param category The chosen category
+ */
+function addSelectionDataToList(startCharacter, endCharacter, category) {
+    let elem = $('#' + category);
+    let array = elem.data('array');
+
+    if (array != null) {
+        // define new object
+        let newElement = {
+            start: startCharacter,
+            end: endCharacter
+        };
+        // update array
+        array.push(newElement);
+    }
+    else {
+        // store first element in array
+        array = [
+            {
+                "start": startCharacter,
+                "end": endCharacter
+            }
+        ]
+    }
+
+    // sort array
+    array.sort(function (a, b) {
+        return a.start - b.start;
+    });
+    // store updated array
+    elem.data('array', array);
+}
+
+/**
+ * Handel the save button click
+ * Iterate over the category cards and send each post request to the back-end
+ */
+function saveButtonHandler() {
+    // show alert message
+    if (window.confirm("Möchten Sie wirklich ihre Annotationen speichern?")) {
+        // declare array of promises
+        let promises = []
+        $('#annotations').find('.category-card').each(function () {
+            let array = $(this).data('array');
+            if (array != null) {
+
+                // initialize the post request
+                let category = $(this).attr('id').toUpperCase();
+                let submissionPartPostRequest = {
+                    userId: getUserTokenFromUrl(),
+                    fullSubmissionId: getSubmissionIdFromUrl(),
+                    category: category,
+                    body: []
+                };
+
+                // iterate over the array
+                for (let i = 0; i < array.length; i++) {
+
+                    // initialize a body element
+                    let submissionPartBodyElement = {
+                        text: $('#documentText').text().slice(array[i].start, array[i].end),
+                        startCharacter: array[i].start,
+                        endCharacter: array[i].end
+                    };
+
+                    // store the body element in the post request
+                    submissionPartPostRequest.body.push(submissionPartBodyElement);
+                }
+
+                // send the post request to the back-end and save promise
+                promises.push(createSubmissionPart(submissionPartPostRequest, function (response) {
+                    console.log("send " + response.category + "'s post request to back-end")
+                }));
+
+            }
+        });
+
+        $.when.apply($, promises).then(function () {
+            // redirect user to project page after saving
+            location.href="project-student.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getQueryVariable("projectId");
+        });
+
+        // redirect user to project page after saving
+        // location.href="project-student.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getProjectIdFromUrl();
+    }
+}
+
+/**
+ * Handle the category click and start the saving event
+ *
+ * @param key The selected category
+ */
+function handleCategoryClick(key) {
+
+    // if saved selection's range count is > 0
+    let sel = rangy.getSelection();
+    if (sel.rangeCount > 0) {
+        // calculate character range offset from range
+        let range = sel.getRangeAt(0);
+        let offsets = range.toCharacterRange($('#documentText')[0]);
+
+        // if selected text's length is > 0
+        let selectedText = getSelectedText();
+        if (selectedText.length > 0) {
+            // save start and end character and handle the selection
+            let startCharacter = offsets.start;
+            let endCharacter = offsets.end;
+            handleCategorySelection(key, startCharacter, endCharacter);
+        }
+    }
+
+}
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/unstructuredRest.js b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredRest.js
new file mode 100644
index 0000000000000000000000000000000000000000..7124c244f062ebe2413829d82e72c79617c1796d
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredRest.js
@@ -0,0 +1,113 @@
+/**
+ * POST: Save an full submission in the database
+ *
+ * @param fullSubmissionPostRequest The post request
+ * @param responseHandler The response handler
+ */
+function createFullSubmission(fullSubmissionPostRequest, responseHandler) {
+    var url = "../rest/submissions/full/";
+    var json = JSON.stringify(fullSubmissionPostRequest);
+    $.ajax({
+        url: url,
+        type: "POST",
+        data: json,
+        contentType: "application/json",
+        dataType: "json",
+        success: function (response) {
+            responseHandler(response);
+        }
+    });
+}
+
+/**
+ * GET: Get a specific full submission for a given id
+ *
+ * @param id The id of the full submission
+ * @param responseHandler The response handler
+ * @param errorHandler The error handler
+ */
+function getFullSubmission(id, responseHandler, errorHandler) {
+    var url = "../rest/submissions/full/" + id;
+    $.ajax({
+        url: url,
+        type: "GET",
+        dataType: "json",
+        success: function (response) {
+            // handle the response
+            responseHandler(response);
+        },
+        error: function () {
+            // handle the error
+            errorHandler();
+        }
+    })
+}
+
+/**
+ * POST: Save an submission part in the database
+ *
+ * @param submissionPartPostRequest The post request
+ * @param responseHandler The response handler
+ * @returns A promise object
+ */
+function createSubmissionPart(submissionPartPostRequest, responseHandler) {
+    var url = "../rest/submissions/part/";
+    var json = JSON.stringify(submissionPartPostRequest);
+    return $.ajax({
+        url: url,
+        type: "POST",
+        data: json,
+        contentType: "application/json",
+        dataType: "json",
+        success: function (response) {
+            responseHandler(response);
+        },
+        error: function (e) {
+            console.log(e);
+        }
+    });
+}
+
+/**
+ * GET: Get a specific submission part for a given full submission id and its category
+ *
+ * @param id The id of the full submission
+ * @param category The category of the submission part
+ * @param responseHandler The response handler
+ * @param errorHandler The error handler
+ */
+function getSubmissionPart(id, category, responseHandler, errorHandler) {
+    var url = "../rest/submissions/full/" + id + "/category/" + category;
+    $.ajax({
+        url: url,
+        type: "GET",
+        dataType: "json",
+        success: function (response) {
+            // handle the response
+            responseHandler(response);
+        },
+        error: function () {
+            // handle the error
+            errorHandler();
+        }
+    })
+}
+
+/**
+ * GET: Get all submission parts for a given full submission id
+ *
+ * @param id The id of the full submission
+ * @param responseHandler The response handler
+ */
+function getAllSubmissionParts(id, responseHandler) {
+    var url = "../rest/submissions/full/" + id + "/parts";
+    $.ajax({
+        url: url,
+        type: "GET",
+        dataType: "json",
+        success: function (response) {
+            // handle the response
+            responseHandler(response);
+        }
+    })
+}
\ No newline at end of file
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/unstructuredUpload.js b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredUpload.js
new file mode 100644
index 0000000000000000000000000000000000000000..66ef3253fb067df445fa217227415361f9b0ed33
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredUpload.js
@@ -0,0 +1,68 @@
+/**
+ * This function will fire when the DOM is ready
+ */
+$(document).ready(function() {
+
+    $('#btnNext').click(function () {
+        if ($('#upload-textarea-form').valid()) {
+
+            // fetch user and text
+            let user = getUserTokenFromUrl();
+            let text = $('#upload-textarea').val();
+
+            // build request
+            var fullSubmissionPostRequest = {
+                user: user,
+                text: text,
+                projectId: getQueryVariable("projectId")
+            };
+
+            // save request in database
+            createFullSubmission(fullSubmissionPostRequest, function (response) {
+                // clear textarea
+                $('#upload-textarea').val("");
+
+                // jump to next page
+                location.href="unstructured-annotation.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getQueryVariable("projectId") + "&submission=" + response.id;
+            });
+        }
+    });
+
+    $('#btnBack').click(function () {
+        // if there is text inside the textarea
+        if ($('#upload-textarea').val().trim().length > 0) {
+            // show user alert message that the text will be lost
+            if (window.confirm("Möchten Sie zur vorherigen Seite zurückkehren? \nIhr bisheriger Text wird nicht gespeichert.")) {
+                // clear textarea
+                $('#upload-textarea').val("");
+
+                // jump to previous page
+                window.history.back();
+                //location.href="project-student.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getProjectIdFromUrl();
+            }
+        }
+        // nothing to check
+        else {
+            // jump to previous page
+            window.history.back();
+            //location.href="project-student.jsp?token=" + getUserTokenFromUrl() + "&projectId=" + getProjectIdFromUrl();
+        }
+    });
+
+    /**
+     * validation of upload textarea
+     */
+    $('#upload-textarea-form').validate({
+        rules: {
+            uploadtextarea: {
+                required: true
+            }
+        },
+        messages: {
+            uploadtextarea: {
+                required: "Ein Text wird benötigt"
+            }
+        }
+    });
+
+});
diff --git a/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js b/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js
deleted file mode 100644
index dd85243d662c9bf71e25212e89c42597e830c3d9..0000000000000000000000000000000000000000
--- a/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js
+++ /dev/null
@@ -1,490 +0,0 @@
-// initialize userId, userColors and targetId
-var userId = randomUserId();
-var userColors = new Map();
-var userColorsDark = new Map();
-var targetId = 200;
-
-// declare document text
-var documentText;
-
-/**
- * This function will fire when the DOM is ready
- */
-$(document).ready(function() {
-
-    /**
-     * Context menu handler
-     */
-    $.contextMenu({
-        selector: '.context-menu-one',
-        callback: function(key, options) {
-
-            // close context menu
-            window.close;
-
-            // initialize selected body
-            var body = getSelectedTextFromTextArea();
-
-            // if user selected something
-            if (body.length > 0) {
-                // annotationPostRequest
-                var request = {
-                    userId: userId,
-                    targetId: targetId,
-                    body: body,
-                    startCharacter: window.getSelection().getRangeAt(0).startOffset,
-                    endCharacter: window.getSelection().getRangeAt(0).endOffset
-                };
-
-                console.log(request);
-
-                createAnnotation(request, function(response) {
-                    // display the new annotation
-                    displayAnnotation(response);
-
-                });
-            }
-
-        },
-        items: {
-            "annotation": {name: "Annotation", icon: "edit"}
-        }
-    });
-
-    $('#btnSave').click(function () {
-        location.href="project-student.jsp?token="+getUserTokenFromUrl();
-    });
-
-    $('#btnBack').click(function () {
-        location.href="project-student.jsp?token="+getUserTokenFromUrl();
-    });
-
-    documentText = $('#documentText').html();
-
-    // fetch annotations from server on page start
-    getAnnotations(targetId, function (response) {
-        // iterate over annotations and display each
-        $.each(response, function (i, annotation) {
-            displayAnnotation(annotation);
-        })
-    });
-
-});
-
-/**
- * POST: Save an annotation in the database
- *
- * @param annotationPostRequest The post request
- * @param responseHandler The response handler
- */
-function createAnnotation(annotationPostRequest, responseHandler) {
-    var url = "http://localhost:8080/rest/annotations/";
-    var json = JSON.stringify(annotationPostRequest);
-    $.ajax({
-        url: url,
-        type: "POST",
-        data: json,
-        contentType: "application/json",
-        dataType: "json",
-        success: function (response) {
-            responseHandler(response);
-        }
-    });
-}
-
-/**
- * PATCH: Alter an annotation in database
- *
- * @param id The annotation id
- * @param annotationPatchRequest The patch request
- * @param responseHandler The response handler
- */
-function alterAnnotation(id, annotationPatchRequest, responseHandler) {
-    var url = "http://localhost:8080/rest/annotations/" + id;
-    var json = JSON.stringify(annotationPatchRequest);
-    $.ajax({
-        url: url,
-        type: "PATCH",
-        data: json,
-        contentType: "application/json",
-        dataType: "json",
-        success: function (response) {
-            responseHandler(response);
-        }
-    });
-}
-
-/**
- * DELETE: Delete an annotation from database
- *
- * @param id The annotation id
- */
-function deleteAnnotation(id) {
-    var url = "http://localhost:8080/rest/annotations/" + id;
-    $.ajax({
-        url: url,
-        type: "DELETE",
-        dataType: "json",
-        success: function (response) {
-            // Nothing to do
-        }
-    });
-}
-
-/**
- * GET: Get all annotations from database for a specific target
- *
- *
- * @param targetId The target id
- * @param responseHandler The response handler
- */
-function getAnnotations(targetId, responseHandler) {
-    var url = "http://localhost:8080/rest/annotations/target/" + targetId;
-    $.ajax({
-        url: url,
-        type: "GET",
-        dataType: "json",
-        success: function (response) {
-            // sort the responding annotations by timestamp (DESC)
-            response.sort(function (a, b) {
-                return a.timestamp - b.timestamp;
-            });
-            // handle the response
-            responseHandler(response);
-        }
-    });
-}
-
-/**
- * Delete annotation from list
- *
- * @param elem The parent li element
- * @param id The id of the annotation
- */
-function deleteUnstructuredAnnotationHandler(elem, id) {
-    // remove annotation from list
-    elem.remove()
-    // remove annotation from database
-    deleteAnnotation(id)
-}
-
-/**
- * Display annotation in the list
- *
- * @param annotation The annotation to be displayed
- */
-function displayAnnotation(annotation) {
-    // fetch list of annotations
-    var list = $('#annotations')
-
-    var deleteIcon = "fas fa-trash";
-    var dateIcon = "fas fa-calendar";
-    if (isTimestampToday(annotation.timestamp)) {
-        dateIcon = "fas fa-clock";
-    }
-
-    // insert annotation card
-    list.prepend(
-        $('<li>')
-            .attr('class', 'listelement')
-            .append(
-                $('<div>').attr('class', 'annotation-card')
-                    .mouseenter(function () {
-                        $(this).children('.annotation-header').css('background-color', getDarkUserColor(annotation.userId));
-                    })
-                    .mouseleave(function () {
-                        $(this).children('.annotation-header').css('background-color', getUserColor(annotation.userId));
-                    })
-                    .append(
-                        $('<div>').attr('class', 'annotation-header')
-                            .css('background-color', getUserColor(annotation.userId))
-                            .append(
-                                $('<div>').attr('class', 'annotation-header-title')
-                                    .append(
-                                        $('<div>').attr('class', 'overflow-hidden')
-                                            .append(
-                                                $('<i>').attr('class', 'fas fa-user')
-                                            )
-                                            .append(
-                                                $('<span>').append(annotation.userId)
-                                            )
-                                    )
-                                    .append(
-                                        $('<div>').attr('class', 'overflow-hidden')
-                                            .append(
-                                                $('<i>').attr('class', 'fas fa-bookmark')
-                                            )
-                                            .append(
-                                                $('<span>').append('title' + annotation.userId)
-                                            )
-                                    )
-                            )
-                            .append(
-                                $('<div>').attr('class', 'annotation-header-toggle')
-                                    .click(function () {
-                                        toggleButtonHandler($(this));
-                                    })
-                                    .append(
-                                        $('<i>').attr('class', 'fas fa-chevron-down')
-                                    )
-                            )
-                    )
-                    .append(
-                        $('<div>').attr('class', 'annotation-body')
-                            .append(
-                                $('<p>').attr('class', 'overflow-hidden').append(annotation.body)
-                            )
-                    )
-                    .append(
-                        $('<div>').attr('class', 'annotation-footer')
-                            .append(
-                                function () {
-                                    if (userId == annotation.userId) {
-                                        return $('<div>').attr('class', 'annotation-footer-delete')
-                                            .append(
-                                                $('<i>').attr('class', deleteIcon)
-                                            )
-                                            .click(function () {
-                                                deleteUnstructuredAnnotationHandler($(this).closest('li'), annotation.id)
-                                            })
-                                    }
-                                }
-                            )
-                            .append(
-                                $('<div>').attr('class', 'annotation-footer-date overflow-hidden')
-                                    .append(
-                                        $('<i>').attr('class', dateIcon)
-                                    )
-                                    .append(
-                                        $('<span>').append(timestampToReadableTime(annotation.timestamp))
-                                    )
-                            )
-
-
-                    )
-            )
-            .data('annotation', annotation)
-            .append(function () {
-                if ($('#annotations li').filter( ".listelement" ).length > 0) {
-                    return $('<div>').attr('class', 'spacing')
-                }
-            })
-    );
-}
-
-/**
- * Add a highlighted text at specific position
- *
- * @param startCharacter The offset of the start character
- * @param endCharacter The offset of the end character
- * @param userId The user id
- */
-function addHighlightedText(startCharacter, endCharacter, userId) {
-    // create <span> tag with the annotated text
-    var replacement = $('<span></span>').css('background-color', getUserColor(userId)).html(documentText.slice(startCharacter, endCharacter));
-
-    // wrap an <p> tag around the replacement, get its parent (the <p>) and ask for the html
-    var replacementHtml = replacement.wrap('<p/>').parent().html();
-
-    // insert the replacementHtml
-    var newDocument = documentText.slice(0, startCharacter) + replacementHtml + documentText.slice(endCharacter);
-
-    // set new document text
-    $('#documentText').html(newDocument);
-}
-
-/**
- * Restore the base text
- */
-function deleteHighlightedText() {
-    $('#documentText').html(documentText);
-}
-
-/**
- * Get the text value of the selected text
- *
- * @returns {string} The text
- */
-function getSelectedText() {
-    if(window.getSelection){
-        return window.getSelection().toString();
-    }
-    else if(document.getSelection){
-        return document.getSelection();
-    }
-    else if(document.selection){
-        return document.selection.createRange().text;
-    }
-}
-
-/**
- * Get the text value of the selected text from a textarea
- *
- * @returns {string} The text
- */
-function getSelectedTextFromTextArea() {
-    // if firefox
-    if( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ){
-        // reference to the textarea
-        var txtarea = document.getElementById("upload-area");
-        // get index of first character
-        var start = txtarea.selectionStart;
-        // get index of last character
-        var end = txtarea.selectionEnd;
-        // return substring from start to end
-        return txtarea.value.substring(start, end);
-    }
-    else if(window.getSelection){
-        return window.getSelection().toString();
-    }
-    else if(document.getSelection){
-        return document.getSelection();
-    }
-    else if(document.selection){
-        return document.selection.createRange().text;
-    }
-}
-
-/**
- * Get color based on user id
- *
- * @param userId The id of the user
- * @returns {string} The user color
- */
-function getUserColor(userId) {
-    // insert new color if there is no userId key
-    if (userColors.get(userId) == null) {
-        generateRandomColor(userId);
-    }
-    // return the color
-    return userColors.get(userId);
-}
-
-/**
- * Get dark color based on user id
- *
- * @param userId The id of the user
- * @returns {string} The dark user color
- */
-function getDarkUserColor(userId) {
-    // insert new color if there is no userId key
-    if (userColorsDark.get(userId) == null) {
-        generateRandomColor(userId);
-    }
-    // return the color
-    return userColorsDark.get(userId);
-}
-
-/**
- * Generate a random color of the format 'rgb(r, g, b)'
- *
- * @param userId The given user id
- */
-function generateRandomColor(userId) {
-    var r = Math.floor(Math.random()*56)+170;
-    var g = Math.floor(Math.random()*56)+170;
-    var b = Math.floor(Math.random()*56)+170;
-    var r_d = r - 50;
-    var g_d = g - 50;
-    var b_d = b - 50;
-
-    var color = 'rgb(' + r + ',' + g + ',' + b + ')';
-    var colorDark = 'rgb(' + r_d + ',' + g_d + ',' + b_d + ')';
-
-    userColors.set(userId, color);
-    userColorsDark.set(userId, colorDark);
-}
-
-/**
- * Calculate and build a readable timestamp from an unix timestamp
- *
- * @param timestamp A unix timestamp
- * @returns {string} A readable timestamp
- */
-function timestampToReadableTime(timestamp) {
-    // build Date object from timestamp
-    var annotationDate = new Date(timestamp);
-    // declare response
-    var responseTimestamp;
-
-    // if annotation is from today
-    if (isTimestampToday(timestamp)) {
-        // get hours from date
-        var hours = annotationDate.getHours();
-        // get minutes from date
-        var minutes = "0" + annotationDate.getMinutes();
-        // get seconds from date
-        // var seconds = "0" + annotationDate.getSeconds();
-
-        // build readable timestamp
-        responseTimestamp = hours + ":" + minutes.substr(-2);
-    }
-    // else annotation is not from today
-    else {
-        // get date
-        var date = annotationDate.getDate();
-        // get month
-        var month = annotationDate.getMonth();
-        // get year
-        var year = annotationDate.getFullYear();
-
-        // build readable timestamp
-        responseTimestamp = date + "." + month + "." + year;
-    }
-
-    return responseTimestamp;
-}
-
-/**
- * Check if given timestamp is from today
- *
- * @param timestamp The given timestamp in milliseconds
- * @returns {boolean} Returns true if the timestamp is from today
- */
-function isTimestampToday(timestamp) {
-    // now
-    var now = new Date();
-    // build Date object from timestamp
-    var date = new Date(timestamp);
-
-    // return true if timestamp is today
-    if (now.getDate() == date.getDate() && now.getMonth() == date.getMonth() && now.getFullYear() == date.getFullYear()) {
-        return true;
-    }
-    else {
-        return false;
-    }
-}
-
-/**
- * Toggle between the toggle button status
- *
- * @param element The given toggle button
- */
-function toggleButtonHandler(element) {
-    // open and close annotation text
-    element.parent().siblings(".annotation-body").children("p").toggleClass("overflow-hidden");
-    // toggle between up and down button
-    element.children("i").toggleClass("fa-chevron-down fa-chevron-up")
-}
-
-function lockButtonHandler() {
-    var lock = $('#btnLock').children('i')
-    lock.toggleClass("fa-lock-open fa-lock")
-
-    var area = $('#upload-area')
-    if (area.attr('readonly'))  {
-        area.attr('readonly', false);
-    }
-    else {
-        area.attr('readonly', true);
-    }
-}
-
-/*
-    MOCKUP FUNCTIONS
- */
-function randomUserId() {
-    return Math.floor((Math.random() * 12) + 1);;
-}
-
diff --git a/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp b/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp
index 0feb17e00df908ca0fc388249264ee4a220b6bf3..d8e499fe40ffe6c526d9785794e086efae0434a0 100644
--- a/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp
+++ b/gemeinsamforschen/src/main/webapp/pages/annotation-document.jsp
@@ -20,10 +20,20 @@
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
     <!-- js - contextMenu script -->
     <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>
+    <!-- js - scrollTo -->
+    <script src="//cdn.jsdelivr.net/npm/jquery.scrollto@2.1.2/jquery.scrollTo.min.js"></script>
+    <!-- js - rangy Core -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js" type="text/javascript"></script>
+    <!-- js - rangy TextRange Module -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js" type="text/javascript"></script>
+    <!-- js - utility -->
+    <script src="../assets/js/utility.js"></script>
     <!-- js - annotation websocket script -->
     <script src="../assets/js/annotationWebsocket.js"></script>
     <!-- js - annotation REST script -->
     <script src="../assets/js/annotationRest.js"></script>
+    <!-- js - unstructuredRest -->
+    <script src="../assets/js/unstructuredRest.js"></script>
     <!-- js - annotationScript -->
     <script src="../assets/js/annotationScript.js"></script>
 </head>
@@ -40,13 +50,13 @@
                     <div class="content-mainpage">
                         <div class="leftcolumn">
                             <div class="leftcontent">
-                                <div class="leftcontent-text context-menu-one" id="documentText">
-                                    Style never met and those among great. At no or september sportsmen he perfectly happiness attending. Depending listening delivered off new she procuring satisfied sex existence. Person plenty answer to exeter it if. Law use assistance especially resolution cultivated did out sentiments unsatiable. Way necessary had intention happiness but september delighted his curiosity. Furniture furnished or on strangers neglected remainder engrossed. Shot what able cold new the see hold. Friendly as an betrayed formerly he. Morning because as to society behaved moments. Put ladies design mrs sister was. Play on hill felt john no gate. Am passed figure to marked in. Prosperous middletons is ye inhabiting as assistance me especially. For looking two cousins regular amongst.
-                                    Style never met and those among great. At no or september sportsmen he perfectly happiness attending. Depending listening delivered off new she procuring satisfied sex existence. Person plenty answer to exeter it if. Law use assistance especially resolution cultivated did out sentiments unsatiable. Way necessary had intention happiness but september delighted his curiosity. Furniture furnished or on strangers neglected remainder engrossed. Shot what able cold new the see hold. Friendly as an betrayed formerly he. Morning because as to society behaved moments. Put ladies design mrs sister was. Play on hill felt john no gate. Am passed figure to marked in. Prosperous middletons is ye inhabiting as assistance me especially. For looking two cousins regular amongst.
-                                </div>
+                                <div class="leftcontent-text context-menu-one" id="documentText"></div>
                                 <div class="leftcontent-buttons">
+                                    <div class="leftcontent-buttons-back">
+                                        <button id="btnBack" type="button" class="btn btn-secondary">Zurück</button>
+                                    </div>
                                     <div class="leftcontent-buttons-next">
-                                        <button id="btnContinue" type="button" class="btn btn-secondary">Weiter</button>
+                                        <button id="btnContinue" type="button" class="btn btn-primary">Weiter</button>
                                     </div>
                                 </div>
                             </div>
diff --git a/gemeinsamforschen/src/main/webapp/pages/project-student.jsp b/gemeinsamforschen/src/main/webapp/pages/project-student.jsp
index 55567371949904fc7116ef7cf01bab56f50def4a..a8be6406cff0e171c884faa3d1eaadaee5bbb083 100644
--- a/gemeinsamforschen/src/main/webapp/pages/project-student.jsp
+++ b/gemeinsamforschen/src/main/webapp/pages/project-student.jsp
@@ -95,14 +95,7 @@
                                     <img src="../assets/img/3.jpg">
                                     <a href="#">student3@uni.de</a>
                                     <hr>
-                                    <ul>
-                                        <li>
-                                            "Viva la Floristika" - Titel hochgeladen
-                                            <a class="annotationview" role="button">
-                                                <label style="font-size:10px;"><i class="far fa-comments"
-                                                                                  style="font-size:15px;"></i>feedback</label>
-                                            </a>
-                                        </li>
+                                    <ul id="submissionUpload">
                                     </ul>
                                 </td>
 
diff --git a/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp b/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..94b29c07de3adfa1681dd11423e4607e69700e7e
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp
@@ -0,0 +1,108 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu" %>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="headLine" %>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="omniDependencies" %>
+
+<!DOCTYPE html>
+<html>
+
+<head>
+    <omniDependencies:omniDependencies/>
+
+    <!-- css - unstructured-annotation -->
+    <link rel="stylesheet" type="text/css" href="../assets/css/unstructured-annotation.css">
+    <!-- css - contextMenu -->
+    <link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
+
+    <!-- js - jQuery validation plugin -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.min.js"></script>
+    <!-- js - jQuery ui position -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
+    <!-- js - contextMenu script -->
+    <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>
+    <!-- js - rangy Core -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js" type="text/javascript"></script>
+    <!-- js - rangy TextRange Module -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js" type="text/javascript"></script>
+    <!-- js - unstructuredRest -->
+    <script src="../assets/js/unstructuredRest.js"></script>
+    <!-- js - unstructuredUpload -->
+    <script src="../assets/js/unstructuredAnnotation.js"></script>
+
+
+</head>
+
+<body>
+<div id="wrapper" class="full-height">
+    <menu:menu></menu:menu>
+    <div class="page-content-wrapper full-height">
+        <div class="container-fluid full-height">
+            <div class="container-fluid-content">
+                <div class="flex">
+                    <headLine:headLine/>
+                </div>
+                <div class="content-mainpage">
+                    <div class="leftcolumn">
+                        <div class="leftcontent">
+                            <div class="leftcontent-text context-menu-one" id="documentText"></div>
+                            <div class="leftcontent-buttons">
+                                <div class="leftcontent-buttons-save">
+                                    <button id="btnSave" type="button" class="btn btn-secondary">Speichern</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="rightcolumn">
+                        <div class="rightcontent">
+                            <ol id="annotations">
+                                <li class="spacing">
+                                    <div id="titel" class="category-card not-added">
+                                        <p>Titel</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="recherche" class="category-card not-added">
+                                        <p>Recherche</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="literaturverzeichnis" class="category-card not-added">
+                                        <p>Literaturverzeichnis</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="forschungsfrage" class="category-card not-added">
+                                        <p>Forschungsfrage</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="untersuchungskonzept" class="category-card not-added">
+                                        <p>Untersuchungskonzept</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="methodik" class="category-card not-added">
+                                        <p>Methodik</p>
+                                    </div>
+                                </li>
+                                <li class="spacing">
+                                    <div id="durchfuehrung" class="category-card not-added">
+                                        <p>Durchführung</p>
+                                    </div>
+                                </li>
+                                <li>
+                                    <div id="auswertung" class="category-card not-added">
+                                        <p>Auswertung</p>
+                                    </div>
+                                </li>
+                            </ol>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</body>
+
+</html>
diff --git a/gemeinsamforschen/src/main/webapp/pages/unstructured-upload.jsp b/gemeinsamforschen/src/main/webapp/pages/unstructured-upload.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..083f71f4cd99bffc55a20c3f311eae53d1fd2bb9
--- /dev/null
+++ b/gemeinsamforschen/src/main/webapp/pages/unstructured-upload.jsp
@@ -0,0 +1,58 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu" %>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="headLine" %>
+<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="omniDependencies" %>
+
+<!DOCTYPE html>
+<html>
+
+<head>
+    <omniDependencies:omniDependencies/>
+
+    <!-- js - jQuery validation plugin -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.min.js"></script>
+    <!-- js - jQuery ui position -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
+
+    <!-- css - upload-unstructured -->
+    <link rel="stylesheet" type="text/css" href="../assets/css/unstructured-upload.css">
+    <!-- js - unstructuredUpload -->
+    <script src="../assets/js/unstructuredUpload.js"></script>
+    <!-- js - unstructuredRest -->
+    <script src="../assets/js/unstructuredRest.js"></script>
+
+</head>
+
+<body>
+<div id="wrapper" class="full-height">
+    <menu:menu></menu:menu>
+    <div class="page-content-wrapper full-height">
+        <div class="container-fluid full-height">
+            <div class="container-fluid-content">
+                <div class="flex">
+                    <headLine:headLine/>
+                </div>
+                <div class="content-mainpage">
+                    <form id="upload-textarea-form">
+                        <div class="form-group upload-text" id="documentText">
+                            <label for="upload-textarea">Texteingabe</label>
+                            <textarea class="upload-text-textarea form-control" placeholder="Text einfügen..." id="upload-textarea" name="uploadtextarea"></textarea>
+                        </div>
+                    </form>
+
+                    <div>
+                        <label for="file">Alternativ bitte Datei wählen</label>
+                        <input type="file" id="file" name="file">
+                    </div>
+                    <div class="document-text-buttons">
+                        <button type="button" class="btn btn-secondary document-text-buttons-back" id="btnBack">Zurück</button>
+                        <button type="button" class="btn btn-primary document-text-buttons-next" id="btnNext">Weiter</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</body>
+
+</html>
diff --git a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html
deleted file mode 100644
index 092ea377d8a07edd36cb249bbf8fb6d665072304..0000000000000000000000000000000000000000
--- a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>muster-gemeinsam-forschen</title>
-
-    <!-- css - annotationStyle -->
-    <link rel="stylesheet" type="text/css" href="../assets/css/upload-unstructured.css">
-    <!-- css - contextMenu -->
-    <link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
-    <!-- css - bootstrap -->
-    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-    <!-- css - styles -->
-    <link rel="stylesheet" href="../assets/css/styles.css">
-    <!-- css - font awesome -->
-    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
-    <!-- css - sidebar -->
-    <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css">
-
-    <!-- js - jQuery -->
-    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
-    <!-- js - bootstrap -->
-    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-    <!-- js - jQuery ui position -->
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
-    <!-- js - contextMenu script -->
-    <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>
-    <!-- js - annotationScript -->
-    <script src="../assets/js/uploadUnstructured.js"></script>
-
-</head>
-
-<body>
-<div id="wrapper">
-    <div id="sidebar-wrapper">
-        <ul class="sidebar-nav">
-            <li class="sidebar-brand"><a href="#">overview</a></li>
-            <li><a href="#">Quizfrage</a></li>
-            <li><a href="#">ePortfolio</a></li>
-            <li><a href="#">Beitrag</a></li>
-            <li><a href="#">Bewertung</a></li>
-            <li><a href="#">Logout</a></li>
-        </ul>
-    </div>
-    <div class="page-content-wrapper">
-        <div class="container-fluid">
-            <h1>Unstrukturierte Abgabe
-                <a href="#">
-                    <span class="glyphicon glyphicon-envelope"
-                          style="font-size:27px;margin-top:-17px;margin-left:600px;"></span>
-                </a>
-                <a href="#">
-                    <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span>
-                </a>
-            </h1>
-            <div class="mainpage">
-                <div class="leftcolumn">
-                    <div class="leftcontent ">
-                        <div class="context-menu-one form-group" id="documentText">
-                            <label for="upload-area">Texteingabe:</label>
-                            <textarea class="unstructured-textarea form-control" rows="20" id="upload-area">
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
-
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
-
-Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
-
-Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
-
-At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
-                            </textarea>
-                            </div>
-                        <div class="document-text-buttons">
-                            <button onclick="lockButtonHandler()" type="button" class="btn btn-secondary document-text-buttons-lock" id="btnLock"><i class="fas fa-lock-open" id="lock"></i></button>
-                            <button type="button" class="btn btn-secondary document-text-buttons-save" id="btnSave">Speichern</i></button>
-                        </div>
-                    </div>
-                </div>
-                <div class="rightcolumn">
-                    <div class="rightcontent">
-                        <ol id="annotations">
-                        </ol>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp
deleted file mode 100644
index 98dba6d3b364f74390ee3854c86089c0fec1f224..0000000000000000000000000000000000000000
--- a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp
+++ /dev/null
@@ -1,90 +0,0 @@
-<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%>
-
-<!DOCTYPE html>
-<html>
-
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>muster-gemeinsam-forschen</title>
-
-    <!-- css - annotationStyle -->
-    <link rel="stylesheet" type="text/css" href="../assets/css/upload-unstructured.css">
-    <!-- css - contextMenu -->
-    <link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
-    <!-- css - bootstrap -->
-    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-    <!-- css - styles -->
-    <link rel="stylesheet" href="../assets/css/styles.css">
-    <!-- css - font awesome -->
-    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
-    <!-- css - sidebar -->
-    <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css">
-
-    <!-- js - jQuery -->
-    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
-    <!-- js - bootstrap -->
-    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-    <!-- js - jQuery ui position -->
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
-    <!-- js - contextMenu script -->
-    <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>
-    <!-- js - utility script -->
-    <script src="../assets/js/utility.js"></script>
-    <!-- js - annotationScript -->
-    <script src="../assets/js/uploadUnstructured.js"></script>
-
-</head>
-
-<body>
-<div id="wrapper">
-    <menu:menu></menu:menu>
-    <div class="page-content-wrapper">
-        <div class="container-fluid">
-            <h1>Unstrukturierte Abgabe
-                <a href="#">
-                    <span class="glyphicon glyphicon-envelope"
-                          style="font-size:27px;margin-top:-17px;margin-left:600px;"></span>
-                </a>
-                <a href="#">
-                    <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span>
-                </a>
-            </h1>
-            <div class="mainpage">
-                <div class="leftcolumn">
-                    <div class="leftcontent ">
-                        <div class="context-menu-one form-group" id="documentText">
-                            <label for="upload-area">Texteingabe:</label>
-                            <textarea class="unstructured-textarea form-control" rows="20" id="upload-area">
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
-
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
-
-Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
-
-Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
-
-At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
-                            </textarea>
-                            </div>
-                        <div class="document-text-buttons">
-                            <button onclick="lockButtonHandler()" type="button" class="btn btn-secondary document-text-buttons-lock" id="btnLock"><i class="fas fa-lock-open" id="lock"></i></button>
-                            <button type="button" class="btn btn-secondary document-text-buttons-back" id="btnBack">Zurück</button>
-                            <button type="button" class="btn btn-primary document-text-buttons-save" id="btnSave">Speichern</button>
-                        </div>
-                    </div>
-                </div>
-                <div class="rightcolumn">
-                    <div class="rightcontent">
-                        <ol id="annotations">
-                        </ol>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/gemeinsamforschen/src/scripts/dbschema/fltrail.sql b/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
index 0d5dfe1643c376e6ac1cdfa6f56451bbc9809633..2e37f5d4949ea62d0cf540294fb7d36886aa83cd 100644
--- a/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
+++ b/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
@@ -113,7 +113,8 @@ CREATE TABLE if not exists `annotations` (
   `id` varchar(120) NOT NULL,
   `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   `userToken` varchar(120) DEFAULT NULL,
-  `targetId` int(11) DEFAULT NULL,
+  `targetId` varchar(120) DEFAULT NULL,
+  `targetCategory` VARCHAR(30) NOT NULL,
   `title` varchar(120) DEFAULT NULL,
   `comment` varchar(400) DEFAULT NULL,
   `startCharacter` int(11) DEFAULT NULL,
@@ -121,6 +122,31 @@ CREATE TABLE if not exists `annotations` (
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
+CREATE TABLE if not exists `fullsubmissions` (
+  `id` VARCHAR(120) NOT NULL,
+  `timestamp` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `user` VARCHAR(120) NOT NULL,
+  `text` MEDIUMTEXT NOT NULL,
+  `projectId` VARCHAR(120) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE if not exists `submissionparts` (
+  `timestamp` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `userId` VARCHAR(120) NOT NULL,
+  `fullSubmissionId` VARCHAR(120) NOT NULL,
+  `category` VARCHAR(30) NOT NULL,
+  PRIMARY KEY (`fullSubmissionId`, `category`)
+) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE if not exists `submissionpartbodyelements` (
+  `fullSubmissionId` VARCHAR(120) NOT NULL,
+  `category` VARCHAR(30) NOT NULL,
+  `startCharacter` int(11) NOT NULL,
+  `endCharacter` int(11) NOT NULL,
+  PRIMARY KEY (`fullSubmissionId`, `category`, `startCharacter`, `endCharacter`)
+) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+
 alter table users
 
   add isStudent tinyint(1) default '1' null;
diff --git a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/AnnotationTest.java b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/AnnotationTest.java
index d0fde6c5871fd1533cc8e37308ec2e3068343327..7faee3414dc619219b3c9e98604dd4b69c4670bb 100644
--- a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/AnnotationTest.java
+++ b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/AnnotationTest.java
@@ -7,6 +7,7 @@ import unipotsdam.gf.modules.annotation.model.Annotation;
 import unipotsdam.gf.modules.annotation.model.AnnotationBody;
 import unipotsdam.gf.modules.annotation.model.AnnotationPatchRequest;
 import unipotsdam.gf.modules.annotation.model.AnnotationPostRequest;
+import unipotsdam.gf.modules.peer2peerfeedback.Category;
 
 import java.util.ArrayList;
 
@@ -37,7 +38,7 @@ public class AnnotationTest {
         String comment = "comment_testAddAnnotation";
 
         // prepare and execute request
-        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", 1, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", "1", Category.TITEL, new AnnotationBody(title, comment, 1, 2));
         Annotation response = controller.addAnnotation(annotationPostRequest);
 
         // the new annotation should be found in the database
@@ -58,7 +59,7 @@ public class AnnotationTest {
         String commentNew = "commentNew_testAlterAnnotation";
 
         // save new annotation in database
-        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", 0, new AnnotationBody(titleOld, commentOld, 1, 2));
+        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", "0", Category.TITEL, new AnnotationBody(titleOld, commentOld, 1, 2));
         Annotation response = controller.addAnnotation(annotationPostRequest);
 
         // the new annotation should be found in the database
@@ -96,7 +97,7 @@ public class AnnotationTest {
         String comment = "comment_testDeleteAnnotation";
 
         // prepare and execute request
-        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", 1, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", "1", Category.TITEL, new AnnotationBody(title, comment, 1, 2));
         Annotation response = controller.addAnnotation(annotationPostRequest);
 
         // the new annotation should be found in the database
@@ -118,7 +119,7 @@ public class AnnotationTest {
         String comment = "comment_testGetAnnotation";
 
         // prepare and execute request
-        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", 1, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", "1", Category.TITEL, new AnnotationBody(title, comment, 1, 2));
         Annotation response = controller.addAnnotation(annotationPostRequest);
 
         // receive the new annotation
@@ -143,26 +144,26 @@ public class AnnotationTest {
         String comment = "comment_testGetAnnotations";
 
         // initialize targetIds
-        ArrayList<Integer> targetIds = new ArrayList<>();
-        targetIds.add(-1);
-        targetIds.add(-2);
+        ArrayList<String> targetIds = new ArrayList<>();
+        targetIds.add("-1");
+        targetIds.add("-2");
 
         // save new annotations in database
-        AnnotationPostRequest request1 = new AnnotationPostRequest("userToken", targetIds.get(0), new AnnotationBody(title, comment, 1, 2));
-        AnnotationPostRequest request2 = new AnnotationPostRequest("userToken", targetIds.get(1), new AnnotationBody(title, comment, 1, 2));
-        AnnotationPostRequest request3 = new AnnotationPostRequest("userToken", targetIds.get(1), new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest request1 = new AnnotationPostRequest("userToken", targetIds.get(0), Category.TITEL, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest request2 = new AnnotationPostRequest("userToken", targetIds.get(1), Category.TITEL, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest request3 = new AnnotationPostRequest("userToken", targetIds.get(1), Category.TITEL, new AnnotationBody(title, comment, 1, 2));
         controller.addAnnotation(request1);
         controller.addAnnotation(request2);
         controller.addAnnotation(request3);
 
         // receive the new annotations with targetId = -2
-        ArrayList<Annotation> getResponse = controller.getAnnotations(targetIds.get(1));
+        ArrayList<Annotation> getResponse = controller.getAnnotations(targetIds.get(1), Category.TITEL);
 
         // the size of the getResponse should be 2
         assertEquals("The size of the response should be 2 but was " + getResponse.size(), 2, getResponse.size());
 
         // receive the new annotations with targetId = -1
-        ArrayList<Annotation> getResponseNew = controller.getAnnotations(targetIds.get(0));
+        ArrayList<Annotation> getResponseNew = controller.getAnnotations(targetIds.get(0), Category.TITEL);
 
         // the size of the getResponse should be 1
         assertEquals("The size of the response should be 1 but was " + getResponseNew.size(), 1, getResponseNew.size());
@@ -183,7 +184,7 @@ public class AnnotationTest {
         String badId = "badId";
 
         // save new annotation in database
-        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", 0, new AnnotationBody(title, comment, 1, 2));
+        AnnotationPostRequest annotationPostRequest = new AnnotationPostRequest("userToken", "0", Category.TITEL, new AnnotationBody(title, comment, 1, 2));
         Annotation response = controller.addAnnotation(annotationPostRequest);
 
         // the annotation shouldn't be found in the database