diff --git a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.html b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.html
index 7b52aea060be2052e558992e4682f0bc588f1ea8..bde177ecc825c95bfcd3acb342d8d6ebea804059 100644
--- a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.html
+++ b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.html
@@ -3,6 +3,15 @@
      [ngClass]="{'search-container' : !scroll, 'search-container-fixed' : scroll}"
      (window:scroll)="checkScroll()"
      fxLayoutAlign="center">
+
+  <button id="filter-close-button"
+          mat-icon-button
+          class="searchBarButton"
+          *ngIf="filter.filterType"
+          (click)="applyFilterByKey(null)"
+          aria-labelledby="close_filter">
+    <mat-icon class="searchBarIcon red">close</mat-icon>
+  </button>
   <mat-label *ngIf="deviceType === 'desktop'"
              fxLayoutAlign="center center">
     <mat-icon class="search-icon">search</mat-icon>
@@ -13,14 +22,14 @@
          [ngClass]="{'desktop-input': deviceType === 'desktop',
    'mobile-input': deviceType === 'mobile' && !search, 'mobile-input-2': deviceType === 'mobile' && search }"
          (input)="searchComments()"
-         [(ngModel)]="searchInput"
+         [(ngModel)]="filter.currentSearch"
          [placeholder]="searchPlaceholder"
          aria-labelledby="search-box-input-description"/>
   <button id="search_close-button"
           mat-icon-button
           class="searchBarButton close red"
-          *ngIf="searchInput !== '' || search"
-          (click)="hideCommentsList=false; searchInput = ''; search = false; searchPlaceholder = '';">
+          *ngIf="filter.currentSearch || search"
+          (click)="abortSearch()">
     <mat-icon>close</mat-icon>
   </button>
 
@@ -55,7 +64,7 @@
             aria-labelledby="time_settings"
             *ngIf="!searchBox.value && comments && comments.length > 0 && !search"
             [matMenuTriggerFor]="timeMenu"
-            [ngClass]="{'active-filter': period !== 'time-all'}"
+            [ngClass]="{'active-filter': filter.period !== 'time-all'}"
             matTooltip="{{ 'comment-list.select-time' | translate }}">
       <mat-icon class="searchBarIcon">history</mat-icon>
     </button>
@@ -73,25 +82,25 @@
             xPosition="before">
     <button mat-menu-item
             matTooltip="{{ 'comment-list.time' | translate }}"
-            (click)="sortComments(time)"
+            (click)="applySortingByKey('time')"
             aria-labelledby="access_time">
-      <mat-icon [ngClass]="{time: 'unread-icon'}[currentSort]">update</mat-icon>
-      <span>{{ 'comment-list.sort-list-time' | translate }}</span>
+      <mat-icon [ngClass]="{time: 'timesort'}[filter.sortType]">update</mat-icon>
+      <span [ngClass]="{time: 'timesort'}[filter.sortType]">{{ 'comment-list.sort-list-time' | translate }}</span>
     </button>
 
     <button mat-menu-item
             matTooltip="{{ 'comment-list.vote-asc' | translate }}"
-            (click)="sortComments(votedesc)"
+            (click)="applySortingByKey('votedesc')"
             aria-labelledby="keyboard_arrow_up">
-      <mat-icon [ngClass]="{votedesc: 'up'}[currentSort]">thumb_up</mat-icon>
+      <mat-icon [ngClass]="{votedesc: 'up'}[filter.sortType]">thumb_up</mat-icon>
       <span>{{ 'comment-list.sort-vote-asc' | translate }}</span>
     </button>
 
     <button mat-menu-item
             matTooltip="{{ 'comment-list.vote-desc' | translate }}"
-            (click)="sortComments(voteasc)"
+            (click)="applySortingByKey('voteasc')"
             aria-labelledby="keyboard_arrow_down">
-      <mat-icon [ngClass]="{voteasc: 'down'}[currentSort]">thumb_down</mat-icon>
+      <mat-icon [ngClass]="{voteasc: 'down'}[filter.sortType]">thumb_down</mat-icon>
       <span>{{ 'comment-list.sort-vote-desc' | translate }}</span>
     </button>
   </mat-menu>
@@ -99,7 +108,7 @@
   <mat-menu #timeMenu="matMenu" xPosition="before">
     <div *ngFor="let periodItem of periodsList">
       <button mat-menu-item (click)="setTimePeriod(periodItem)" class="period"
-              [ngClass]="{'selected': periodItem === period}"
+              [ngClass]="{'selected': periodItem === filter.period}"
               aria-labelledby="{{periodItem}}">
         <span>{{ ('comment-list.select-' + periodItem) | translate }}</span>
       </button>
@@ -122,7 +131,10 @@
                [userRole]="user.role"
                [parseVote]="getVote(current)"
                [moderator]="true"
-               (clickedUserNumber)="clickedUserNumber($event)">
+               [commentsWrittenByUser]="commentsWrittenByUsers.get(current.creatorId).size"
+               (clickedOnTag)="applyFilterByKey('tag', $event)"
+               (clickedUserNumber)="applyFilterByKey('userNumber', $event)"
+               (clickedOnKeyword)="applyFilterByKey('keyword', $event)">
   </app-comment>
 </div>
 <ars-mat-paginator
@@ -136,7 +148,7 @@
 <ars-row [height]="64">
 </ars-row>
 
-<div *ngIf="comments && (commentsFilteredByTime.length < 1 && period === 'time-all' || comments.length === 0) && !isLoading"
+<div *ngIf="comments && (commentsFilteredByTime.length < 1 && filter.period === 'time-all' || comments.length === 0) && !isLoading"
      fxLayout="row"
      fxLayoutAlign="center center"
      class="no-comments">
@@ -145,7 +157,7 @@
 </div>
 
 <div *ngIf="(filteredComments && filteredComments.length === 0 && hideCommentsList)
-            || (comments && commentsFilteredByTime.length === 0 && period !== 'time-all') && !isLoading && comments.length > 0"
+            || (comments && commentsFilteredByTime.length === 0 && filter.period !== 'time-all') && !isLoading && comments.length > 0"
      fxLayout="row"
      fxLayoutAlign="center center"
      class="no-comments">
diff --git a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.scss b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.scss
index 34b3f2feb31cf55bd7c878a39d808a1c3ddd54da..b39d91b167a734eccd46af85f5c1475478ee931f 100644
--- a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.scss
+++ b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.scss
@@ -101,6 +101,10 @@ h3 {
   margin: 10px;
 }
 
+.timesort {
+  color: var(--primary);
+}
+
 .up {
   color: var(--green);
 }
diff --git a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts
index 96ad723dc770ba147dde5249889d7451553a3202..7cf488d0a7634df86b6e2bf5bb163b8d73caf217 100644
--- a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts
+++ b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts
@@ -21,8 +21,16 @@ import { DeleteCommentsComponent } from '../../creator/_dialogs/delete-comments/
 import { Export } from '../../../models/export';
 import { NotificationService } from '../../../services/util/notification.service';
 import { BonusTokenService } from '../../../services/http/bonus-token.service';
-import { CommentFilter, Period } from '../../../utils/filter-options';
+import { Period } from '../../../utils/filter-options';
 import { PageEvent } from '@angular/material/paginator';
