diff --git a/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css
index 7a2ec45ed3709ceabe0bc56576e28f395c276f5a..dc0b139450bfeeacdf085eeef19effc9008aa19c 100644
--- a/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css
+++ b/gemeinsamforschen/src/main/webapp/assets/css/unstructured-annotation.css
@@ -91,9 +91,75 @@ body, html {
     border-color: lightgray;
     color: lightgray;
 }
-.added {
+
+.titel {
+    background-color: lightgreen;
+}
+.added-titel {
     border-style: solid;
     border-color: lightgreen;
     color: lightgreen;
 }
 
+.recherche {
+    background-color: lightblue;
+}
+.added-recherche {
+    border-style: solid;
+    border-color: lightblue;
+    color: lightblue;
+}
+
+.literaturverzeichnis {
+    background-color: lightcoral;
+}
+.added-literaturverzeichnis {
+    border-style: solid;
+    border-color: lightcoral;
+    color: lightcoral;
+}
+
+.forschungsfrage {
+    background-color: cyan;
+}
+.added-forschungsfrage {
+    border-style: solid;
+    border-color: cyan;
+    color: cyan;
+}
+
+.untersuchungskonzept {
+    background-color: goldenrod;
+}
+.added-untersuchungskonzept {
+    border-style: solid;
+    border-color: goldenrod;
+    color: goldenrod;
+}
+
+.methodik {
+    background-color: lightpink;
+}
+.added-methodik {
+    border-style: solid;
+    border-color: lightpink;
+    color: lightpink;
+}
+
+.durchfuehrung {
+    background-color: lightsalmon;
+}
+.added-durchfuehrung {
+    border-style: solid;
+    border-color: lightsalmon;
+    color: lightsalmon;
+}
+
+.auswertung {
+    background-color: lightseagreen;
+}
+.added-auswertung {
+    border-style: solid;
+    border-color: lightseagreen;
+    color: lightseagreen;
+}
\ 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
index ea01fb022ae5aaed29a724bab93448c8f64093c4..d3008597b456b6e2410de340dc08b60ba20f85fe 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/unstructuredAnnotation.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredAnnotation.js
@@ -1,5 +1,3 @@
-var documentText;
-
 /**
  * This function will fire when the DOM is ready
  */
@@ -15,6 +13,11 @@ $(document).ready(function() {
         location.href="unstructured-upload.jsp?token="+getUserTokenFromUrl();
     });
 
+    // set click listener to save button
+    $('#btnSave').click(function () {
+        saveButtonHandler();
+    });
+
 
 
     /**
@@ -24,24 +27,7 @@ $(document).ready(function() {
         selector: '.context-menu-one',
         callback: function(key, options) {
 
-            // TODO - show and handle more options
-            if (key === "titel" ||
-                key === "recherche" ||
-                key === "literaturverzeichnis" ||
-                key === "forschungsfrage" ||
-                key === "untersuchungskonzept" ||
-                key === "methodik" ||
-                key === "durchfuehrung" ||
-                key === "auswertung") {
-                if (getSelectedText().length > 0) {
-                    let startCharacter = window.getSelection().getRangeAt(0).startOffset;
-                    let endCharacter = window.getSelection().getRangeAt(0).endOffset;
-                    let selectedText = getSelectedText();
-
-                    handleCategorySelection(selectedText, key, startCharacter, endCharacter);
-
-                }
-            }
+            handleContextStuff(key);
 
         },
         items: {
@@ -81,14 +67,34 @@ function getSubmissionIdFromUrl() {
 
 }
 
+/**
+ * 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) {
 
-function handleCategorySelection(text, category, startCharacter, endCharacter) {
-    var elem = $('#' + category);
-    elem.toggleClass("not-added added");
+    // if highlighting is possible
+    if (!isAlreadyHighlighted(startCharacter, endCharacter)) {
 
-    addHighlightedText(startCharacter, endCharacter);
+        // check if element has 'not-added' class
+        var elem = $('#' + category);
+        if (elem.hasClass("not-added")) {
+            elem.toggleClass("not-added added-" + category);
+        }
 
-    isAlreadyHighlighted(startCharacter, endCharacter);
+        // 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.")
+    }
 
 }
 
@@ -114,30 +120,171 @@ function getSelectedText() {
  *
  * @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) {
+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>').css('background-color', 'lightgreen').html(documentText.slice(startCharacter, endCharacter));
+    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 = 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);
 }
 
+/**
+ * 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) {
-    $('#annotations').each(function () {
-        if ($(this).find(".category-card").attr("added")) {
-            console.log("hi")
+    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 false;
+    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?")) {
+        $('#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
+                createSubmissionPart(submissionPartPostRequest, function (response) {
+                    console.log("send " + response.category + "'s post request to back-end")
+                })
+
+            }
+        });
+    }
+}
+
+function handleContextStuff(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
index 56bc502dc7e272b8d4c1cfaa2de564e01f1bb48c..80d3b51f9bee2f174725f84cab0aabc87cb52e81 100644
--- a/gemeinsamforschen/src/main/webapp/assets/js/unstructuredRest.js
+++ b/gemeinsamforschen/src/main/webapp/assets/js/unstructuredRest.js
@@ -51,7 +51,7 @@ function getFullSubmission(id, responseHandler, errorHandler) {
  */
 function createSubmissionPart(submissionPartPostRequest, responseHandler) {
     var url = "../rest/submissions/part/";
-    var json = JSON.stringify(fullSubmissionPostRequest);
+    var json = JSON.stringify(submissionPartPostRequest);
     $.ajax({
         url: url,
         type: "POST",
@@ -60,6 +60,9 @@ function createSubmissionPart(submissionPartPostRequest, responseHandler) {
         dataType: "json",
         success: function (response) {
             responseHandler(response);
+        },
+        error: function (e) {
+            console.log(e);
         }
     });
 }
diff --git a/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp b/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp
index bdce1c3724d8c2fb5fa79f4f538a467953ea2daf..94b29c07de3adfa1681dd11423e4607e69700e7e 100644
--- a/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp
+++ b/gemeinsamforschen/src/main/webapp/pages/unstructured-annotation.jsp
@@ -20,6 +20,10 @@
     <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 -->