diff --git a/package-lock.json b/package-lock.json
index 8315bc02a18e320e1fb69a4db5f7dfb33de78ab5..d6f1a578cad4cae9ae63b44019aa23432c207f74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21599,9 +21599,9 @@
       "dev": true
     },
     "@types/marked": {
-      "version": "0.7.2",
-      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.7.2.tgz",
-      "integrity": "sha512-A3EDyNaq6OCcpaOia2HQ/tu2QYt8DKuj4ExP21VU3cU3HTo2FLslvbqa2T1vux910RHvuSVqpwKnnykSFcRWOA=="
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.2.tgz",
+      "integrity": "sha512-P4zanhCQKs4tiWPPBGpB7lHflgFCP9DFGNI5YtpW9MALKoy2qs9rHNWJ+z55cegD9uCfnmsKuaosq9FNvbxrOw=="
     },
     "@types/minimatch": {
       "version": "3.0.4",
@@ -22653,6 +22653,11 @@
         "object.assign": "^4.1.0"
       }
     },
+    "badwords-list": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/badwords-list/-/badwords-list-1.0.0.tgz",
+      "integrity": "sha1-XphW2/E0gqKVw7CzBK+51M/FxXk="
+    },
     "balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -23433,9 +23438,9 @@
       "dev": true
     },
     "clipboard": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
-      "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
+      "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
       "optional": true,
       "requires": {
         "good-listener": "^1.2.2",
@@ -23558,7 +23563,8 @@
     "commander": {
       "version": "2.20.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
-      "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
+      "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
+      "dev": true
     },
     "comment-parser": {
       "version": "1.1.5",
@@ -24707,6 +24713,11 @@
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
     },
+    "emoji-toolkit": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/emoji-toolkit/-/emoji-toolkit-6.5.1.tgz",
+      "integrity": "sha512-oY5E81cXvRUxXkbVgOI8NxYHKF5FeWfJhFCIYUKhbVfSmdCH8+bmJzgDdhufExa7t1+WEzpUFdHwYxJTXS90vQ=="
+    },
     "emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
@@ -27896,11 +27907,18 @@
       }
     },
     "katex": {
-      "version": "0.11.1",
-      "resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
-      "integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/katex/-/katex-0.13.11.tgz",
+      "integrity": "sha512-yJBHVIgwlAaapzlbvTpVF/ZOs8UkTj/sd46Fl8+qAf2/UiituPYVeapVD8ADZtqyRg/qNWUKt7gJoyYVWLrcXw==",
       "requires": {
-        "commander": "^2.19.0"
+        "commander": "^6.0.0"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+          "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="
+        }
       }
     },
     "killable": {
@@ -28323,9 +28341,9 @@
       }
     },
     "marked": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.0.tgz",
-      "integrity": "sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ=="
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
+      "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA=="
     },
     "mat-color-picker": {
       "version": "1.4.3",
@@ -28873,6 +28891,11 @@
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "naughty-words": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/naughty-words/-/naughty-words-1.2.0.tgz",
+      "integrity": "sha512-0iadX6fN+3NsfvIRtWmmpEX9VsoIQ6n9FwyIxmew9w5yzFNqMgs/Ky0eAC/z5xXSHtqlVoByiovdROikwH9SXQ=="
+    },
     "needle": {
       "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
@@ -28931,14 +28954,16 @@
       }
     },
     "ngx-markdown": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-9.0.0.tgz",
