diff --git a/.gitignore b/.gitignore
index 0261a90deccd65899998610b512a0de5128f65b0..51094d15974ca28dbffd1186764f209aa81fae13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,7 +39,4 @@ testem.log
 .DS_Store
 Thumbs.db
 
-
-src/environments/environment.ts
 .gitignore
-
diff --git a/Makefile b/Makefile
index c045e1b51127d1080cfcc1c292e286516deaae87..e31459f85d939f26aac7d34b3e4a15dde51184a7 100644
--- a/Makefile
+++ b/Makefile
@@ -13,24 +13,12 @@ down:
 build:
 	docker-compose -f docker/docker-compose.yml build
 
-# TODO does not wait for server to start and fails
-# test: run-detached test-unit test-e2e stop
-
 test-unit:
 	docker-compose -f docker/docker-compose.yml exec testcenter-frontend-dev ng test --watch=false
 
 test-e2e:
 	docker-compose -f docker/docker-compose.yml exec testcenter-frontend-dev ng e2e --webdriver-update=false --port 4202
 
-init-dev-config:
-	cp src/environments/environment.dev.ts src/environments/environment.ts
-
-build-image:
-	docker build --target prod -t iqbberlin/testcenter-frontend -f docker/Dockerfile .
-
-push-image:
-	docker push iqbberlin/testcenter-frontend:latest
-
 tag-major:
 	scripts/new_version.py major
 
diff --git a/docker/Dockerfile b/docker/Dockerfile
index db5a1091040fde46111ca2186b11989c3e32eb6b..4ae2ab7e5342e60323f1ef76ade506cc40ea0656 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -19,9 +19,7 @@ RUN npx webdriver-manager update --versions.chrome=`google-chrome --product-vers
 
 COPY . /app
 
-RUN ng test --watch=false
-
-RUN ng build --prod="true" --output-path=dist
+RUN ng build --prod
 
 EXPOSE 4200
 
diff --git a/package.json b/package.json
index a97675b662c0c2f8c853e6bb5ccb541fba41378a..1e7be35bedff522b85eadffb65a0db6a9170c003 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "itc-ng",
-  "version": "6.4.0",
+  "version": "6.5.0",
   "license": "MIT",
   "repository": {
     "type": "git",
@@ -10,7 +10,7 @@
     "ng": "ng",
     "start": "ng serve",
     "build": "ng build",
-    "test": "ng test",
+    "test": "ng test  --watch=false",
     "lint": "ng lint",
     "e2e": "ng e2e"
   },
diff --git a/src/app/app-root/status-card/status-card.component.html b/src/app/app-root/status-card/status-card.component.html
index 354b4fb0c91ecd021e1314b872b8857a4c580e25..14dd57b66bbef2a7b3685fe0b2095e46cdb8b6ae 100644
--- a/src/app/app-root/status-card/status-card.component.html
+++ b/src/app/app-root/status-card/status-card.component.html
@@ -12,11 +12,16 @@
   <p *ngIf="!loginName"><b>Status: Derzeit nicht angemeldet.</b></p>
   <p style="margin-bottom: 0;"><b>Angaben zu dieser Web-Anwendung:</b></p>
   <ul style="margin: 0;">
-    <li>Interner Programmname: {{ appName }}</li>
-    <li>Programmversion: {{ appVersion }}</li>
     <li *ngIf="!isProductionMode">Build-Modus: Dev</li>
-    <li>Erforderliche Version der Server-Programmierung: {{ apiVersionExpected }}</li>
-    <li>Unterstützte Version der Verona Interfaces Player Definition: {{ veronaApiVersionSupported }}</li>
-    <li>Copyright: {{ appPublisher }}</li>
+    <li>Version {{appVersion}}</li>
+    <li>API: Version {{mds.apiVersion}}, {{apiVersionExpected}} erforderlich</li>
+    <li>Broadcasting-Service: {{mds.broadcastingServiceInfo.status}}
+      <span *ngIf="mds.broadcastingServiceInfo.version">
+        - Version {{mds.broadcastingServiceInfo.version}},
+        {{mds.broadcastingServiceInfo.versionExpected}} erforderlich
+      </span>
+    </li>
+    <li>Verona Player Interface: Version {{veronaApiVersionSupported}}</li>
+    <li>Copyright: {{appPublisher}}</li>
   </ul>
 </div>
diff --git a/src/app/app-root/status-card/status-card.component.ts b/src/app/app-root/status-card/status-card.component.ts
index 4c807d1cd527ff07a78dac811e2e5321c13d27db..be3b49809a57293962a6fa60db575426543f51c8 100644
--- a/src/app/app-root/status-card/status-card.component.ts
+++ b/src/app/app-root/status-card/status-card.component.ts
@@ -9,6 +9,7 @@ import {AuthAccessKeyType, AuthFlagType} from '../../app.interfaces';
 export class StatusCardComponent implements OnInit {
   loginName = '';
   loginAuthority: string[] = [];
+  apiVersion: string;
 
   constructor(
     @Inject('APP_NAME') public appName: string,
@@ -16,7 +17,8 @@ export class StatusCardComponent implements OnInit {
     @Inject('APP_VERSION') public appVersion: string,
     @Inject('API_VERSION_EXPECTED') public apiVersionExpected: string,
     @Inject('VERONA_API_VERSION_SUPPORTED') public veronaApiVersionSupported: string,
-    @Inject('IS_PRODUCTION_MODE') public isProductionMode
+    @Inject('IS_PRODUCTION_MODE') public isProductionMode,
+    public mds: MainDataService
   ) { }
 
   ngOnInit(): void {
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index ab917c380c7c94996a0c7d77c59b79d9d37926e4..ff6eb29521e5ac049c691839667f023308135b12 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -6,6 +6,7 @@ import { CustomtextService } from 'iqb-components';
 import { MainDataService } from './maindata.service';
 import { BackendService } from './backend.service';
 import { AppError } from './app.interfaces';
+import {BroadCastingServiceInfo, SysConfig} from './config/app.config';
 
 @Component({
   selector: 'tc-root',
@@ -30,43 +31,32 @@ export class AppComponent implements OnInit, OnDestroy {
     if (expectedVersion) {
       const searchPattern = /\d+/g;
       const expectedVersionNumbers = expectedVersion.match(searchPattern);
-      if (!expectedVersionNumbers) {
-        return false;
-      }
-      if (!reportedVersion) {
-        return false;
-      }
-      const reportedVersionNumbers = reportedVersion.match(searchPattern);
-      if (!reportedVersionNumbers) {
-        return false;
-      }
-      if (reportedVersionNumbers[0] !== expectedVersionNumbers[0]) {
-        return false;
-      }
-      if (expectedVersionNumbers.length > 1) {
-        if ((reportedVersionNumbers.length < 2) || +reportedVersionNumbers[1] < +expectedVersionNumbers[1]) {
-          return false;
-        }
-        if ((expectedVersionNumbers.length > 2) && reportedVersionNumbers[1] === expectedVersionNumbers[1]) {
-          if ((reportedVersionNumbers.length < 3) || +reportedVersionNumbers[2] < +expectedVersionNumbers[2]) {
+      if (expectedVersionNumbers) {
+        if (reportedVersion) {
+          const reportedVersionNumbers = reportedVersion.match(searchPattern);
+          if (reportedVersionNumbers) {
+            if (reportedVersionNumbers[0] !== expectedVersionNumbers[0]) {
+              return false;
+            } else if (expectedVersionNumbers.length > 1) {
+              if ((reportedVersionNumbers.length < 2) || +reportedVersionNumbers[1] < +expectedVersionNumbers[1]) {
+                return false;
+              } else if ((expectedVersionNumbers.length > 2) && reportedVersionNumbers[1] === expectedVersionNumbers[1]) {
+                if ((reportedVersionNumbers.length < 3) || +reportedVersionNumbers[2] < +expectedVersionNumbers[2]) {
+                  return false;
+                }
+              }
+            }
+          } else {
             return false;
           }
+        } else {
+          return false;
         }
       }
     }
     return true;
   }
 
-  private static localTime(date: Date): string {
-    const year = date.getFullYear();
-    const month = (`0${date.getMonth() + 1}`).slice(-2);
-    const day = (`0${date.getDate()}`).slice(-2);
-    const hours = (`0${date.getHours()}`).slice(-2);
-    const minutes = (`0${date.getMinutes()}`).slice(-2);
-    const seconds = (`0${date.getSeconds()}`).slice(-2);
-    return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`;
-  }
-
   closeErrorBox(): void {
     this.showError = false;
   }
