diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.html b/src/app/components/shared/_dialogs/create-comment/create-comment.component.html
index 6fa43925f1a14a6f207aca8da48814c6bc04c5e5..66e9ee29f13060e03cff1886d4b3b8122461b028 100644
--- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.html
+++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.html
@@ -1,26 +1,26 @@
 <ars-row ars-flex-box>
   <ars-row>
     <div class="lang-selection">
-    <button class="lang-btn" mat-button (click)="select.open()"
-            matTooltip="{{ 'spacy-dialog.lang-button-hint' | translate }}"
-            matTooltipShowDelay="750">
-    <i class="material-icons">language</i>
-      <span *ngIf="!(selectedLang === 'auto')">
-      {{'spacy-dialog.' + (languagetoolService.mapLanguageToSpacyModel(selectedLang)) | translate}}
-      </span>
-      <span *ngIf="(selectedLang === 'auto')" id="langSelect">
+      <button class="lang-btn" mat-button (click)="select.open()"
+              matTooltip="{{ 'spacy-dialog.lang-button-hint' | translate }}"
+              matTooltipShowDelay="750">
+        <i class="material-icons">language</i>
+        <span *ngIf="!(grammarChecker.selectedLang === 'auto')">
+          {{'spacy-dialog.' + (languagetoolService.mapLanguageToSpacyModel(grammarChecker.selectedLang)) | translate}}
+        </span>
+        <span *ngIf="(grammarChecker.selectedLang === 'auto')" id="langSelect">
          auto
-      </span>
-        <mat-select class="select-list" #select [(ngModel)]="selectedLang">
-        <mat-option *ngFor="let lang of languages" [value]="lang">
-          <span *ngIf="lang == 'de-DE'">{{ 'spacy-dialog.de' | translate }}</span>
-          <span *ngIf="lang == 'en-US'">{{ 'spacy-dialog.en' | translate }}</span>
-          <span *ngIf="lang == 'fr'">{{ 'spacy-dialog.fr' | translate }}</span>
-          <span *ngIf="lang == 'auto'">{{ 'spacy-dialog.auto' | translate }}</span>
-        </mat-option>
-      </mat-select>
-    </button>
-  </div>
+        </span>
+        <mat-select class="select-list" #select [(ngModel)]="grammarChecker.selectedLang">
+          <mat-option *ngFor="let lang of grammarChecker.languages" [value]="lang">
+            <span *ngIf="lang == 'de-DE'">{{ 'spacy-dialog.de' | translate }}</span>
+            <span *ngIf="lang == 'en-US'">{{ 'spacy-dialog.en' | translate }}</span>
+            <span *ngIf="lang == 'fr'">{{ 'spacy-dialog.fr' | translate }}</span>
+            <span *ngIf="lang == 'auto'">{{ 'spacy-dialog.auto' | translate }}</span>
+          </mat-option>
+        </mat-select>
+      </button>
+    </div>
     <div class="anchor-wrp">
       <div class="anchor-right">
         <mat-form-field *ngIf="tags" class="tag-form-field">
@@ -47,8 +47,9 @@
           <mat-form-field style="width:100%;">
             <input [disabled]="true" matInput>
             <div
+              (document:click)="grammarChecker.onDocumentClick($event)"
               [contentEditable]="true"
-              (paste)="onPaste($event); maxLength(commentBody)"
+              (paste)="grammarChecker.onPaste($event); grammarChecker.maxLength(commentBody, user.role === 3 ? 1000 : 500)"
               [spellcheck]="false"
               (focus)="eventService.makeFocusOnInputTrue()"
               style="margin-top:15px;width:100%;"
@@ -56,7 +57,7 @@
               #commentBody
               aria-labelledby="ask-question-description"
               autofocus
-              (input)="maxLength(commentBody)"
+              (input)="grammarChecker.maxLength(commentBody, user.role === 3 ? 1000 : 500)"
               id="answer-input">
             </div>
             <mat-placeholder class="placeholder">
@@ -69,10 +70,10 @@
             </mat-hint>
             <mat-hint align="end">
               <span aria-hidden="true">
-                {{inputText.length}} / {{user.role === 3 ? 1000 : 500}}
+                {{commentBody.innerHTML.length}} / {{user.role === 3 ? 1000 : 500}}
               </span>
             </mat-hint>
-            <span *ngIf="!this.hasSpellcheckConfidence">
+            <span *ngIf="!grammarChecker.hasSpellcheckConfidence">
               <p class="lang-confidence">{{ 'spacy-dialog.force-language-selection' | translate }}</p>
             </span>
 
@@ -88,7 +89,7 @@
         <ars-row [height]="12"></ars-row>
         <ars-row>
           <markdown katex emoji lineNumbers lineHighlight
