diff --git a/proxy.conf.json b/proxy.conf.json
index ea2af167e93cb8a36258701a4ad8d33a48dd4e9b..603e23b9ea844bcf7f57f2590ea71217ea63268e 100644
--- a/proxy.conf.json
+++ b/proxy.conf.json
@@ -9,7 +9,7 @@
     "logLevel": "debug"
   },
   "/spacy": {
-    "target": "https://spacy.frag.jetzt/dep",
+    "target": "https://spacy.frag.jetzt/noun",
     "secure": true,
     "changeOrigin": true,
     "pathRewrite": {
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 f91956bc6fa891459e7ccca3a836cfd4245a4714..992447b3c8cde1042d8017f3eb3ae6804bcd5aef 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
@@ -17,6 +17,8 @@ import { LanguagetoolService, Language } from '../../../../services/http/languag
 })
 export class CreateCommentComponent implements OnInit, OnDestroy {
 
+  @ViewChild('commentBody', {static: true}) commentBody: HTMLDivElement;
+
   comment: Comment;
 
   user: User;
@@ -34,8 +36,6 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
   isSpellchecking = false;
   hasSpellcheckConfidence = true;
 
-  @ViewChild('commentBody', { static: true }) commentBody: HTMLDivElement;
-
   constructor(
     private notification: NotificationService,
     public dialogRef: MatDialogRef<CommentListComponent>,
@@ -46,6 +46,7 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     public eventService: EventService,
     @Inject(MAT_DIALOG_DATA) public data: any) {
   }
+
   ngOnInit() {
     this.translateService.use(localStorage.getItem('currentLang'));
     setTimeout(() => {
@@ -71,7 +72,8 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
   onNoClick(): void {
     this.dialogRef.close();
   }
-  clearHTML(e){
+
+  clearHTML(e) {
     e.preventDefault();
     const text = e.clipboardData.getData('text');
     document.getElementById('answer-input').innerText += text.replace(/<[^>]*>?/gm, '');
@@ -100,33 +102,27 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     }
   }
 
-  checkUTFEmoji(body: string): string{
-    var regex = /(?:\:.*?\:|[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
-  
-    return  body.replace(regex, '');
+  checkUTFEmoji(body: string): string {
+    const regex = /(?:\:.*?\:|[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
+
+    return body.replace(regex, '');
   }
 
   openSpacyDialog(comment: Comment): void {
-    let filteredInputText = this.checkUTFEmoji(this.inputText);
+    const filteredInputText = this.checkUTFEmoji(this.inputText);
     this.checkSpellings(filteredInputText).subscribe((res) => {
       const words: string[] = filteredInputText.trim().split(' ');
       const errorQuotient = (res.matches.length * 100) / words.length;
       const hasSpellcheckConfidence = this.checkLanguageConfidence(res);
 
       if (hasSpellcheckConfidence && errorQuotient <= 20) {
-        let commentBodyChecked = filteredInputText;
         const commentLang = this.languagetoolService.mapLanguageToSpacyModel(res.language.code);
 
-        for (let i = res.matches.length - 1; i >= 0; i--) {
-          commentBodyChecked = commentBodyChecked.substr(0, res.matches[i].offset) +
-            commentBodyChecked.substr(res.matches[i].offset + res.matches[i].length, commentBodyChecked.length);
-        }
-
         const dialogRef = this.dialog.open(SpacyDialogComponent, {
           data: {
             comment,
             commentLang,
-            commentBodyChecked
+            commentBodyChecked: filteredInputText
           }
         });
 
@@ -142,8 +138,6 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     });
   };
 
-
-
   /**
    * Returns a lambda which closes the dialog on call.
    */
@@ -151,7 +145,6 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     return () => this.onNoClick();
   }
 
-
   /**
    * Returns a lambda which executes the dialog dedicated action on call.
    */
@@ -170,8 +163,8 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
       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>','');
+    if (this.body.length === 1 && this.body.charCodeAt(this.body.length - 1) === 10) {
+      commentBody.innerHTML = commentBody.innerHTML.replace('<br>', '');
     }
     this.inputText = commentBody.innerText;
   }
@@ -182,7 +175,7 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
     this.isSpellchecking = true;
     this.hasSpellcheckConfidence = true;
     this.checkSpellings(commentBody.innerText).subscribe((wordsCheck) => {
-      if(!this.checkLanguageConfidence(wordsCheck)) {
+      if (!this.checkLanguageConfidence(wordsCheck)) {
         this.hasSpellcheckConfidence = false;
         return;
       }
diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts
index 4a69313c912f7eafc40aff1070177819db8c91c6..06ee485a9838ce22483b93f1a3bf55b3ea2111ed 100644
--- a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts
+++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts
@@ -61,31 +61,20 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit {
 
   evalInput(model: Model) {
     const keywords: Keyword[] = [];
-    let regex;
-    if(this.commentLang === 'de') {
-      regex = new RegExp('(?!Der|Die|Das)[A-ZAÄÖÜ][a-zäöüß]+(-[A-Z][a-zäöüß]+)*', 'g');
-    } else if (this.commentLang === 'en') {
-      regex = new RegExp('(?!he|she|it|for|with)[a-z]{2,}(-[a-z]{2,})*', 'gi');
-    } else {
-      regex = new RegExp('(?!au|de|la|le|en|un)[A-ZÀ-Ÿ]{2,}', 'gi');
-    }
 
     this.isLoading = true;
 
     // N at first pos = all Nouns(NN de/en) including singular(NN, NNP en), plural (NNPS, NNS en), proper Noun(NNE, NE de)
     this.spacyService.getKeywords(this.commentBodyChecked, model)
       .subscribe(words => {
-        for(const word of words) {
-          const filteredwords = word.match(regex) || [];
-          for (const filteredword of filteredwords) {
-            if(filteredword !== null && filteredword !== undefined && keywords.filter(item => item.word === filteredword).length < 1) {
-              keywords.push({
-                word: filteredword,
-                completed: false,
-                editing: false,
-                selected: false
-              });
-            }
+        for (const word of words) {
+          if (keywords.findIndex(item => item.word === word) < 0) {
+            keywords.push({
+              word,
+              completed: false,
+              editing: false,
+              selected: false
+            });
           }
         }
         this.keywords = keywords;
diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..97722af6e6b0e42f4616978b0feac119eb4547d6
--- /dev/null
+++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html
@@ -0,0 +1,14 @@
+<div id="worker-content">
+  <div id="header">
+    <button id="btn_hide" (click)="close()">X</button>
+    <details>
+      <summary>Laufend # {{getNumberInQueue()}}</summary>
+      <div mat-dialog-content>
+        <div *ngFor="let task of taskQueue">
+          <span>{{ task.room.name }}, # {{ task.comments.length }}</span>
+        </div>
+      </div>
+    </details>
+  </div>
+</div>
+
diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.scss b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d91e724918261fa302dbf16598697da6a74d641b
--- /dev/null
+++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.scss
@@ -0,0 +1,16 @@
+button {
+  position: absolute !important;
+  right: 5px;
+  top: 5px;
+}
+
+::ng-deep .workerContainer > .mat-dialog-container {
+  padding: 5px !important;
+  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);
+  overflow: hidden !important;
+  position: relative !important;
+}
+
+#worker-content {
+  padding-left: 5px;
+}
diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.spec.ts b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..650d036a9c0941d90bc163f29cb475c4c543bd63
--- /dev/null
+++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+/*import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { WorkerDialogComponent } from './worker-dialog.component';
+
+describe('WorkerDialogComponent', () => {
+  let component: WorkerDialogComponent;
+  let fixture: ComponentFixture<WorkerDialogComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ WorkerDialogComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(WorkerDialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});*/
diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.ts b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..da93bb80e8865f5a714a0ae7a3ce4f5eef4a9b50
--- /dev/null
+++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.ts
@@ -0,0 +1,95 @@
+import { Component, OnInit } from '@angular/core';
+import { Room } from '../../../../models/room';
+import { CommentService } from '../../../../services/http/comment.service';
+import { Comment } from '../../../../models/comment';
+import { SpacyService } from '../../../../services/http/spacy.service';
+import { TSMap } from 'typescript-map';
+
+export interface WorkTask {
+  room: Room;
+  comments: Comment[];
+}
+
+@Component({
+  selector: 'app-worker-dialog',
+  templateUrl: './worker-dialog.component.html',
+  styleUrls: ['./worker-dialog.component.scss']
+})
+export class WorkerDialogComponent implements OnInit {
+
+  isRunning = false;
+  taskQueue: WorkTask[] = [];
+  closeCallback: any = null;
+
+  constructor(private commentService: CommentService,
+              private spacyService: SpacyService) {
+  }
+
+  ngOnInit(): void {
+  }
+
+  _callNextInQueue(): void {
+    if (!this.isQueueEmpty()) {
+      this.isRunning = true;
+      const task = this.taskQueue[0];
+      this.runWorkTask(task);
+    } else {
+      this.isRunning = false;
+      setTimeout(() => this.close(), 2000);
+    }
+  }
+
+  addWorkTask(room: Room): void {
+    if (this.taskQueue.find((t: WorkTask) => t.room.id === room.id)) {
+      return;
+    }
+
+    this.commentService.getAckComments(room.id).subscribe((comments: Comment[]) => {
+      const task: WorkTask = {room, comments};
+      this.taskQueue.push(task);
+
+      if (!this.isRunning) {
+        this._callNextInQueue();
+      }
+    });
+  }
+
+  runWorkTask(task: WorkTask): void {
+    task.comments.forEach((c: Comment) => {
+      const model = 'de';
+      const text = c.body;
+      this.spacyService.getKeywords(text, model).subscribe((keywords: string[]) => {
+        const changes = new TSMap<string, string>();
+        changes.set('keywordsFromSpacy', JSON.stringify(keywords));
+        this.taskQueue = this.taskQueue.slice(1, this.taskQueue.length);
+
+        this.commentService.patchComment(c, changes).subscribe(_ => {
+          console.log('PATCHED .........................');
+          this._callNextInQueue();
+        }, _ => {
+          this._callNextInQueue();
+        });
+      });
+    });
+  }
+
+  getNumberInQueue() {
+    return this.taskQueue.length;
+  }
+
+  isQueueEmpty(): boolean {
+    return this.taskQueue.length === 0;
+  }
+
+  close(): void {
+    if (this.closeCallback) {
+      this.closeCallback();
+    }
+  }
+
+  getCloseCallback(callback: () => void): void {
+    this.closeCallback = callback;
+  }
+
+}
+
diff --git a/src/app/components/shared/header/header.component.html b/src/app/components/shared/header/header.component.html
index af0ed5650534a3f3053fac3340340ccd496edd9e..c72627dae7d5d85aa9cb766bcb3d2dc65d28a9ac 100644
--- a/src/app/components/shared/header/header.component.html
+++ b/src/app/components/shared/header/header.component.html
@@ -163,6 +163,16 @@
                 <span>{{'header.tag-cloud' | translate}}</span>
               </button>
 
+
+              <button mat-menu-item
+                      tabindex="0"
+                      (click)="startWorkerDialog()">
+                <mat-icon>update
+                </mat-icon>
+                <span>{{'header.update-spacy-keywords' | translate}}</span>
+              </button>
+
+
             </ng-container>
             <ng-container *ngIf="router.url.includes('/participant/room/')">
             </ng-container>
diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts
index c547702ec43704f0f588b3ad1708faa0434284a2..9cbf857e9730fbfd44952ced637db8bd0ee8a1f1 100644
--- a/src/app/components/shared/header/header.component.ts
+++ b/src/app/components/shared/header/header.component.ts
@@ -6,7 +6,7 @@ import { User } from '../../../models/user';
 import { UserRole } from '../../../models/user-roles.enum';
 import { Location } from '@angular/common';
 import { TranslateService } from '@ngx-translate/core';
-import { MatDialog, MatDialogRef } from '@angular/material/dialog';
+import {_MatDialogBase, MAT_DIALOG_DEFAULT_OPTIONS, MatDialog, MatDialogRef} from '@angular/material/dialog';
 import { LoginComponent } from '../login/login.component';
 import { DeleteAccountComponent } from '../_dialogs/delete-account/delete-account.component';
 import { UserService } from '../../../services/http/user.service';
@@ -24,6 +24,7 @@ import { TopicCloudFilterComponent } from '../_dialogs/topic-cloud-filter/topic-
 import { RoomService } from '../../../services/http/room.service';
 import { Room } from '../../../models/room';
 import { TagCloudMetaData } from '../../../services/util/tag-cloud-data.service';
+import {WorkerDialogComponent} from "../_dialogs/worker-dialog/worker-dialog.component";
 
 @Component({
   selector: 'app-header',
@@ -42,6 +43,7 @@ export class HeaderComponent implements OnInit {
   commentsCountQuestions = 0;
   commentsCountUsers = 0;
   commentsCountKeywords = 0;
+  workerDialogRef: MatDialogRef<WorkerDialogComponent, null> = null;
 
   constructor(public location: Location,
               private authenticationService: AuthenticationService,
@@ -322,4 +324,34 @@ export class HeaderComponent implements OnInit {
     this.roomService.updateRoom(this.room).subscribe(r => this.room = r);
   }
 
+  public startWorkerDialog() {
+
+    if (this.workerDialogRef == null) {
+
+      this.workerDialogRef = this.dialog.open(WorkerDialogComponent, {
+        width: '200px',
+        disableClose: true,
+        autoFocus: false,
+        position: {left: '50px', bottom: '50px'},
+        role: 'dialog',
+        hasBackdrop: false,
+        closeOnNavigation: false,
+        panelClass: 'workerContainer'
+      });
+
+      const component: WorkerDialogComponent = this.workerDialogRef.componentInstance;
+      component.getCloseCallback(() => {
+        this.workerDialogRef.close();
+        this.workerDialogRef = null;
+      });
+      component.addWorkTask(this.room);
+    } else {
+      const component: WorkerDialogComponent = this.workerDialogRef.componentInstance;
+      component.addWorkTask(this.room);
+    }
+
+    }
+
+
+
 }
diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts
index 9e1fa76e707e4fe232456bbe490910b5f1b96b51..f022dfac582d8515332e41d4450ead18c6e6db9a 100644
--- a/src/app/components/shared/shared.module.ts
+++ b/src/app/components/shared/shared.module.ts
@@ -37,19 +37,22 @@ import { TopicDialogCommentComponent } from './dialog/topic-dialog-comment/topic
 import { TopicCloudFilterComponent } from './_dialogs/topic-cloud-filter/topic-cloud-filter.component';
 import { SpacyDialogComponent } from './_dialogs/spacy-dialog/spacy-dialog.component';
 import { TagCloudPopUpComponent } from './tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component';
+import { WorkerDialogComponent } from './_dialogs/worker-dialog/worker-dialog.component';
+import {DragDropModule} from "@angular/cdk/drag-drop";
 
 @NgModule({
-  imports: [
-    CommonModule,
-    EssentialsModule,
-    SharedRoutingModule,
-    MatRippleModule,
-    ArsModule,
-    MarkdownModule,
-    QRCodeModule,
-    TagCloudModule,
-    ColorPickerModule
-  ],
+    imports: [
+        CommonModule,
+        EssentialsModule,
+        SharedRoutingModule,
+        MatRippleModule,
+        ArsModule,
+        MarkdownModule,
+        QRCodeModule,
+        TagCloudModule,
+        ColorPickerModule,
+        DragDropModule
+    ],
   declarations: [
     RoomJoinComponent,
     PageNotFoundComponent,
@@ -79,7 +82,8 @@ import { TagCloudPopUpComponent } from './tag-cloud/tag-cloud-pop-up/tag-cloud-p
     TopicDialogCommentComponent,
     TopicCloudFilterComponent,
     SpacyDialogComponent,
-    TagCloudPopUpComponent
+    TagCloudPopUpComponent,
+    WorkerDialogComponent
   ],
     exports: [
         RoomJoinComponent,
diff --git a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.html b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.html
index 65e367adb959663a8e22fe6966624e26368b9c44..2fb3006994edebc06e0231cb87e40867b338c128 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.html
+++ b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.html
@@ -1,39 +1,70 @@
 <div #popupContainer
      class="popupContainer"
-     (focusout)="onFocus($event)"
-      tabindex="0">
-  <span>
-    <mat-icon matTooltip="{{'tag-cloud.overview-question-topic-tooltip' | translate}}">comment</mat-icon>
-    <p>
-      {{tagData && tagData.comments.length}}
-    </p>
-    <mat-icon matTooltip="{{'tag-cloud.overview-questioners-topic-tooltip' | translate}}">person</mat-icon>
-    <p>
-      {{tagData && tagData.distinctUsers.size}}
-    </p>
-    <mat-icon matTooltip="{{'tag-cloud.upvote-topic' | translate}}">thumb_up</mat-icon>
-    <p>
-      {{tagData && tagData.cachedUpVotes}}
-    </p>
-    <mat-icon matTooltip="{{'tag-cloud.downvote-topic' | translate}}">thumb_down</mat-icon>
-    <p>
-      {{tagData && tagData.cachedDownVotes}}
-    </p>
-    <button *ngIf="user && user.role >= 1" mat-button (click)="addBlacklistWord()">
-      <mat-icon matTooltip="{{'tag-cloud.blacklist-topic' | translate}}">gavel</mat-icon>
-    </button>
-  </span>
-  <br>
-  <span>
-    <mat-icon matTooltip="{{'tag-cloud.period-since-first-comment' | translate}}">date_range</mat-icon>
-    <p>
-      {{timePeriodText}}
-    </p>
-  </span>
-  <div *ngIf="categories && categories.length">
-    <p>Kategorien:</p>
-    <ul>
-      <li *ngFor="let category of categories">{{category}}</li>
-    </ul>
+     (focusout)="onFocusOut()"
+     tabindex="0">
+  <div>
+    <div>
+      <span>
+        <mat-icon matTooltip="{{'tag-cloud.overview-question-topic-tooltip' | translate}}">comment</mat-icon>
+        <p>
+          {{tagData && tagData.comments.length}}
+        </p>
+      </span>
+      <span>
+        <mat-icon matTooltip="{{'tag-cloud.overview-questioners-topic-tooltip' | translate}}">person</mat-icon>
+        <p>
+          {{tagData && tagData.distinctUsers.size}}
+        </p>
+      </span>
+      <button *ngIf="user && user.role >= 1" mat-button (click)="addBlacklistWord()">
+        <mat-icon matTooltip="{{'tag-cloud.blacklist-topic' | translate}}">gavel</mat-icon>
+      </button>
+    </div>
+    <div>
+      <span>
+        <mat-icon matTooltip="{{'tag-cloud.upvote-topic' | translate}}">thumb_up</mat-icon>
+        <p>
+          {{tagData && tagData.cachedUpVotes}}
+        </p>
+      </span>
+      <span>
+        <mat-icon matTooltip="{{'tag-cloud.downvote-topic' | translate}}">thumb_down</mat-icon>
+        <p>
+          {{tagData && tagData.cachedDownVotes}}
+        </p>
+      </span>
+    </div>
+    <div>
+      <span>
+        <mat-icon matTooltip="{{'tag-cloud.period-since-first-comment' | translate}}">date_range</mat-icon>
+        <p>
+          {{timePeriodText}}
+        </p>
+      </span>
+    </div>
+    <div class="replacementContainer" *ngIf="checkLanguage">
+      <mat-form-field>
+        <mat-label>{{'tag-cloud-popup.tag-correction-placeholder' | translate}}</mat-label>
+        <input type="text"
+               aria-label="{{'tag-cloud-popup.tag-correction-placeholder' | translate}}"
+               matInput
+               (keyup)="checkEnter($event)"
+               [formControl]="replacementInput"
+               [matAutocomplete]="auto">
+        <mat-autocomplete #auto="matAutocomplete">
+          <mat-option *ngFor="let data of spellingData" [value]="data">
+            {{data}}
+          </mat-option>
+        </mat-autocomplete>
+      </mat-form-field>
+      <br>
+      <button mat-button class="replace-button" (click)="updateTag()">{{"comment-page.send" | translate}}</button>
+    </div>
+    <div *ngIf="categories && categories.length">
+      <p>Kategorien:</p>
+      <ul>
+        <li *ngFor="let category of categories">{{category}}</li>
+      </ul>
+    </div>
   </div>
 </div>
diff --git a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.scss b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.scss
index 057e27b57a667a064649da4332cadcb7b5a40733..9ac82a2670707fee059ec00fc7e4ff7941f11b39 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.scss
+++ b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.scss
@@ -16,6 +16,18 @@ $header-size: 67px;
   z-index: 3;
   color: var(--on-dialog);
   transform: translateY(-$header-size);
+  min-width: 200px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+
+  & > div {
+    display: flex;
+    justify-content: center;
+    overflow: auto;
+    flex-direction: column;
+    align-items: flex-start;
+  }
 
   &:focus {
     outline: none;
@@ -116,3 +128,48 @@ button {
   padding-left: 10px;
   padding-right: 10px;
 }
+
+.replace-button {
+  background-color: var(--primary);
+  color: var(--on-primary);
+  min-width: 30px !important;
+  min-height: 10px !important;
+  width: 100%;
+  z-index: 3;
+}
+
+::ng-deep .replacementContainer {
+  align-self: center;
+
+  .mat-form-field-infix {
+    min-width: 150px;
+    width: min-content;
+  }
+
+  .mat-form-field-wrapper {
+    margin-bottom: -0.8em;
+  }
+}
+
+mat-form-field {
+  border-radius: 5px;
+  line-height: 80%;
+  caret-color: var(--on-surface);
+  -webkit-appearance: textarea;
+  min-height: 30px;
+  min-width: 140px;
+  cursor: text;
+  color: var(--on-dialog);
+  background-color: var(--dialog);
+  margin-top: 0.2em;
+
+  &:focus {
+    outline: none;
+  }
+}
+
+#replacement {
+  color: var(--on-dialog);
+  background-color: var(--dialog);
+  border-radius: 5px;
+}
diff --git a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
index 2b3210c4330c47da7851821ffbf8b9e268d176f0..c4fed49e87dcc9ad06cfcf33b36a6378bcfd9316 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
+++ b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
@@ -1,10 +1,15 @@
-import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
+import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
 import { TranslateService } from '@ngx-translate/core';
 import { LanguageService } from '../../../../services/util/language.service';
-import { TagCloudComponent } from '../tag-cloud.component';
 import { AuthenticationService } from '../../../../services/http/authentication.service';
 import { User } from '../../../../models/user';
-import { TagCloudDataTagEntry } from '../../../../services/util/tag-cloud-data.service';
+import { TagCloudDataService, TagCloudDataTagEntry } from '../../../../services/util/tag-cloud-data.service';
+import { Language, LanguagetoolService } from '../../../../services/http/languagetool.service';
+import { FormControl } from '@angular/forms';
+import { TSMap } from 'typescript-map';
+import { CommentService } from '../../../../services/http/comment.service';
+import { NotificationService } from '../../../../services/util/notification.service';
+import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
 
 const CLOSE_TIME = 1500;
 
@@ -15,19 +20,28 @@ const CLOSE_TIME = 1500;
 })
 export class TagCloudPopUpComponent implements OnInit, AfterViewInit {
 
-  @Input() parent: TagCloudComponent;
   @ViewChild('popupContainer') popupContainer: ElementRef;
+  @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
+  replacementInput = new FormControl();
   tag: string;
   tagData: TagCloudDataTagEntry;
   categories: string[];
   timePeriodText: string;
   user: User;
+  selectedLang: Language = 'en-US';
+  spellingData: string[] = [];
+  checkLanguage = false;
   private _popupHoverTimer: number;
   private _popupCloseTimer: number;
+  private _hasLeft = true;
 
   constructor(private langService: LanguageService,
               private translateService: TranslateService,
-              private authenticationService: AuthenticationService) {
+              private authenticationService: AuthenticationService,
+              private tagCloudDataService: TagCloudDataService,
+              private languagetoolService: LanguagetoolService,
+              private commentService: CommentService,
+              private notificationService: NotificationService) {
     this.langService.langEmitter.subscribe(lang => {
       this.translateService.use(lang);
     });
@@ -46,30 +60,40 @@ export class TagCloudPopUpComponent implements OnInit, AfterViewInit {
     const html = this.popupContainer.nativeElement as HTMLDivElement;
     html.addEventListener('mouseenter', () => {
       clearTimeout(this._popupCloseTimer);
+      this._hasLeft = false;
     });
     html.addEventListener('mouseleave', () => {
-      this._popupCloseTimer = setTimeout(() => {
-        this.close();
-      }, CLOSE_TIME);
+      this._hasLeft = true;
+      this.close();
     });
   }
 
-  onFocus(event) {
-    if (!this.popupContainer.nativeElement.contains(event.target)) {
-      this.close();
-    }
+  onFocusOut() {
+    this.close();
   }
 
   leave(): void {
     clearTimeout(this._popupHoverTimer);
-    this._popupCloseTimer = setTimeout(() => {
-      this.close();
-    }, CLOSE_TIME);
+    this.close();
   }
 
-  enter(elem: HTMLElement, tag: string, tagData: TagCloudDataTagEntry, hoverDelayInMs: number): void {
+  enter(elem: HTMLElement, tag: string, tagData: TagCloudDataTagEntry, hoverDelayInMs: number, checkLanguage: boolean): void {
+    this.checkLanguage = checkLanguage;
+    if (checkLanguage) {
+      this.spellingData = [];
+      this.languagetoolService.checkSpellings(tag, this.selectedLang).subscribe(correction => {
+        for (const match of correction.matches) {
+          if (match.replacements != null && match.replacements.length > 0) {
+            for (const replacement of match.replacements) {
+              this.spellingData.push(replacement.value);
+            }
+          }
+        }
+      });
+    }
     clearTimeout(this._popupCloseTimer);
     clearTimeout(this._popupHoverTimer);
+    this._hasLeft = true;
     this._popupHoverTimer = setTimeout(() => {
       this.tag = tag;
       this.tagData = tagData;
@@ -81,13 +105,63 @@ export class TagCloudPopUpComponent implements OnInit, AfterViewInit {
   }
 
   addBlacklistWord(): void {
-    this.parent.dataManager.blockWord(this.tag);
-    this.close();
+    this.tagCloudDataService.blockWord(this.tag);
+    this.close(false);
   }
 
-  close(): void {
+  close(addDelay = true): void {
     const html = this.popupContainer.nativeElement as HTMLDivElement;
-    html.classList.remove('up', 'down', 'right', 'left');
+    clearTimeout(this._popupCloseTimer);
+    if (addDelay) {
+      if (!this._hasLeft || (html.contains(document.activeElement) && html !== document.activeElement)) {
+        return;
+      }
+      this._popupCloseTimer = setTimeout(() => {
+        if (html.contains(document.activeElement) && html !== document.activeElement) {
+          return;
+        }
+        html.classList.remove('up', 'down', 'right', 'left');
+      }, CLOSE_TIME);
+    } else {
+      html.classList.remove('up', 'down', 'right', 'left');
+    }
+  }
+
+  updateTag(): void {
+    const tagReplacementInput = this.replacementInput.value.trim();
+    if (tagReplacementInput.length < 1 || tagReplacementInput === this.tag) {
+      return;
+    }
+    const renameKeyword = (elem: string, index: number, array: string[]) => {
+      if (elem === this.tag) {
+        array[index] = tagReplacementInput;
+      }
+    };
+    this.tagData.comments.forEach(comment => {
+      const changes = new TSMap<string, any>();
+      comment.keywordsFromQuestioner.forEach(renameKeyword);
+      changes.set('keywordsFromQuestioner', JSON.stringify(comment.keywordsFromQuestioner));
+      comment.keywordsFromSpacy.forEach(renameKeyword);
+      changes.set('keywordsFromSpacy', JSON.stringify(comment.keywordsFromSpacy));
+      this.commentService.patchComment(comment, changes).subscribe(_ => {
+        this.translateService.get('topic-cloud-dialog.keyword-edit').subscribe(msg => {
+          this.notificationService.show(msg);
+        });
+      }, _ => {
+        this.translateService.get('topic-cloud-dialog.changes-gone-wrong').subscribe(msg => {
+          this.notificationService.show(msg);
+        });
+      });
+    });
+    this.close(false);
+    this.replacementInput.reset();
+    this.trigger.closePanel();
+  }
+
+  checkEnter(e: KeyboardEvent) {
+    if (e.key === 'Enter') {
+      this.updateTag();
+    }
   }
 
   private position(elem: HTMLElement) {
diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.html b/src/app/components/shared/tag-cloud/tag-cloud.component.html
index 6f6afd01783495837b2d1ac015d6a7644755fc2c..ece66e1f97ae2378b904bfac66a9605ab499c5d7 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud.component.html
+++ b/src/app/components/shared/tag-cloud/tag-cloud.component.html
@@ -1,11 +1,11 @@
 <ars-screen ars-flex-box>
   <mat-drawer-container class="spacyTagCloudContainer">
-    <mat-drawer [(opened)]="configurationOpen" position="end" mode="push">
+    <mat-drawer [(opened)]="configurationOpen" position="end" mode="over">
       <app-cloud-configuration [parent]="this"></app-cloud-configuration>
     </mat-drawer>
     <mat-drawer-content>
       <ars-fill ars-flex-box>
-        <app-tag-cloud-pop-up [parent]="this"></app-tag-cloud-pop-up>
+        <app-tag-cloud-pop-up></app-tag-cloud-pop-up>
         <div [ngClass]="{'hidden': !isLoading}" fxLayout="row" fxLayoutAlign="center center" fxFill>
           <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner>
         </div>
diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.ts b/src/app/components/shared/tag-cloud/tag-cloud.component.ts
index 451e5bb905137f85500b9aa7824f08e4aef690dc..b0d32a0a21568814681165aff06b8dc1dd105f2a 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud.component.ts
+++ b/src/app/components/shared/tag-cloud/tag-cloud.component.ts
@@ -110,6 +110,10 @@ const getDefaultCloudParameters = (): CloudParameters => {
     {maxVisibleElements: -1, color: resDefaultColors[10], rotation: 0},
   ];
   return {
+    fontFamily: 'Helvetica,Arial,sans-serif',
+    fontWeight: 'normal',
+    fontStyle: 'normal',
+    fontSize: '10px',
     backgroundColor: resDefaultColors[11],
     fontColor: resDefaultColors[0],
     fontSizeMin: 100,
@@ -121,7 +125,7 @@ const getDefaultCloudParameters = (): CloudParameters => {
     randomAngles: false,
     checkSpelling: true,
     sortAlphabetically: false,
-    textTransform: CloudTextStyle.lowercase,
+    textTransform: CloudTextStyle.normal,
     cloudWeightSettings: weightSettings
   };
 };
@@ -198,7 +202,7 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
     const temp: CloudParameters = jsonData != null ? JSON.parse(jsonData) : null;
     const elem = getDefaultCloudParameters();
     if (temp != null) {
-      for (const key in Object.keys(elem)) {
+      for (const key of Object.keys(elem)) {
         if (temp[key] !== undefined) {
           elem[key] = temp[key];
         }
@@ -310,7 +314,6 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
     this.setCloudParameters(getDefaultCloudParameters());
   }
 
-
   onResize(event: UIEvent): any {
     this.updateTagCloud();
   }
@@ -375,7 +378,7 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
   }
 
   openTags(tag: CloudData): void {
-    if (this._subscriptionCommentlist !== null) {
+    if (this.dataManager.demoActive || this._subscriptionCommentlist !== null) {
       return;
     }
     this._subscriptionCommentlist = this.eventService.on('commentListCreated').subscribe(() => {
@@ -421,7 +424,8 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
       });
       elem.addEventListener('mouseenter', () => {
         this.popup.enter(elem, dataElement.text, dataElement.tagData,
-          (this._currentSettings.hoverTime + this._currentSettings.hoverDelay) * 1_000);
+          (this._currentSettings.hoverTime + this._currentSettings.hoverDelay) * 1_000,
+          this._currentSettings.checkSpelling);
       });
     });
   }
@@ -437,25 +441,33 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
     for (let i = rules.length - 1; i >= 0; i--) {
       customTagCloudStyles.sheet.deleteRule(i);
     }
+    // global
     let textTransform = '';
     if (this._currentSettings.textTransform === CloudTextStyle.capitalized) {
-      textTransform = 'text-transform: uppercase;';
+      textTransform = 'text-transform: capitalize;';
     } else if (this._currentSettings.textTransform === CloudTextStyle.lowercase) {
       textTransform = 'text-transform: lowercase;';
+    } else if (this._currentSettings.textTransform === CloudTextStyle.uppercase) {
+      textTransform = 'text-transform: uppercase;';
     }
+    customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span, .spacyTagCloud > span > a { ' +
+      textTransform + ' font-family: ' + this._currentSettings.fontFamily + '; ' +
+      'font-size: ' + this._currentSettings.fontSize + '; ' +
+      'font-weight: ' + this._currentSettings.fontWeight + '; ' +
+      'font-style' + this._currentSettings.fontStyle + '; }');
+    // custom spans
     const fontRange = (this._currentSettings.fontSizeMax - this._currentSettings.fontSizeMin) / 10;
     for (let i = 1; i <= 10; i++) {
-      customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span.w' + i +
-        ', .spacyTagCloud > span.w' + i + ' > a { '
-        + 'color: ' + this._currentSettings.cloudWeightSettings[i - 1].color + ';' +
-        textTransform + ' font-size: ' +
-        (this._currentSettings.fontSizeMin + fontRange * i).toFixed(0) + '%; }', rules.length);
+      customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span.w' + i + ', ' +
+        '.spacyTagCloud > span.w' + i + ' > a { ' +
+        'color: ' + this._currentSettings.cloudWeightSettings[i - 1].color + '; ' +
+        'font-size: ' + (this._currentSettings.fontSizeMin + fontRange * i).toFixed(0) + '%; }');
     }
-    customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span:hover, .spacyTagCloud > span:hover > a { color: ' +
-      this._currentSettings.fontColor + '; background-color: ' +
-      this._currentSettings.backgroundColor + '; }', rules.length);
-    customTagCloudStyles.sheet.insertRule('.spacyTagCloudContainer { background-color: ' +
-      this._currentSettings.backgroundColor + '; }', rules.length);
+    customTagCloudStyles.sheet.insertRule('.spacyTagCloud > span:hover, .spacyTagCloud > span:hover > a { ' +
+      'color: ' + this._currentSettings.fontColor + '; ' +
+      'background-color: ' + this._currentSettings.backgroundColor + '; }');
+    customTagCloudStyles.sheet.insertRule('.spacyTagCloudContainer { ' +
+      'background-color: ' + this._currentSettings.backgroundColor + '; }');
   }
 
   /**
@@ -470,8 +482,9 @@ export class TagCloudComponent implements OnInit, AfterViewInit, OnDestroy {
     /*
     hoverScale, hoverTime, hoverDelay, delayWord can be updated without refreshing
      */
-    const cssUpdates = ['backgroundColor', 'fontColor', 'fontSizeMin', 'fontSizeMax', 'textTransform'];
-    const dataUpdates = ['randomAngles', 'sortAlphabetically', 'checkSpelling'];
+    const cssUpdates = ['backgroundColor', 'fontColor'];
+    const dataUpdates = ['randomAngles', 'sortAlphabetically',
+      'fontSizeMin', 'fontSizeMax', 'textTransform', 'fontStyle', 'fontWeight', 'fontFamily', 'fontSize'];
     const cssWeightUpdates = ['color'];
     const dataWeightUpdates = ['maxVisibleElements', 'rotation'];
     //data updates
diff --git a/src/app/components/shared/tag-cloud/tag-cloud.interface.ts b/src/app/components/shared/tag-cloud/tag-cloud.interface.ts
index ca84784ddeec0566a7f302f303831c87aa7c5415..b6f0edf187bf9b80fc536327d88e54c876e8b7c5 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud.interface.ts
+++ b/src/app/components/shared/tag-cloud/tag-cloud.interface.ts
@@ -33,10 +33,27 @@ export type CloudWeightSettings = [
 export enum CloudTextStyle {
   normal,
   lowercase,
-  capitalized
+  capitalized,
+  uppercase
 }
 
 export interface CloudParameters {
+  /**
+   * The general font family for the tag cloud
+   */
+  fontFamily: string;
+  /**
+   * The general font style for the tag cloud
+   */
+  fontStyle: string;
+  /**
+   * The general font weight for the tag cloud
+   */
+  fontWeight: string;
+  /**
+   * The general font size for the tag cloud
+   */
+  fontSize: string;
   /**
    * Background color of the Tag-cloud
    */
diff --git a/src/app/services/http/spacy.service.ts b/src/app/services/http/spacy.service.ts
index 92825bb8dc2bb79c17bd494feaedab11be444a4a..394000f9c7c237963f8200ee39dce98671221c43 100644
--- a/src/app/services/http/spacy.service.ts
+++ b/src/app/services/http/spacy.service.ts
@@ -2,65 +2,29 @@ import { Injectable } from '@angular/core';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Observable } from 'rxjs';
 import { BaseHttpService } from './base-http.service';
-import { catchError, map } from 'rxjs/operators';
+import { catchError, map, tap } from 'rxjs/operators';
 
-export type Model = 'de' | 'en' | 'fr';
+export type Model = 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'pt';
 
-export class Result {
-  arcs: Arc[];
-  words: Word[];
-
-  constructor(
-    arcs: Arc[] = [],
-    words: Word[] = []
-  ) {
-    this.arcs = arcs;
-    this.words = words;
-  }
-
-  static empty(): Result {
-    return new Result();
-  }
-}
-
-export class Word {
-  tag: string;
-  text: string;
-
-  constructor(
-    tag: string,
-    text: string
-  ) {
-    this.tag = tag;
-    this.text = text;
-  }
-}
-
-export class Arc {
-  dir: string;
-  end: number;
-  label: string;
-  start: number;
-  text: string;
-
-  constructor(
-    dir: string,
-    end: number,
-    label: string,
-    start: number,
-    text: string,
-  ) {
-    this.dir = dir;
-    this.end = end;
-    this.label = label;
-    this.start = start;
-    this.text = text;
-  }
+//[B]egin, [I]nside, [O]utside or unset
+type EntityPosition = 'B' | 'I' | 'O' | '';
 
+interface NounToken {
+  dep: string; // dependency inside the sentence
+  // eslint-disable-next-line @typescript-eslint/naming-convention
+  entity_pos: EntityPosition; // entity position
+  // eslint-disable-next-line @typescript-eslint/naming-convention
+  entity_type: string; // entity type
+  lemma: string; // lemma of token
+  tag: string; // tag of token
+  text: string; // text of token
 }
 
+type NounCompound = NounToken[];
+type NounCompoundList = NounCompound[];
 
 const httpOptions = {
+  // eslint-disable-next-line @typescript-eslint/naming-convention
   headers: new HttpHeaders({'Content-Type': 'application/json'})
 };
 
@@ -73,17 +37,44 @@ export class SpacyService extends BaseHttpService {
     super();
   }
 
-  getKeywords(text: string, model: string): Observable<string[]> {
-    return this.analyse(text, model).pipe(
-      map(result => result.words.filter(v => v.tag.charAt(0) === 'N').map(v => v.text))
-    );
+  private static processCompound(result: string[], data: NounCompound) {
+    let isInEntity = false;
+    let start = 0;
+    const pushNew = (i: number) => {
+      if (start < i) {
+        result.push(data.slice(start, i).reduce((acc, current) => acc + ' ' + current.lemma, ''));
+        start = i;
+      }
+    };
+    data.forEach((noun, i) => {
+      if (noun.entity_pos === 'B' || (noun.entity_pos === 'I' && !isInEntity)) {
+        // entity begins
+        pushNew(i);
+        isInEntity = true;
+      } else if (isInEntity) {
+        if (noun.entity_pos === '' || noun.entity_pos === 'O') {
+          // entity ends
+          pushNew(i);
+          isInEntity = false;
+        }
+      }
+    });
+    pushNew(data.length);
   }
 
-  analyse(text: string, model: string): Observable<Result> {
+  getKeywords(text: string, model: Model): Observable<string[]> {
     const url = '/spacy';
-    return this.http.post<Result>(url, {text, model}, httpOptions)
+    return this.http.post<NounCompoundList>(url, {text, model}, httpOptions)
       .pipe(
-        catchError(this.handleError<any>('analyse'))
+        tap(_ => ''),
+        catchError(this.handleError<any>('getKeywords')),
+        map((result: NounCompoundList) => {
+          const filteredNouns: string[] = [];
+          result.forEach(compound => {
+            SpacyService.processCompound(filteredNouns, compound);
+          });
+          return filteredNouns;
+        })
       );
   }
 }
diff --git a/src/app/services/util/tag-cloud-data.service.ts b/src/app/services/util/tag-cloud-data.service.ts
index 48e81f9512fb43f10f050551c026c574dc538509..8d9ec90e30d238b75c59974a951da943d12e11aa 100644
--- a/src/app/services/util/tag-cloud-data.service.ts
+++ b/src/app/services/util/tag-cloud-data.service.ts
@@ -81,9 +81,7 @@ export class TagCloudDataService {
   private readonly _currentMetaData: TagCloudMetaData;
   private _demoData: TagCloudData = null;
   private _adminData: TopicCloudAdminData = null;
-  private _currentBlacklist: string[] = [];
   private _subscriptionAdminData: Subscription;
-  private _subscriptionBlacklist: Subscription;
 
   constructor(private _wsCommentService: WsCommentServiceService,
               private _commentService: CommentService,
@@ -109,16 +107,11 @@ export class TagCloudDataService {
 
   bindToRoom(roomId: string): void {
     this._roomId = roomId;
+    this.onReceiveAdminData(this._tagCloudAdmin.getDefaultAdminData);
     this._subscriptionAdminData = this._tagCloudAdmin.getAdminData.subscribe(adminData => {
-      this._adminData = adminData;
-      this._calcWeightType = this._adminData.considerVotes ? TagCloudCalcWeightType.byLengthAndVotes : TagCloudCalcWeightType.byLength;
-      this._supplyType = this._adminData.keywordORfulltext as unknown as TagCloudDataSupplyType;
-      this.rebuildTagData();
-    });
-    this._subscriptionBlacklist = this._tagCloudAdmin.getBlacklist().subscribe(blacklist => {
-      this._currentBlacklist = blacklist || [];
-      this.rebuildTagData();
+      this.onReceiveAdminData(adminData,true);
     });
+
     this.fetchData();
     if (!CommentFilterOptions.readFilter().paused) {
       this._wsCommentSubscription = this._wsCommentService
@@ -127,7 +120,6 @@ export class TagCloudDataService {
   }
 
   unbindRoom(): void {
-    this._subscriptionBlacklist.unsubscribe();
     this._subscriptionAdminData.unsubscribe();
     if (this._wsCommentSubscription !== null) {
       this._wsCommentSubscription.unsubscribe();
@@ -252,6 +244,15 @@ export class TagCloudDataService {
     this._dataBus.next(newData);
   }
 
+  private onReceiveAdminData(data: TopicCloudAdminData, update = false) {
+    this._adminData = data;
+    this._calcWeightType = this._adminData.considerVotes ? TagCloudCalcWeightType.byLengthAndVotes : TagCloudCalcWeightType.byLength;
+    this._supplyType = this._adminData.keywordORfulltext as unknown as TagCloudDataSupplyType;
+    if(update) {
+      this.rebuildTagData();
+    }
+  }
+
   private getCurrentData(): TagCloudData {
     if (this._isDemoActive) {
       return this._demoData;
@@ -304,7 +305,7 @@ export class TagCloudDataService {
       for (const keyword of keywords) {
         const lowerCaseKeyWord = keyword.toLowerCase();
         let profanity = false;
-        for (const word of this._currentBlacklist) {
+        for (const word of this._adminData.blacklist) {
           if (lowerCaseKeyWord.includes(word)) {
             profanity = true;
             break;
@@ -399,6 +400,14 @@ export class TagCloudDataService {
                   comment.downvotes = value as number;
                   needRebuild = true;
                   break;
+                case 'keywordsFromSpacy':
+                  comment.keywordsFromSpacy = JSON.parse(value as string);
+                  needRebuild = true;
+                  break;
+                case 'keywordsFromQuestioner':
+                  comment.keywordsFromQuestioner = JSON.parse(value as string);
+                  needRebuild = true;
+                  break;
                 case 'ack':
                   const isNowAck = value as boolean;
                   if (!isNowAck) {
diff --git a/src/assets/i18n/home/de.json b/src/assets/i18n/home/de.json
index e54b40b66a45a4530e80e9aa144bb5ef949697aa..33ec19d02e982e9a88488ed9071dae8c0feea975 100644
--- a/src/assets/i18n/home/de.json
+++ b/src/assets/i18n/home/de.json
@@ -100,7 +100,8 @@
     "questions-blocked": "Fragen sind deaktiviert!",
     "overview-question-tooltip": "Anzahl gestellter Fragen",
     "overview-questioners-tooltip": "Anzahl Fragensteller*innen",
-    "overview-keywords-tooltip": "Anzahl Schlüsselwörter"
+    "overview-keywords-tooltip": "Anzahl Schlüsselwörter",
+    "update-spacy-keywords": "Stichwörter anlegen"
   },
   "help": {
     "cancel": "Schließen",
diff --git a/src/assets/i18n/home/en.json b/src/assets/i18n/home/en.json
index b886992ec32e98181f3c3a17c4d455cb38749ba4..2c6b9e93e1f6a502e9946db05131bf9059fb761e 100644
--- a/src/assets/i18n/home/en.json
+++ b/src/assets/i18n/home/en.json
@@ -92,7 +92,8 @@
     "questions-blocked": "No further questions!",
     "overview-question-tooltip": "Number of questions",
     "overview-questioners-tooltip": "Number of questioners",
-    "overview-keywords-tooltip": "Number of Keywords"
+    "overview-keywords-tooltip": "Number of Keywords",
+    "update-spacy-keywords": "Add keywords"
   },
   "help": {
     "cancel": "Close",
diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json
index baee4ae21a3d403ad978fbfa9e0ab322966b7986..800272a2057b95ef362e5f269befd79433b5f8b1 100644
--- a/src/assets/i18n/participant/de.json
+++ b/src/assets/i18n/participant/de.json
@@ -251,7 +251,8 @@
     "some-days": "{{days}} Tage",
     "one-week": "1 Woche",
     "some-weeks": "{{weeks}} Wochen",
-    "some-months": "{{months}} Monate"
+    "some-months": "{{months}} Monate",
+    "tag-correction-placeholder": "Korrektur"
   },
   "topic-cloud-dialog": {
     "cancel": "Abbrechen",
@@ -354,4 +355,4 @@
     "rotate-weight": "Einige Einträge dieser Klasse zufällig um x Grad drehen",
     "rotate-weight-tooltip": "einige Einträge dieser Wichtigkeitsklasse zufällig um x Grad drehen"
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json
index da69a91b4d84e963b43e8fddf3245a0d70bb2305..218f91314adbdc87d0ecca09914245e3bc4251f3 100644
--- a/src/assets/i18n/participant/en.json
+++ b/src/assets/i18n/participant/en.json
@@ -257,7 +257,8 @@
     "some-days": "{{days}} days",
     "one-week": "1 week",
     "some-weeks": "{{weeks}} weeks",
-    "some-months": "{{months}} months"
+    "some-months": "{{months}} months",
+    "tag-correction-placeholder": "Correction"
   },
   "topic-cloud-dialog":{
     "edit": "Edit",
@@ -360,4 +361,4 @@
     "highestWeight-tooltip": "show x tags with the highest weight",
     "rotate-weight": "Rotate some entries of this weight class randomly by x degrees"
   }
-}
\ No newline at end of file
+}