@@ -84,7 +74,7 @@ export class AppComponent implements OnInit, OnDestroy {
 
       window.addEventListener('message', (event: MessageEvent) => {
         const msgData = event.data;
-        const msgType = msgData.type;
+        const msgType = msgData['type'];
         if ((msgType !== undefined) && (msgType !== null)) {
           if (msgType.substr(0, 2) === 'vo') {
             this.mds.postMessage$.next(event);
@@ -95,38 +85,36 @@ export class AppComponent implements OnInit, OnDestroy {
       this.setupFocusListeners();
 
       this.bs.getSysConfig().subscribe(sysConfig => {
-        if (!sysConfig) {
-          this.mds.isApiValid = false; // push on this.mds.appError$ ?
-          return;
-        }
-        this.cts.addCustomTexts(sysConfig.customTexts);
-        const authData = MainDataService.getAuthData();
-        if (authData) {
-          this.cts.addCustomTexts(authData.customTexts);
-        }
-        this.mds.isApiValid = AppComponent.isValidVersion(this.expectedApiVersion, sysConfig.version);
-        if (!this.mds.isApiValid) {
-          this.mds.appError$.next({
-            label: 'Server-Problem: API-Version ungültig',
-            description: `erwartet: ${this.expectedApiVersion}, gefunden: ${sysConfig.version}`,
-            category: 'FATAL'
-          });
-        }
-        const clientTime = new Date();
-        const serverTime = new Date(sysConfig.serverTimestamp);
-        if (Math.abs(sysConfig.serverTimestamp - clientTime.getTime()) > 90000) {
-          this.mds.appError$.next({
-            label: 'Server- und Client-Uhr stimmen nicht überein.',
-            description: `Server-Zeit: ${AppComponent.localTime(serverTime)}, 
-              Client-Zeit: ${AppComponent.localTime(clientTime)}`,
-            category: 'FATAL'
-          });
+        if (sysConfig) {
+          this.cts.addCustomTexts(sysConfig.customTexts);
+          const authData = MainDataService.getAuthData();
+          if (authData) {
+            this.cts.addCustomTexts(authData.customTexts);
+          }
+          console.log('info', sysConfig);
+          if (sysConfig.broadcastingService && sysConfig.broadcastingService.status) {
+            this.mds.broadcastingServiceInfo = sysConfig.broadcastingService;
+          }
+          this.mds.isApiValid = AppComponent.isValidVersion(this.expectedApiVersion, sysConfig.version);
+          this.mds.apiVersion = sysConfig.version;
+          if (!this.mds.isApiValid) {
+            this.mds.appError$.next({
+              label: 'Server-Problem: API-Version ungültig',
+              description: `erwartet: ${this.expectedApiVersion}, gefunden: ${sysConfig.version}`,
+              category: 'FATAL'
+            });
+          }
+          if (sysConfig.mainLogo) {
+            console.warn('SysConfig.mainLogo not implemented yet');
+          }
+          this.mds.setTestConfig(sysConfig.testConfig);
+        } else {
+          this.mds.isApiValid = false;
         }
-        this.mds.setTestConfig(sysConfig.testConfig);
       });
 
-      this.bs.getSysCheckInfo().subscribe(sysChecks => {
-        this.mds.sysCheckAvailable = !!sysChecks;
+      this.bs.getSysCheckInfo().subscribe((myConfigs) => {
+        this.mds.sysCheckAvailable = !!myConfigs;
       });
     });
   }
@@ -137,15 +125,12 @@ export class AppComponent implements OnInit, OnDestroy {
     if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
       hidden = 'hidden';
       visibilityChange = 'visibilitychange';
-      // eslint-disable-next-line @typescript-eslint/dot-notation
     } else if (typeof document['msHidden'] !== 'undefined') {
       hidden = 'msHidden';
       visibilityChange = 'msvisibilitychange';
-      // eslint-disable-next-line @typescript-eslint/dot-notation
     } else if (typeof document['mozHidden'] !== 'undefined') {
       hidden = 'mozHidden';
       visibilityChange = 'mozHidden';
-      // eslint-disable-next-line @typescript-eslint/dot-notation
     } else if (typeof document['webkitHidden'] !== 'undefined') {
       hidden = 'webkitHidden';
       visibilityChange = 'webkitvisibilitychange';
diff --git a/src/app/config/app.config.ts b/src/app/config/app.config.ts
index da2072c5f4dc992ca7c5ff693722b54bad0910a6..38cc5036800330e6bc531cd933101cd57ed61527 100644
--- a/src/app/config/app.config.ts
+++ b/src/app/config/app.config.ts
@@ -7,7 +7,13 @@ export interface SysConfig {
   version: string;
   mainLogo: string;
   testConfig: KeyValuePairs;
-  serverTimestamp: number;
+  broadcastingService: BroadCastingServiceInfo;
+}
+
+export interface BroadCastingServiceInfo {
+  status: string;
+  version?: string;
+  versionExpected?: string;
 }
 
 export class AppConfig {
@@ -16,11 +22,11 @@ export class AppConfig {
   ) {
   }
 
-  setDefaultCustomTexts(): void {
+  setDefaultCustomTexts() {
     const ctDefaults = {};
-    Object.keys(customTextsDefault).forEach(key => {
-      ctDefaults[key] = customTextsDefault[key].defaultvalue;
-    });
+    for (const k of Object.keys(customTextsDefault)) {
+      ctDefaults[k] = customTextsDefault[k].defaultvalue
+    }
     this.cts.addCustomTexts(ctDefaults);
   }
 }
diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts
index 2bfa502c856be218e2afd060a96117ff05111a06..94b385608c49efad0ccfdffad390d5ecda7e9c3b 100644
--- a/src/app/maindata.service.ts
+++ b/src/app/maindata.service.ts
@@ -6,7 +6,7 @@ import {
   AuthData, KeyValuePairs
 } from './app.interfaces';
 import { BackendService } from './backend.service';
-import { AppConfig } from './config/app.config';
+import {AppConfig, BroadCastingServiceInfo, SysConfig} from './config/app.config';
 
 const localStorageAuthDataKey = 'iqb-tc-a';
 const localStorageTestConfigKey = 'iqb-tc-c';
@@ -21,6 +21,8 @@ export class MainDataService {
   public isSpinnerOn$ = new BehaviorSubject<boolean>(false);
   public progressVisualEnabled = true;
   public isApiValid = true;
+  public apiVersion: string;
+  public broadcastingServiceInfo: BroadCastingServiceInfo = { status: 'none' };
   public appConfig: AppConfig = null;
   public sysCheckAvailable = false;
 
diff --git a/src/app/test-controller/backend.service.ts b/src/app/test-controller/backend.service.ts
index bdad2d215698ecec9780b5aced086212047c3dc3..43221e1a5f664a0251ce14697c097b2ebdbf62e9 100644
--- a/src/app/test-controller/backend.service.ts
+++ b/src/app/test-controller/backend.service.ts
@@ -1,21 +1,20 @@
 import { Injectable, Inject } from '@angular/core';
 import { HttpClient, HttpParams } from '@angular/common/http';
-import {Observable, of, Subscription} from 'rxjs';
-import {catchError, map, switchMap} from 'rxjs/operators';
+import { Observable, of, Subscription } from 'rxjs';
+import { catchError, map, switchMap } from 'rxjs/operators';
 import {
   UnitData,
   TaggedString,
   TestData,
-  StateReportEntry
+  TestStateKey,
+  StateReportEntry, AppFocusState
 } from './test-controller.interfaces';
-import {ApiError} from '../app.interfaces';
-
+import { ApiError } from '../app.interfaces';
 
 @Injectable({
   providedIn: 'root'
 })
 export class BackendService {
-
   constructor(
     @Inject('SERVER_URL') private serverUrl: string,
     private http: HttpClient
@@ -24,7 +23,7 @@ export class BackendService {
   saveUnitReview(testId: string, unitName: string, priority: number, categories: string, entry: string)
     : Observable<boolean> {
     return this.http
-      .put(this.serverUrl + `test/${testId}/unit/${unitName}/review`, {priority, categories, entry})
+      .put(`${this.serverUrl}test/${testId}/unit/${unitName}/review`, { priority, categories, entry })
       .pipe(
         map(() => true),
         catchError((err: ApiError) => {
@@ -36,7 +35,7 @@ export class BackendService {
 
   saveTestReview(testId: string, priority: number, categories: string, entry: string): Observable<boolean> {
     return this.http
-      .put(this.serverUrl + `test/${testId}/review`, {priority, categories, entry})
+      .put(`${this.serverUrl}test/${testId}/review`, { priority, categories, entry })
       .pipe(
         map(() => true),
         catchError((err: ApiError) => {
@@ -48,7 +47,7 @@ export class BackendService {
 
   getTestData(testId: string): Observable<TestData | boolean> {
     return this.http
-      .get<TestData>(this.serverUrl + 'test/' + testId)
+      .get<TestData>(`${this.serverUrl}test/${testId}`)
       .pipe(
         catchError((err: ApiError) => {
           console.warn(`getTestData Api-Error: ${err.code} ${err.info} `);
@@ -57,9 +56,9 @@ export class BackendService {
       );
   }
 
-  getUnitData(testId: string, unitid: string): Observable<UnitData | boolean> {
+  getUnitData(testId: string, unitid: string, unitalias: string): Observable<UnitData | boolean> {
     return this.http
-      .get<UnitData>(this.serverUrl + 'test/' + testId + '/unit/' + unitid)
+      .get<UnitData>(`${this.serverUrl}test/${testId}/unit/${unitid}/alias/${unitalias}`)
       .pipe(
         catchError((err: ApiError) => {
           console.warn(`getUnitData Api-Error: ${err.code} ${err.info} `);
@@ -71,13 +70,14 @@ export class BackendService {
   getResource(testId: string, internalKey: string, resId: string, versionning = false): Observable<TaggedString | number> {
     return this.http
       .get(
-        this.serverUrl + `test/${testId}/resource/${resId}`,
+        `${this.serverUrl}test/${testId}/resource/${resId}`,
         {
           params: new HttpParams().set('v', versionning ? '1' : 'f'),
           responseType: 'text'
-        })
+        }
+      )
       .pipe(
-        map(def => <TaggedString>{tag: internalKey, value: def}),
+        map(def => <TaggedString>{ tag: internalKey, value: def }),
         catchError((err: ApiError) => {
           console.warn(`getResource Api-Error: ${err.code} ${err.info} `);
           return of(err.code);
@@ -87,37 +87,35 @@ export class BackendService {
 
   updateTestState(testId: string, newState: StateReportEntry[]): Subscription {
     return this.http
-      .patch(this.serverUrl + `test/${testId}/state`, newState)
-      .subscribe({error: (err: ApiError) => console.error(`updateTestState Api-Error: ${err.code} ${err.info}`)});
+      .patch(`${this.serverUrl}test/${testId}/state`, newState)
+      .subscribe({ error: (err: ApiError) => console.error(`updateTestState Api-Error: ${err.code} ${err.info}`) });
   }
 
   addTestLog(testId: string, logEntries: StateReportEntry[]): Subscription {
     return this.http
-      .put(this.serverUrl + `test/${testId}/log`, logEntries)
-      .subscribe({error: (err: ApiError) => console.error(`addTestLog Api-Error: ${err.code} ${err.info}`)});
+      .put(`${this.serverUrl}test/${testId}/log`, logEntries)
+      .subscribe({ error: (err: ApiError) => console.error(`addTestLog Api-Error: ${err.code} ${err.info}`) });
   }
 
   updateUnitState(testId: string, unitName: string, newState: StateReportEntry[]): Subscription {
     return this.http
-      .patch(this.serverUrl + `test/${testId}/unit/${unitName}/state`, newState)
-      .subscribe({error: (err: ApiError) => console.error(`setUnitState Api-Error: ${err.code} ${err.info}`)});
+      .patch(`${this.serverUrl}test/${testId}/unit/${unitName}/state`, newState)
+      .subscribe({ error: (err: ApiError) => console.error(`setUnitState Api-Error: ${err.code} ${err.info}`) });
   }
 
   addUnitLog(testId: string, unitName: string, logEntries: StateReportEntry[]): Subscription {
     return this.http
-      .put(this.serverUrl + `test/${testId}/unit/${unitName}/log`, logEntries)
-      .subscribe({error: (err: ApiError) => console.error(`addUnitLog Api-Error: ${err.code} ${err.info}`)});
+      .put(`${this.serverUrl}test/${testId}/unit/${unitName}/log`, logEntries)
+      .subscribe({ error: (err: ApiError) => console.error(`addUnitLog Api-Error: ${err.code} ${err.info}`) });
   }
 
-  notifyDyingTest(testId: string): void {
-      if (navigator.sendBeacon) {
-          navigator.sendBeacon(this.serverUrl + `test/${testId}/connection-lost`);
-      } else {
-          fetch(this.serverUrl + `test/${testId}/connection-lost`, {
-              keepalive: true,
-              method: 'POST'
-          });
-      }
+  notifyDyingTest(testId: string) {
+    // TODO add auth or change end point
+    if (navigator.sendBeacon) {
+      navigator.sendBeacon(`${this.serverUrl}test/${testId}/state`, JSON.stringify(<StateReportEntry>{
+        key: TestStateKey.FOCUS, timeStamp: Date.now(), content: AppFocusState.DEAD
+      }));
+    }
   }
 
   updateUnitStateData(testId: string, timeStamp: number, unitName: string, dataPartsAllString: string, unitStateDataType: string)
@@ -127,19 +125,17 @@ export class BackendService {
     const restorePoint = dataPartsAllString;
     const responseType = unitStateDataType;
     return this.http
-      .put(this.serverUrl + `test/${testId}/unit/${unitName}/response`, {timeStamp, response, responseType})
+      .put(`${this.serverUrl}test/${testId}/unit/${unitName}/response`, { timeStamp, response, responseType })
       .pipe(
-        switchMap(() => {
-          return this.http
-            .patch(this.serverUrl + `test/${testId}/unit/${unitName}/restorepoint`, {timeStamp, restorePoint})
-            .pipe(
-              map(() => true),
-              catchError((err: ApiError) => {
-                console.warn(`newUnitStateData/restorepoint Api-Error: ${err.code} ${err.info} `);
-                return of(false);
-              })
-            );
-        }),
+        switchMap(() => this.http
+          .patch(`${this.serverUrl}test/${testId}/unit/${unitName}/restorepoint`, { timeStamp, restorePoint })
+          .pipe(
+            map(() => true),
+            catchError((err: ApiError) => {
+              console.warn(`newUnitStateData/restorepoint Api-Error: ${err.code} ${err.info} `);
+              return of(false);
+            })
+          )),
         catchError((err: ApiError) => {
           console.warn(`newUnitStateData/response Api-Error: ${err.code} ${err.info} `);
           return of(false);
@@ -149,7 +145,7 @@ export class BackendService {
 
   lockTest(testId: string, timeStamp: number, content: string): Observable<boolean> {
     return this.http
-      .patch<boolean>(this.serverUrl + `test/${testId}/lock`, {timeStamp, content})
+      .patch<boolean>(`${this.serverUrl}test/${testId}/lock`, { timeStamp, content })
       .pipe(
         map(() => true),
         catchError((err: ApiError) => {
diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts
index cf2fa7cb9debd9d7dd1e973e483c299cd7ef7c95..a8e86095c64766507673f389183d6498b4d2b87d 100644
--- a/src/app/test-controller/test-controller.component.ts
+++ b/src/app/test-controller/test-controller.component.ts
@@ -1,11 +1,17 @@
-import {ReviewDialogComponent} from './review-dialog/review-dialog.component';
-import {ActivatedRoute, Router} from '@angular/router';
-import {MainDataService} from '../maindata.service';
-import {BackendService} from './backend.service';
-
-import {TestControllerService} from './test-controller.service';
-import {Component, HostListener, Inject, OnDestroy, OnInit} from '@angular/core';
-import {EnvironmentData, MaxTimerData, Testlet, UnitDef} from './test-controller.classes';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import {
+  Component, HostListener, Inject, OnDestroy, OnInit
+} from '@angular/core';
+import {
+  from, Observable, of, Subscription, throwError
+} from 'rxjs';
+import {
+  concatMap, debounceTime, distinctUntilChanged, map, switchMap
+} from 'rxjs/operators';
+import { CustomtextService } from 'iqb-components';
+import { MatDialog } from '@angular/material/dialog';
+import { MatSnackBar } from '@angular/material/snack-bar';
 import {
   AppFocusState,
   Command,
@@ -21,15 +27,17 @@ import {
   UnitNavigationTarget, UnitStateKey,
   WindowFocusState
 } from './test-controller.interfaces';
-import {from, Observable, of, Subscription, throwError} from 'rxjs';
-import {concatMap, debounceTime, distinctUntilChanged, map, switchMap} from 'rxjs/operators';
-import {CustomtextService} from 'iqb-components';
-import {MatDialog} from '@angular/material/dialog';
-import {MatSnackBar} from '@angular/material/snack-bar';
-import {BookletConfig} from '../config/booklet-config';
-import {TestMode} from '../config/test-mode';
-import {CommandService} from './command.service';
-
+import {
+  EnvironmentData, MaxTimerData, Testlet, UnitDef
+} from './test-controller.classes';
+import { BackendService } from './backend.service';
+import { MainDataService } from '../maindata.service';
+import { TestControllerService } from './test-controller.service';
+import { ReviewDialogComponent } from './review-dialog/review-dialog.component';
+// eslint-disable-next-line import/extensions
+import { BookletConfig } from '../config/booklet-config';
+import { TestMode } from '../config/test-mode';
+import { CommandService } from './command.service';
 
 @Component({
   templateUrl: './test-controller.component.html',
@@ -57,8 +65,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
   unitNavigationTarget = UnitNavigationTarget;
   debugPane = false;
 
-
-  constructor (
+  constructor(
     @Inject('APP_VERSION') public appVersion: string,
     @Inject('IS_PRODUCTION_MODE') public isProductionMode,
     private mds: MainDataService,
@@ -75,7 +82,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
 
   private static getChildElements(element) {
     return Array.prototype.slice.call(element.childNodes)
-    .filter(function (e) { return e.nodeType === 1; });
+      .filter(e => e.nodeType === 1);
   }
 
   // private: recursive reading testlets/units from xml
@@ -106,7 +113,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
             const restrictionParameter = restrictionElements[childIndex].getAttribute('minutes');
             if ((typeof restrictionParameter !== 'undefined') && (restrictionParameter !== null)) {
               maxTime = Number(restrictionParameter);
-              if (isNaN(maxTime)) {
+              if (Number.isNaN(maxTime)) {
                 maxTime = -1;
               }
             }
@@ -135,20 +142,19 @@ export class TestControllerComponent implements OnInit, OnDestroy {
           let myUnitAliasClear = myUnitAlias;
           let unitIdSuffix = 1;
           while (this.allUnitIds.indexOf(myUnitAliasClear) > -1) {
-            myUnitAliasClear = myUnitAlias + '-' + unitIdSuffix.toString();
+            myUnitAliasClear = `${myUnitAlias}-${unitIdSuffix.toString()}`;
             unitIdSuffix += 1;
           }
           this.allUnitIds.push(myUnitAliasClear);
 
           targetTestlet.addUnit(this.lastUnitSequenceId, myUnitId,
-                childElements[childIndex].getAttribute('label'), myUnitAliasClear,
-                childElements[childIndex].getAttribute('labelshort'));
+            childElements[childIndex].getAttribute('label'), myUnitAliasClear,
+            childElements[childIndex].getAttribute('labelshort'));
           this.lastUnitSequenceId += 1;
-
         } else if (childElements[childIndex].nodeName === 'Testlet') {
           let testletId: string = childElements[childIndex].getAttribute('id');
           if (!testletId) {
-            testletId = 'Testlet' + this.lastTestletIndex.toString();
+            testletId = `Testlet${this.lastTestletIndex.toString()}`;
             this.lastTestletIndex += 1;
           }
           let testletLabel: string = childElements[childIndex].getAttribute('label');
@@ -219,85 +225,81 @@ export class TestControllerComponent implements OnInit, OnDestroy {
   }
 
   // private: read unitdata
-  private loadUnitOk (myUnit: UnitDef, sequenceId: number): Observable<number> {
+  private loadUnitOk(myUnit: UnitDef, sequenceId: number): Observable<number> {
     myUnit.setCanEnter('n', 'Fehler beim Laden');
-    return this.bs.getUnitData(this.tcs.testId, myUnit.id)
+    return this.bs.getUnitData(this.tcs.testId, myUnit.id, myUnit.alias)
       .pipe(
         switchMap(myData => {
           if (myData === false) {
             return throwError(`error requesting unit ${this.tcs.testId}/${myUnit.id}`);
-          } else {
-            const myUnitData = myData as UnitData;
-            if (myUnitData.restorepoint) {
-              this.tcs.addUnitStateData(sequenceId, JSON.parse(myUnitData.restorepoint));
-            }
-            let playerId = null;
-            let definitionRef = '';
-            if (myUnitData.laststate && myUnitData.laststate[UnitStateKey.PRESENTATION_PROGRESS]) {
-              this.tcs.setOldUnitPresentationComplete(sequenceId, myUnitData.laststate[UnitStateKey.PRESENTATION_PROGRESS]);
-            }
+          }
+          const myUnitData = myData as UnitData;
+          if (myUnitData.restorepoint) {
+            this.tcs.addUnitStateData(sequenceId, JSON.parse(myUnitData.restorepoint));
+          }
+          let playerId = null;
+          let definitionRef = '';
+          if (myUnitData.laststate && myUnitData.laststate[UnitStateKey.PRESENTATION_PROGRESS]) {
+            this.tcs.setOldUnitPresentationComplete(sequenceId, myUnitData.laststate[UnitStateKey.PRESENTATION_PROGRESS]);
+          }
 
-            try {
-              const oParser = new DOMParser();
-              const oDOM = oParser.parseFromString(myUnitData.xml, 'text/xml');
+          try {
+            const oParser = new DOMParser();
+            const oDOM = oParser.parseFromString(myUnitData.xml, 'text/xml');
 
-              if (oDOM.documentElement.nodeName === 'Unit') {
-                const defElements = oDOM.documentElement.getElementsByTagName('Definition');
+            if (oDOM.documentElement.nodeName === 'Unit') {
+              const defElements = oDOM.documentElement.getElementsByTagName('Definition');
 
-                if (defElements.length > 0) {
-                  const defElement = defElements[0];
-                  this.tcs.addUnitDefinition(sequenceId, defElement.textContent);
-                  playerId = defElement.getAttribute('player');
-                } else {
-                  const defRefElements = oDOM.documentElement.getElementsByTagName('DefinitionRef');
+              if (defElements.length > 0) {
+                const defElement = defElements[0];
+                this.tcs.addUnitDefinition(sequenceId, defElement.textContent);
+                playerId = defElement.getAttribute('player');
+              } else {
+                const defRefElements = oDOM.documentElement.getElementsByTagName('DefinitionRef');
 
-                  if (defRefElements.length > 0) {
-                    const defRefElement = defRefElements[0];
-                    definitionRef = defRefElement.textContent;
-                    // this.tcs.addUnitDefinition(sequenceId, '');
-                    playerId = defRefElement.getAttribute('player');
-                  }
+                if (defRefElements.length > 0) {
+                  const defRefElement = defRefElements[0];
+                  definitionRef = defRefElement.textContent;
+                  // this.tcs.addUnitDefinition(sequenceId, '');
+                  playerId = defRefElement.getAttribute('player');
                 }
               }
-            } catch (error) {
-              return throwError(`error parsing unit def ${this.tcs.testId}/${myUnit.id} (${error.toString()})`);
             }
+          } catch (error) {
+            return throwError(`error parsing unit def ${this.tcs.testId}/${myUnit.id} (${error.toString()})`);
+          }
 
-            if (playerId) {
-              myUnit.playerId = playerId;
-              if (definitionRef.length > 0) {
-                this.unitLoadQueue.push(<TaggedString>{
-                  tag: sequenceId.toString(),
-                  value: definitionRef
-                });
-              }
-              myUnit.setCanEnter('y', '');
+          if (playerId) {
+            myUnit.playerId = playerId;
+            if (definitionRef.length > 0) {
+              this.unitLoadQueue.push(<TaggedString>{
+                tag: sequenceId.toString(),
+                value: definitionRef
+              });
+            }
+            myUnit.setCanEnter('y', '');
 
-              if (this.tcs.hasPlayer(playerId)) {
-                return of(sequenceId);
-              } else {
-                // to avoid multiple calls before returning:
-                this.tcs.addPlayer(playerId, '');
-                return this.bs.getResource(this.tcs.testId, '', this.tcs.normaliseId(playerId, 'html'), true)
-                  .pipe(
-                    switchMap((data: number|TaggedString) => {
-                      if (typeof data === 'number') {
-                        return throwError(`error getting player "${playerId}"`);
-                      } else {
-                        const player = data as TaggedString;
-                        if (player.value.length > 0) {
-                          this.tcs.addPlayer(playerId, player.value);
-                          return of(sequenceId);
-                        } else {
-                          return throwError(`error getting player "${playerId}" (size = 0)`);
-                        }
-                      }
-                    }));
-              }
-            } else {
-              return throwError(`player def missing for unit ${this.tcs.testId}/${myUnit.id}`);
+            if (this.tcs.hasPlayer(playerId)) {
+              return of(sequenceId);
             }
+            // to avoid multiple calls before returning:
+            this.tcs.addPlayer(playerId, '');
+            return this.bs.getResource(this.tcs.testId, '', this.tcs.normaliseId(playerId, 'html'), true)
+              .pipe(
+                switchMap((data: number|TaggedString) => {
+                  if (typeof data === 'number') {
+                    return throwError(`error getting player "${playerId}"`);
+                  }
+                  const player = data as TaggedString;
+                  if (player.value.length > 0) {
+                    this.tcs.addPlayer(playerId, player.value);
+                    return of(sequenceId);
+                  }
+                  return throwError(`error getting player "${playerId}" (size = 0)`);
+                })
+              );
           }
+          return throwError(`player def missing for unit ${this.tcs.testId}/${myUnit.id}`);
         })
       );
   }
@@ -318,7 +320,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
       }
       this.errorReportingSubscription = this.mds.appError$.subscribe(e => {
         if (this.isProductionMode && this.tcs.testMode.saveResponses) {
-          console.error(e.label + ' / ' + e.description);
+          console.error(`${e.label} / ${e.description}`);
         }
         this.tcs.testStatus$.next(TestControllerState.ERROR);
       });
@@ -344,28 +346,28 @@ export class TestControllerComponent implements OnInit, OnDestroy {
         this.tcs.windowFocusState$.next(hasFocus ? WindowFocusState.HOST : WindowFocusState.UNKNOWN);
       });
       this.commandSubscription = this.cmd.command$.pipe(
-          distinctUntilChanged((command1: Command, command2: Command): boolean => (command1.id === command2.id))
-        )
+        distinctUntilChanged((command1: Command, command2: Command): boolean => (command1.id === command2.id))
+      )
         .subscribe((command: Command) => {
           this.handleCommand(command.keyword, command.arguments);
-      });
+        });
 
       this.routingSubscription = this.route.params.subscribe(params => {
         if (this.tcs.testStatus$.getValue() !== TestControllerState.ERROR) {
-          this.tcs.testId = params['t'];
-          localStorage.setItem(TestControllerComponent.localStorageTestKey, params['t']);
+          this.tcs.testId = params.t;
+          localStorage.setItem(TestControllerComponent.localStorageTestKey, params.t);
 
           this.unsubscribeTestSubscriptions();
 
           this.maxTimerSubscription = this.tcs.maxTimeTimer$.subscribe(maxTimerData => {
             switch (maxTimerData.type) {
               case MaxTimerDataType.STARTED:
-                this.snackBar.open(this.cts.getCustomText('booklet_msgTimerStarted')
-                    + maxTimerData.timeLeftMinString, '', {duration: 3000});
+                this.snackBar.open(this.cts.getCustomText('booklet_msgTimerStarted') +
+                    maxTimerData.timeLeftMinString, '', { duration: 3000 });
                 this.timerValue = maxTimerData;
                 break;
               case MaxTimerDataType.ENDED:
-                this.snackBar.open(this.cts.getCustomText('booklet_msgTimeOver'), '', {duration: 3000});
+                this.snackBar.open(this.cts.getCustomText('booklet_msgTimeOver'), '', { duration: 3000 });
                 this.tcs.rootTestlet.setTimeLeft(maxTimerData.testletId, 0);
                 this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0;
                 if (this.tcs.testMode.saveResponses) {
@@ -380,7 +382,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                 }
                 break;
               case MaxTimerDataType.CANCELLED:
-                this.snackBar.open(this.cts.getCustomText('booklet_msgTimerCancelled'), '', {duration: 3000});
+                this.snackBar.open(this.cts.getCustomText('booklet_msgTimerCancelled'), '', { duration: 3000 });
                 this.tcs.rootTestlet.setTimeLeft(maxTimerData.testletId, 0);
                 this.tcs.LastMaxTimerState[maxTimerData.testletId] = 0;
                 if (this.tcs.testMode.saveResponses) {
@@ -405,9 +407,9 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                   }
                 }
                 if ((maxTimerData.timeLeftSeconds / 60) === 5) {
-                  this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver5Minutes'), '', {duration: 3000});
+                  this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver5Minutes'), '', { duration: 3000 });
                 } else if ((maxTimerData.timeLeftSeconds / 60) === 1) {
-                  this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver1Minute'), '', {duration: 3000});
+                  this.snackBar.open(this.cts.getCustomText('booklet_msgSoonTimeOver1Minute'), '', { duration: 3000 });
                 }
                 break;
             }
@@ -454,11 +456,11 @@ export class TestControllerComponent implements OnInit, OnDestroy {
               this.tcs.rootTestlet = this.getBookletFromXml(testData.xml);
 
               document.documentElement.style.setProperty('--tc-unit-title-height',
-                  this.tcs.bookletConfig.unit_title === 'ON' ? this.mds.defaultTcUnitTitleHeight : '0');
+                this.tcs.bookletConfig.unit_title === 'ON' ? this.mds.defaultTcUnitTitleHeight : '0');
               document.documentElement.style.setProperty('--tc-header-height',
-                  this.tcs.bookletConfig.unit_screenheader === 'OFF' ? '0' : this.mds.defaultTcHeaderHeight);
+                this.tcs.bookletConfig.unit_screenheader === 'OFF' ? '0' : this.mds.defaultTcHeaderHeight);
               document.documentElement.style.setProperty('--tc-unit-page-nav-height',
-                  this.tcs.bookletConfig.page_navibuttons === 'SEPARATE_BOTTOM' ? this.mds.defaultTcUnitPageNavHeight : '0');
+                this.tcs.bookletConfig.page_navibuttons === 'SEPARATE_BOTTOM' ? this.mds.defaultTcUnitPageNavHeight : '0');
 
               if (this.tcs.rootTestlet === null) {
                 this.mds.appError$.next({
@@ -485,91 +487,88 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                     return this.loadUnitOk(ud.unitDef, uSequ);
                   })
                 ).subscribe(() => {
-                    this.incrementProgressValueBy1();
-                  },
-                  errorMessage => {
-                    this.mds.appError$.next({
-                      label: 'Problem beim Laden der Testinformation',
-                      description: errorMessage,
-                      category: 'PROBLEM'
-                    });
-                  },
-                  () => {
-                    this.tcs.rootTestlet.lockUnitsIfTimeLeftNull();
-                    let navTarget = 1;
-                    if (navTargetUnitId) {
-                      const tmpNavTarget = this.tcs.rootTestlet.getSequenceIdByUnitAlias(navTargetUnitId);
-                      if (tmpNavTarget > 0) {
-                        navTarget = tmpNavTarget;
-                      }
+                  this.incrementProgressValueBy1();
+                },
+                errorMessage => {
+                  this.mds.appError$.next({
+                    label: 'Problem beim Laden der Testinformation',
+                    description: errorMessage,
+                    category: 'PROBLEM'
+                  });
+                },
+                () => {
+                  this.tcs.rootTestlet.lockUnitsIfTimeLeftNull();
+                  let navTarget = 1;
+                  if (navTargetUnitId) {
+                    const tmpNavTarget = this.tcs.rootTestlet.getSequenceIdByUnitAlias(navTargetUnitId);
+                    if (tmpNavTarget > 0) {
+                      navTarget = tmpNavTarget;
                     }
-                    this.tcs.updateMinMaxUnitSequenceId(navTarget);
-                    this.loadedUnitCount = 0;
-
-                    this.unitLoadBlobSubscription = from(this.unitLoadQueue).pipe(
-                      concatMap(queueEntry => {
-                        const unitSequ = Number(queueEntry.tag);
-                        if (this.tcs.bookletConfig.loading_mode === 'EAGER') {
-                          this.incrementProgressValueBy1();
-                        }
-                        // avoid to load unit def if not necessary
-                        if (unitSequ < this.tcs.minUnitSequenceId) {
-                          return of(<TaggedString>{tag: unitSequ.toString(), value: ''});
-                        } else {
-                          return this.bs.getResource(this.tcs.testId, queueEntry.tag, queueEntry.value).pipe(
-                            map(response => {
-                              if (typeof response === 'number') {
-                                return throwError(`error loading voud ${this.tcs.testId} / ${queueEntry.tag} / ${queueEntry.value}: status ${response}`);
-                              } else {
-                                return response;
-                              }
-                            })
-                          );
-                        }
-                      })
-                    ).subscribe(
-                      (def: TaggedString) => {
-                        this.tcs.addUnitDefinition(Number(def.tag), def.value);
-                      },
-                      errorMessage => {
-                        this.mds.appError$.next({
-                          label: 'Problem beim Laden der Testinformation',
-                          description: errorMessage,
-                          category: 'PROBLEM'
-                        });
-                        this.tcs.testStatus$.next(TestControllerState.ERROR);
-                      },
-                      () => { // complete
-                        if (this.tcs.testMode.saveResponses) {
-                          envData.loadTime = Date.now() - loadStartTimeStamp;
-                          this.bs.addTestLog(this.tcs.testId, [<StateReportEntry>{
-                            key: TestLogEntryKey.LOADCOMPLETE, timeStamp: Date.now(), content: JSON.stringify(envData)
-                          }]);
-                        }
-                        this.tcs.loadProgressValue = 100;
-
-                        this.tcs.loadComplete = true;
-                        if (this.tcs.bookletConfig.loading_mode === 'EAGER') {
-                          this.resumeTargetUnitId = navTarget;
-                          this.tcs.setUnitNavigationRequest(navTarget.toString());
-                          this.tcs.testStatus$.next(newTestStatus);
-                          if (this.tcs.testMode.saveResponses) {
-                            this.addAppFocusSubscription();
+                  }
+                  this.tcs.updateMinMaxUnitSequenceId(navTarget);
+                  this.loadedUnitCount = 0;
+
+                  this.unitLoadBlobSubscription = from(this.unitLoadQueue).pipe(
+                    concatMap(queueEntry => {
+                      const unitSequ = Number(queueEntry.tag);
+                      if (this.tcs.bookletConfig.loading_mode === 'EAGER') {
+                        this.incrementProgressValueBy1();
+                      }
+                      // avoid to load unit def if not necessary
+                      if (unitSequ < this.tcs.minUnitSequenceId) {
+                        return of(<TaggedString>{ tag: unitSequ.toString(), value: '' });
+                      }
+                      return this.bs.getResource(this.tcs.testId, queueEntry.tag, queueEntry.value).pipe(
+                        map(response => {
+                          if (typeof response === 'number') {
+                            return throwError(`error loading voud ${this.tcs.testId} / ${queueEntry.tag} / ${queueEntry.value}: status ${response}`);
                           }
-                        }
+                          return response;
+                        })
+                      );
+                    })
+                  ).subscribe(
+                    (def: TaggedString) => {
+                      this.tcs.addUnitDefinition(Number(def.tag), def.value);
+                    },
+                    errorMessage => {
+                      this.mds.appError$.next({
+                        label: 'Problem beim Laden der Testinformation',
+                        description: errorMessage,
+                        category: 'PROBLEM'
+                      });
+                      this.tcs.testStatus$.next(TestControllerState.ERROR);
+                    },
+                    () => { // complete
+                      if (this.tcs.testMode.saveResponses) {
+                        envData.loadTime = Date.now() - loadStartTimeStamp;
+                        this.bs.addTestLog(this.tcs.testId, [<StateReportEntry>{
+                          key: TestLogEntryKey.LOADCOMPLETE, timeStamp: Date.now(), content: JSON.stringify(envData)
+                        }]);
                       }
-                    );
+                      this.tcs.loadProgressValue = 100;
 
-                    if (this.tcs.bookletConfig.loading_mode === 'LAZY') {
-                      this.resumeTargetUnitId = navTarget;
-                      this.tcs.setUnitNavigationRequest(navTarget.toString());
-                      this.tcs.testStatus$.next(newTestStatus);
-                      if (this.tcs.testMode.saveResponses) {
-                        this.addAppFocusSubscription();
+                      this.tcs.loadComplete = true;
+                      if (this.tcs.bookletConfig.loading_mode === 'EAGER') {
+                        this.resumeTargetUnitId = navTarget;
+                        this.tcs.setUnitNavigationRequest(navTarget.toString());
+                        this.tcs.testStatus$.next(newTestStatus);
+                        if (this.tcs.testMode.saveResponses) {
+                          this.addAppFocusSubscription();
+                        }
                       }
                     }
-
-                  } // complete
+                  );
+
+                  if (this.tcs.bookletConfig.loading_mode === 'LAZY') {
+                    this.resumeTargetUnitId = navTarget;
+                    this.tcs.setUnitNavigationRequest(navTarget.toString());
+                    this.tcs.testStatus$.next(newTestStatus);
+                    if (this.tcs.testMode.saveResponses) {
+                      this.addAppFocusSubscription();
+                    }
+                  }
+                } // complete
                 );
               }
             }
@@ -602,9 +601,9 @@ export class TestControllerComponent implements OnInit, OnDestroy {
       debounceTime(500)
     ).subscribe((newState: WindowFocusState) => {
       if (newState === WindowFocusState.UNKNOWN) {
-          this.bs.updateTestState(this.tcs.testId, [<StateReportEntry>{
-            key: TestStateKey.FOCUS, timeStamp: Date.now(), content: AppFocusState.HAS_NOT
-          }]);
+        this.bs.updateTestState(this.tcs.testId, [<StateReportEntry>{
+          key: TestStateKey.FOCUS, timeStamp: Date.now(), content: AppFocusState.HAS_NOT
+        }]);
       } else {
         this.bs.updateTestState(this.tcs.testId, [<StateReportEntry>{
           key: TestStateKey.FOCUS, timeStamp: Date.now(), content: AppFocusState.HAS
@@ -615,7 +614,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
 
   showReviewDialog() {
     if (this.tcs.rootTestlet === null) {
-      this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000});
+      this.snackBar.open('Kein Testheft verfügbar.', '', { duration: 3000 });
     } else {
       const authData = MainDataService.getAuthData();
       const dialogRef = this.reviewDialog.open(ReviewDialogComponent, {
@@ -631,32 +630,32 @@ export class TestControllerComponent implements OnInit, OnDestroy {
       dialogRef.afterClosed().subscribe(result => {
         if (typeof result !== 'undefined') {
           if (result !== false) {
-            const targetSelection = result['target'];
+            const targetSelection = result.target;
             if (targetSelection === 'u') {
               this.bs.saveUnitReview(
                 this.tcs.testId,
                 this.tcs.currentUnitDbKey,
-                result['priority'],
+                result.priority,
                 dialogRef.componentInstance.getCategories(),
-                result['sender'] ? result['sender'] + ': ' + result['entry'] : result['entry']
-                ).subscribe(ok => {
-                  if (!ok) {
-                    this.snackBar.open('Konnte Kommentar nicht speichern', '', {duration: 3000});
-                  } else {
-                    this.snackBar.open('Kommentar gespeichert', '', {duration: 1000});
-                  }
-                });
+                result.sender ? `${result.sender}: ${result.entry}` : result.entry
+              ).subscribe(ok => {
+                if (!ok) {
+                  this.snackBar.open('Konnte Kommentar nicht speichern', '', { duration: 3000 });
+                } else {
+                  this.snackBar.open('Kommentar gespeichert', '', { duration: 1000 });
+                }
+              });
             } else {
               this.bs.saveTestReview(
                 this.tcs.testId,
-                result['priority'],
+                result.priority,
                 dialogRef.componentInstance.getCategories(),
-                result['sender'] ? result['sender'] + ': ' + result['entry'] : result['entry']
+                result.sender ? `${result.sender}: ${result.entry}` : result.entry
               ).subscribe(ok => {
                 if (!ok) {
-                  this.snackBar.open('Konnte Kommentar nicht speichern', '', {duration: 3000});
+                  this.snackBar.open('Konnte Kommentar nicht speichern', '', { duration: 3000 });
                 } else {
-                  this.snackBar.open('Kommentar gespeichert', '', {duration: 1000});
+                  this.snackBar.open('Kommentar gespeichert', '', { duration: 1000 });
                 }
               });
             }
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index 4422e58c408dfdacfc9d5d1450ea711277ed6ee6..6c9895f3a9949699e444e610bd3ecc553515cabc 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -1,9 +1,7 @@
-// ng build --prod
-
 export const environment = {
   production: true,
   testcenterUrl: '/api/',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
-  apiVersionExpected: '9.0.0-nextmajor',
+  apiVersionExpected: '9.1.0',
   veronaApiVersionSupported: '2.1.0'
 };
diff --git a/src/environments/environment.dev.ts b/src/environments/environment.ts
similarity index 80%
rename from src/environments/environment.dev.ts
rename to src/environments/environment.ts
index c172344b23705ebeb801acb0794125b7e5833793..1468f991e774b2db88b4a45be6ea505c129dd2bc 100644
--- a/src/environments/environment.dev.ts
+++ b/src/environments/environment.ts
@@ -4,8 +4,8 @@
 
 export const environment = {
   production: false,
-  testcenterUrl: '/api/',
+  testcenterUrl: 'http://localhost/2020/testcenter-iqb-php/',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
-  apiVersionExpected: '9.0.0-nextmajor',
+  apiVersionExpected: '9.1.0',
   veronaApiVersionSupported: '2.1.0'
 };