-      "integrity": "sha512-wcXMxA4Skgk9SzhfDRjihap/Kjq17jmMQiE/Ccp0bNibGaDgS5DbZiPBlMNLkp669UvjY9wVuxE4NuDtmQHS9w==",
-      "requires": {
-        "@types/marked": "^0.7.2",
-        "katex": "^0.11.0",
-        "marked": "^0.8.0",
-        "prismjs": "^1.16.0"
+      "version": "11.1.3",
+      "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-11.1.3.tgz",
+      "integrity": "sha512-z32q8l76ubrcP62L03mdvrizwueLBHV10LkT8MEDnFcjmY+8J1PytxFJ9EBTJpvc+CaPolgAoi7felN2XJZTSg==",
+      "requires": {
+        "@types/marked": "^2.0.0",
+        "emoji-toolkit": "^6.0.1",
+        "katex": "^0.13.0",
+        "marked": "^2.0.0",
+        "prismjs": "^1.23.0",
+        "tslib": "^2.0.0"
       }
     },
     "ngx-matomo": {
diff --git a/package.json b/package.json
index b4859819ff5162d1408de08e5b619cf3682a2198..fb7150b4892395abbf9caf87b620744810cb4cf5 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
     "@stomp/ng2-stompjs": "^7.2.0",
     "angular-tag-cloud-module": "^5.3.0",
     "angularx-qrcode": "^11.0.0",
+    "badwords-list": "^1.0.0",
     "chart.js": "^2.9.4",
     "core-js": "^2.5.7",
     "get-stream": "^6.0.1",
@@ -38,8 +39,9 @@
     "is-promise": "^4.0.0",
     "mat-color-picker": "^1.4.3",
     "material-design-icons": "^3.0.1",
+    "naughty-words": "^1.2.0",
     "ngx-color-picker": "^11.0.0",
-    "ngx-markdown": "^9.0.0",
+    "ngx-markdown": "^11.1.3",
     "ngx-matomo": "^0.1.4",
     "ngx-matomo-v9": "^0.3.0",
     "rxjs": "^6.5.4",
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
index 9f6b4c7cdf25f7555f1556ae3c0cd62fc64004b9..8c9066e9b8fae24d45d6329f65ef020b33273a0f 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
@@ -1,15 +1,71 @@
 <mat-dialog-content>
-  <mat-card>
-    <mat-slide-toggle [(ngModel)]="considerVotes">{{'topic-cloud-dialog.consider-votes' | translate}}</mat-slide-toggle>
-    <mat-slide-toggle [(ngModel)]="tagsLowerCase">{{'topic-cloud-dialog.tags-lowercase' | translate}}</mat-slide-toggle>
-  </mat-card>
+  <mat-card class="color-surface">
+    <div>
+      <mat-slide-toggle [(ngModel)]="considerVotes">
+        {{'topic-cloud-dialog.consider-votes' | translate}}
+      </mat-slide-toggle>
+      <mat-slide-toggle (change)="refreshAllLists()" [(ngModel)]="profanityFilter">
+        {{'topic-cloud-dialog.profanity' | translate}}
+      </mat-slide-toggle>
+      <mat-slide-toggle [(ngModel)]="hideIrrelevant">
+        {{'topic-cloud-dialog.hide-irrelevant' | translate}}
+      </mat-slide-toggle>
+
+      <mat-accordion hideToggle class="new-Badword" multi>
+        <mat-expansion-panel class="color-background"
+                            (opened)="enterBadword = true; focusBadWordInput()"
+                            (closed)="enterBadword = false">
+          <mat-expansion-panel-header class="color-background">
+            <mat-panel-description>
+              {{'topic-cloud-dialog.add-profanity-word' | translate}}
+                <mat-icon>{{!enterBadword ? 'add' : 'remove'}}</mat-icon>
+          </mat-panel-description>
+          </mat-expansion-panel-header>
+
+          <mat-form-field>
+            <mat-label>{{'topic-cloud-dialog.enter-word' | translate}}</mat-label>
+            <input matInput id="bad-word-input" [(ngModel)]="newBadWord">
+          </mat-form-field>
+
+          <button mat-button color="primary" (click)="addBadword()">
+            <mat-icon>add_circle</mat-icon>
+              {{'topic-cloud-dialog.send' | translate}}
+          </button>
+        </mat-expansion-panel>
+      <!-- </mat-accordion>
+
+      <mat-accordion hideToggle class="new-Badword" multi> -->
+        <mat-expansion-panel class="color-background"
+                            (opened)="enterIrrelevantWord = true; focusIrrelevantWordInput()"
+                            (closed)="enterIrrelevantWord = false">
+          <mat-expansion-panel-header class="color-background">
+            <mat-panel-description>
+              {{'topic-cloud-dialog.add-irrelevant-word' | translate}}
+                <mat-icon>{{!enterIrrelevantWord ? 'add' : 'remove'}}</mat-icon>
+          </mat-panel-description>
+          </mat-expansion-panel-header>
+
+          <mat-form-field>
+            <mat-label>{{'topic-cloud-dialog.enter-word' | translate}}</mat-label>
+            <input matInput id="irrelevant-word-input" [(ngModel)]="newIrrelevantWord">
+          </mat-form-field>
+
+          <button mat-button color="primary" (click)="addIrrelevantWord()">
+            <mat-icon>add_circle</mat-icon>
+              {{'topic-cloud-dialog.send' | translate}}
+          </button>
+        </mat-expansion-panel>
+      </mat-accordion>
+
+    </div>
+   </mat-card>
 
   <div fxLayout="row" style="margin-top: 10px;">
     <mat-label fxLayoutAlign="center center">
       <mat-icon>search</mat-icon>
     </mat-label>
     <div style="margin-left: 10px;">
-      <mat-form-field class="example-form-field">
+      <mat-form-field [ngClass]="{'search': searchMode}">
         <input #searchBox id="searchBox" (input)="searchKeyword()"
                [(ngModel)]="searchedKeyword" matInput type="text"
                placeholder="{{'topic-cloud-dialog.keyword-search' | translate}}">
@@ -18,41 +74,49 @@
                 mat-button matSuffix mat-icon-button aria-label="topic-cloud-dialog.keyword-search">
           <mat-icon>close</mat-icon>
         </button>
+
       </mat-form-field>
     </div>
-    <div fxLayoutAlign="end" style="margin-left: 52%;">
-      <button  mat-button [matMenuTriggerFor]="sortMenu" mat-ripple>
+    <div fxLayoutAlign="center center" style="margin-left: 52%; font-weight: bold;"  >
+      <p [ngClass]="{'animation-blink': searchMode}">{{searchMode ? filteredKeywords.length : keywords.length}}</p>
+    </div>
+    <div fxLayoutAlign="end" *ngIf="!searchMode">
+      <button [ngClass]="{'animation-blink': sortMode!=='alphabetic'}" mat-button [matMenuTriggerFor]="sortMenu" mat-ripple>
         <mat-icon>sort</mat-icon>
       </button>
     </div>
   </div>
 
   <mat-menu #sortMenu>
-    <button mat-menu-item (click)="sortQuestions('alphabetic')">
+    <button [ngClass]="{'animation-blink': sortMode==='alphabetic'}" mat-menu-item (click)="sortQuestions('alphabetic')">
       <mat-icon>sort_by_alpha</mat-icon>
       {{'topic-cloud-dialog.sort-alpha' | translate}} </button>
-    <button mat-menu-item (click)="sortQuestions('questionsCount')">
+    <button [ngClass]="{'animation-blink': sortMode==='questionsCount'}" mat-menu-item (click)="sortQuestions('questionsCount')">
       <mat-icon>swap_vert</mat-icon>
       {{'topic-cloud-dialog.sort-count' | translate}} </button>
-    <button mat-menu-item (click)="sortQuestions('voteCount')">
+    <button [ngClass]="{'animation-blink': sortMode==='voteCount'}" mat-menu-item (click)="sortQuestions('voteCount')">
       <mat-icon>swap_vert</mat-icon>
       {{'topic-cloud-dialog.sort-vote' | translate}} </button>
   </mat-menu>
 
   <mat-accordion>
-    <mat-expansion-panel hideToggle *ngIf="searchMode && filteredKeywords.length === 0">
-        <mat-expansion-panel-header>
+    <mat-expansion-panel class="color-surface" hideToggle *ngIf="searchMode && filteredKeywords.length === 0">
+        <mat-expansion-panel-header class="color-surface">
             <mat-panel-title fxLayoutAlign="center">
               {{'topic-cloud-dialog.no-keywords-note' | translate}}
             </mat-panel-title>
         </mat-expansion-panel-header>
       </mat-expansion-panel>
-    <mat-expansion-panel (opened)="panelOpenState = true"
-                         (closed)="panelOpenState = edit = false"
-                         *ngFor="let keyword of (searchMode ? filteredKeywords : keywords); let i = index" [attr.data-index]="i">
-      <mat-expansion-panel-header class="color">
-        <mat-panel-title [ngClass]="{'edit-keyword': editedKeyword}">
-          {{keyword.keyword}}
+      <!-- *ngFor="let keyword of (searchMode ? filteredKeywords : keywords); let i = index" [attr.data-index]="i">
+       -->
+    <mat-expansion-panel class="color-surface"
+                        (opened)="panelOpenState = true"
+                        (closed)="panelOpenState = edit = false"
+                        *ngFor="let keyword of
+                        (searchMode ? filteredKeywords : keywords); let i = index" [attr.data-index]="i">
+      <mat-expansion-panel-header class="color-surface">
+        <mat-panel-title>
+          {{profanityFilter ? getKeywordWithoutProfanity(keyword.keyword) : keyword.keyword}}
         </mat-panel-title>
         <mat-panel-description>
           {{keyword.questions.length}}
@@ -66,6 +130,7 @@
         [keyword]="keyword.keyword"
         [maxShowedCharachters]="140"
         [isCollapsed]="!panelOpenState"
+        [profanityFilter]="profanityFilter"
         ></app-topic-dialog-comment>
       </div>
 
@@ -93,9 +158,9 @@
         <!-- TODO: textinput and buttons in one row -->
         <div align="end">
           <button mat-raised-button class="redBackground margin-right" (click)="cancelEdit()">{{'topic-cloud-dialog.cancel' | translate}}</button>
-          <button mat-raised-button class="primaryBackground" (click)="confirmEdit(keyword.keywordID)">{{'topic-cloud-dialog.save' | translate}}</button>
+          <button mat-raised-button class="primaryBackground" (click)="confirmEdit(keyword)">{{'topic-cloud-dialog.save' | translate}}</button>
         </div>
       </div>
-    </mat-expansion-panel>
+    </mat-expansion-panel><br>
   </mat-accordion>
 </mat-dialog-content>
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
index a947d843613ebf92e8d6d0405f1dd087937ca49d..427087987b7078fa7811a59dda8bb3061625c7b0 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
@@ -10,6 +10,7 @@
 
 .primary {
   color: var(--primary);
+  background: none;
 }
 
 .red {
@@ -32,10 +33,25 @@ mat-icon {
   fill: currentColor;
 }
 
-mat-expansion-panel-header, mat-expansion-panel, mat-card {
+.color-surface {
   background-color: var(--surface);
 }
 
+.color-background {
+  background-color: var(--dialog);
+}
+
+.search{
+  box-sizing: border-box;
+  padding: 0 10px 0 5px;
+  border: none;
+  outline: none;
+  min-height: 60px;
+  font-size: large;
+  border-radius: 5px;
+  color: var(--on-surface);
+  transition: width 300ms linear;
+}
 
 label {
   color: var(--on-surface)
@@ -57,7 +73,7 @@ mat-panel-title, mat-panel-description {
   }
 }
 
-.edit-keyword .mat-panel-title {
+.animation-blink{
   color: var(--red) !important;
   animation-name: animation_blink_5s;
   animation-timing-function: ease-in;
@@ -65,4 +81,18 @@ mat-panel-title, mat-panel-description {
   animation-iteration-count: 2;
   opacity: 1.0 !important;
 }
- 
\ No newline at end of file
+
+.new-Badword .mat-expansion-panel-header-title,
+.new-Badword .mat-expansion-panel-header-description {
+  flex-basis: 0;
+}
+
+.new-Badword .mat-expansion-panel-header-description,
+.new-Badword .button {
+  justify-content: space-between;
+  align-items: center;
+}
+
+.new-Badword .mat-form-field + .mat-form-field {
+  margin-left: 8px;
+}
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
index c18be92350c9ad7f1ea277be0a42a265a7af72a4..8b306ff956eaf8ffc24badb18dca45529e5126c8 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
@@ -7,6 +7,9 @@ import { AuthenticationService } from '../../../../services/http/authentication.
 import { UserRole } from '../../../../models/user-roles.enum';
 import { TranslateService } from '@ngx-translate/core';
 import { LanguageService } from '../../../../services/util/language.service';
+import { FormControl } from '@angular/forms';
+import { SpacyService } from '../../../../services/http/spacy.service';
+import { TopicCloudAdminService } from '../../../../services/util/topic-cloud-admin.service';
 
 @Component({
   selector: 'app-topic-cloud-administration',
@@ -16,13 +19,17 @@ import { LanguageService } from '../../../../services/util/language.service';
 export class TopicCloudAdministrationComponent implements OnInit {
   public panelOpenState = false;
   public considerVotes: boolean; // should be sent back to tagCloud component
-  public tagsLowerCase: boolean; // should be sent back to tagCloud component
+  public profanityFilter = true; // should be sent back to tagCloud component
+  public hideIrrelevant: boolean; // should be sent back to tagCloud component
   newKeyword = undefined;
   edit = false;
   isCreatorOrMod: boolean;
+  enterBadword = false;
+  enterIrrelevantWord = false;
+  newBadWord: string = undefined;
+  newIrrelevantWord: string = undefined;
 
   sortMode = 'alphabetic';
-  editedKeyword = false;
   searchedKeyword = undefined;
   searchMode = false;
   filteredKeywords: Keyword[] = [];
@@ -32,7 +39,7 @@ export class TopicCloudAdministrationComponent implements OnInit {
       keywordID: 1,
       keyword: 'Cloud',
       questions: [
-        'Wieviel speicherplatz steht mir in der Cloud zur verfuegung? Ich habe eine Frage, sind Fragen zum thema \'Frage\' auch erlaubt?',
+        'Wieviel speicherplatz steht mir in der Cloud zur verfügung?',
         'Sollen wir die Tag Cloud implementieren?',
         // eslint-disable-next-line max-len
         'Wie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegungWie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegungWie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegungWie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegungWie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegungWie genau ist die Cloud aufgebaut? Wieviel speicherplatz steht mir in der Cloud zur verfuegung',
@@ -71,6 +78,18 @@ export class TopicCloudAdministrationComponent implements OnInit {
         'gibt es heute übung?'
       ]
     },
+    {
+      keywordID: 6,
+      keyword: 'Arsch',
+      questions: [
+        'Das ist eine Testfrage fuer den Profanity Filter, du Arschloch',
+        'Englisch: Fuck you!',
+        'Deutsch: Fick dich!',
+        'Französisch: Gros con!',
+        'Multi language: Ficken, Fuck, con',
+        'Custom: Nieder mit KQC'
+      ]
+    },
 
   ];
 
@@ -79,7 +98,8 @@ export class TopicCloudAdministrationComponent implements OnInit {
               private notificationService: NotificationService,
               private authenticationService: AuthenticationService,
               private translateService: TranslateService,
-              private langService: LanguageService) {
+              private langService: LanguageService,
+              private topicCloudAdminService: TopicCloudAdminService) {
 
                 this.langService.langEmitter.subscribe(lang => {
                   this.translateService.use(lang);
@@ -93,6 +113,10 @@ export class TopicCloudAdministrationComponent implements OnInit {
     this.sortQuestions();
   }
 
+  getKeywordWithoutProfanity(keyword: string): string {
+    return this.topicCloudAdminService.filterProfanityWords(keyword);
+  }
+
   sortQuestions(sortMode?: string) {
     if (sortMode !== undefined) {
       this.sortMode = sortMode;
@@ -135,9 +159,9 @@ export class TopicCloudAdministrationComponent implements OnInit {
     }, 0);
   }
 
-  deleteKeyword(id: number): void{
+  deleteKeyword(key: Keyword): void{
     this.keywords.map(keyword => {
-      if (keyword.keywordID === id) {
+      if (keyword.keywordID === key.keywordID) {
           this.keywords.splice(this.keywords.indexOf(keyword, 0), 1);
       }
     });
@@ -155,14 +179,14 @@ export class TopicCloudAdministrationComponent implements OnInit {
     this.newKeyword = undefined;
   }
 
-  confirmEdit(id: number): void {
+  confirmEdit(key: Keyword): void {
     this.keywords.map(keyword => {
-      if (keyword.keywordID === id) {
+      if (keyword.keywordID === key.keywordID) {
+          this.integrateIfKeywordExists(keyword, this.newKeyword.trim().toLowerCase());
           keyword.keyword = this.newKeyword.trim();
       }
     });
     this.edit = false;
-    this.editedKeyword = true;
     this.newKeyword = undefined;
     this.sortQuestions();
     if (this.searchMode){
@@ -177,14 +201,14 @@ export class TopicCloudAdministrationComponent implements OnInit {
 
     confirmDialogRef.afterClosed().subscribe(result => {
       if (result === 'delete') {
-        this.deleteKeyword(keyword.keywordID);
+        this.deleteKeyword(keyword);
       }
     });
   }
 
   searchKeyword(): void {
     if (!this.searchedKeyword){
-        this.searchMode = false;
+      this.searchMode = false;
     } else {
       this.filteredKeywords = this.keywords.filter(keyword =>
         keyword.keyword.toLowerCase().includes(this.searchedKeyword.toLowerCase())
@@ -192,6 +216,59 @@ export class TopicCloudAdministrationComponent implements OnInit {
       this.searchMode = true;
     }
   }
+
+  //TODO: confirm dialog -> keyword does already exist, do you want to merge the questions with the existing keyword?
+
+  integrateIfKeywordExists(keyword: Keyword, keyname: string) {
+    const key = this.checkIfKeywordExists(keyname);
+    if (key !== undefined){
+      key.questions.map(question => {
+        keyword.questions.push(question);
+      });
+      this.deleteKeyword(key);
+    }
+  }
+
+  checkIfKeywordExists(key: string): Keyword {
+    for(const keyword of this.keywords){
+      if(keyword.keyword.toLowerCase() === key){
+        return keyword;
+      }
+    }
+    return undefined;
+  }
+
+  focusBadWordInput() {
+    setTimeout(() => {
+      document.getElementById('bad-word-input').focus();
+    }, 100);
+  }
+
+  focusIrrelevantWordInput() {
+    setTimeout(() => {
+      document.getElementById('irrelevant-word-input').focus();
+    }, 100);
+  }
+
+  addBadword() {
+    this.topicCloudAdminService.addToBadwordList(this.newBadWord);
+    this.newBadWord = undefined;
+    if (this.searchMode){
+      this.searchKeyword();
+    }
+  }
+
+  addIrrelevantWord() {
+    this.topicCloudAdminService.addToIrrelevantwordList(this.newIrrelevantWord);
+    this.newIrrelevantWord = undefined;
+    if (this.searchMode){
+      this.searchKeyword();
+    }
+  }
+
+  refreshAllLists(){
+    this.searchKeyword();
+  }
 }
 
 interface Keyword {
diff --git a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.html b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.html
index 9284e8b2e8ed4a124697947a2890df604257abd5..ef9738a6ac20839cafc7e1ac53c074644dd9ef66 100644
--- a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.html
+++ b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.html
@@ -1,6 +1,5 @@
 <div>
   <p>
-    <!--{{(isCollapsed) ? question : question | slice:0:maxShowedCharachters}}{{question.length > maxShowedCharachters && !isCollapsed? "..." : ""}} -->
     <span *ngFor="let part Of partsOfQuestion; let i = index">{{part}}<mark *ngIf="i < partsOfQuestion.length -1">{{keyword}}</mark></span>
     <button
           *ngIf = "question.length > maxShowedCharachters"
@@ -9,3 +8,5 @@
     </button>
   </p>
 </div>
+
+
diff --git a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
index 3102627513ef19d75be15672b932553d54b74da2..73b5b508b750e6094a9fe7492bffe5c3b29d7d75 100644
--- a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
+++ b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
@@ -1,24 +1,43 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, Input, OnChanges, OnInit, SimpleChange, SimpleChanges } from '@angular/core';
+import { TopicCloudAdminService } from '../../../../services/util/topic-cloud-admin.service';
 
 @Component({
   selector: 'app-topic-dialog-comment',
   templateUrl: './topic-dialog-comment.component.html',
   styleUrls: ['./topic-dialog-comment.component.scss']
 })
-export class TopicDialogCommentComponent implements OnInit {
+export class TopicDialogCommentComponent implements OnInit, OnChanges {
 
   @Input() question: string;
   @Input() keyword: string ;
   @Input() maxShowedCharachters: number;
   @Input() isCollapsed = false;
-  constructor() { }
+  @Input() profanityFilter = true;
 
-  get partsOfQuestion(){
+  public badWords = [];
+  questionWithProfinity: string = undefined;
 
-    return this.question.slice(0,this.isCollapsed? this.question.length: this.maxShowedCharachters).split(new RegExp(this.keyword,'i')) ;
+  public shortQuestion: string;
 
+  constructor(private topicCloudAdminService: TopicCloudAdminService) { }
+
+  ngOnChanges(changes: SimpleChanges) {
+  }
+
+  get partsOfQuestion() {
+    if (this.profanityFilter) {
+      const question = this.topicCloudAdminService.filterProfanityWords(this.question);
+      return question
+          .slice(0,this.isCollapsed? this.question.length: this.maxShowedCharachters)
+          .split(new RegExp(this.keyword,'i'));
+    } else {
+      return this.question
+          .slice(0,this.isCollapsed? this.question.length: this.maxShowedCharachters)
+          .split(new RegExp(this.keyword,'i'));
+    }
   }
 
   ngOnInit(): void {
+    this.questionWithProfinity = this.topicCloudAdminService.filterProfanityWords(this.question);
   }
 }
diff --git a/src/app/services/util/topic-cloud-admin.service.spec.ts b/src/app/services/util/topic-cloud-admin.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89683b0355d2eb788ff044c5d2873bb452c68b8a
--- /dev/null
+++ b/src/app/services/util/topic-cloud-admin.service.spec.ts
@@ -0,0 +1,18 @@
+/*
+import { TestBed } from '@angular/core/testing';
+
+import { TopicCloudAdminService } from './topic-cloud-admin.service';
+
+describe('TopicCloudAdminServiceService', () => {
+  let service: TopicCloudAdminService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TopicCloudAdminService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
+*/
diff --git a/src/app/services/util/topic-cloud-admin.service.ts b/src/app/services/util/topic-cloud-admin.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac2fac3ec162ca126be09c33ceaec301014091cf
--- /dev/null
+++ b/src/app/services/util/topic-cloud-admin.service.ts
@@ -0,0 +1,66 @@
+import { Injectable } from '@angular/core';
+import * as BadWords from 'naughty-words';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { BaseHttpService } from '../http/base-http.service';
+import { catchError } from 'rxjs/operators';
+
+const httpOptions = {
+  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
+};
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TopicCloudAdminService extends BaseHttpService{
+
+  private badWords = [];
+  private irrelevantWords = [];
+
+  constructor(private http: HttpClient) {
+    super();
+    this.badWords = BadWords;
+    this.badWords['custom'] = [];
+  }
+
+  get getBadWordList(): string[]{
+    return this.badWords['custom'];
+  }
+
+  filterProfanityWords(str: string): string {
+    let questionWithProfanity = str;
+    // TODO: another languages
+    /* put all arrays of languages together */
+    const profanityWords = this.badWords['en'].concat(this.badWords['de'])
+                           .concat(this.badWords['fr']).concat(this.badWords['custom']);
+    profanityWords.map(word =>{
+      questionWithProfanity = questionWithProfanity.toLowerCase().includes(word.toLowerCase()) ?
+      this.replaceString(questionWithProfanity.toLowerCase(), word.toLowerCase(), this.generateXWord(word.length))
+      : questionWithProfanity;
+    });
+    return questionWithProfanity;
+  }
+
+  addToBadwordList(word: string) {
+    if (word !== undefined) {
+      this.badWords['custom'].push(word);
+    }
+  }
+
+  addToIrrelevantwordList(word: string) {
+    if (word !== undefined) {
+      this.irrelevantWords.push(word);
+    }
+  }
+
+  private replaceString(str: string, search: string, replace: string){
+    return str.split(search).join(replace);
+  }
+
+  private generateXWord(count: number){
+    let res = '';
+    for (let i = 0; i < count; i++){
+      res += '*';
+    }
+    return res;
+  }
+}
diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json
index f771bcb75477bad3f4d0e659eef7950a5c4f7e59..f82fa30c7e299e1c96e95d9223eef07e1871b3ae 100644
--- a/src/assets/i18n/participant/de.json
+++ b/src/assets/i18n/participant/de.json
@@ -238,11 +238,20 @@
     "edit-keyword-tip": "Neues Thema",
     "no-keywords-note": "Es gibt keine Themen",
     "consider-votes": "Votes berücksichtigen",
-    "tags-lowercase": "Themen klein schreiben",
+    "profanity": "Schimpfwörter zensieren",
+    "hide-irrelevant": "Irrelevante Stichworte verbergen",
     "sort-alpha": "Alphabetisch",
     "sort-count": "Fragenanzahl",
     "sort-vote": "Votes",
-    "keyword-search": "Stichwort suchen"
+    "keyword-search": "Stichwort suchen",
+    "add-profanity-word": "Wort zur Zensurliste hinzufügen",
+    "add-irrelevant-word": "Wort zur Irrelevantliste hinzufügen",
+    "send": "Abschicken",
+    "enter-word": "Wort eingeben",
+    "english": "Englisch",
+    "german": "Deutsch",
+    "french": "Französisch",
+    "sendKey": "schickt keyword zu spacy"
   },
   "topic-cloud-confirm-dialog": {
     "cancel": "Abbrechen",
diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json
index 1bcb5b82c054256ce208326de9dc2ea522128901..3383cfd16c303da8b9ce9eea5a9a59d194f82e89 100644
--- a/src/assets/i18n/participant/en.json
+++ b/src/assets/i18n/participant/en.json
@@ -243,11 +243,20 @@
     "edit-keyword-tip": "New topic",
     "no-keywords-note": "There are no topics!",
     "consider-votes": "Consider Votes",
-    "tags-lowercase": "Topics in lowercase",
+    "profanity": "Censor profanity",
+    "hide-irrelevant": "Hide irrelevant keywords",
     "sort-alpha": "Alphabetically",
     "sort-count": "Questions count",
     "sort-vote": "Votes",
-    "keyword-search": "Search keyword"
+    "keyword-search": "Search keyword",
+    "add-profanity-word": "Add word to profanity list",
+    "add-irrelevant-word": "Add word to irrelevant list",
+    "send": "Send",
+    "enter-word": "Enter word",
+    "english": "English",
+    "german": "German",
+    "french": "French",
+    "sendKey": "send keyword to spacy"
   },
   "topic-cloud-confirm-dialog":{
     "cancel": "Cancel",