+import {
+  CommentListFilter,
+  FilterType,
+  FilterTypeKey,
+  SortType,
+  SortTypeKey
+} from '../../shared/comment-list/comment-list.filter';
+import { ModeratorService } from '../../../services/http/moderator.service';
 
 
 @Component({
@@ -47,7 +55,6 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
   voteasc = 'voteasc';
   votedesc = 'votedesc';
   time = 'time';
-  currentSort: string;
   read = 'read';
   unread = 'unread';
   favorite = 'favorite';
@@ -56,21 +63,19 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
   ack = 'ack';
   bookmark = 'bookmark';
   userNumber = 'userNumber';
-  currentFilter = '';
   commentVoteMap = new Map<string, Vote>();
   scroll = false;
   scrollExtended = false;
-  searchInput = '';
   search = false;
   searchPlaceholder = '';
   periodsList = Object.values(Period);
-  period: Period = Period.twoWeeks;
-  fromNow: number;
   headerInterface = null;
   pageIndex = 0;
   pageSize = 10;
   pageSizeOptions = [5, 10, 25];
   showFirstLastButtons = true;
+  commentsWrittenByUsers: Map<string, Set<string>> = new Map<string, Set<string>>();
+  filter: CommentListFilter;
 
   constructor(
     private commentService: CommentService,
@@ -83,12 +88,14 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     private router: Router,
     private notificationService: NotificationService,
     private translationService: TranslateService,
-    private bonusTokenService: BonusTokenService
+    private bonusTokenService: BonusTokenService,
+    private moderationService: ModeratorService
   ) {
     langService.langEmitter.subscribe(lang => translateService.use(lang));
+    this.filter = CommentListFilter.loadCurrentFilter();
   }
 
-  handlePageEvent(e:PageEvent){
+  handlePageEvent(e: PageEvent) {
     this.pageIndex = e.pageIndex;
     this.pageSize = e.pageSize;
   }
@@ -113,25 +120,25 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
       }
       dialogRef.componentInstance.tags = tags;
       dialogRef.afterClosed()
-      .subscribe(result => {
-        if (!result || result === 'abort') {
-          return;
-        } else {
-          updRoom.tags = result;
-          this.roomService.updateRoom(updRoom)
-          .subscribe((room) => {
-              this.room = room;
-              this.translateService.get('room-page.changes-successful').subscribe(msg => {
-                this.notificationService.show(msg);
-              });
-            },
-            error => {
-              this.translateService.get('room-page.changes-gone-wrong').subscribe(msg => {
-                this.notificationService.show(msg);
-              });
-            });
-        }
-      });
+        .subscribe(result => {
+          if (!result || result === 'abort') {
+            return;
+          } else {
+            updRoom.tags = result;
+            this.roomService.updateRoom(updRoom)
+              .subscribe((room) => {
+                  this.room = room;
+                  this.translateService.get('room-page.changes-successful').subscribe(msg => {
+                    this.notificationService.show(msg);
+                  });
+                },
+                error => {
+                  this.translateService.get('room-page.changes-gone-wrong').subscribe(msg => {
+                    this.notificationService.show(msg);
+                  });
+                });
+          }
+        });
     });
     nav('deleteQuestions', () => {
       const dialogRef = this.dialog.open(DeleteCommentsComponent, {
@@ -139,14 +146,14 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
       });
       dialogRef.componentInstance.roomId = this.roomId;
       dialogRef.afterClosed()
-      .subscribe(result => {
-        if (result === 'delete') {
-          this.translationService.get('room-page.comments-deleted').subscribe(msg => {
-            this.notificationService.show(msg);
-          });
-          this.commentService.deleteCommentsByRoomId(this.roomId).subscribe();
-        }
-      });
+        .subscribe(result => {
+          if (result === 'delete') {
+            this.translationService.get('room-page.comments-deleted').subscribe(msg => {
+              this.notificationService.show(msg);
+            });
+            this.commentService.deleteCommentsByRoomId(this.roomId).subscribe();
+          }
+        });
     });
     nav('exportQuestions', () => {
       const exp: Export = new Export(
@@ -166,6 +173,7 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
   }
 
   ngOnDestroy() {
+    this.filter.save();
     if (this.headerInterface) {
       this.headerInterface.unsubscribe();
     }
@@ -175,8 +183,12 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     this.initNavigation();
     this.roomId = localStorage.getItem(`roomId`);
     const userId = this.user.id;
+    this.filter.updateUserId(userId);
     this.userRole = this.user.role;
-    this.roomService.getRoom(this.roomId).subscribe(room => this.room = room);
+    this.roomService.getRoom(this.roomId).subscribe(room => {
+      this.room = room;
+      this.filter.updateRoom(room);
+    });
     this.hideCommentsList = false;
     this.wsCommentService.getModeratorCommentStream(this.roomId).subscribe((message: Message) => {
       this.parseIncomingModeratorMessage(message);
@@ -187,30 +199,23 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     this.translateService.use(localStorage.getItem('currentLang'));
     this.deviceType = localStorage.getItem('deviceType');
     this.isSafari = localStorage.getItem('isSafari');
-    this.currentSort = this.votedesc;
-    this.commentService.getRejectedComments(this.roomId)
-      .subscribe(comments => {
-        this.comments = comments;
-        this.setTimePeriod(this.period);
-        this.isLoading = false;
+    this.filter.sortType = SortType.votedesc;
+    this.moderationService.get(this.roomId)
+      .subscribe((mods) => {
+        this.filter.updateModerators(mods.map(mod => mod.accountId));
+
+        this.commentService.getRejectedComments(this.roomId)
+          .subscribe(comments => {
+            this.comments = comments;
+            this.setTimePeriod(this.filter.period);
+            this.isLoading = false;
+          });
       });
     this.translateService.get('comment-list.search').subscribe(msg => {
       this.searchPlaceholder = msg;
     });
   }
 
-  private getCurrentFilter() {
-    const filter = new CommentFilter();
-    filter.filterSelected = this.currentFilter;
-    filter.periodSet = this.period;
-
-    if (filter.periodSet === Period.fromNow) {
-      filter.timeStampNow = new Date().getTime();
-    }
-
-    CommentFilter.currentFilter = filter;
-  }
-
   checkScroll(): void {
     const currentScroll = document.documentElement.scrollTop;
     this.scroll = currentScroll >= 65;
@@ -223,18 +228,14 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
 
   searchComments(): void {
     this.search = true;
-    if (this.searchInput && this.searchInput.length > 1) {
+    if (this.filter.currentSearch) {
       this.hideCommentsList = true;
-      this.filteredComments = this.comments
-        .filter(c => this.checkIfIncludesKeyWord(c.body, this.searchInput)
-          || (!!c.answer ? this.checkIfIncludesKeyWord(c.answer, this.searchInput) : false));
+      this.filteredComments = this.filter.filterCommentsBySearch(this.comments);
+    } else if (!this.filter.filterType) {
+      this.hideCommentsList = false;
     }
   }
 
-  checkIfIncludesKeyWord(body: string, keyword: string) {
-    return body.toLowerCase().includes(keyword.toLowerCase());
-  }
-
   activateSearch() {
     this.translateService.get('comment-list.search').subscribe(msg => {
       this.searchPlaceholder = msg;
@@ -243,6 +244,13 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     this.searchField.nativeElement.focus();
   }
 
+  abortSearch() {
+    this.hideCommentsList = false;
+    this.filter.currentSearch = '';
+    this.search = false;
+    this.refreshFiltering();
+  }
+
   getComments(): void {
     this.isLoading = false;
     let commentThreshold = -10;
@@ -254,7 +262,7 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
         this.comments = this.comments.filter(x => x.score >= commentThreshold);
       }
     }
-    this.setTimePeriod(this.period);
+    this.setTimePeriod(this.filter.period);
   }
 
   getVote(comment: Comment): Vote {
@@ -278,7 +286,7 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
                   this.comments = this.comments.filter(function (el) {
                     return el.id !== payload.id;
                   });
-                  this.setTimePeriod(this.period);
+                  this.setTimePeriod(this.filter.period);
                 }
                 switch (key) {
                   case this.read:
@@ -318,7 +326,7 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
         }
         break;
     }
-    this.setTimePeriod(this.period);
+    this.setTimePeriod(this.filter.period);
     if (this.hideCommentsList) {
       this.searchComments();
     }
@@ -336,70 +344,49 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
         c.timestamp = payload.timestamp;
         c.creatorId = payload.creatorId;
         c.keywordsFromQuestioner = payload.keywordsFromQuestioner ?
-                                   JSON.parse(payload.keywordsFromQuestioner as unknown as string) : null;
+          JSON.parse(payload.keywordsFromQuestioner as unknown as string) : null;
         c.userNumber = this.commentService.hashCode(c.creatorId);
         this.comments = this.comments.concat(c);
         break;
     }
-    this.setTimePeriod(this.period);
+    this.setTimePeriod(this.filter.period);
     if (this.hideCommentsList) {
       this.searchComments();
     }
   }
 
-  filterComments(type: string, compare?: any): void {
-    this.currentFilter = type;
-    if (type === '') {
-      this.filteredComments = this.commentsFilteredByTime;
+  refreshFiltering(): void {
+    this.commentsWrittenByUsers.clear();
+    for (const comment of this.comments) {
+      let set = this.commentsWrittenByUsers.get(comment.creatorId);
+      if (!set) {
+        set = new Set<string>();
+        this.commentsWrittenByUsers.set(comment.creatorId, set);
+      }
+      set.add(comment.id);
+    }
+    this.isLoading = false;
+    if (this.search) {
+      this.filteredComments = this.filter.filterCommentsBySearch(this.comments);
       return;
     }
-    this.filteredComments = this.commentsFilteredByTime.filter(c => {
-      switch (type) {
-        case this.correct:
-          return c.correct === CorrectWrong.CORRECT ? 1 : 0;
-        case this.wrong:
-          return c.correct === CorrectWrong.WRONG ? 1 : 0;
-        case this.favorite:
-          return c.favorite;
-        case this.bookmark:
-          return c.bookmark;
-        case this.read:
-          return c.read;
-        case this.unread:
-          return !c.read;
-        case this.userNumber:
-          return c.userNumber === compare;
-      }
-    });
-    this.hideCommentsList = true;
-    this.sortComments(this.currentSort);
-  }
-
-  clickedUserNumber(usrNumber: number): void {
-    this.filterComments(this.userNumber, usrNumber);
+    this.commentsFilteredByTime = this.filter.filterCommentsByTime(this.comments);
+    this.hideCommentsList = !!this.filter.filterType;
+    this.filteredComments = this.hideCommentsList ?
+      this.filter.filterCommentsByType(this.commentsFilteredByTime) : this.commentsFilteredByTime;
+    this.filter.sortCommentsBySortType(this.filteredComments);
   }
 
-  sort(array: any[], type: string): void {
-    array.sort((a, b) => {
-      if (type === this.voteasc) {
-        return (a.score > b.score) ? 1 : (b.score > a.score) ? -1 : 0;
-      } else if (type === this.votedesc) {
-        return (b.score > a.score) ? 1 : (a.score > b.score) ? -1 : 0;
-      }
-      const dateA = new Date(a.timestamp), dateB = new Date(b.timestamp);
-      if (type === this.time) {
-        return (+dateB > +dateA) ? 1 : (+dateA > +dateB) ? -1 : 0;
-      }
-    });
+  applyFilterByKey(type: FilterTypeKey, compare?: any): void {
+    this.pageIndex = 0;
+    this.filter.filterType = FilterType[type];
+    this.filter.filterCompare = compare;
+    this.refreshFiltering();
   }
 
-  sortComments(type: string): void {
-    if (this.hideCommentsList === true) {
-      this.sort(this.filteredComments, type);
-    } else {
-      this.sort(this.commentsFilteredByTime, type);
-    }
-    this.currentSort = type;
+  applySortingByKey(type: SortTypeKey) {
+    this.filter.sortType = SortType[type];
+    this.refreshFiltering();
   }
 
   switchToCommentList(): void {
@@ -411,44 +398,12 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     }
     this.router.navigate([`/${role}/room/${this.room.shortId}/comments`]);
   }
+
   setTimePeriod(period?: Period) {
     if (period) {
-      this.period = period;
-      this.fromNow = null;
+      this.filter.period = period;
+      this.filter.fromNow = null;
     }
-    const currentTime = new Date();
-    const hourInSeconds = 3600000;
-    let periodInSeconds;
-    if (this.period !== Period.all) {
-      switch (this.period) {
-        case Period.fromNow:
-          if (!this.fromNow) {
-            this.fromNow = new Date().getTime();
-          }
-          break;
-        case Period.oneHour:
-          periodInSeconds = hourInSeconds;
-          break;
-        case Period.threeHours:
-          periodInSeconds = hourInSeconds * 2;
-          break;
-        case Period.oneDay:
-          periodInSeconds = hourInSeconds * 24;
-          break;
-        case Period.oneWeek:
-          periodInSeconds = hourInSeconds * 168;
-          break;
-        case Period.twoWeeks:
-          periodInSeconds = hourInSeconds * 336;
-          break;
-      }
-      this.commentsFilteredByTime = this.comments
-        .filter(c => new Date(c.timestamp).getTime() >=
-          (this.period === Period.fromNow ? this.fromNow : (currentTime.getTime() - periodInSeconds)));
-    } else {
-      this.commentsFilteredByTime = this.comments;
-    }
-
-    this.filterComments(this.currentFilter);
+    this.refreshFiltering();
   }
 }
diff --git a/src/app/components/shared/comment-list/comment-list.component.html b/src/app/components/shared/comment-list/comment-list.component.html
index e9ad89156959299c38bc985b8539cbe57f27ff33..fbff84b4b2518059e2fc911ddab877635aee8081 100644
--- a/src/app/components/shared/comment-list/comment-list.component.html
+++ b/src/app/components/shared/comment-list/comment-list.component.html
@@ -7,8 +7,8 @@
   <button id="filter-close-button"
           mat-icon-button
           class="searchBarButton"
-          *ngIf="currentFilter !== ''"
-          (click)="filterComments('');"
+          *ngIf="filter.filterType"
+          (click)="applyFilterByKey(null)"
           aria-labelledby="close_filter">
     <mat-icon class="searchBarIcon red">close</mat-icon>
   </button>
@@ -22,14 +22,14 @@
          [ngClass]="{'desktop-input': deviceType === 'desktop',
    'mobile-input': deviceType === 'mobile' && !search, 'mobile-input-2': deviceType === 'mobile' && search }"
          (input)="searchComments()"
-         [(ngModel)]="searchInput"
+         [(ngModel)]="filter.currentSearch"
          [placeholder]="searchPlaceholder"
          aria-labelledby="search-box-input-description">
   <button id="search_close-button"
           mat-icon-button
           class="searchBarButton close red"
-          *ngIf="searchInput !== '' || search"
-          (click)="hideCommentsList=false; searchInput = ''; search = false;"
+          *ngIf="filter.currentSearch || search"
+          (click)="abortSearch()"
           aria-labelledby="close_search">
     <mat-icon>close</mat-icon>
   </button>
@@ -49,7 +49,7 @@
 
     <button mat-icon-button
             class="searchBarButton"
-            (click)="activateSearch(); filterComments('')"
+            (click)="activateSearch(); applyFilterByKey(null)"
             *ngIf="deviceType === 'mobile' && !search && comments && comments.length > 0">
       <mat-icon class="searchBarIcon">search</mat-icon>
     </button>
@@ -81,7 +81,7 @@
             aria-labelledby="time_settings"
             *ngIf="!searchBox.value && comments && comments.length > 0 && !search"
             [matMenuTriggerFor]="timeMenu"
-            [ngClass]="{'active-filter': period !== 'time-all'}"
+            [ngClass]="{'active-filter': filter.period !== 'time-all'}"
             matTooltip="{{ 'comment-list.select-time' | translate }}">
       <mat-icon class="searchBarIcon">history</mat-icon>
     </button>
@@ -91,7 +91,7 @@
             aria-labelledby="pause"
             class="freezeButton"
             *ngIf="!searchBox.value && !search && !freeze && comments.length > 2"
-            (click)="pauseCommentStream()"
+            (click)="activateCommentStream(true)"
             matTooltip="{{ 'comment-list.pause-comments' | translate }}">
       <mat-icon class="freezeIcon">pause</mat-icon>
     </button>
@@ -101,7 +101,7 @@
             aria-labelledby="play"
             class="freezeButton"
             *ngIf="!searchBox.value && !search && freeze"
-            (click)="playCommentStream()"
+            (click)="activateCommentStream(false)"
             matTooltip="{{ 'comment-list.play-comments' | translate }}">
       <mat-icon class="playIcon">play_arrow</mat-icon>
     </button>
@@ -114,7 +114,7 @@
       <button mat-menu-item
               (click)="setTimePeriod(periodItem)"
               class="period"
-              [ngClass]="{'selected': periodItem === period}"
+              [ngClass]="{'selected': periodItem === filter.period}"
               aria-labelledby="{{periodItem}}">
         <span>{{ ('comment-list.select-' + periodItem) | translate }}</span>
       </button>
@@ -125,24 +125,24 @@
             xPosition="before">
 
     <button mat-menu-item
-            (click)="sortComments(time)"
+            (click)="applySortingByKey('time')"
             aria-labelledby="access_time">
-      <mat-icon [ngClass]="{time: 'timesort'}[currentSort]">update</mat-icon>
-      <span [ngClass]="{time: 'timesort'}[currentSort]">{{ 'comment-list.sort-list-time' | translate }}</span>
+      <mat-icon [ngClass]="{time: 'timesort'}[filter.sortType]">update</mat-icon>
+      <span [ngClass]="{time: 'timesort'}[filter.sortType]">{{ 'comment-list.sort-list-time' | translate }}</span>
     </button>
 
     <button mat-menu-item
-            (click)="sortComments(votedesc)"
+            (click)="applySortingByKey('votedesc')"
             aria-labelledby="keyboard_arrow_up">
-      <mat-icon [ngClass]="{votedesc: 'up'}[currentSort]">thumb_up</mat-icon>
-      <span [ngClass]="{votedesc: 'up'}[currentSort]">{{ 'comment-list.sort-vote-asc' | translate }}</span>
+      <mat-icon [ngClass]="{votedesc: 'up'}[filter.sortType]">thumb_up</mat-icon>
+      <span [ngClass]="{votedesc: 'up'}[filter.sortType]">{{ 'comment-list.sort-vote-asc' | translate }}</span>
     </button>
 
     <button mat-menu-item
-            (click)="sortComments(voteasc)"
+            (click)="applySortingByKey('voteasc')"
             aria-labelledby="keyboard_arrow_down">
-      <mat-icon [ngClass]="{voteasc: 'down'}[currentSort]">thumb_down</mat-icon>
-      <span [ngClass]="{voteasc: 'down'}[currentSort]">{{ 'comment-list.sort-vote-desc' | translate }}</span>
+      <mat-icon [ngClass]="{voteasc: 'down'}[filter.sortType]">thumb_down</mat-icon>
+      <span [ngClass]="{voteasc: 'down'}[filter.sortType]">{{ 'comment-list.sort-vote-desc' | translate }}</span>
     </button>
 
   </mat-menu>
@@ -152,53 +152,53 @@
     <div>
 
       <button mat-menu-item
-              (click)="filterComments(favorite)"
+              (click)="applyFilterByKey('favorite')"
               aria-labelledby="grade">
         <mat-icon class="star"
-                  [ngClass]="{favorite: 'favorite-icon'}[currentFilter]">grade
+                  [ngClass]="{favorite: 'favorite-icon'}[filter.filterType]">grade
         </mat-icon>
         <span
-          [ngClass]="{favorite: 'favorite-icon'}[currentFilter]">{{ 'comment-list.filter-favorite' | translate }}</span>
+          [ngClass]="{favorite: 'favorite-icon'}[filter.filterType]">{{ 'comment-list.filter-favorite' | translate }}</span>
       </button>
 
       <button mat-menu-item
-              (click)="filterComments(bookmark)"
+              (click)="applyFilterByKey('bookmark')"
               aria-labelledby="bookmark">
         <mat-icon class="bookmark"
-                  [ngClass]="{bookmark: 'bookmark-icon'}[currentFilter]">bookmark
+                  [ngClass]="{bookmark: 'bookmark-icon'}[filter.filterType]">bookmark
         </mat-icon>
         <span
-          [ngClass]="{bookmark: 'bookmark-icon'}[currentFilter]">{{ 'comment-list.filter-bookmark' | translate }}</span>
+          [ngClass]="{bookmark: 'bookmark-icon'}[filter.filterType]">{{ 'comment-list.filter-bookmark' | translate }}</span>
       </button>
 
       <button mat-menu-item
               (focus)="hideCommentsList=true"
-              (click)="filterComments(answer)"
+              (click)="applyFilterByKey('answer')"
               aria-labelledby="comment">
         <mat-icon class="answer"
-                  [ngClass]="{answer: 'answered-icon'}[currentFilter]">comment
+                  [ngClass]="{answer: 'answered-icon'}[filter.filterType]">comment
         </mat-icon>
         <span
-          [ngClass]="{answer: 'answered-icon'}[currentFilter]">{{ 'comment-list.filter-answered' | translate }}</span>
+          [ngClass]="{answer: 'answered-icon'}[filter.filterType]">{{ 'comment-list.filter-answered' | translate }}</span>
       </button>
 
       <button mat-menu-item
               (focus)="hideCommentsList=true"
-              (click)="filterComments(unanswered)"
+              (click)="applyFilterByKey('unanswered')"
               aria-labelledby="comment">
         <mat-icon class="unanswered"
-                  [ngClass]="{unanswered: 'unanswered-icon'}[currentFilter]">comment
+                  [ngClass]="{unanswered: 'unanswered-icon'}[filter.filterType]">comment
         </mat-icon>
         <span
-          [ngClass]="{unanswered: 'unanswered-icon'}[currentFilter]">{{ 'comment-list.filter-unanswered' | translate }}</span>
+          [ngClass]="{unanswered: 'unanswered-icon'}[filter.filterType]">{{ 'comment-list.filter-unanswered' | translate }}</span>
       </button>
 
       <button mat-menu-item
               (focus)="hideCommentsList=true"
-              (click)="filterComments(owner)"
+              (click)="applyFilterByKey('owner')"
               aria-labelledby="comment">
-        <mat-icon [ngClass]="{owner: 'owner-icon'}[currentFilter]">person_pin_circle</mat-icon>
-        <span [ngClass]="{owner: 'owner-icon'}[currentFilter]">{{ 'comment-list.filter-owner' | translate }}</span>
+        <mat-icon [ngClass]="{owner: 'owner-icon'}[filter.filterType]">person_pin_circle</mat-icon>
+        <span [ngClass]="{owner: 'owner-icon'}[filter.filterType]">{{ 'comment-list.filter-owner' | translate }}</span>
       </button>
 
       <!--
@@ -227,7 +227,7 @@
 
       <button mat-menu-item
               (focus)="hideCommentsList=false"
-              (click)="sortComments(currentSort); filterComments('')"
+              (click)="applyFilterByKey(null)"
               aria-labelledby="close">
         <mat-icon>close</mat-icon>
         <span>{{ 'comment-list.filter-reset' | translate }}</span>
@@ -275,9 +275,9 @@
                [user]="user"
                [disabled]="!commentsEnabled"
                [commentsWrittenByUser]="commentsWrittenByUsers.get(current.creatorId).size"
-               (clickedOnTag)="clickedOnTag($event)"
-               (clickedUserNumber)="clickedUserNumber($event)"
-               (clickedOnKeyword)="clickedOnKeyword($event)"
+               (clickedOnTag)="applyFilterByKey('tag', $event)"
+               (clickedUserNumber)="applyFilterByKey('userNumber', $event)"
+               (clickedOnKeyword)="applyFilterByKey('keyword', $event)"
                (votedComment)="votedComment($event)">
   </app-comment>
   <ars-mat-paginator
@@ -297,7 +297,7 @@
 
 <!-- No Questions Present -->
 <div
-  *ngIf="comments && (commentsFilteredByTime.length < 1 && period === 'time-all' || comments.length === 0) && !isLoading"
+  *ngIf="comments && (commentsFilteredByTime.length < 1 && filter.period === 'time-all' || comments.length === 0) && !isLoading"
   fxLayout="row"
   fxLayoutAlign="center center"
   class="no-comments">
@@ -305,7 +305,7 @@
 </div>
 
 <div *ngIf="(filteredComments && filteredComments.length === 0 && hideCommentsList)
-            || (comments && commentsFilteredByTime.length === 0 && period !== 'time-all') && !isLoading && comments.length > 0"
+            || (comments && commentsFilteredByTime.length === 0 && filter.period !== 'time-all') && !isLoading && comments.length > 0"
      fxLayout="row"
      fxLayoutAlign="center center"
      class="no-comments">
diff --git a/src/app/components/shared/comment-list/comment-list.component.ts b/src/app/components/shared/comment-list/comment-list.component.ts
index 1e73a75e1abb5c8ba331c4848ea5ded383b1c393..ca87614756f787d498bf547f5f8a0f50e3cf0d20 100644
--- a/src/app/components/shared/comment-list/comment-list.component.ts
+++ b/src/app/components/shared/comment-list/comment-list.component.ts
@@ -11,7 +11,6 @@ import { Room } from '../../../models/room';
 import { RoomService } from '../../../services/http/room.service';
 import { VoteService } from '../../../services/http/vote.service';
 import { NotificationService } from '../../../services/util/notification.service';
-import { CorrectWrong } from '../../../models/correct-wrong.enum';
 import { LiveAnnouncer } from '@angular/cdk/a11y';
 import { EventService } from '../../../services/util/event.service';
 import { Subscription } from 'rxjs';
@@ -34,6 +33,7 @@ import { ActiveUserService } from '../../../services/http/active-user.service';
 import { OnboardingService } from '../../../services/util/onboarding.service';
 import { WorkerDialogComponent } from '../_dialogs/worker-dialog/worker-dialog.component';
 import { PageEvent } from '@angular/material/paginator';
+import { CommentListFilter, FilterType, FilterTypeKey, SortType, SortTypeKey } from './comment-list.filter';
 
 export interface CommentListData {
   currentFilter: CommentFilter;
@@ -60,60 +60,32 @@ export class CommentListComponent implements OnInit, OnDestroy {
   deviceType: string;
   isSafari: string;
   isLoading = true;
-  voteasc = 'voteasc';
-  votedesc = 'votedesc';
-  time = 'time';
-  currentSort: string;
-  read = 'read';
-  unread = 'unread';
-  favorite = 'favorite';
-  correct = 'correct';
-  wrong = 'wrong';
-  ack = 'ack';
-  bookmark = 'bookmark';
-  moderator = 'moderator';
-  lecturer = 'lecturer';
-  tag = 'tag';
-  selectedTag = '';
-  userNumber = 'userNumber';
-  keyword = 'keyword';
-  selectedKeyword = '';
-  answer = 'answer';
-  unanswered = 'unanswered';
-  owner = 'owner';
-  currentFilter = '';
-  currentFilterCompare: any = null;
   commentVoteMap = new Map<string, Vote>();
   scroll = false;
   scrollExtended = false;
-  searchInput = '';
   search = false;
   searchPlaceholder = '';
   moderationEnabled = true;
   directSend = true;
-  thresholdEnabled = false;
   newestComment: string;
   freeze = false;
   commentStream: Subscription;
   periodsList = Object.values(Period);
   headerInterface = null;
-  period: Period = Period.twoWeeks;
-  fromNow: number;
-  moderatorIds: string[];
   commentsEnabled: boolean;
-  userNumberSelection = 0;
   createCommentWrapper: CreateCommentWrapper = null;
   isJoyrideActive = false;
   focusCommentId = '';
   activeUsers = 0;
-  commentsWrittenByUsers: Map<string, Set<string>> = new Map<string, Set<string>>();
-  private _subscriptionEventServiceTagConfig = null;
-  private _subscriptionEventServiceRoomData = null;
-  private _subscriptionRoomService = null;
   pageIndex = 0;
   pageSize = 10;
   pageSizeOptions = [5, 10, 25];
   showFirstLastButtons = true;
+  commentsWrittenByUsers: Map<string, Set<string>> = new Map<string, Set<string>>();
+  filter: CommentListFilter;
+  private _subscriptionEventServiceTagConfig = null;
+  private _subscriptionEventServiceRoomData = null;
+  private _subscriptionRoomService = null;
 
   constructor(
     private commentService: CommentService,
@@ -144,9 +116,10 @@ export class CommentListComponent implements OnInit, OnDestroy {
         this.searchPlaceholder = msg;
       });
     });
+    this.filter = CommentListFilter.loadCurrentFilter();
   }
 
-  handlePageEvent(e:PageEvent){
+  handlePageEvent(e: PageEvent) {
     this.pageIndex = e.pageIndex;
     this.pageSize = e.pageSize;
   }
@@ -154,7 +127,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
   initNavigation() {
     this._subscriptionEventServiceTagConfig = this.eventService.on<string>('setTagConfig').subscribe(tag => {
       this.setTimePeriod(Period.all);
-      this.clickedOnKeyword(tag);
+      this.applyFilterByKey('keyword', tag);
     });
     this._subscriptionEventServiceRoomData = this.eventService.on<string>('pushCurrentRoomData').subscribe(_ => {
       this.eventService.broadcast('currentRoomData', {
@@ -239,6 +212,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
     this.authenticationService.watchUser.subscribe(newUser => {
       if (newUser) {
         this.user = newUser;
+        this.filter.updateUserId(this.user.id);
         if (this.userRole === UserRole.PARTICIPANT) {
           this.voteService.getByRoomIdAndUserID(this.roomId, this.user.id).subscribe(votes => {
             for (const v of votes) {
@@ -254,21 +228,13 @@ export class CommentListComponent implements OnInit, OnDestroy {
       this.authenticationService.checkAccess(this.shortId);
       this.authenticationService.guestLogin(UserRole.PARTICIPANT).subscribe(r => {
         this.roomService.getRoomByShortId(this.shortId).subscribe(room => {
-          this.room = room;
-          this.roomId = room.id;
+          this.receiveRoom(room);
           this._subscriptionRoomService = this.wsRoomService.getRoomStream(this.roomId).subscribe(msg => {
             const message = JSON.parse(msg.body);
             if (message.type === 'RoomPatched') {
-              this.room = message.payload.changes;
-              this.roomId = this.room.id;
-              this.moderationEnabled = this.room.moderated;
-              this.directSend = this.room.directSend;
-              this.commentsEnabled = (this.userRole > UserRole.PARTICIPANT) || !this.room.questionsBlocked;
+              this.receiveRoom(message.payload.changes);
             }
           });
-          this.moderationEnabled = this.room.moderated;
-          this.directSend = this.room.directSend;
-          this.commentsEnabled = (this.userRole > UserRole.PARTICIPANT) || !this.room.questionsBlocked;
           this.createCommentWrapper = new CreateCommentWrapper(this.translateService,
             this.notificationService, this.commentService, this.dialog, this.room);
           localStorage.setItem('moderationEnabled', JSON.stringify(this.moderationEnabled));
@@ -277,8 +243,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
             this.authenticationService.setAccess(this.shortId, UserRole.PARTICIPANT);
           }
           this.moderatorService.get(this.roomId).subscribe(list => {
-            this.moderatorIds = list.map(m => m.accountId);
-            this.moderatorIds.push(this.room.ownerId);
+            this.filter.updateModerators(list.map(m => m.accountId));
 
             this.roomDataService.getRoomData(this.room.id).subscribe(comments => {
               if (comments === null) {
@@ -286,7 +251,11 @@ export class CommentListComponent implements OnInit, OnDestroy {
               }
               this.comments = comments;
               this.generateKeywordsIfEmpty();
-              this.getComments();
+              if (this.filter.currentSearch) {
+                this.search = true;
+                this.hideCommentsList = true;
+              }
+              this.refreshFiltering();
               this.eventService.broadcast('commentListCreated', null);
               this.isJoyrideActive = this.onboardingService.startDefaultTour();
             });
@@ -295,7 +264,6 @@ export class CommentListComponent implements OnInit, OnDestroy {
         });
       });
     });
-    this.currentSort = this.votedesc;
     this.hideCommentsList = false;
     this.translateService.use(localStorage.getItem('currentLang'));
     this.deviceType = localStorage.getItem('deviceType');
@@ -306,6 +274,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
   }
 
   ngOnDestroy() {
+    this.filter.save();
     if (!this.freeze && this.commentStream) {
       this.commentStream.unsubscribe();
     }
@@ -336,31 +305,47 @@ export class CommentListComponent implements OnInit, OnDestroy {
 
   searchComments(): void {
     this.search = true;
-    if (this.searchInput) {
-      if (this.searchInput.length > 1) {
-        this.hideCommentsList = true;
-        this.filteredComments = this.comments
-          .filter(c => this.checkIfIncludesKeyWord(c.body, this.searchInput)
-            || (!!c.answer ? this.checkIfIncludesKeyWord(c.answer, this.searchInput) : false));
-      }
-    } else if (this.searchInput.length === 0 && this.currentFilter === '') {
+    if (this.filter.currentSearch) {
+      this.hideCommentsList = true;
+      this.filteredComments = this.filter.filterCommentsBySearch(this.comments);
+    } else if (!this.filter.filterType) {
       this.hideCommentsList = false;
     }
   }
 
-  checkIfIncludesKeyWord(body: string, keyword: string) {
-    return body.toLowerCase().includes(keyword.toLowerCase());
-  }
-
   activateSearch() {
     this.search = true;
     this.searchField.nativeElement.focus();
   }
 
-  getComments(): void {
-    this.thresholdEnabled = !!this.room.threshold;
+  abortSearch() {
+    this.hideCommentsList = false;
+    this.filter.currentSearch = '';
+    this.search = false;
+    this.refreshFiltering();
+  }
+
+  refreshFiltering(): void {
+    this.commentsWrittenByUsers.clear();
+    for (const comment of this.comments) {
+      let set = this.commentsWrittenByUsers.get(comment.creatorId);
+      if (!set) {
+        set = new Set<string>();
+        this.commentsWrittenByUsers.set(comment.creatorId, set);
+      }
+      set.add(comment.id);
+    }
     this.isLoading = false;
-    this.setTimePeriod();
+    this.commentsFilteredByTime = this.filter.filterCommentsByTime(this.comments);
+    this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')');
+    if (this.search) {
+      this.filteredComments = this.filter.filterCommentsBySearch(this.comments);
+      return;
+    }
+    this.hideCommentsList = !!this.filter.filterType;
+    this.filteredComments = this.hideCommentsList ?
+      this.filter.filterCommentsByType(this.commentsFilteredByTime) : this.commentsFilteredByTime;
+    this.filter.sortCommentsBySortType(this.filteredComments);
   }
 
   getVote(comment: Comment): Vote {
@@ -373,115 +358,16 @@ export class CommentListComponent implements OnInit, OnDestroy {
     this.dialog.closeAll();
   }
 
-  filterComments(type: string, compare?: any): void {
-    this.pageIndex=0;
-    this.currentFilter = type;
-    this.currentFilterCompare = compare;
-    if (type === '') {
-      this.filteredComments = this.commentsFilteredByTime;
-      this.hideCommentsList = false;
-      this.currentFilter = '';
-      this.selectedTag = '';
-      this.selectedKeyword = '';
-      this.userNumberSelection = 0;
-      this.sortComments(this.currentSort);
-      return;
-    }
-    this.filteredComments = this.commentsFilteredByTime.filter(c => {
-      switch (type) {
-        case this.correct:
-          return c.correct === CorrectWrong.CORRECT ? 1 : 0;
-        case this.wrong:
-          return c.correct === CorrectWrong.WRONG ? 1 : 0;
-        case this.favorite:
-          return c.favorite;
-        case this.bookmark:
-          return c.bookmark;
-        case this.read:
-          return c.read;
-        case this.unread:
-          return !c.read;
-        case this.tag:
-          this.selectedTag = compare;
-          return c.tag === compare;
-        case this.userNumber:
-          return c.userNumber === compare;
-        case this.keyword:
-          this.selectedKeyword = compare;
-          const isInQuestioner = c.keywordsFromQuestioner ? c.keywordsFromQuestioner.findIndex(k => k.text === compare) >= 0 : false;
-          const isInSpacy = c.keywordsFromSpacy ? c.keywordsFromSpacy.findIndex(k => k.text === compare) >= 0 : false;
-          return isInQuestioner || isInSpacy;
-        case this.answer:
-          return c.answer;
-        case this.unanswered:
-          return !c.answer;
-        case this.owner:
-          return c.creatorId === this.user.id;
-        case this.moderator:
-          return this.moderatorIds.includes(c.creatorId);
-        case this.lecturer:
-          return c.createdFromLecturer;
-      }
-    });
-    const testForModerator = () => {
-      this.comments.forEach(e => {
-        this.commentService.role(e).subscribe(i => {
-          console.log(e, i);
-        });
-      });
-    };
-    if (type === 'moderator') {
-      console.log(
-        'TEST moderator',
-        this.moderatorIds,
-        this.user,
-        this.room
-      );
-      testForModerator();
-    }
-    this.hideCommentsList = true;
-    this.sortComments(this.currentSort);
-  }
-
-  sort(array: any[], type: string): any[] {
-    const sortedArray = array.sort((a, b) => {
-      if (type === this.voteasc) {
-        return (a.score > b.score) ? 1 : (b.score > a.score) ? -1 : 0;
-      } else if (type === this.votedesc) {
-        return (b.score > a.score) ? 1 : (a.score > b.score) ? -1 : 0;
-      } else if (type === this.time) {
-        const dateA = new Date(a.timestamp);
-        const dateB = new Date(b.timestamp);
-        return (+dateB > +dateA) ? 1 : (+dateA > +dateB) ? -1 : 0;
-      }
-    });
-    return sortedArray.sort((a, b) => this.isCreatedByModeratorOrCreator(a) ? -1 : this.isCreatedByModeratorOrCreator(b) ? 1 : 0);
+  applyFilterByKey(type: FilterTypeKey, compare?: any): void {
+    this.pageIndex = 0;
+    this.filter.filterType = FilterType[type];
+    this.filter.filterCompare = compare;
+    this.refreshFiltering();
   }
 
-  isCreatedByModeratorOrCreator(comment: Comment): boolean {
-    return this.moderatorIds.indexOf(comment.creatorId) > -1;
-  }
-
-  sortComments(type: string): void {
-    if (this.hideCommentsList === true) {
-      this.filteredComments = this.sort(this.filteredComments, type);
-    } else {
-      this.setComments(this.sort(this.commentsFilteredByTime, type));
-    }
-    this.currentSort = type;
-  }
-
-  clickedOnTag(tag: string): void {
-    this.filterComments(this.tag, tag);
-  }
-
-  clickedOnKeyword(keyword: string): void {
-    this.filterComments(this.keyword, keyword);
-  }
-
-  clickedUserNumber(usrNumber: number): void {
-    this.userNumberSelection = usrNumber;
-    this.filterComments(this.userNumber, usrNumber);
+  applySortingByKey(type: SortTypeKey) {
+    this.filter.sortType = SortType[type];
+    this.refreshFiltering();
   }
 
   votedComment(voteInfo: string) {
@@ -489,34 +375,24 @@ export class CommentListComponent implements OnInit, OnDestroy {
     setTimeout(() => this.focusCommentId = voteInfo, 100);
   }
 
-  pauseCommentStream() {
-    this.freeze = true;
-    this.roomDataService.getRoomData(this.roomId, true).subscribe(comments => {
-      if (comments === null) {
-        return;
-      }
-      this.comments = comments;
-      this.setComments(comments);
-      this.getComments();
-    });
-    this.commentStream.unsubscribe();
-    this.translateService.get('comment-list.comment-stream-stopped').subscribe(msg => {
-      this.notificationService.show(msg);
-    });
-  }
-
-  playCommentStream() {
-    this.freeze = false;
-    this.roomDataService.getRoomData(this.roomId).subscribe(comments => {
+  activateCommentStream(freezed: boolean) {
+    this.freeze = freezed;
+    this.roomDataService.getRoomData(this.roomId, freezed).subscribe(comments => {
       if (comments === null) {
         return;
       }
       this.comments = comments;
-      this.setComments(comments);
-      this.getComments();
+      this.refreshFiltering();
     });
-    this.subscribeCommentStream();
-    this.translateService.get('comment-list.comment-stream-started').subscribe(msg => {
+    let message: string;
+    if (freezed) {
+      this.commentStream?.unsubscribe();
+      message = 'comment-list.comment-stream-stopped';
+    } else {
+      this.subscribeCommentStream();
+      message = 'comment-list.comment-stream-started';
+    }
+    this.translateService.get(message).subscribe(msg => {
       this.notificationService.show(msg);
     });
   }
@@ -524,17 +400,13 @@ export class CommentListComponent implements OnInit, OnDestroy {
   subscribeCommentStream() {
     this.commentStream = this.roomDataService.receiveUpdates([
       { type: 'CommentCreated', finished: true },
-      { type: 'CommentPatched', subtype: this.favorite },
-      { type: 'CommentPatched', subtype: 'score' },
+      { type: 'CommentPatched', subtype: 'favorite' },
       { finished: true }
     ]).subscribe(update => {
       if (update.type === 'CommentCreated') {
         this.announceNewComment(update.comment.body);
-        this.setComments(this.comments);
       } else if (update.type === 'CommentPatched') {
-        if (update.subtype === 'score') {
-          this.getComments();
-        } else if (update.subtype === this.favorite) {
+        if (update.subtype === 'favorite') {
           if (this.user.id === update.comment.creatorId && update.comment.favorite) {
             this.translateService.get('comment-list.comment-got-favorited').subscribe(ret => {
               this.notificationService.show(ret);
@@ -543,10 +415,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
         }
       }
       if (update.finished) {
-        this.setTimePeriod();
-        if (this.hideCommentsList) {
-          this.searchComments();
-        }
+        this.refreshFiltering();
       }
     });
   }
@@ -555,20 +424,6 @@ export class CommentListComponent implements OnInit, OnDestroy {
     this.router.navigate([`/moderator/room/${this.room.shortId}/moderator/comments`]);
   }
 
-  setComments(comments: Comment[]) {
-    this.commentsWrittenByUsers.clear();
-    for (const comment of this.comments) {
-      let set = this.commentsWrittenByUsers.get(comment.creatorId);
-      if (!set) {
-        set = new Set<string>();
-        this.commentsWrittenByUsers.set(comment.creatorId, set);
-      }
-      set.add(comment.id);
-    }
-    this.commentsFilteredByTime = comments;
-    this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')');
-  }
-
   writeComment() {
     this.createCommentWrapper.openCreateDialog(this.user)
       .subscribe(comment => this.focusCommentId = comment && comment.id);
@@ -594,57 +449,31 @@ export class CommentListComponent implements OnInit, OnDestroy {
     }, 450);
   }
 
-  public setTimePeriod(period?: Period) {
+  setTimePeriod(period?: Period) {
     if (period) {
-      this.period = period;
-      this.fromNow = null;
-    }
-    const comments = this.thresholdEnabled ? this.comments.filter(x => x.score >= this.room.threshold) : this.comments;
-    const currentTime = new Date();
-    const hourInSeconds = 3600000;
-    let periodInSeconds;
-    if (this.period !== Period.all) {
-      switch (this.period) {
-        case Period.fromNow:
-          if (!this.fromNow) {
-            this.fromNow = new Date().getTime();
-          }
-          break;
-        case Period.oneHour:
-          periodInSeconds = hourInSeconds;
-          break;
-        case Period.threeHours:
-          periodInSeconds = hourInSeconds * 2;
-          break;
-        case Period.oneDay:
-          periodInSeconds = hourInSeconds * 24;
-          break;
-        case Period.oneWeek:
-          periodInSeconds = hourInSeconds * 168;
-          break;
-        case Period.twoWeeks:
-          periodInSeconds = hourInSeconds * 336;
-          break;
-      }
-      this.commentsFilteredByTime = comments
-        .filter(c => new Date(c.timestamp).getTime() >=
-          (this.period === Period.fromNow ? this.fromNow : (currentTime.getTime() - periodInSeconds)));
-    } else {
-      this.commentsFilteredByTime = comments;
+      this.filter.period = period;
+      this.filter.fromNow = null;
     }
+    this.refreshFiltering();
+  }
 
-    this.filterComments(this.currentFilter, this.currentFilterCompare);
-    this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')');
+  private receiveRoom(room: Room) {
+    this.room = room;
+    this.filter.updateRoom(room);
+    this.roomId = room.id;
+    this.moderationEnabled = room.moderated;
+    this.directSend = room.directSend;
+    this.commentsEnabled = (this.userRole > UserRole.PARTICIPANT) || !room.questionsBlocked;
   }
 
   private getCurrentFilter(): CommentFilter {
     const filter = new CommentFilter();
-    filter.filterSelected = this.currentFilter;
+    filter.filterSelected = this.filter.filterType;
     filter.paused = this.freeze;
-    filter.periodSet = this.period;
-    filter.keywordSelected = this.selectedKeyword;
-    filter.tagSelected = this.selectedTag;
-    filter.userNumberSelected = this.userNumberSelection;
+    filter.periodSet = this.filter.period;
+    filter.keywordSelected = this.filter.filterCompare;
+    filter.tagSelected = this.filter.filterCompare;
+    filter.userNumberSelected = this.filter.filterCompare;
 
     if (filter.periodSet === Period.fromNow) {
       filter.timeStampNow = new Date().getTime();
diff --git a/src/app/components/shared/comment-list/comment-list.filter.ts b/src/app/components/shared/comment-list/comment-list.filter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..016fe74c8a43ccab2dddf222c955b3d0930ed64b
--- /dev/null
+++ b/src/app/components/shared/comment-list/comment-list.filter.ts
@@ -0,0 +1,248 @@
+import { Period } from '../../../utils/filter-options';
+import { Comment } from '../../../models/comment';
+import { CorrectWrong } from '../../../models/correct-wrong.enum';
+import { Room } from '../../../models/room';
+
+export enum FilterType {
+  voteasc = 'voteasc',
+  votedesc = 'votedesc',
+  time = 'time',
+  read = 'read',
+  unread = 'unread',
+  favorite = 'favorite',
+  correct = 'correct',
+  wrong = 'wrong',
+  ack = 'ack',
+  bookmark = 'bookmark',
+  moderator = 'moderator',
+  lecturer = 'lecturer',
+  tag = 'tag',
+  userNumber = 'userNumber',
+  keyword = 'keyword',
+  answer = 'answer',
+  unanswered = 'unanswered',
+  owner = 'owner',
+}
+
+export type FilterTypeKey = keyof typeof FilterType;
+
+export enum SortType {
+  voteasc = 'voteasc',
+  votedesc = 'votedesc',
+  time = 'time'
+}
+
+export type SortTypeKey = keyof typeof SortType;
+
+const DEFAULT_PERIOD = Period.all;
+const DEFAULT_SORT = SortType.time;
+
+export class CommentListFilter {
+  //own properties
+  period: Period;
+  fromNow: number;
+  filterType: FilterType;
+  filterCompare: any;
+  sortType: SortType;
+  currentSearch: string;
+  //dependencies to other values
+  private userId: string;
+  private moderatorIds: Set<string>;
+  private threshold: number;
+  private ownerId: string;
+  private lastRoomId: string;
+
+  constructor(obj) {
+    if (!obj) {
+      this.resetToDefault();
+      return;
+    }
+    this.period = obj.period;
+    this.fromNow = obj.fromNow;
+    this.filterType = obj.filterType;
+    this.filterCompare = obj.filterCompare;
+    this.sortType = obj.sortType;
+    this.currentSearch = obj.currentSearch;
+    this.lastRoomId = obj.lastRoomId;
+  }
+
+  static loadCurrentFilter(): CommentListFilter {
+    return new CommentListFilter(JSON.parse(localStorage.getItem('currentFilter')));
+  }
+
+  resetToDefault() {
+    this.period = DEFAULT_PERIOD;
+    this.fromNow = null;
+    this.filterType = null;
+    this.filterCompare = null;
+    this.sortType = DEFAULT_SORT;
+    this.currentSearch = '';
+  }
+
+  updateRoom(room: Room) {
+    if (room.id !== this.lastRoomId) {
+      this.resetToDefault();
+    }
+    this.ownerId = room.ownerId;
+    this.lastRoomId = room.id;
+    this.threshold = room.threshold;
+  }
+
+  updateUserId(userId: string) {
+    this.userId = userId;
+  }
+
+  updateModerators(moderators: string[]) {
+    this.moderatorIds = new Set<string>([...moderators]);
+  }
+
+  save() {
+    const ownerId = this.ownerId;
+    const threshold = this.threshold;
+    const userId = this.userId;
+    const moderatorIds = this.moderatorIds;
+    this.ownerId = this.threshold = this.userId = this.moderatorIds = undefined;
+    localStorage.setItem('currentFilter', JSON.stringify(this));
+    this.ownerId = ownerId;
+    this.threshold = threshold;
+    this.userId = userId;
+    this.moderatorIds = moderatorIds;
+  }
+
+  get thresholdEnabled() {
+    return !!this.threshold;
+  }
+
+  filterCommentsBySearch(comments: Comment[]): Comment[] {
+    const search = this.currentSearch.toLowerCase();
+    return comments
+      .filter(c =>
+        c.body.toLowerCase().includes(search) ||
+        c.answer?.toLowerCase().includes(search) ||
+        c.keywordsFromSpacy?.some(e => e.text.toLowerCase().includes(search)) ||
+        c.keywordsFromQuestioner?.some(e => e.text.toLowerCase().includes(search)) ||
+        c.questionerName?.toLowerCase().includes(search)
+      );
+  }
+
+  filterCommentsByTime(comments: Comment[], moderation = false): Comment[] {
+    const thresholdComments =
+      this.thresholdEnabled && !moderation ? comments.filter(comment => comment.score >= this.threshold) : comments;
+    if (this.period === null || this.period === undefined) {
+      this.period = DEFAULT_PERIOD;
+    }
+    if (this.period === Period.all) {
+      return thresholdComments;
+    }
+    const currentTime = new Date().getTime();
+    let periodInSeconds;
+    const hourInSeconds = 3_600_000;
+    switch (this.period) {
+      case Period.fromNow:
+        if (!this.fromNow) {
+          this.fromNow = currentTime;
+        }
+        break;
+      case Period.oneHour:
+        periodInSeconds = hourInSeconds;
+        break;
+      case Period.threeHours:
+        periodInSeconds = hourInSeconds * 3;
+        break;
+      case Period.oneDay:
+        periodInSeconds = hourInSeconds * 24;
+        break;
+      case Period.oneWeek:
+        periodInSeconds = hourInSeconds * 168;
+        break;
+      case Period.twoWeeks:
+        periodInSeconds = hourInSeconds * 336;
+        break;
+      default:
+        throw new Error('Time period is invalid.');
+    }
+    const filterTime = (this.period === Period.fromNow ? this.fromNow : currentTime - periodInSeconds);
+    return thresholdComments.filter(c => new Date(c.timestamp).getTime() >= filterTime);
+  }
+
+  filterCommentsByType(comment: Comment[]): Comment[] {
+    let filterFunc: (c: Comment) => boolean;
+    switch (this.filterType) {
+      case FilterType.correct:
+        filterFunc = (c) => c.correct === CorrectWrong.CORRECT;
+        break;
+      case FilterType.wrong:
+        filterFunc = (c) => c.correct === CorrectWrong.WRONG;
+        break;
+      case FilterType.favorite:
+        filterFunc = (c) => c.favorite;
+        break;
+      case FilterType.bookmark:
+        filterFunc = (c) => c.bookmark;
+        break;
+      case FilterType.read:
+        filterFunc = (c) => c.read;
+        break;
+      case FilterType.unread:
+        filterFunc = (c) => !c.read;
+        break;
+      case FilterType.tag:
+        filterFunc = (c) => c.tag === this.filterCompare;
+        break;
+      case FilterType.userNumber:
+        filterFunc = (c) => c.userNumber === this.filterCompare;
+        break;
+      case FilterType.keyword:
+        filterFunc = (c) => !!(c.keywordsFromQuestioner?.find(k => k.text === this.filterCompare) ||
+          c.keywordsFromSpacy?.find(k => k.text === this.filterCompare));
+        break;
+      case FilterType.answer:
+        filterFunc = (c) => !!c.answer;
+        break;
+      case FilterType.unanswered:
+        filterFunc = (c) => !c.answer;
+        break;
+      case FilterType.owner:
+        filterFunc = (c) => c.creatorId === this.userId;
+        break;
+      case FilterType.moderator:
+        filterFunc = (c) => this.moderatorIds.has(c.creatorId);
+        break;
+      case FilterType.lecturer:
+        filterFunc = (c) => c.creatorId === this.ownerId;
+        break;
+      default:
+        return comment;
+    }
+    return comment.filter(filterFunc);
+  }
+
+  sortCommentsBySortType(comments: Comment[]): Comment[] {
+    let sortFunc: (a: Comment, b: Comment) => number;
+    switch (this.sortType) {
+      case SortType.voteasc:
+        sortFunc = (a, b) => a.score - b.score;
+        break;
+      case SortType.votedesc:
+        sortFunc = (a, b) => b.score - a.score;
+        break;
+      case SortType.time:
+        sortFunc = (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
+        break;
+    }
+    if (sortFunc) {
+      comments.sort(sortFunc);
+    }
+    comments.sort((a, b) => this.getCommentRoleValue(b) - this.getCommentRoleValue(a));
+    return comments;
+  }
+
+  private getCommentRoleValue(comment: Comment): number {
+    if (comment.creatorId === this.ownerId) {
+      return 2;
+    } else if (this.moderatorIds.has(comment.creatorId)) {
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/src/app/services/util/room-data.service.ts b/src/app/services/util/room-data.service.ts
index 6465af45aae2340bb87019aba083f63e19e2a12f..59271f5523ba2450994f66340ef43aba778927cd 100644
--- a/src/app/services/util/room-data.service.ts
+++ b/src/app/services/util/room-data.service.ts
@@ -13,7 +13,7 @@ import { SpacyKeyword } from '../http/spacy.service';
 
 export interface UpdateInformation {
   type: 'CommentCreated' | 'CommentPatched' | 'CommentHighlighted' | 'CommentDeleted';
-  subtype?: string;
+  subtype?: (keyof Comment);
   comment: Comment;
   finished?: boolean;
   updates?: (keyof Comment)[];
@@ -100,7 +100,7 @@ export class RoomDataService {
 
   private _currentSubscriptions: RoomDataUpdateSubscription[] = [];
   private _currentComments: Comment[] = null;
-  private _commentUpdates: BehaviorSubject<Comment[]> = new BehaviorSubject<Comment[]>(null);
+  private _currentRoomComments: BehaviorSubject<Comment[]> = new BehaviorSubject<Comment[]>(null);
   private _fastCommentAccess: FastRoomAccessObject = null;
   private _wsCommentServiceSubscription: Subscription = null;
   private _currentRoomId: string = null;
@@ -140,10 +140,10 @@ export class RoomDataService {
   getRoomData(roomId: string, freezed: boolean = false): Observable<Comment[]> {
     const tempSubject = new BehaviorSubject<Comment[]>(null);
     if (this._currentRoomId !== roomId) {
-      this._commentUpdates.next(null);
+      this._currentRoomComments.next(null);
     }
     let subscription: Subscription = null;
-    subscription = this._commentUpdates.subscribe(comments => {
+    subscription = this._currentRoomComments.subscribe(comments => {
       if (comments === null) {
         return;
       }
@@ -287,7 +287,7 @@ export class RoomDataService {
 
   private triggerUpdate(type: UpdateType, additionalInformation: UpdateInformation) {
     if (type === UpdateType.force) {
-      this._commentUpdates.next(this._currentComments);
+      this._currentRoomComments.next(this._currentComments);
     } else if (type === UpdateType.commentStream) {
       for (const subscription of this._currentSubscriptions) {
         subscription.onUpdate(additionalInformation);
diff --git a/src/app/utils/create-comment-keywords.ts b/src/app/utils/create-comment-keywords.ts
index 9ba833a870ee2d266fa01a7abe411d47f1c6060c..26cc24f06f3c2928e1fa1a81aac54a39dbe5d477 100644
--- a/src/app/utils/create-comment-keywords.ts
+++ b/src/app/utils/create-comment-keywords.ts
@@ -91,7 +91,6 @@ export class CreateCommentKeywords {
     const wordCount = text.trim().split(' ').length;
     const hasConfidence = selectedLanguage === 'auto' ? result.language.detectedLanguage.confidence >= 0.5 : true;
     const errorQuotient = (result.matches.length * 100) / wordCount;
-    console.log(errorQuotient);
     if (!hasConfidence ||
       errorQuotient > ERROR_QUOTIENT_USE_DEEPL ||
       (!useDeepl && errorQuotient > ERROR_QUOTIENT_WELL_SPELLED)) {