-                    [data]="body"></markdown>
+                    [data]="commentBody.innerText"></markdown>
         </ars-row>
       </mat-tab>
     </mat-tab-group>
@@ -101,9 +102,9 @@
       <button
         [disabled]="this.commentBody.innerHTML.length < 4 "
         mat-flat-button class="spell-button"
-        (click)="grammarCheck(commentBody)">
+        (click)="grammarChecker.grammarCheck(commentBody)">
         {{ 'comment-page.grammar-check' | translate}}
-        <mat-icon *ngIf="isSpellchecking" style="margin: 0;">
+        <mat-icon *ngIf="grammarChecker.isSpellchecking" style="margin: 0;">
           <mat-spinner diameter="20"></mat-spinner>
         </mat-icon>
       </button>
@@ -112,7 +113,7 @@
       <app-dialog-action-buttons
         buttonsLabelSection="comment-page"
         confirmButtonLabel="send"
-        [showLoadingCycle] = "isSendingToSpacy"
+        [showLoadingCycle]="isSendingToSpacy"
         [showDivider]="false"
         [spacing]="false"
         [cancelButtonClickAction]="buildCloseDialogActionCallback()"
diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts
index 5ca59b3528a5543b164bdd09a603854fb9d0d20f..0b5c95145aa8241b5397a2be7e1baad629be586d 100644
--- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts
+++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts
@@ -1,4 +1,4 @@
-import { Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { Component, Inject, OnInit, ViewChild } from '@angular/core';
 import { Comment, Language as CommentLanguage } from '../../../../models/comment';
 import { NotificationService } from '../../../../services/util/notification.service';
 import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
@@ -10,15 +10,16 @@ import { EventService } from '../../../../services/util/event.service';
 import { SpacyDialogComponent } from '../spacy-dialog/spacy-dialog.component';
 import { LanguagetoolService, Language } from '../../../../services/http/languagetool.service';
 import { CreateCommentKeywords } from '../../../../utils/create-comment-keywords';
+import { GrammarChecker } from '../../../../utils/grammar-checker';
 
 @Component({
   selector: 'app-submit-comment',
   templateUrl: './create-comment.component.html',
   styleUrls: ['./create-comment.component.scss']
 })
-export class CreateCommentComponent implements OnInit, OnDestroy {
+export class CreateCommentComponent implements OnInit {
 
-  @ViewChild('commentBody', {static: true}) commentBody: HTMLDivElement;
+  @ViewChild('commentBody', { static: true }) commentBody: HTMLDivElement;
 
   comment: Comment;
 
@@ -26,19 +27,11 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
   roomId: string;
   tags: string[];
   selectedTag: string;
-  inputText = '';
-  body: string;
-
-  languages: Language[] = ['de-DE', 'en-US', 'fr', 'auto'];
-  selectedLang: Language = 'auto';
 
   bodyForm = new FormControl('', [Validators.required]);
 
-  isSpellchecking = false;
   isSendingToSpacy = false;
-  hasSpellcheckConfidence = true;
-
-  newLang = 'auto';
+  grammarChecker: GrammarChecker;
 
   constructor(
     private notification: NotificationService,
@@ -49,49 +42,17 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     public languagetoolService: LanguagetoolService,
     public eventService: EventService,
     @Inject(MAT_DIALOG_DATA) public data: any) {
+    this.grammarChecker = new GrammarChecker(languagetoolService);
   }
 
   ngOnInit() {
     this.translateService.use(localStorage.getItem('currentLang'));
-    setTimeout(() => {
-      document.getElementById('answer-input').focus();
-      document.addEventListener('click', this.onDocumentClick);
-    }, 0);
-  }
-
-  onDocumentClick(e) {
-    const container = document.getElementsByClassName('dropdownBlock');
-    Array.prototype.forEach.call(container, (elem) => {
-      if (!elem.contains(e.target) && (!(e.target as Node).parentElement.classList.contains('markUp')
-        || (e.target as HTMLElement).dataset.id !== ((elem as Node).parentElement as HTMLElement).dataset.id)) {
-        (elem as HTMLElement).style.display = 'none';
-      }
-    });
-  }
-
-  ngOnDestroy() {
-    document.removeEventListener('click', this.onDocumentClick);
   }
 
   onNoClick(): void {
     this.dialogRef.close();
   }
 
-  onPaste(e) {
-    e.preventDefault();
-    const elem = document.getElementById('answer-input');
-    const text = e.clipboardData.getData('text');
-    elem.innerText += text.replace(/<[^>]*>?/gm, '');
-
-    const range = document.createRange();
-    range.setStart(elem.lastChild, elem.lastChild.textContent.length);
-    range.collapse(true);
-
-    const sel = window.getSelection();
-    sel.removeAllRanges();
-    sel.addRange(range);
-  }
-
   checkInputData(body: string): boolean {
     body = body.trim();
     if (!body) {
@@ -117,13 +78,14 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
   }
 
   openSpacyDialog(comment: Comment): void {
-    CreateCommentKeywords.isSpellingAcceptable(this.languagetoolService, this.inputText, this.selectedLang)
+    CreateCommentKeywords.isSpellingAcceptable(this.languagetoolService, this.commentBody.innerHTML, this.grammarChecker.selectedLang)
       .subscribe((result) => {
         if (result.isAcceptable) {
           const commentLang = this.languagetoolService.mapLanguageToSpacyModel(result.result.language.code as Language);
-          const selectedLangExtend = this.selectedLang[2] === '-' ? this.selectedLang.substr(0, 2) : this.selectedLang;
+          const selectedLangExtend = this.grammarChecker.selectedLang[2] === '-' ?
+            this.grammarChecker.selectedLang.substr(0, 2) : this.grammarChecker.selectedLang;
           // Store language if it was auto-detected
-          if (this.selectedLang === 'auto') {
+          if (this.grammarChecker.selectedLang === 'auto') {
             comment.language = Comment.mapModelToLanguage(commentLang);
           } else if (CommentLanguage[selectedLangExtend]) {
             comment.language = CommentLanguage[selectedLangExtend];
@@ -161,128 +123,4 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
   buildCreateCommentActionCallback(text: HTMLDivElement): () => void {
     return () => this.closeDialog(text.innerText);
   }
-
-  checkSpellings(text: string, language: Language = this.selectedLang) {
-    return this.languagetoolService.checkSpellings(CreateCommentKeywords.cleaningFunction(text), language);
-  }
-
-  maxLength(commentBody: HTMLDivElement): void {
-    if (this.user.role === 3 && commentBody.innerText.length > 1000) {
-      commentBody.innerText = commentBody.innerText.slice(0, 1000);
-    } else if (this.user.role !== 3 && commentBody.innerText.length > 500) {
-      commentBody.innerText = commentBody.innerText.slice(0, 500);
-    }
-    this.body = commentBody.innerText;
-    if (this.body.length === 1 && this.body.charCodeAt(this.body.length - 1) === 10) {
-      commentBody.innerHTML = commentBody.innerHTML.replace('<br>', '');
-    }
-    this.inputText = commentBody.innerText;
-  }
-
-  grammarCheck(commentBody: HTMLDivElement): void {
-    const wrongWords: string[] = [];
-    commentBody.innerHTML = this.inputText;
-    this.isSpellchecking = true;
-    this.hasSpellcheckConfidence = true;
-    this.checkSpellings(commentBody.innerText).subscribe((wordsCheck) => {
-      if (!this.checkLanguageConfidence(wordsCheck)) {
-        this.hasSpellcheckConfidence = false;
-        return;
-      }
-      if (this.selectedLang === 'auto' && (document.getElementById('langSelect').innerText.includes(this.newLang)
-        || document.getElementById('langSelect').innerText.includes('auto'))) {
-        if (wordsCheck.language.name.includes('German')) {
-          this.selectedLang = 'de-DE';
-        } else if (wordsCheck.language.name.includes('English')) {
-          this.selectedLang = 'en-US';
-        } else if (wordsCheck.language.name.includes('French')) {
-          this.selectedLang = 'fr';
-        } else {
-          this.newLang = wordsCheck.language.name;
-        }
-        document.getElementById('langSelect').innerHTML = this.newLang;
-      }
-      if (wordsCheck.matches.length > 0) {
-        wordsCheck.matches.forEach(grammarError => {
-          const wrongWord = commentBody.innerText.slice(grammarError.offset, grammarError.offset + grammarError.length);
-          wrongWords.push(wrongWord);
-        });
-
-        this.checkSpellings(commentBody.innerHTML).subscribe((res) => {
-          for (let i = res.matches.length - 1; i >= 0; i--) {
-            const wrongWord = commentBody.innerHTML
-              .slice(res.matches[i].offset, res.matches[i].offset + res.matches[i].length);
-
-            if (wrongWords.includes(wrongWord)) {
-              const suggestions: any[] = res.matches[i].replacements;
-              let displayOptions = 3;
-              let suggestionsHTML = '';
-
-              if (!suggestions.length) {
-                suggestionsHTML = '<span style="color: black; display: block; text-align: center;">' + res.matches[i].message + '</span>';
-              }
-
-              if (suggestions.length < displayOptions) {
-                displayOptions = suggestions.length;
-              }
-
-              for (let j = 0; j < displayOptions; j++) {
-                // eslint-disable-next-line max-len
-                suggestionsHTML += '<span class="suggestions"' + ' style="color: black; display: block; text-align: center; cursor: pointer;">' + suggestions[j].value + '</span>';
-              }
-
-              const replacement =
-                '<div class="markUp" data-id="'+i+'" style="position: relative; display: inline-block; border-bottom: 1px dotted black">' +
-                  '<span data-id="' + i + '" style="text-decoration: underline wavy red; cursor: pointer;">' +
-                          wrongWord +
-                  '</span>' +
-                  // eslint-disable-next-line max-len
-                  '<div class="dropdownBlock" style="display: none; width: 160px; background-color: white; border-style: solid; border-color: var(--primary); color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1000; bottom: 100%;">' +
-                        suggestionsHTML +
-                  '</div>' +
-                '</div>';
-
-              commentBody.innerHTML = commentBody.innerHTML.substr(0, res.matches[i].offset) +
-                replacement + commentBody.innerHTML.substr(res.matches[i].offset + wrongWord.length, commentBody.innerHTML.length);
-            }
-          }
-
-          setTimeout(() => {
-            Array.from(document.getElementsByClassName('markUp')).forEach(markup => {
-              markup.addEventListener('click', () => {
-                ((markup as HTMLElement).lastChild as HTMLElement).style.display = 'block';
-                const rectdiv = (document.getElementById('answer-input')).getBoundingClientRect();
-                const rectmarkup = markup.getBoundingClientRect();
-                let offset;
-                if (rectmarkup.x + rectmarkup.width / 2 > rectdiv.right - 80) {
-                  offset = rectdiv.right - rectmarkup.x - rectmarkup.width;
-                  ((markup as HTMLElement).lastChild as HTMLElement).style.right = -offset + 'px';
-                } else if (rectmarkup.x + rectmarkup.width / 2 < rectdiv.left + 80) {
-                  offset = rectmarkup.x - rectdiv.left;
-                  ((markup as HTMLElement).lastChild as HTMLElement).style.left = -offset + 'px';
-                } else {
-                  ((markup as HTMLElement).lastChild as HTMLElement).style.left = '50%';
-                  ((markup as HTMLElement).lastChild as HTMLElement).style.marginLeft = '-80px';
-                }
-                setTimeout(() => {
-                  Array.from(document.getElementsByClassName('suggestions')).forEach(suggestion => {
-                    suggestion.addEventListener('click', () => {
-                      suggestion.parentElement.parentElement.outerHTML = suggestion.innerHTML;
-                      this.inputText = commentBody.innerText;
-                    });
-                  });
-                }, 500);
-              });
-            });
-          }, 500);
-        });
-      }
-    }, () => '', () => {
-      this.isSpellchecking = false;
-    });
-  }
-
-  checkLanguageConfidence(wordsCheck: any) {
-    return this.selectedLang === 'auto' ? wordsCheck.language.detectedLanguage.confidence >= 0.5 : true;
-  }
 }
diff --git a/src/app/components/shared/comment-answer/comment-answer.component.html b/src/app/components/shared/comment-answer/comment-answer.component.html
index e96bc84b6a25d5cb7bc5c7f4b48b67822a3bfa75..2036f274b2b7e12187afa36deb4ec795f82fa2ce 100644
--- a/src/app/components/shared/comment-answer/comment-answer.component.html
+++ b/src/app/components/shared/comment-answer/comment-answer.component.html
@@ -12,63 +12,107 @@
               *ngIf="!isStudent || answer">
       <div *ngIf="(isStudent || !edit) && answer">
         <markdown class="images" katex emoji lineNumbers lineHighlight
-          [data]="answer"></markdown>
+                  [data]="answer"></markdown>
         <div fxLayout="row"
              fxLayoutAlign="end">
           <button mat-raised-button
                   *ngIf="!isStudent && !edit"
                   class="save"
-                  (click)="edit = true">
+                  (click)="onEditClick()">
             <mat-icon>edit</mat-icon>
             {{'comment-page.edit-answer' | translate}}
           </button>
         </div>
       </div>
-      <mat-tab-group *ngIf="!isStudent && (edit || !answer)"
-                     [dynamicHeight]="false">
-        <mat-tab label="{{'comment-page.your-answer' | translate}}">
-          <mat-form-field class="input-block">
-            <textarea [(ngModel)]="answer"
-                      (input)="edit = true"
-                      (keyup)="$event.cancelBubble=true"
-                      matInput
-                      matTextareaAutosize
-                      matAutosizeMinRows="3"
-                      matAutosizeMaxRows="10"
-                      maxlength="2000"
-                      name="answer"
-                      autofocus>
-            </textarea>
-            <mat-hint align="start">
+      <div class="lang-selection"
+           *ngIf="!isStudent && (edit || !answer)">
+        <button class="lang-btn" mat-button (click)="select.open()"
+                matTooltip="{{ 'spacy-dialog.lang-button-hint' | translate }}"
+                matTooltipShowDelay="750">
+          <i class="material-icons">language</i>
+          <span *ngIf="!(grammarChecker.selectedLang === 'auto')">
+            {{'spacy-dialog.' + (languagetoolService.mapLanguageToSpacyModel(grammarChecker.selectedLang)) | translate}}
+          </span>
+          <span *ngIf="(grammarChecker.selectedLang === 'auto')" id="langSelect">
+            auto
+          </span>
+          <mat-select class="select-list" #select [(ngModel)]="grammarChecker.selectedLang">
+            <mat-option *ngFor="let lang of grammarChecker.languages" [value]="lang">
+              <span *ngIf="lang == 'de-DE'">{{ 'spacy-dialog.de' | translate }}</span>
+              <span *ngIf="lang == 'en-US'">{{ 'spacy-dialog.en' | translate }}</span>
+              <span *ngIf="lang == 'fr'">{{ 'spacy-dialog.fr' | translate }}</span>
+              <span *ngIf="lang == 'auto'">{{ 'spacy-dialog.auto' | translate }}</span>
+            </mat-option>
+          </mat-select>
+        </button>
+      </div>
+      <div *ngIf="!isStudent && (edit || !answer)">
+        <mat-tab-group [dynamicHeight]="false">
+          <mat-tab label="{{'comment-page.your-answer' | translate}}">
+            <mat-divider></mat-divider>
+            <mat-form-field class="input-block">
+              <input [disabled]="true" matInput>
+              <div
+                (document:click)="grammarChecker.onDocumentClick($event)"
+                [contentEditable]="true"
+                (paste)="grammarChecker.onPaste($event); grammarChecker.maxLength(commentBody, 2000)"
+                [spellcheck]="false"
+                (focus)="eventService.makeFocusOnInputTrue()"
+                style="margin-top:1.25em; width:100%;"
+                (blur)="eventService.makeFocusOnInputFalse()"
+                #commentBody
+                aria-labelledby="ask-question-description"
+                autofocus
+                (input)="grammarChecker.maxLength(commentBody, 2000); answer = commentBody.innerText"
+                id="answer-input">
+              </div>
+              <mat-hint align="start">
               <span aria-hidden="true">
                 {{ 'comment-page.Markdown-hint' | translate }}
               </span>
-            </mat-hint>
-            <mat-hint align="end">
+              </mat-hint>
+              <mat-hint align="end">
             <span aria-hidden="true">
               {{ answer ? answer.length : 0 }} / 2000
             </span>
-            </mat-hint>
-          </mat-form-field>
-        </mat-tab>
-        <mat-tab label="{{'session.preview' | translate}}"
-                 [disabled]="!answer">
-          <markdown class="images" katex emoji lineNumbers lineHighlight
-            [data]="answer"></markdown>
-        </mat-tab>
-      </mat-tab-group>
-      <div fxLayout="row"
-           fxLayoutAlign="end">
-        <button mat-raised-button
-                *ngIf="!isStudent && answer && edit"
-                class="delete"
-                (click)="openDeleteAnswerDialog()">
-          {{'comment-page.delete-answer' | translate}}</button>
-        <button mat-raised-button
-                *ngIf="!isStudent && (edit || !answer)"
-                class="save"
-                (click)="saveAnswer()">
-          {{'comment-page.save-answer' | translate}}</button>
+              </mat-hint>
+            </mat-form-field>
+          </mat-tab>
+          <mat-tab label="{{'session.preview' | translate}}"
+                   [disabled]="!answer">
+            <markdown class="images" katex emoji lineNumbers lineHighlight
+                      [data]="answer"></markdown>
+          </mat-tab>
+        </mat-tab-group>
+        <div id="buttonWrapper"
+             fxLayout="col">
+          <div fxLayout="row">
+            <button
+              *ngIf="edit"
+              [disabled]="commentBody.innerHTML.length < 4 "
+              mat-raised-button
+              (click)="grammarChecker.grammarCheck(commentBody)"
+              class="spell-button">
+              {{ 'comment-page.grammar-check' | translate}}
+              <mat-icon *ngIf="grammarChecker.isSpellchecking" style="margin: 0;">
+                <mat-spinner diameter="20"></mat-spinner>
+              </mat-icon>
+            </button>
+          </div>
+          <div fxLayout="row">
+            <button mat-raised-button
+                    *ngIf="answer"
+                    class="delete"
+                    style="display: inline-block"
+                    (click)="openDeleteAnswerDialog()">
+              {{'comment-page.delete-answer' | translate}}</button>
+            <button mat-raised-button
+                    class="save"
+                    style="display: inline-block"
+                    (click)="answer = commentBody.innerText; saveAnswer()">
+              {{'comment-page.save-answer' | translate}}</button>
+          </div>
+        </div>
       </div>
     </mat-card>
   </div>
diff --git a/src/app/components/shared/comment-answer/comment-answer.component.scss b/src/app/components/shared/comment-answer/comment-answer.component.scss
index b87b500b6b06a4fe23dc4d3fdb661110396419cb..b11d9ee32e57c8109e9c25e47bddb2fe8b166aad 100644
--- a/src/app/components/shared/comment-answer/comment-answer.component.scss
+++ b/src/app/components/shared/comment-answer/comment-answer.component.scss
@@ -45,3 +45,57 @@ mat-icon {
 .border-answer {
   box-shadow: 0 2px 1px -1px rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12), -4px 0 0 0 var(--primary);
 }
+
+.material-icons {
+  margin-right: 18px;
+}
+
+.select-list {
+  width: calc(100% - 24px);
+}
+
+.lang-selection {
+  vertical-align: middle;
+  margin-right: 0;
+}
+
+::ng-deep .mat-select-value {
+  width: auto !important;
+}
+
+::ng-deep .mat-select-arrow-wrapper .mat-select-arrow {
+  color: var(--on-surface);
+  margin-right: 50px;
+}
+
+::ng-deep .mat-select-panel {
+  background: var(--dialog);
+}
+
+.mat-option {
+  color: var(--on-surface);
+}
+
+.spell-button{
+  background-color: var(--primary);
+  color: var(--on-primary);
+  display: inline-block
+}
+
+#buttonWrapper {
+  justify-content: space-between;
+}
+
+#answer-input {
+  line-height: 120%;
+  color: var(--on-surface);
+  caret-color: var(--on-surface);
+  -webkit-appearance: textarea;
+  min-height: 50px;
+  cursor: text;
+  word-wrap: break-word;
+
+  &:focus {
+    outline: none;
+  }
+}
diff --git a/src/app/components/shared/comment-answer/comment-answer.component.ts b/src/app/components/shared/comment-answer/comment-answer.component.ts
index c4641fc14f04fdac912d98ff94a15a935f9161e2..aa1fcfbbed294460005e9c9e9729ee28a151d37d 100644
--- a/src/app/components/shared/comment-answer/comment-answer.component.ts
+++ b/src/app/components/shared/comment-answer/comment-answer.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { TranslateService } from '@ngx-translate/core';
 import { LanguageService } from '../../../services/util/language.service';
@@ -11,7 +11,9 @@ import { UserRole } from '../../../models/user-roles.enum';
 import { NotificationService } from '../../../services/util/notification.service';
 import { MatDialog } from '@angular/material/dialog';
 import { DeleteAnswerComponent } from '../../creator/_dialogs/delete-answer/delete-answer.component';
-import { RoomDataService } from '../../../services/util/room-data.service';
+import { LanguagetoolService } from '../../../services/http/languagetool.service';
+import { GrammarChecker } from '../../../utils/grammar-checker';
+import { EventService } from '../../../services/util/event.service';
 
 @Component({
   selector: 'app-comment-answer',
@@ -27,6 +29,10 @@ export class CommentAnswerComponent implements OnInit {
   isStudent = true;
   edit = false;
 
+  grammarChecker: GrammarChecker;
+
+  @ViewChild('commentBody') commentBody: ElementRef<HTMLDivElement>;
+
   constructor(protected route: ActivatedRoute,
               private notificationService: NotificationService,
               private translateService: TranslateService,
@@ -34,8 +40,11 @@ export class CommentAnswerComponent implements OnInit {
               protected wsCommentService: WsCommentService,
               protected commentService: CommentService,
               private authenticationService: AuthenticationService,
-              private roomDataService: RoomDataService,
-              public dialog: MatDialog) { }
+              public languagetoolService: LanguagetoolService,
+              public dialog: MatDialog,
+              eventService: EventService) {
+    this.grammarChecker = new GrammarChecker(languagetoolService);
+  }
 
   ngOnInit() {
     this.user = this.authenticationService.getUser();
@@ -46,13 +55,14 @@ export class CommentAnswerComponent implements OnInit {
       this.commentService.getComment(params['commentId']).subscribe(comment => {
         this.comment = comment;
         this.answer = this.comment.answer;
+        this.edit = !this.answer;
         this.isLoading = false;
       });
     });
   }
 
   saveAnswer() {
-    this.edit = false;
+    this.edit = !this.answer;
     this.commentService.answer(this.comment, this.answer).subscribe();
     this.translateService.get('comment-page.comment-answered').subscribe(msg => {
       this.notificationService.show(msg);
@@ -72,10 +82,20 @@ export class CommentAnswerComponent implements OnInit {
   }
 
   deleteAnswer() {
+    if (this.commentBody) {
+      this.commentBody.nativeElement.innerText = '';
+    }
     this.answer = null;
     this.commentService.answer(this.comment, this.answer).subscribe();
     this.translateService.get('comment-page.answer-deleted').subscribe(msg => {
       this.notificationService.show(msg);
     });
   }
+
+  onEditClick() {
+    this.edit = true;
+    setTimeout(() => {
+      this.commentBody.nativeElement.innerText = this.answer;
+    });
+  }
 }
diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts
index 9cd33abc6679160ee477ec020816bac3c1049885..557d35a5d9f501ef0aa5090271e11d9faf0c4fd0 100644
--- a/src/app/components/shared/shared.module.ts
+++ b/src/app/components/shared/shared.module.ts
@@ -40,7 +40,7 @@ import { TagCloudPopUpComponent } from './tag-cloud/tag-cloud-pop-up/tag-cloud-p
 import { WorkerDialogComponent } from './_dialogs/worker-dialog/worker-dialog.component';
 import { DragDropModule } from '@angular/cdk/drag-drop';
 import { ActiveUserComponent } from './overlay/active-user/active-user.component';
-import { AutofocusDirective } from '../../directive/autofocus.directive';
+import { AutofocusDirective } from '../../directives/autofocus.directive';
 
 @NgModule({
   imports: [
diff --git a/src/app/directive/autofocus.directive.spec.ts b/src/app/directives/autofocus.directive.spec.ts
similarity index 100%
rename from src/app/directive/autofocus.directive.spec.ts
rename to src/app/directives/autofocus.directive.spec.ts
diff --git a/src/app/directive/autofocus.directive.ts b/src/app/directives/autofocus.directive.ts
similarity index 100%
rename from src/app/directive/autofocus.directive.ts
rename to src/app/directives/autofocus.directive.ts
diff --git a/src/app/utils/grammar-checker.ts b/src/app/utils/grammar-checker.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2524e73a92c2ce9e627cef2574f747b58b3aeb2f
--- /dev/null
+++ b/src/app/utils/grammar-checker.ts
@@ -0,0 +1,163 @@
+import { Language, LanguagetoolService } from '../services/http/languagetool.service';
+import { CreateCommentKeywords } from './create-comment-keywords';
+
+export class GrammarChecker {
+
+  languages: Language[] = ['de-DE', 'en-US', 'fr', 'auto'];
+  selectedLang: Language = 'auto';
+  isSpellchecking = false;
+  hasSpellcheckConfidence = true;
+  newLang = 'auto';
+
+  constructor(private languagetoolService: LanguagetoolService) {
+  }
+
+  onDocumentClick(e) {
+    const container = document.getElementsByClassName('dropdownBlock');
+    Array.prototype.forEach.call(container, (elem) => {
+      if (!elem.contains(e.target) && (!(e.target as Node).parentElement.classList.contains('markUp')
+        || (e.target as HTMLElement).dataset.id !== ((elem as Node).parentElement as HTMLElement).dataset.id)) {
+        (elem as HTMLElement).style.display = 'none';
+      }
+    });
+  }
+
+  maxLength(commentBody: HTMLDivElement, size: number): void {
+    if (commentBody.innerText.length > size) {
+      commentBody.innerText = commentBody.innerText.slice(0, size);
+    }
+    const body = commentBody.innerText;
+    if (body.length === 1 && body.charCodeAt(body.length - 1) === 10) {
+      commentBody.innerHTML = commentBody.innerHTML.replace('<br>', '');
+    }
+  }
+
+  onPaste(e) {
+    e.preventDefault();
+    const elem = document.getElementById('answer-input');
+    const text = e.clipboardData.getData('text');
+    elem.innerText += text.replace(/<[^>]*>?/gm, '');
+
+    const range = document.createRange();
+    range.setStart(elem.lastChild, elem.lastChild.textContent.length);
+    range.collapse(true);
+
+    const sel = window.getSelection();
+    sel.removeAllRanges();
+    sel.addRange(range);
+  }
+
+  grammarCheck(commentBody: HTMLDivElement): void {
+    const wrongWords: string[] = [];
+    this.isSpellchecking = true;
+    this.hasSpellcheckConfidence = true;
+    const text = CreateCommentKeywords.cleaningFunction(commentBody.innerText);
+    this.checkSpellings(text).subscribe((wordsCheck) => {
+      if (!this.checkLanguageConfidence(wordsCheck)) {
+        this.hasSpellcheckConfidence = false;
+        return;
+      }
+      if (this.selectedLang === 'auto' && (document.getElementById('langSelect').innerText.includes(this.newLang)
+        || document.getElementById('langSelect').innerText.includes('auto'))) {
+        if (wordsCheck.language.name.includes('German')) {
+          this.selectedLang = 'de-DE';
+        } else if (wordsCheck.language.name.includes('English')) {
+          this.selectedLang = 'en-US';
+        } else if (wordsCheck.language.name.includes('French')) {
+          this.selectedLang = 'fr';
+        } else {
+          this.newLang = wordsCheck.language.name;
+        }
+        document.getElementById('langSelect').innerHTML = this.newLang;
+      }
+      if (wordsCheck.matches.length > 0) {
+        wordsCheck.matches.forEach(grammarError => {
+          const wrongWord = commentBody.innerText.slice(grammarError.offset, grammarError.offset + grammarError.length);
+          wrongWords.push(wrongWord);
+        });
+
+        let html = '';
+        let lastFound = text.length;
+        this.checkSpellings(text).subscribe((res) => {
+          for (let i = res.matches.length - 1; i >= 0; i--) {
+            const end = res.matches[i].offset + res.matches[i].length;
+            const start = res.matches[i].offset;
+            const wrongWord = text.slice(start, end);
+
+            if (wrongWords.includes(wrongWord)) {
+              const suggestions: any[] = res.matches[i].replacements;
+              let displayOptions = 3;
+              let suggestionsHTML = '';
+
+              if (!suggestions.length) {
+                suggestionsHTML = '<span style="color: black; display: block; text-align: center;">' + res.matches[i].message + '</span>';
+              }
+
+              if (suggestions.length < displayOptions) {
+                displayOptions = suggestions.length;
+              }
+
+              for (let j = 0; j < displayOptions; j++) {
+                // eslint-disable-next-line max-len
+                suggestionsHTML += '<span class="suggestions"' + ' style="color: black; display: block; text-align: center; cursor: pointer;">' + suggestions[j].value + '</span>';
+              }
+
+              const replacement =
+                '<div class="markUp" data-id="' + i + '" style="position: relative; display: inline-block; border-bottom: 1px dotted black">' +
+                '<span data-id="' + i + '" style="text-decoration: underline wavy red; cursor: pointer;">' +
+                wrongWord +
+                '</span>' +
+                // eslint-disable-next-line max-len
+                '<div class="dropdownBlock" style="display: none; width: 160px; background-color: white; border-style: solid; border-color: var(--primary); color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1000; bottom: 100%;">' +
+                suggestionsHTML +
+                '</div>' +
+                '</div>';
+
+              html = replacement + text.slice(end, lastFound) + html;
+              lastFound = res.matches[i].offset;
+            }
+          }
+          commentBody.innerHTML = text.slice(0, lastFound) + html;
+
+          setTimeout(() => {
+            Array.from(document.getElementsByClassName('markUp')).forEach(markup => {
+              markup.addEventListener('click', () => {
+                ((markup as HTMLElement).lastChild as HTMLElement).style.display = 'block';
+                const rectdiv = (document.getElementById('answer-input')).getBoundingClientRect();
+                const rectmarkup = markup.getBoundingClientRect();
+                let offset;
+                if (rectmarkup.x + rectmarkup.width / 2 > rectdiv.right - 80) {
+                  offset = rectdiv.right - rectmarkup.x - rectmarkup.width;
+                  ((markup as HTMLElement).lastChild as HTMLElement).style.right = -offset + 'px';
+                } else if (rectmarkup.x + rectmarkup.width / 2 < rectdiv.left + 80) {
+                  offset = rectmarkup.x - rectdiv.left;
+                  ((markup as HTMLElement).lastChild as HTMLElement).style.left = -offset + 'px';
+                } else {
+                  ((markup as HTMLElement).lastChild as HTMLElement).style.left = '50%';
+                  ((markup as HTMLElement).lastChild as HTMLElement).style.marginLeft = '-80px';
+                }
+                setTimeout(() => {
+                  Array.from(document.getElementsByClassName('suggestions')).forEach(suggestion => {
+                    suggestion.addEventListener('click', () => {
+                      suggestion.parentElement.parentElement.outerHTML = suggestion.innerHTML;
+                    });
+                  });
+                }, 500);
+              });
+            });
+          }, 500);
+        });
+      }
+    }, () => '', () => {
+      this.isSpellchecking = false;
+    });
+  }
+
+  checkLanguageConfidence(wordsCheck: any) {
+    return this.selectedLang === 'auto' ? wordsCheck.language.detectedLanguage.confidence >= 0.5 : true;
+  }
+
+  checkSpellings(text: string, language: Language = this.selectedLang) {
+    return this.languagetoolService.checkSpellings(text, language);
+  }
+}