From 1c63d9fe49c888bdd9bf2638d1fa828568c9aa88 Mon Sep 17 00:00:00 2001
From: Martin Mechtel <mechtelm@user.hu-berlin.de>
Date: Mon, 17 Sep 2018 20:19:52 +0200
Subject: [PATCH] 1st after recoding: startpage works

---
 package-lock.json                             |  22 +-
 package.json                                  |   7 +-
 .../about-dialog/about-dialog.component.css   |   0
 .../about-dialog/about-dialog.component.html  |  15 -
 .../about-dialog.component.spec.ts            |  25 -
 .../about-dialog/about-dialog.component.ts    |  19 -
 src/app/about/about.component.css             |   4 +
 src/app/about/about.component.html            |  46 ++
 .../about.component.spec.ts}                  |  12 +-
 src/app/about/about.component.ts              |  20 +
 src/app/app-routing.module.ts                 |  10 +-
 src/app/app.component.html                    |  28 +-
 src/app/app.component.ts                      |  63 +--
 src/app/app.module.ts                         |  26 +-
 src/app/{shared => }/backend.service.spec.ts  |   0
 src/app/backend.service.ts                    | 218 ++++++++
 src/app/home/home.component.css               |  14 -
 src/app/home/home.component.html              |  29 --
 src/app/home/home.component.ts                |  51 --
 src/app/iqb-files/index.ts                    |   3 -
 src/app/iqb-files/iqb-files.module.ts         |  33 --
 src/app/iqb-files/iqbFile.scss                |  61 ---
 .../iqbFileUpload.component.html              |  13 -
 .../iqbFileUpload/iqbFileUpload.component.ts  | 191 -------
 .../iqbFileUploadInputFor.directive.spec.ts   |   0
 .../iqbFileUploadInputFor.directive.ts        |  59 ---
 .../iqbFileUploadQueue.component.html         |  18 -
 .../iqbFileUploadQueue.component.spec.ts      |   0
 .../iqbFileUploadQueue.component.ts           | 118 -----
 src/app/logindata.service.spec.ts             |  15 +
 src/app/logindata.service.ts                  |  82 +++
 src/app/shared/backend.service.ts             | 142 ------
 src/app/shared/global-store.service.spec.ts   |  15 -
 src/app/shared/global-store.service.ts        |  28 --
 src/app/start/start.component.css             |   6 +-
 src/app/start/start.component.html            | 103 +++-
 src/app/start/start.component.ts              | 343 +++++++++----
 .../test-controller/backend.service.spec.ts   |  15 -
 src/app/test-controller/backend.service.ts    | 225 ---------
 src/app/test-controller/index.ts              |   4 -
 .../resize-IFrameChild.directive.spec.ts      |   0
 .../resize-IFrameChild.directive.ts           |  30 --
 .../test-controller-routing.module.ts         |  31 --
 .../test-controller.component.spec.ts         |  25 -
 .../test-controller.component.ts              |   7 -
 .../test-controller/test-controller.module.ts |  34 --
 .../test-controller/testdata.service.spec.ts  |  15 -
 src/app/test-controller/testdata.service.ts   | 468 ------------------
 .../unithost/unit-routing.spec.ts             |  28 --
 .../test-controller/unithost/unit-routing.ts  |  56 ---
 .../unithost/unithost.component.css           |   3 -
 .../unithost/unithost.component.html          |   3 -
 .../unithost/unithost.component.spec.ts       |  25 -
 .../unithost/unithost.component.ts            |  77 ---
 src/environments/environment.ts               |   2 +-
 55 files changed, 789 insertions(+), 2098 deletions(-)
 delete mode 100644 src/app/about-dialog/about-dialog.component.css
 delete mode 100644 src/app/about-dialog/about-dialog.component.html
 delete mode 100644 src/app/about-dialog/about-dialog.component.spec.ts
 delete mode 100644 src/app/about-dialog/about-dialog.component.ts
 create mode 100644 src/app/about/about.component.css
 create mode 100644 src/app/about/about.component.html
 rename src/app/{home/home.component.spec.ts => about/about.component.spec.ts} (57%)
 create mode 100644 src/app/about/about.component.ts
 rename src/app/{shared => }/backend.service.spec.ts (100%)
 create mode 100644 src/app/backend.service.ts
 delete mode 100644 src/app/home/home.component.css
 delete mode 100644 src/app/home/home.component.html
 delete mode 100644 src/app/home/home.component.ts
 delete mode 100644 src/app/iqb-files/index.ts
 delete mode 100644 src/app/iqb-files/iqb-files.module.ts
 delete mode 100644 src/app/iqb-files/iqbFile.scss
 delete mode 100644 src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.html
 delete mode 100644 src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.ts
 delete mode 100644 src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.spec.ts
 delete mode 100644 src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.ts
 delete mode 100644 src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.html
 delete mode 100644 src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.spec.ts
 delete mode 100644 src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.ts
 create mode 100644 src/app/logindata.service.spec.ts
 create mode 100644 src/app/logindata.service.ts
 delete mode 100644 src/app/shared/backend.service.ts
 delete mode 100644 src/app/shared/global-store.service.spec.ts
 delete mode 100644 src/app/shared/global-store.service.ts
 delete mode 100644 src/app/test-controller/backend.service.spec.ts
 delete mode 100644 src/app/test-controller/backend.service.ts
 delete mode 100644 src/app/test-controller/index.ts
 delete mode 100644 src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.spec.ts
 delete mode 100644 src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.ts
 delete mode 100644 src/app/test-controller/test-controller-routing.module.ts
 delete mode 100644 src/app/test-controller/test-controller.component.spec.ts
 delete mode 100644 src/app/test-controller/test-controller.component.ts
 delete mode 100644 src/app/test-controller/test-controller.module.ts
 delete mode 100644 src/app/test-controller/testdata.service.spec.ts
 delete mode 100644 src/app/test-controller/testdata.service.ts
 delete mode 100644 src/app/test-controller/unithost/unit-routing.spec.ts
 delete mode 100644 src/app/test-controller/unithost/unit-routing.ts
 delete mode 100644 src/app/test-controller/unithost/unithost.component.css
 delete mode 100644 src/app/test-controller/unithost/unithost.component.html
 delete mode 100644 src/app/test-controller/unithost/unithost.component.spec.ts
 delete mode 100644 src/app/test-controller/unithost/unithost.component.ts

diff --git a/package-lock.json b/package-lock.json
index 007da886..39703228 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -337,6 +337,14 @@
         "tslib": "^1.9.0"
       }
     },
+    "@angular/flex-layout": {
+      "version": "6.0.0-beta.18",
+      "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-6.0.0-beta.18.tgz",
+      "integrity": "sha512-1Alv3YSIZYp0CTUIESIaSQLoSVyLzuNKPa5bGM/RzOmeSrndm5plVgI9wopGfJUDiwM18R97rq/4XjDvNT/+ig==",
+      "requires": {
+        "tslib": "^1.7.1"
+      }
+    },
     "@angular/forms": {
       "version": "6.1.2",
       "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-6.1.2.tgz",
@@ -420,6 +428,14 @@
         "@angular-devkit/core": "0.6.8",
         "@angular-devkit/schematics": "0.6.8",
         "typescript": ">=2.6.2 <2.8"
+      },
+      "dependencies": {
+        "typescript": {
+          "version": "2.7.2",
+          "resolved": "http://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
+          "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
+          "dev": true
+        }
       }
     },
     "@schematics/update": {
@@ -9627,9 +9643,9 @@
       "dev": true
     },
     "typescript": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
-      "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
+      "version": "2.9.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
+      "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
       "dev": true
     },
     "uglify-js": {
diff --git a/package.json b/package.json
index fd9ecc4d..4a206b4b 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "@angular/common": "^6.0.3",
     "@angular/compiler": "^6.0.3",
     "@angular/core": "^6.0.3",
+    "@angular/flex-layout": "^6.0.0-beta.18",
     "@angular/forms": "^6.0.3",
     "@angular/http": "^6.0.3",
     "@angular/material": "^6.4.3",
@@ -27,10 +28,9 @@
     "zone.js": "^0.8.26"
   },
   "devDependencies": {
-    "@angular/compiler-cli": "^6.0.3",
     "@angular-devkit/build-angular": "~0.6.8",
-    "typescript": "~2.7.2",
     "@angular/cli": "~6.0.8",
+    "@angular/compiler-cli": "^6.0.3",
     "@angular/language-service": "^6.0.3",
     "@types/jasmine": "~2.8.6",
     "@types/jasminewd2": "~2.0.3",
@@ -45,6 +45,7 @@
     "karma-jasmine-html-reporter": "^0.2.2",
     "protractor": "~5.3.0",
     "ts-node": "~5.0.1",
-    "tslint": "~5.9.1"
+    "tslint": "~5.9.1",
+    "typescript": "^2.9.2"
   }
 }
diff --git a/src/app/about-dialog/about-dialog.component.css b/src/app/about-dialog/about-dialog.component.css
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/about-dialog/about-dialog.component.html b/src/app/about-dialog/about-dialog.component.html
deleted file mode 100644
index d1db4b07..00000000
--- a/src/app/about-dialog/about-dialog.component.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<h1 mat-dialog-title>Programm-Info</h1>
-<mat-dialog-content>
-  <ul>
-    <li>Programmname: {{ appName }}</li>
-    <li>Programmversion: {{ appVersion }}</li>
-    <li>Copyright: {{ appPublisher }}</li>
-  </ul>
-  <p>Der Zugriff auf den nicht-öffentlichen Bereich ist nur über Kontaktaufnahme mit dem IQB möglich.
-    Das System befindet sich in einem sehr frühen Entwicklungsstadium. Informationen zur OpenCBA-Initiative
-    sind auch nur direkt über das IQB erhältlich.
-  </p>
-</mat-dialog-content>
-<mat-dialog-actions>
-  <button mat-raised-button mat-dialog-close>Schließen</button>
-</mat-dialog-actions>
diff --git a/src/app/about-dialog/about-dialog.component.spec.ts b/src/app/about-dialog/about-dialog.component.spec.ts
deleted file mode 100644
index 7fc637d3..00000000
--- a/src/app/about-dialog/about-dialog.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { AboutDialogComponent } from './about-dialog.component';
-
-describe('AboutDialogComponent', () => {
-  let component: AboutDialogComponent;
-  let fixture: ComponentFixture<AboutDialogComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ AboutDialogComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(AboutDialogComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/about-dialog/about-dialog.component.ts b/src/app/about-dialog/about-dialog.component.ts
deleted file mode 100644
index aefd041a..00000000
--- a/src/app/about-dialog/about-dialog.component.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { GlobalStoreService } from './../shared/global-store.service';
-import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
-import { Component, Inject } from '@angular/core';
-
-@Component({
-  selector: 'tc-about-dialog',
-  templateUrl: './about-dialog.component.html',
-  styleUrls: ['./about-dialog.component.css']
-})
-export class AboutDialogComponent {
-
-  constructor(
-    @Inject('APP_NAME') private appName: string,
-    @Inject('APP_PUBLISHER') private appPublisher: string,
-    @Inject('APP_VERSION') private appVersion: string,
-    @Inject(MAT_DIALOG_DATA) public data: any,
-    private gss: GlobalStoreService) { }
-
-}
diff --git a/src/app/about/about.component.css b/src/app/about/about.component.css
new file mode 100644
index 00000000..f4269125
--- /dev/null
+++ b/src/app/about/about.component.css
@@ -0,0 +1,4 @@
+div.intro-main {
+  margin: 40px;
+  max-width: 600px;
+}
diff --git a/src/app/about/about.component.html b/src/app/about/about.component.html
new file mode 100644
index 00000000..582dc50d
--- /dev/null
+++ b/src/app/about/about.component.html
@@ -0,0 +1,46 @@
+<div class="page-body">
+  <div class="sheetofpaper">
+    <div class="intro-main">
+      <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a>
+      betreibt auf diesen Seiten eine Pilotanwendung für das computerbasierte Leistungstesten von
+      Schülerinnen und Schülern. Der Zugang zu einem Test ist nur möglich, wenn Sie von Testverantwortlichen
+      Zugangsdaten erhalten haben. Es sind keine weiteren Seiten öffentlich verfügbar.</p>
+
+      <p>Die mit diesem Testsystem erhobenen Daten sind vertraulich und enthalten grundsätzlich keinen direkten
+        Personenbezug. Es werden z. B. nie Namen gespeichert. Um Auskünfte zu einer bestimmten Studie
+        zu erhalten, wenden Sie sich bitte an das <a href="mailto:mechtel@iqb.hu-berlin.de?subject=Zum%20IQB-Testsystem">
+        IQB</a>. Wir benötigen dazu den ungefähren Testzeitraum und das Bundesland, in dem die Studie
+        durchgeführt wurde.</p>
+
+      <!--<tc-statustext></tc-statustext>-->
+
+      <ul>
+        <li>Programmname: {{ appName }}</li>
+        <li>Programmversion: {{ appVersion }}</li>
+        <li>Copyright: {{ appPublisher }}</li>
+      </ul>
+
+      <p>
+          <em>Postanschrift:</em><br/>
+          Humboldt-Universität zu Berlin<br/>
+          Institut zur Qualitätsentwicklung im Bildungswesen<br/>
+          Unter den Linden 6<br/>
+          10099 Berlin</p>
+      <p>
+          <em>Sitz:</em><br/>
+          Luisenstr. 56<br/>
+          10117 Berlin<br/>
+          Tel: +49 [30] 2093 - 46500 (Zentrale)<br/>
+          Fax: +49 [30] 2093 - 46599<br/>
+          E-Mail: <a href="mailto:iqboffice@iqb.hu-berlin.de">iqboffice@iqb.hu-berlin.de</a>
+      </p>
+      <p>
+          <em>Name und Anschrift der Datenschutzbeauftragten</em><br/>
+          Frau Gesine Hoffmann-Holland<br/>
+          Tel: +49 (30) 2093-2591<br/>
+          E-Mail: datenschutz@uv.hu-berlin.de<br/>
+          <a href="http://www.hu-berlin.de/de/datenschutz" target="_blank">www.hu-berlin.de/de/datenschutz</a>
+      </p>
+    </div>
+  </div>
+</div>
diff --git a/src/app/home/home.component.spec.ts b/src/app/about/about.component.spec.ts
similarity index 57%
rename from src/app/home/home.component.spec.ts
rename to src/app/about/about.component.spec.ts
index 490e81bd..6b773448 100644
--- a/src/app/home/home.component.spec.ts
+++ b/src/app/about/about.component.spec.ts
@@ -1,20 +1,20 @@
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { HomeComponent } from './home.component';
+import { AboutComponent } from './about.component';
 
-describe('HomeComponent', () => {
-  let component: HomeComponent;
-  let fixture: ComponentFixture<HomeComponent>;
+describe('AboutComponent', () => {
+  let component: AboutComponent;
+  let fixture: ComponentFixture<AboutComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ HomeComponent ]
+      declarations: [ AboutComponent ]
     })
     .compileComponents();
   }));
 
   beforeEach(() => {
-    fixture = TestBed.createComponent(HomeComponent);
+    fixture = TestBed.createComponent(AboutComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
   });
diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts
new file mode 100644
index 00000000..01393470
--- /dev/null
+++ b/src/app/about/about.component.ts
@@ -0,0 +1,20 @@
+import { Component, Inject, OnInit } from '@angular/core';
+import { LogindataService } from '../logindata.service';
+
+@Component({
+  templateUrl: './about.component.html',
+  styleUrls: ['./about.component.css']
+})
+export class AboutComponent implements OnInit {
+
+  constructor(
+    @Inject('APP_NAME') private appName: string,
+    @Inject('APP_PUBLISHER') private appPublisher: string,
+    @Inject('APP_VERSION') private appVersion: string,
+    private lds: LogindataService
+  ) { }
+
+  ngOnInit() {
+    this.lds.pageTitle$.next('IQB-Testcenter - Impressum/Datenschutz');
+  }
+}
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index c3e58cd0..5aaa3a6a 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,15 +1,15 @@
-import { TestControllerComponent } from './test-controller';
+import { AboutComponent } from './about/about.component';
+// import { TestControllerComponent } from './test-controller';
 import { StartComponent } from './start/start.component';
-import { HomeComponent } from './home/home.component';
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
 
 
 const routes: Routes = [
-  {path: '', redirectTo: 'home', pathMatch: 'full'},
-  {path: 'home', component: HomeComponent},
+  {path: '', redirectTo: 'start', pathMatch: 'full'},
   {path: 'start', component: StartComponent},
-  {path: 't', component: TestControllerComponent}
+  {path: 'about', component: AboutComponent}
+//  {path: 't', component: TestControllerComponent}
 ];
 
 @NgModule({
diff --git a/src/app/app.component.html b/src/app/app.component.html
index ae52372d..3a6131bc 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,3 +1,4 @@
+<!--<tc-navi-buttons></tc-navi-buttons>-->
 <mat-toolbar color="primary">
   <a [routerLink]="['/']">
     <img class="logo" src="assets/IQB-LogoA.png" matTooltip="Startseite"/>
@@ -5,18 +6,12 @@
   <span>{{ title }}</span>
   <span class="itp-fill-remaining-space"></span>
 
-  <button mat-fab [disabled]="!navPrevEnabled" color="accent" (click)="navPrev()">
-    <i class="material-icons">chevron_left</i>
-  </button>
-  <button mat-fab [disabled]="!navNextEnabled" color="accent" (click)="navNext()">
-    <i class="material-icons">chevron_right</i>
-  </button>
   <button mat-icon-button [matMenuTriggerFor]="menu">
     <i class="material-icons">menu</i>
   </button>
 
   <mat-menu #menu="matMenu">
-    <button mat-menu-item (click)="showAboutDialog()">
+    <button mat-menu-item [routerLink]="['/about']">
       <mat-icon>info</mat-icon>
       <span>Programm-Info</span>
     </button>
@@ -24,23 +19,8 @@
       <mat-icon>home</mat-icon>
       <span>Anmeldeseite</span>
     </button>
-    <button mat-menu-item *ngIf="isSession" [routerLink]="['/start']">
-        <mat-icon>trending_up</mat-icon>
-        <span>Zum Test</span>
-    </button>
-    <button mat-menu-item *ngIf="isAdmin" [routerLink]="['/admin/myfiles']">
-      <mat-icon>settings</mat-icon>
-      <span>Testverwaltung</span>
-    </button>
-    <button mat-menu-item *ngIf="isAdmin" (click)="logout()">
-      <mat-icon>exit_to_app</mat-icon>
-      <span>Logout</span>
-    </button>
-    <button mat-menu-item *ngIf="!isAdmin" (click)="login()">
-      <mat-icon>input</mat-icon>
-      <span>Testverwaltung</span>
-    </button>
-  </mat-menu>
+    <!--<tc-menu-buttons></tc-menu-buttons>-->
+</mat-menu>
 </mat-toolbar>
 
 <router-outlet></router-outlet>
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 4e29fc2d..de9d843a 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,16 +1,9 @@
-import { environment } from './../environments/environment';
-import { merge ,  Observable ,  Observer ,  Subscriber ,  Subscription } from 'rxjs';
+import { LogindataService } from './logindata.service';
+import { merge } from 'rxjs';
 
-import { distinctUntilChanged ,  switchMap } from 'rxjs/operators';
-import { TestdataService } from './test-controller';
-import { IqbCommonModule, ConfirmDialogComponent, ConfirmDialogData } from './iqb-common';
-import { BackendService } from './shared/backend.service';
+// import { TestdataService } from './test-controller';
 import { Router } from '@angular/router';
-import { AboutDialogComponent } from './about-dialog/about-dialog.component';
-import { GlobalStoreService } from './shared/global-store.service';
 import { Component, OnInit } from '@angular/core';
-import { MatDialog, MatDialogRef } from '@angular/material';
-import { FormGroup } from '@angular/forms';
 
 @Component({
   selector: 'tc-root',
@@ -21,47 +14,23 @@ import { FormGroup } from '@angular/forms';
 
 export class AppComponent implements OnInit {
   public title = '';
-  public navPrevEnabled = false;
-  public navNextEnabled = false;
-  public isSession = false;
 
   constructor (
-    private gss: GlobalStoreService,
-    private tss: TestdataService,
-    private bsApp: BackendService,
-    private router: Router,
-    private bs: BackendService,
-    public aboutDialog: MatDialog) { }
+    private lds: LogindataService,
+    private router: Router) { }
 
   ngOnInit() {
-    this.tss.isSession$.subscribe(is => this.isSession = is);
-    this.tss.navNextEnabled$.subscribe(is => this.navNextEnabled = is);
-    this.tss.navPrevEnabled$.subscribe(is => this.navPrevEnabled = is);
-
-    merge(
-      this.gss.pageTitle$,
-      this.tss.pageTitle$).subscribe(t => {
-        this.title = t;
-      });
-
-    window.addEventListener('message', (event) => {
-      this.tss.processMessagePost(event);
-    }, false);
-  }
-
-  // *******************************************************************************************************
-  showAboutDialog() {
-    const dialogRef = this.aboutDialog.open(AboutDialogComponent, {
-      width: '500px',
-      data: {}
+    this.lds.pageTitle$.subscribe(t => {
+      this.title = t;
     });
-  }
-
-  navPrev() {
-    this.tss.gotoPrevUnit();
-  }
-
-  navNext() {
-    this.tss.gotoNextUnit();
+    // merge(
+    //   this.gss.pageTitle$,
+    //   this.tss.pageTitle$).subscribe(t => {
+    //     this.title = t;
+    //   });
+
+    // window.addEventListener('message', (event) => {
+    //   this.lds.processMessagePost(event);
+    // }, false);
   }
 }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 3cb3222e..e5e2e459 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,7 +1,4 @@
-import { TestControllerModule } from './test-controller';
-import { IqbCommonModule } from './iqb-common';
-import { GlobalStoreService } from './shared/global-store.service';
-import { BackendService } from './shared/backend.service';
+import { AboutComponent } from './about/about.component';
 import { BrowserModule } from '@angular/platform-browser';
 import { HttpClientModule } from '@angular/common/http';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@@ -11,19 +8,20 @@ import { ReactiveFormsModule } from '@angular/forms';
 import { MatButtonModule, MatCheckboxModule, MatMenuModule, MatTooltipModule,
   MatToolbarModule, MatIconModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatTabsModule } from '@angular/material';
 import { AppRoutingModule } from './app-routing.module';
-
 import { AppComponent } from './app.component';
-import { HomeComponent } from './home/home.component';
-import { AboutDialogComponent } from './about-dialog/about-dialog.component';
+
+// import { TestControllerModule } from './test-controller';
+import { IqbCommonModule } from './iqb-common';
+import { BackendService } from './backend.service';
 import { StartComponent } from './start/start.component';
 import { LocationStrategy, HashLocationStrategy } from '@angular/common';
+import { FlexLayoutModule } from '@angular/flex-layout';
 
 @NgModule({
   declarations: [
     AppComponent,
-    HomeComponent,
-    AboutDialogComponent,
     StartComponent,
+    AboutComponent
   ],
   imports: [
     BrowserModule,
@@ -37,17 +35,17 @@ import { LocationStrategy, HashLocationStrategy } from '@angular/common';
     MatTooltipModule,
     MatDialogModule,
     MatTabsModule,
+    FlexLayoutModule,
     ReactiveFormsModule,
     HttpClientModule,
-    TestControllerModule,
+//    TestControllerModule,
     AppRoutingModule,
     IqbCommonModule
   ],
-  entryComponents: [
-    AboutDialogComponent,
-  ],
+  // entryComponents: [
+  //   AboutDialogComponent,
+  // ],
   providers: [
-    GlobalStoreService,
     BackendService,
     {
       provide: LocationStrategy,
diff --git a/src/app/shared/backend.service.spec.ts b/src/app/backend.service.spec.ts
similarity index 100%
rename from src/app/shared/backend.service.spec.ts
rename to src/app/backend.service.spec.ts
diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts
new file mode 100644
index 00000000..b01044ef
--- /dev/null
+++ b/src/app/backend.service.ts
@@ -0,0 +1,218 @@
+import { Injectable, Inject } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpEvent, HttpErrorResponse } from '@angular/common/http';
+import { Observable, of } from 'rxjs';
+import { catchError } from 'rxjs/operators';
+
+
+
+
+
+@Injectable()
+export class BackendService {
+
+  constructor(
+    @Inject('SERVER_URL') private serverUrl: string,
+    private http: HttpClient) { }
+
+  /*
+  getStatus(admintoken: string, logintoken: string, sessiontoken: string): Observable<LoginResponseData> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<LoginResponseData>(this.serverUrl + 'getStatus.php', {at: admintoken, lt: logintoken, st: sessiontoken}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  } */
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  login(name: string, password: string): Observable<string | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<string>(this.serverUrl + 'testlogin.php', {n: name, p: password}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  // don't use LoginData.code!
+  getLoginDataByLoginToken(logintoken: string): Observable<LoginData | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<LoginData>(this.serverUrl + 'getLoginDataByLoginToken.php', {lt: logintoken}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+   // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+   getLoginDataByPersonToken(persontoken: string): Observable<LoginData | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<LoginData>(this.serverUrl + 'getLoginDataByPersonToken.php', {lt: persontoken}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  getBookletStatusByNameAndPersonToken(persontoken: string, bookletname: string): Observable<BookletStatus | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<BookletStatus>(this.serverUrl + 'getBookletStatusByNameAndPersonToken.php', {
+        pt: persontoken, b: bookletname}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  getBookletStatusByNameAndLoginToken(logintoken: string, code: string, bookletname: string): Observable<BookletStatus | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<BookletStatus>(this.serverUrl + 'getBookletStatusByNameAndLoginToken.php', {
+        lt: logintoken, b: bookletname, c: code}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  getBookletStatusByDbId(persontoken: string, bookletid: number): Observable<BookletStatus | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<BookletStatus>(this.serverUrl + 'getBookletStatusByDbId.php', {
+        pt: persontoken, b: bookletid}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  startBookletByLoginToken(logintoken: string, code: string, bookletFilename: string): Observable<PersonTokenAndBookletId | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<PersonTokenAndBookletId>(this.serverUrl +
+            'startBookletByLoginToken.php', {lt: logintoken, c: code, b: bookletFilename}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+  startBookletByPersonToken(persontoken: string, bookletFilename: string): Observable<number | ServerError> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        'Content-Type':  'application/json'
+      })
+    };
+    return this.http
+      .post<number>(this.serverUrl + 'startBookletByPersonToken.php', {pt: persontoken, b: bookletFilename}, httpOptions)
+        .pipe(
+          catchError(this.handleError)
+        );
+  }
+
+  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+  private handleError(errorObj: HttpErrorResponse): Observable<ServerError> {
+    const myreturn = new ServerError(errorObj.status, 'Fehler bei Datenübertragung');
+
+    if (errorObj.status === 401) {
+      myreturn.label = 'Fehler: Zugriff verweigert - bitte (neu) anmelden!';
+    } else if (errorObj.status === 503) {
+      myreturn.label = 'Fehler: Server meldet Datenbankproblem.';
+    } else if (errorObj.error instanceof ErrorEvent) {
+      myreturn.label = 'Fehler: ' + (<ErrorEvent>errorObj.error).message;
+    } else {
+      myreturn.label = 'Fehler: ' + errorObj.message;
+    }
+
+    return of(myreturn);
+  }
+}
+
+
+// #############################################################################################
+
+// class to be able to use instanceof to check type
+export class ServerError {
+  public code: number;
+  public label: string;
+  constructor(code: number, label: string) {
+    this.code = code;
+    this.label = label;
+  }
+}
+
+export interface LoginResponseData {
+  t: string;
+  n: string;
+  ws: string;
+}
+
+export interface BookletData {
+  name: string;
+  filename: string;
+  title: string;
+}
+
+export interface BookletDataList {
+  [code: string]: BookletData[];
+}
+
+export interface LoginData {
+  mode: string;
+  groupname: string;
+  loginname: string;
+  workspaceName: string;
+  booklets: BookletDataList;
+  code: string;
+}
+
+export interface BookletStatus {
+  statusLabel: string;
+  lastUnit: number;
+  canStart: boolean;
+  id: number;
+  label: string;
+  name: string;
+}
+
+export interface PersonTokenAndBookletId {
+  personToken: string;
+  bookletId: number;
+}
+
diff --git a/src/app/home/home.component.css b/src/app/home/home.component.css
deleted file mode 100644
index 25a5f362..00000000
--- a/src/app/home/home.component.css
+++ /dev/null
@@ -1,14 +0,0 @@
-div.intro-main {
-  margin: 40px;
-}
-
-form {
-  margin: 40px;
-  min-width: 150px;
-  max-width: 500px;
-}
-
-.full-width {
-  width: 100%;
-}
-
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
deleted file mode 100644
index 6f62e7c3..00000000
--- a/src/app/home/home.component.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<div class="page-body">
-  <div class="sheetofpaper">
-    <div class="intro-main">
-      <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a>
-      betreibt auf diesen Seiten eine Pilotanwendung für den Standard OpenCBA. Es handelt sich dabei um eine Initiative
-      von Institutionen zur Entwicklung eines modularen Systems zum computerbasierten Testen.</p>
-      <p>Um sich für einen bestimmten Test anzumelden, geben Sie bitte den Namen und das Kennwort für einen Tests ein.
-        Sie können über das Seitenmenü oben rechts weitere Funktionen aufrufen.</p>
-      <p *ngIf="isSession">Derzeit sind Sie am System angemeldet. Über das Menü oben rechts können Sie zur Startseite eines Tests gelangen.</p>
-      <p>Bei Fragen zu diesem System wenden Sie sich bitte an <a href="mailto:mechtel@iqb.hu-berlin.de?subject=Zum%20OpenCBA-Testsystem">Martin Mechtel</a>.</p>
-    </div>
-
-
-    <form [formGroup]="testtakerloginform" (ngSubmit)="testtakerlogin()">
-      <mat-form-field class="full-width">
-        <input matInput formControlName="testname" placeholder="Testname">
-      </mat-form-field>
-      <mat-form-field class="full-width">
-        <input matInput type="password" formControlName="testpw" placeholder="Kennwort" (keyup.enter)="testtakerlogin()">
-      </mat-form-field>
-      <button mat-raised-button type="submit" [disabled]="testtakerloginform.invalid">Test starten</button>
-    </form>
-
-    <div *ngIf="isError" class="intro-main">
-        <p>{{ errorMessage }}</p>
-    </div>
-
-  </div>
-</div>
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
deleted file mode 100644
index 7dff3291..00000000
--- a/src/app/home/home.component.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { TestdataService } from './../test-controller';
-import { BackendService } from './../shared/backend.service';
-import { Router } from '@angular/router';
-import { GlobalStoreService } from './../shared/global-store.service';
-import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
-import { FormGroup, FormBuilder, FormArray, FormControl, Validators } from '@angular/forms';
-
-
-@Component({
-  selector: 'tc-home',
-  templateUrl: './home.component.html',
-  styleUrls: ['./home.component.css']
-})
-export class HomeComponent implements OnInit {
-  testtakerloginform: FormGroup;
-  isSession: boolean;
-  isError = false;
-  errorMessage = '';
-
-  constructor(private fb: FormBuilder,
-    private router: Router,
-    private gss: GlobalStoreService,
-    private tss: TestdataService,
-    private bs: BackendService) { }
-
-  ngOnInit() {
-    this.gss.updatePageTitle('IQB-Testcenter - Willkommen!');
-    this.tss.isSession$.subscribe(is => {
-      this.isSession = is;
-    });
-
-    this.testtakerloginform = this.fb.group({
-      testname: this.fb.control('', [Validators.required, Validators.minLength(3)]),
-      testpw: this.fb.control('', [Validators.required, Validators.minLength(3)])
-    });
-  }
-
-  testtakerlogin() {
-    this.isError = false;
-    this.errorMessage = '';
-    this.bs.testlogin(this.testtakerloginform.get('testname').value, this.testtakerloginform.get('testpw').value).subscribe(
-      (loginToken: string) => {
-        this.gss.loginToken = loginToken;
-        this.router.navigateByUrl('/start');
-      }, (errormsg: string) => {
-        this.isError = true;
-        this.errorMessage = errormsg;
-       }
-    );
-  }
-}
diff --git a/src/app/iqb-files/index.ts b/src/app/iqb-files/index.ts
deleted file mode 100644
index f0228b06..00000000
--- a/src/app/iqb-files/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { IqbFileUploadQueueComponent } from './iqbFileUploadQueue/iqbFileUploadQueue.component';
-export { IqbFileUploadInputForDirective } from  './iqbFileUploadInputFor/iqbFileUploadInputFor.directive';
-export { IqbFilesModule } from './iqb-files.module';
diff --git a/src/app/iqb-files/iqb-files.module.ts b/src/app/iqb-files/iqb-files.module.ts
deleted file mode 100644
index 75493f34..00000000
--- a/src/app/iqb-files/iqb-files.module.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { IqbCommonModule } from './../iqb-common';
-import { NgModule } from '@angular/core';
-import { IqbFileUploadComponent } from './iqbFileUpload/iqbFileUpload.component';
-import { IqbFileUploadQueueComponent } from './iqbFileUploadQueue/iqbFileUploadQueue.component';
-import { IqbFileUploadInputForDirective } from './iqbFileUploadInputFor/iqbFileUploadInputFor.directive';
-
-import { MatProgressBarModule, MatCardModule, MatButtonModule } from '@angular/material';
-import { MatIconModule } from '@angular/material/icon';
-import { HttpClientModule } from '@angular/common/http';
-import { CommonModule } from '@angular/common';
-
-
-@NgModule({
-  imports: [
-    MatButtonModule,
-    MatProgressBarModule,
-    MatIconModule,
-    MatCardModule,
-    HttpClientModule,
-    IqbCommonModule,
-    CommonModule
-  ],
-  declarations: [
-    IqbFileUploadComponent,
-    IqbFileUploadQueueComponent,
-    IqbFileUploadInputForDirective
-  ],
-  exports: [
-    IqbFileUploadQueueComponent,
-    IqbFileUploadInputForDirective,
-  ]
-})
-export class IqbFilesModule { }
diff --git a/src/app/iqb-files/iqbFile.scss b/src/app/iqb-files/iqbFile.scss
deleted file mode 100644
index a7b1fc43..00000000
--- a/src/app/iqb-files/iqbFile.scss
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-.dropzone {
-    background-color: brown;
-    width: 100px;
-    height: 100px;
-}
-
-
-mat-card {
-  padding: 15px;
-}
-
-.example-section {
-  display: flex;
-  align-content: center;
-  align-items: center;
-  height: 10px;
-}
-
-.file-info, .file-info-error {
-  font-size: .85rem;
-}
-
-.file-info-error {
-  color: red;
-}
-
-#drop_zone {
-  border: 5px solid blue;
-  width:  200px;
-  height: 100px;
-}
-
-.action {
-  cursor: pointer;
-  outline: none;
-}
-
-a.disabled {
-  pointer-events: none;
-}
-
-.upload-drop-zone {
-  height: 200px;
-  border-width: 2px;
-  margin-bottom: 20px;
-}
-
-/* skin.css Style*/
-.upload-drop-zone {
-  color: #ccc;
-  border-style: dashed;
-  border-color: #ccc;
-  line-height: 200px;
-  text-align: center
-}
-.upload-drop-zone.drop {
-  color: #222;
-  border-color: #222;
-}
diff --git a/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.html b/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.html
deleted file mode 100644
index 4307132f..00000000
--- a/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<mat-card>
-    <span class="file-info">{{file.name}} ({{file.size | bytes}})</span>
-    <section *ngIf="status<=1" class="example-section">
-        <mat-progress-bar class="example-margin" [value]="progressPercentage"></mat-progress-bar>
-        <a *ngIf="status == 0"><mat-icon class="action" (click)="upload()">file_upload</mat-icon></a>
-        <mat-icon class="action" (click)="remove()">cancel</mat-icon>
-    </section>
-    <span *ngIf="status == 1" class="file-info">{{progressPercentage}} %</span><br/>
-    <span *ngIf="status != 1">
-      <span *ngIf="status == 3" class="file-info-error">{{statustext}}</span>
-      <span *ngIf="status != 3" class="file-info">{{statustext}}</span>
-    </span>
-</mat-card>
diff --git a/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.ts b/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.ts
deleted file mode 100644
index f298c65c..00000000
--- a/src/app/iqb-files/iqbFileUpload/iqbFileUpload.component.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-import { BytesPipe } from './../../iqb-common';
-import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, Optional, Inject, forwardRef } from '@angular/core';
-import { HttpClient, HttpEventType, HttpHeaders, HttpParams,
-  HttpErrorResponse, HttpEvent } from '@angular/common/http';
-
-
-@Component({
-    selector: 'iqb-file-upload',
-    templateUrl: `./iqbFileUpload.component.html`,
-    exportAs: 'iqbFileUpload',
-    host: {
-      'class': 'iqb-file-upload',
-    },
-    styleUrls: ['./../iqbFile.scss'],
-  })
-
-  export class IqbFileUploadComponent implements OnInit {
-
-    constructor(
-      private myHttpClient: HttpClient) { }
-
-    // ''''''''''''''''''''''''
-    private _status: UploadStatus;
-    get status(): UploadStatus {
-      return this._status;
-    }
-
-    set status(newstatus: UploadStatus) {
-      this._status = newstatus;
-      this.statusChangedEvent.emit(this);
-    }
-
-    // ''''''''''''''''''''''''
-    private requestResponseText: string;
-    get statustext(): string {
-      let myreturn = '';
-      switch (this._status) {
-        case UploadStatus.busy: {
-          myreturn = 'Bitte warten';
-          break;
-        }
-        case UploadStatus.ready: {
-          myreturn = 'Bereit';
-          break;
-        }
-        default: {
-          myreturn = this.requestResponseText;
-          break;
-        }
-      }
-      return myreturn;
-    }
-
-    /* Http request input bindings */
-    @Input()
-    httpUrl = 'http://localhost:8080';
-
-    @Input()
-    httpRequestHeaders: HttpHeaders | {
-      [header: string]: string | string[];
-    } = new HttpHeaders().set('Content-Type', 'multipart/form-data');
-
-    @Input()
-    httpRequestParams: HttpParams | {
-      [param: string]: string | string[];
-    } = new HttpParams();
-
-    @Input()
-    fileAlias = 'file';
-
-    @Input()
-    tokenName = '';
-
-    @Input()
-    token = '';
-
-    @Input()
-    folderName = '';
-
-    @Input()
-    folder = '';
-
-    @Input()
-    get file(): any {
-      return this._file;
-    }
-    set file(file: any) {
-      this._file = file;
-      this._filedate = this._file.lastModified;
-      this.total = this._file.size;
-    }
-
-    @Input()
-    set id(id: number) {
-      this._id = id;
-    }
-
-    get id(): number {
-      return this._id;
-    }
-
-    @Output() removeFileRequestEvent = new EventEmitter<IqbFileUploadComponent>();
-    @Output() statusChangedEvent = new EventEmitter<IqbFileUploadComponent>();
-
-    private progressPercentage = 0;
-    public loaded = 0;
-    private total = 0;
-    private _file: any;
-    private _filedate = '';
-    private _id: number;
-    private fileUploadSubscription: any;
-
-
-    ngOnInit() {
-      this._status = UploadStatus.ready;
-      this.requestResponseText = '';
-    }
-
-    // ==================================================================
-    public upload(): void {
-      if (this.status === UploadStatus.ready) {
-
-        this.status = UploadStatus.busy;
-        const formData = new FormData();
-        formData.set(this.fileAlias, this._file, this._file.name);
-        if ((typeof this.tokenName !== 'undefined') && (typeof this.token !== 'undefined')) {
-          if (this.tokenName.length > 0) {
-            formData.append(this.tokenName, this.token);
-          }
-        }
-        if ((typeof this.folderName !== 'undefined') && (typeof this.folder !== 'undefined')) {
-          if (this.folderName.length > 0) {
-            formData.append(this.folderName, this.folder);
-          }
-        }
-        this.fileUploadSubscription = this.myHttpClient.post(this.httpUrl, formData, {
-        // headers: this.httpRequestHeaders,
-          observe: 'events',
-          params: this.httpRequestParams,
-          reportProgress: true,
-          responseType: 'json'
-        }).subscribe((event: HttpEvent<any>) => {
-          if (event.type === HttpEventType.UploadProgress) {
-            this.progressPercentage = Math.floor( event.loaded * 100 / event.total );
-            this.loaded = event.loaded;
-            this.total = event.total;
-            this.status = UploadStatus.busy;
-          } else if (event.type === HttpEventType.Response) {
-            this.requestResponseText = event.body;
-            if ((this.requestResponseText.length > 5) && (this.requestResponseText.substr(0, 2) === 'e:')) {
-              this.requestResponseText = this.requestResponseText.substr(2);
-              this.status = UploadStatus.error;
-            } else {
-              this.status = UploadStatus.ok;
-            }
-          }
-        }, (errorObj: HttpErrorResponse) => {
-          if (this.fileUploadSubscription) {
-            this.fileUploadSubscription.unsubscribe();
-          }
-
-          this.status = UploadStatus.error;
-          if (errorObj.status === 401) {
-            this.requestResponseText = 'Fehler: Zugriff verweigert - bitte (neu) anmelden!';
-          } else if (errorObj.status === 503) {
-            this.requestResponseText = 'Fehler: Server meldet Problem mit Datenbank oder Datei zu groß.';
-          } else if (errorObj.error instanceof ErrorEvent) {
-            this.requestResponseText = 'Fehler: ' + (<ErrorEvent>errorObj.error).message;
-          } else {
-            this.requestResponseText = 'Fehler: ' + errorObj.message;
-          }
-        });
-      }
-    }
-
-    // ==================================================================
-    public remove(): void {
-      if (this.fileUploadSubscription) {
-        this.fileUploadSubscription.unsubscribe();
-      }
-      this.removeFileRequestEvent.emit(this);
-    }
-
-}
-
-export enum UploadStatus {
-  ready,
-  busy,
-  ok,
-  error
-}
diff --git a/src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.spec.ts b/src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.spec.ts
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.ts b/src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.ts
deleted file mode 100644
index 994448e7..00000000
--- a/src/app/iqb-files/iqbFileUploadInputFor/iqbFileUploadInputFor.directive.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Component, Directive, ElementRef, EventEmitter, HostListener,
-    Input, OnDestroy, OnInit, Output } from '@angular/core';
-
-
-  @Directive({
-    selector: 'input[iqbFileUploadInputFor], div[iqbFileUploadInputFor]',
-  })
-  export class IqbFileUploadInputForDirective  {
-
-
-    private _queue: any = null;
-    private _element: HTMLElement;
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    constructor(private element: ElementRef) {
-        this._element = this.element.nativeElement;
-    }
-
-
-    @Input('iqbFileUploadInputFor')
-    set fileUploadQueue(value: any) {
-        if (value) {
-            this._queue = value;
-        }
-    }
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    @HostListener('change')
-    public onChange(): any {
-      const files = this.element.nativeElement.files;
-      // this.onFileSelected.emit(files);
-
-      for (let i = 0; i < files.length; i++) {
-        this._queue.add(files[i]);
-      }
-      this.element.nativeElement.value = '';
-    }
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    @HostListener('drop', [ '$event' ])
-    public onDrop(event: any): any {
-      const files = event.dataTransfer.files;
-      // this.onFileSelected.emit(files);
-
-      for (let i = 0; i < files.length; i++) {
-        this._queue.add(files[i]);
-      }
-      event.preventDefault();
-      event.stopPropagation();
-      this.element.nativeElement.value = '';
-    }
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    @HostListener('dragover', [ '$event' ])
-    public onDropOver(event: any): any {
-      event.preventDefault();
-    }
-
-  }
diff --git a/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.html b/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.html
deleted file mode 100644
index 52ffbc49..00000000
--- a/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<iqb-file-upload
-  [file]="file"
-  [id]="i"
-  *ngFor="let file of files; let i = index"
-  [httpUrl]="httpUrl"
-  [fileAlias]="fileAlias"
-  [tokenName]="tokenName"
-  [token]="token"
-  [folderName]="folderName"
-  [folder]="folder"
-
-  (removeFileRequestEvent)="removeFile($event)"
-  (statusChangedEvent)="analyseStatus()">
-</iqb-file-upload>
-<br/>
-<button mat-raised-button color="primary" [disabled]="disableUploadAllButton"
-  *ngIf="files.length > 0" (click)="uploadAll()">Alle hochladen</button>
-<button mat-raised-button color="primary" *ngIf="files.length > 0" (click)="removeAll()">Liste leeren</button>
diff --git a/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.spec.ts b/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.spec.ts
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.ts b/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.ts
deleted file mode 100644
index ca22751a..00000000
--- a/src/app/iqb-files/iqbFileUploadQueue/iqbFileUploadQueue.component.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { Component, EventEmitter, OnInit, OnDestroy, QueryList, ViewChildren, Input, Output } from '@angular/core';
-import { IqbFileUploadComponent, UploadStatus } from './../iqbFileUpload/iqbFileUpload.component';
-import { Observable ,  merge } from 'rxjs';
-import { startWith } from 'rxjs/operators';
-import { HttpHeaders, HttpParams } from '@angular/common/http';
-
-
-/**
- * A material design file upload queue component.
- */
-@Component({
-    selector: 'iqb-file-upload-queue',
-    templateUrl: `iqbFileUploadQueue.component.html`,
-    exportAs: 'iqbFileUploadQueue',
-  })
-  export class IqbFileUploadQueueComponent implements OnDestroy {
-
-    @ViewChildren(IqbFileUploadComponent) fileUploads: QueryList<IqbFileUploadComponent>;
-
-    private files: Array<any> = [];
-    private numberOfErrors = 0;
-    private numberOfUploads = 0;
-    private disableUploadAllButton: boolean;
-
-    /* Http request input bindings */
-    @Input()
-    httpUrl: string;
-
-    @Input()
-    httpRequestHeaders: HttpHeaders | {
-      [header: string]: string | string[];
-    } = new HttpHeaders().set('Content-Type', 'multipart/form-data');
-
-    @Input()
-    httpRequestParams: HttpParams | {
-      [param: string]: string | string[];
-    } = new HttpParams();
-
-    @Input()
-    fileAlias: string;
-
-    @Input()
-    tokenName: string;
-
-    @Input()
-    token: string;
-
-    @Input()
-    folderName: string;
-
-    @Input()
-    folder: string;
-
-    @Output() uploadCompleteEvent = new EventEmitter<IqbFileUploadQueueComponent>();
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    add(file: any) {
-      this.files.push(file);
-      this.disableUploadAllButton = false;
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    public uploadAll() {
-      this.fileUploads.forEach((fileUpload) => {
-        fileUpload.upload();
-      });
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    public removeAll() {
-      this.files.splice(0, this.files.length);
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    ngOnDestroy() {
-      if (this.files) {
-        this.removeAll();
-      }
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    removeFile(fileToRemove: IqbFileUploadComponent) {
-      this.files.splice(fileToRemove.id, 1);
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    updateStatus() {
-      this.numberOfErrors = 0;
-      this.numberOfUploads = 0;
-
-      this.fileUploads.forEach((fileUpload) => {
-
-        fileUpload.upload();
-      });
-    }
-
-    // +++++++++++++++++++++++++++++++++++++++++++++++++
-    analyseStatus() {
-      let someoneiscomplete = false;
-      let someoneisbusy = false;
-      let someoneisready = false;
-      this.fileUploads.forEach((fileUpload) => {
-        if (fileUpload.status === UploadStatus.ok) {
-          someoneiscomplete = true;
-        } else if (fileUpload.status === UploadStatus.busy) {
-          someoneisbusy = true;
-          return; // forEach
-        } else if (fileUpload.status === UploadStatus.ready) {
-          someoneisready = true;
-        }
-      });
-
-      if (someoneiscomplete && !someoneisbusy) {
-        this.uploadCompleteEvent.emit();
-      }
-      this.disableUploadAllButton = !someoneisready || someoneisbusy;
-    }
-}
diff --git a/src/app/logindata.service.spec.ts b/src/app/logindata.service.spec.ts
new file mode 100644
index 00000000..4bc1cf2b
--- /dev/null
+++ b/src/app/logindata.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { LogindataService } from './logindata.service';
+
+describe('LogindataService', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      providers: [LogindataService]
+    });
+  });
+
+  it('should be created', inject([LogindataService], (service: LogindataService) => {
+    expect(service).toBeTruthy();
+  }));
+});
diff --git a/src/app/logindata.service.ts b/src/app/logindata.service.ts
new file mode 100644
index 00000000..8ceef376
--- /dev/null
+++ b/src/app/logindata.service.ts
@@ -0,0 +1,82 @@
+import { BackendService, ServerError, LoginData, BookletStatus, BookletDataList } from './backend.service';
+import { BehaviorSubject } from 'rxjs';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class LogindataService {
+
+  public pageTitle$ = new BehaviorSubject<string>('IQB-Testcenter - Willkommen');
+  public loginName$ = new BehaviorSubject<string>('');
+  public loginMode$ = new BehaviorSubject<string>('');
+  public workspaceName$ = new BehaviorSubject<string>('');
+  public groupName$ = new BehaviorSubject<string>('');
+  public personToken$ = new BehaviorSubject<string>('');
+  public personCode$ = new BehaviorSubject<string>('');
+  public bookletDbId$ = new BehaviorSubject<number>(0);
+  public bookletLabel$ = new BehaviorSubject<string>('');
+  public globalErrorMsg$ = new BehaviorSubject<string>('');
+  public allBooklets$ = new BehaviorSubject<BookletDataList>(null);
+
+  constructor(
+    private bs: BackendService
+  ) {
+    // on reload of application:
+    // look for personToken and get booklets and (if stored) selected booklet
+    const pt = localStorage.getItem('pt');
+    if ((typeof pt !== 'string') || (pt.length === 0)) {
+      localStorage.setItem('bi', '');
+      console.log('yop');
+    } else {
+      this.bs.getLoginDataByPersonToken(pt).subscribe(loginDataUntyped => {
+        if (loginDataUntyped instanceof ServerError) {
+          const e = loginDataUntyped as ServerError;
+          this.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+          localStorage.setItem('pt', '');
+          localStorage.setItem('bi', '');
+        } else {
+          const loginData = loginDataUntyped as LoginData;
+          this.globalErrorMsg$.next('');
+          this.groupName$.next(loginData.groupname);
+          this.workspaceName$.next(loginData.workspaceName);
+          this.personCode$.next(loginData.code);
+          this.allBooklets$.next(loginData.booklets);
+          this.loginMode$.next(loginData.mode);
+          this.personToken$.next(pt);
+          this.loginName$.next(loginData.loginname);
+
+          const b = localStorage.getItem('bi');
+          if (b !== null) {
+            this.bs.getBookletStatusByDbId(pt, +b).subscribe(bookletStatusUntyped => {
+              if (bookletStatusUntyped instanceof ServerError) {
+                const e = bookletStatusUntyped as ServerError;
+                this.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+                localStorage.setItem('bi', '');
+              } else {
+                const bookletStatus = bookletStatusUntyped as BookletStatus;
+                this.globalErrorMsg$.next('');
+                if (bookletStatus.canStart) {
+                  this.bookletDbId$.next(bookletStatus.id);
+                  this.bookletLabel$.next(bookletStatus.label);
+                } else {
+                  localStorage.setItem('bi', '');
+                }
+              }
+            });
+          }
+        }
+      }
+    );
+
+    }
+
+    this.personToken$.subscribe(t => localStorage.setItem('pt', t));
+    this.bookletDbId$.subscribe(id => localStorage.setItem('bi', id.toString()));
+  }
+
+  // *****************************************************
+  login(name: string, pw: string) {
+
+  }
+}
diff --git a/src/app/shared/backend.service.ts b/src/app/shared/backend.service.ts
deleted file mode 100644
index 107e7484..00000000
--- a/src/app/shared/backend.service.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import { Injectable, Inject } from '@angular/core';
-import { HttpClient, HttpHeaders, HttpEvent, HttpErrorResponse } from '@angular/common/http';
-import { Observable, throwError } from 'rxjs';
-import { catchError } from 'rxjs/operators';
-
-
-
-
-
-@Injectable()
-export class BackendService {
-
-  constructor(
-    @Inject('SERVER_URL') private serverUrl: string,
-    private http: HttpClient) { }
-
-  /*
-  getStatus(admintoken: string, logintoken: string, sessiontoken: string): Observable<LoginResponseData> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<LoginResponseData>(this.serverUrl + 'getStatus.php', {at: admintoken, lt: logintoken, st: sessiontoken}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  } */
-
-  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-  testlogin(name: string, password: string): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<string>(this.serverUrl + 'testlogin.php', {n: name, p: password}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-  getSessions(token: string): Observable<GetBookletsResponseData | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<GetBookletsResponseData>(this.serverUrl + 'getBooklets.php', {lt: token}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-
-  getBookletStatus(logintoken: string, code: string, bookletId: string): Observable<GetBookletResponseData | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<GetBookletResponseData>(this.serverUrl + 'getBookletStatus.php', {
-        lt: logintoken, c: code, b: bookletId}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-  startSession(token: string, code: string, bookletFilename: string): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<string>(this.serverUrl + 'startSession.php', {lt: token, c: code, b: bookletFilename}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-}
-
-  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-  private handleError(errorObj: HttpErrorResponse): Observable<ServerError> {
-    const myreturn: ServerError = {
-      label: 'Fehler bei Datenübertragung',
-      code: errorObj.status
-    };
-    if (errorObj.status === 401) {
-      myreturn.label = 'Fehler: Zugriff verweigert - bitte (neu) anmelden!';
-    } else if (errorObj.status === 503) {
-      myreturn.label = 'Fehler: Server meldet Datenbankproblem.';
-    } else if (errorObj.error instanceof ErrorEvent) {
-      myreturn.label = 'Fehler: ' + (<ErrorEvent>errorObj.error).message;
-    } else {
-      myreturn.label = 'Fehler: ' + errorObj.message;
-    }
-
-    return Observable.throw(myreturn.label);
-  }
-}
-
-
-// #############################################################################################
-
-export interface ServerError {
-  code: number;
-  label: string;
-}
-
-export interface LoginResponseData {
-  t: string;
-  n: string;
-  ws: string;
-}
-
-export interface BookletData {
-  name: string;
-  filename: string;
-  title: string;
-}
-
-export interface BookletDataList {
-  [code: string]: BookletData[];
-}
-
-export interface GetBookletsResponseData {
-  mode: string;
-  ws: string;
-  booklets: {[code: string]: BookletData[]};
-}
-
-export interface GetBookletResponseData {
-  statusLabel: string;
-  lastUnit: number;
-  canStart: boolean;
-}
-
diff --git a/src/app/shared/global-store.service.spec.ts b/src/app/shared/global-store.service.spec.ts
deleted file mode 100644
index 9bd3b1ac..00000000
--- a/src/app/shared/global-store.service.spec.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TestBed, inject } from '@angular/core/testing';
-
-import { GlobalStoreService } from './global-store.service';
-
-describe('GlobalStoreService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [GlobalStoreService]
-    });
-  });
-
-  it('should be created', inject([GlobalStoreService], (service: GlobalStoreService) => {
-    expect(service).toBeTruthy();
-  }));
-});
diff --git a/src/app/shared/global-store.service.ts b/src/app/shared/global-store.service.ts
deleted file mode 100644
index 36bfee38..00000000
--- a/src/app/shared/global-store.service.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { BehaviorSubject } from 'rxjs';
-import { Injectable, Component, Input, Output, EventEmitter } from '@angular/core';
-
-@Injectable()
-export class GlobalStoreService {
-
-  private _loginToken = '';
-
-  // title __________________________________________________
-  public pageTitle$ = new BehaviorSubject('IQB-Testcenter - Willkommen');
-  updatePageTitle(newTitle) {
-    this.pageTitle$.next(newTitle);
-  }
-
-  // tokens __________________________________________________
-  set loginToken(newToken: string) {
-    if (newToken !== this._loginToken) {
-      localStorage.setItem('lt', newToken);
-      this._loginToken = newToken;
-    }
-  }
-  get loginToken(): string {
-    if (this._loginToken.length === 0) {
-      this._loginToken = localStorage.getItem('lt');
-    }
-    return this._loginToken;
-  }
-}
diff --git a/src/app/start/start.component.css b/src/app/start/start.component.css
index cdba6bcb..16e70417 100644
--- a/src/app/start/start.component.css
+++ b/src/app/start/start.component.css
@@ -1,8 +1,8 @@
-div.codeinput, div.testselect {
+div.inputform {
   margin: 40px;
 }
 
-div.buttongroup {
+div.bookletbuttongroup {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
@@ -18,7 +18,7 @@ form {
   width: 100%;
 }
 
-button.testselectbutton {
+button.bookletselectbutton {
   margin: 10px;
 }
 
diff --git a/src/app/start/start.component.html b/src/app/start/start.component.html
index a88ea679..bf63ef05 100644
--- a/src/app/start/start.component.html
+++ b/src/app/start/start.component.html
@@ -1,31 +1,98 @@
 <div class="page-body">
-  <div class="sheetofpaper">
-    <div class="codeinput" *ngIf="showCodeinput">
-      <p>Für das Starten eines Tests ist die Eingabe eines Start-Kennwortes nötig. Damit werden einzelne
-        Testpersonen erkennbar. Bei Fragen bitte an die Betreuerin bzw. den Betreuer des Tests wenden!</p>
+  <div class="sheetofpaper" fxLayout="row">
 
-      <form [formGroup]="codeinputform" (ngSubmit)="codeinput()">
+    <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+    <div fxFlex fxLayout="column" fxLayoutGap="30px">
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="showLoginForm">
+        <p>Das <a href="http://www.iqb.hu-berlin.de" target="_blank">Institut zur Qualitätsentwicklung im Bildungswesen</a>
+          betreibt auf diesen Seiten eine Pilotanwendung für das computerbasierte Leistungstesten von
+          Schülerinnen und Schülern. Der Zugang zu einem Test ist nur möglich, wenn Sie von Testverantwortlichen
+          Zugangsdaten erhalten haben, die Sie bitte rechts eingeben. Es sind keine weiteren Seiten öffentlich verfügbar.</p>
+
+        <p>Die mit diesem Testsystem erhobenen Daten sind vertraulich und enthalten grundsätzlich keinen direkten
+          Personenbezug. Es werden z. B. nie Namen gespeichert. Um Auskünfte zu einer bestimmten Studie
+          zu erhalten, wenden Sie sich bitte an das <a href="mailto:mechtel@iqb.hu-berlin.de?subject=Zum%20IQB-Testsystem">
+            IQB</a>. Wir benötigen dazu den ungefähren Testzeitraum und das Bundesland, in dem die Studie
+            durchgeführt wurde.</p>
+      </div>
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="!showLoginForm">
+        <p>Anmeldestatus: {{ loginStatusText }}</p>
+      </div>
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="showCodeForm">
+        <p>Für das Starten eines Tests ist die Eingabe eines Personen-Codes nötig.</p>
+        <p>{{ codeInputPromt }}</p>
+      </div>
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="showBookletButtons">
+        <p *ngIf="bookletlist.length === 0">Fehler: Kein Testmaterial für diese Anmeldung gefunden.</p>
+        <p *ngIf="bookletlist.length === 1">{{ bookletSelectPromptOne }}</p>
+        <p *ngIf="bookletlist.length > 1">{{ bookletSelectPromptMany }}</p>
+      </div>
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="showTestRunningButtons">
+          <p>Es wird gerade ein Test ausgeführt. Bitte wählen Sie durch Klichen auf einen der beiden Schaltflächen
+            rechts, ob der Test fortgesetzt oder beendet werden soll!</p>
+      </div>
+    </div>
+
+    <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+    <div fxFlex="200px" fxLayout="column">
+      <!-- - - - - - - - - - - - - - - - - -->
+      <form [formGroup]="testtakerloginform" (ngSubmit)="testtakerlogin()" *ngIf="showLoginForm">
+        <mat-form-field class="full-width">
+          <input matInput formControlName="testname" placeholder="Anmeldename">
+        </mat-form-field>
         <mat-form-field class="full-width">
-          <input matInput formControlName="code" placeholder="Kennwort">
+          <input matInput type="password" formControlName="testpw" placeholder="Kennwort" (keyup.enter)="testtakerlogin()">
         </mat-form-field>
-        <button mat-raised-button type="submit" [disabled]="codeinputform.invalid">Weiter</button>
+        <button mat-raised-button type="submit" [disabled]="testtakerloginform.invalid" color="primary">Weiter</button>
       </form>
 
-      <p *ngIf="isError">{{ errorMessage }}</p>
-    </div>
-
-    <div class="testselect" *ngIf="showTeststartButtons">
-      <p>{{ select_message }}</p>
+      <!-- - - - - - - - - - - - - - - - - -->
+      <form [formGroup]="codeinputform" (ngSubmit)="codeinput()" *ngIf="showCodeForm">
+        <mat-form-field class="full-width">
+          <input matInput formControlName="code" placeholder="Personen-Code"(keyup.enter)="codeinput()">
+        </mat-form-field>
+        <button mat-raised-button type="submit" [disabled]="codeinputform.invalid" color="primary">Weiter</button>
+      </form>
 
-      <div class="buttongroup">
-        <button mat-raised-button class="testselectbutton" (click)="buttonStartTest($event)"
-          [value]="t.filename_and_lastUnit" [disabled]="!t.isEnabled" *ngFor="let t of testlist">
-            <p class="booklet_title">{{t.title}}</p>
-            <p class="booklet_status">{{t.statustxt}}</p>
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div fxLayout="row" fxLayoutGap="20px" *ngIf="showBookletButtons">
+        <p *ngIf="bookletlist.length === 0">
+          Für diese Anmeldung wurde kein Test gefunden.
+        </p>
+        <button mat-raised-button class="bookletselectbutton" (click)="buttonStartTest($event)"
+          [value]="b.filename_and_lastUnit" [disabled]="!t.isEnabled" *ngFor="let b of bookletlist">
+            <p class="booklet_title">{{b.title}}</p>
+            <p class="booklet_status">{{b.statustxt}}</p>
         </button>
       </div>
+
+      <!-- - - - - - - - - - - - - - - - - -->
+      <div *ngIf="showTestRunningButtons">
+        <div fxLayout="row" fxLayoutGap="20px">
+          <button mat-raised-button color="primary">Zum Test zurückkehren</button>
+          <button mat-raised-button color="primary">Test beenden</button>
+        </div>
+      </div>
+
     </div>
 
-    <p *ngIf="isError">{{ errorMessage }}</p>
+    <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+    <div fxFlex="200px" fxLayout="column">
+      <button mat-raised-button color="foreground" *ngIf="!showLoginForm">Test-Anmeldung ändern</button>
+      <button mat-raised-button color="foreground" *ngIf="validCodes.length > 1">Personen-Code ändern</button>
+      <p *ngIf="!showLoginForm || validCodes.length > 1">&nbsp;</p>
+      <button mat-raised-button color="foreground">Impressum/Datenschutz</button>
+      <p> {{ errorMsg }}</p>
+    </div>
   </div>
 </div>
diff --git a/src/app/start/start.component.ts b/src/app/start/start.component.ts
index ada50141..90345019 100644
--- a/src/app/start/start.component.ts
+++ b/src/app/start/start.component.ts
@@ -1,9 +1,10 @@
-import { TestdataService } from './../test-controller';
+import { map } from 'rxjs/operators';
+import { LogindataService } from './../logindata.service';
 import { MessageDialogComponent, MessageDialogData, MessageType } from './../iqb-common';
 import { MatDialog } from '@angular/material';
-import { BackendService, BookletData, GetBookletsResponseData, GetBookletResponseData } from './../shared/backend.service';
+import { BackendService, BookletData, PersonTokenAndBookletId,
+  BookletDataList, LoginData, BookletStatus, ServerError } from './../backend.service';
 import { Router } from '@angular/router';
-import { GlobalStoreService } from './../shared/global-store.service';
 import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
 import { FormGroup, FormBuilder, FormArray, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
 
@@ -12,111 +13,200 @@ import { FormGroup, FormBuilder, FormArray, FormControl, Validators, ReactiveFor
   styleUrls: ['./start.component.css']
 })
 export class StartComponent implements OnInit {
+  // for template
+  private showLoginForm = true;
+  private loginStatusText = 'nicht angemeldet';
+  private showCodeForm = false;
+  private codeInputPromt = 'Bitte gib den Personen-Code ein, den du auf dem Zettel am Platz gefunden hast!';
+  private showBookletButtons = false;
+  private bookletlist: StartButtonData[] = [];
+  private bookletSelectPromptOne = 'Bitte klick auf die Schaltfläche rechts, um den Test zu starten!';
+  private bookletSelectPromptMany = 'Bitte klicken Sie auf eine der Schaltflächen rechts, um einen Test zu starten!';
+  private showTestRunningButtons = false;
+  private validCodes = [];
 
-  codeinputform: FormGroup;
-  public showCodeinput: boolean;
-  public showTeststartButtons: boolean;
-  public select_message: string;
-  private sessiondata: GetBookletsResponseData;
-  private testlist: StartButtonData[];
-  private code = '';
-  private isError = false;
-  private errorMessage = '';
+  private testtakerloginform: FormGroup;
+  private codeinputform: FormGroup;
+  private errorMsg = '';
+  private loginToken = '';
+
+  // ??
+  // private sessiondata: PersonBooklets;
+  // private code = '';
+  // private isError = false;
+  // private errorMessage = '';
 
 
   constructor(private fb: FormBuilder,
-    private gss: GlobalStoreService,
-    private tss: TestdataService,
+    private lds: LogindataService,
     public messsageDialog: MatDialog,
     private router: Router,
     private bs: BackendService) {
-      this.showCodeinput = false;
-      this.showTeststartButtons = true;
-      this.select_message = 'Bitte warten.';
-      this.testlist = [];
-    }
+
+  }
 
   ngOnInit() {
-    this.gss.updatePageTitle('IQB-Testcenter - Start');
+    this.lds.pageTitle$.next('IQB-Testcenter - Start');
+
+    this.lds.personToken$.subscribe(pt => {
+      const bId = this.lds.bookletDbId$.getValue();
+      if (pt.length > 0) {
+        this.showLoginForm = false;
+        this.showCodeForm = false;
+        this.showBookletButtons = bId === 0;
+        this.showTestRunningButtons = bId > 0;
+        this.loginStatusText = 'angemeldet als "' + this.lds.loginName$.getValue();
+        const code = this.lds.personCode$.getValue();
+        if (code.length > 0) {
+          this.loginStatusText += '/' + code;
+        }
+        this.loginStatusText += '", ' + this.lds.loginMode$.getValue();
+      } else {
+        this.showLoginForm = this.loginToken.length === 0;
+        this.showCodeForm = this.validCodes.length > 1;
+        this.showBookletButtons = false;
+        this.showTestRunningButtons = false;
+        this.loginStatusText = 'nicht angemeldet';
+      }
+    });
+
+    this.lds.bookletDbId$.subscribe(id => {
+      const ptLength = this.lds.personToken$.getValue().length;
+      if (id > 0) {
+        this.showLoginForm = false;
+        this.showCodeForm = false;
+        this.showBookletButtons = false;
+        this.showTestRunningButtons = ptLength > 0;
+      } else {
+        this.showLoginForm = ptLength === 0;
+        this.showCodeForm = false;
+        this.showBookletButtons = ptLength > 0;
+        this.showTestRunningButtons = false;
+      }
+    });
+
+    this.lds.globalErrorMsg$.subscribe(m => this.errorMsg = m);
+
+    this.testtakerloginform = this.fb.group({
+      testname: this.fb.control(this.lds.loginName$.getValue(), [Validators.required, Validators.minLength(3)]),
+      testpw: this.fb.control('', [Validators.required, Validators.minLength(3)])
+    });
 
     this.codeinputform = this.fb.group({
       code: this.fb.control('', [Validators.required, Validators.minLength(1)])
     });
+  }
 
-    this.bs.getSessions(this.gss.loginToken).subscribe(
-      (bdata: GetBookletsResponseData) => {
-        this.sessiondata = bdata;
-
-        if (Object.keys(this.sessiondata.booklets).length > 1) {
-          this.showCodeinput = true;
-          this.showTeststartButtons = false;
+  // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+  testtakerlogin() {
+    this.bs.login(this.testtakerloginform.get('testname').value, this.testtakerloginform.get('testpw').value).subscribe(
+      loginTokenUntyped => {
+        if (loginTokenUntyped instanceof ServerError) {
+          const e = loginTokenUntyped as ServerError;
+          this.lds.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+          // no change in other data
         } else {
-          this.setTestselectButtons();
-        }
-      }, (errormsg: string) => {
-        this.isError = true;
-        this.select_message = errormsg;
+          this.validCodes = [];
+          this.bookletlist = [];
+          this.lds.personToken$.next('');
+          this.lds.personCode$.next('');
+          this.lds.globalErrorMsg$.next('');
+          this.lds.workspaceName$.next('');
+          this.lds.allBooklets$.next(null);
+          this.lds.bookletDbId$.next(0);
+          this.lds.bookletLabel$.next('');
+          this.lds.loginMode$.next('');
+          this.lds.loginName$.next('');
+
+          this.loginToken = loginTokenUntyped as string;
+
+          // overwrite all data
+          this.bs.getLoginDataByLoginToken(this.loginToken).subscribe(
+            loginDataUntyped => {
+              if (loginDataUntyped instanceof ServerError) {
+                const e = loginDataUntyped as ServerError;
+                this.lds.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+                this.loginToken = '';
+              } else {
+                const loginData = loginDataUntyped as LoginData;
+                this.lds.personToken$.next('');
+                this.lds.allBooklets$.next(loginData.booklets);
+                this.lds.groupName$.next(loginData.groupname);
+                this.lds.workspaceName$.next(loginData.workspaceName);
+                this.lds.loginMode$.next(loginData.mode);
+                this.lds.loginName$.next(loginData.loginname);
+
+                this.validCodes = Object.keys(loginData.booklets);
+                this.showLoginForm = false;
+
+                if (this.validCodes.length > 1) {
+                  this.showCodeForm = true;
+                } else {
+                  this.lds.personCode$.next((this.validCodes.length > 0) ? this.validCodes[0] : '');
+                  this.showCodeForm = false;
+                  this.showBookletButtons = true;
+                  this.bookletlist = this.getStartButtonData(this.lds.allBooklets$.getValue());
+                }
+              }
+            });
+          }
       }
     );
   }
 
   // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   codeinput() {
-    this.isError = false;
-    this.errorMessage = '';
-    if (this.setTestselectButtons()) {
-      this.showCodeinput = false;
-      this.showTeststartButtons = true;
+    const myCode = this.codeinputform.get('code').value as string;
+    if (myCode.length === 0) {
+      this.messsageDialog.open(MessageDialogComponent, {
+        width: '400px',
+        data: <MessageDialogData>{
+          title: 'Eingabe Personen-Code',
+          content: 'Bitte geben Sie einen Personen-Code ein!.',
+          type: MessageType.error
+        }
+      });
+    } else if (this.validCodes.indexOf(myCode) < 0) {
+      this.messsageDialog.open(MessageDialogComponent, {
+        width: '400px',
+        data: <MessageDialogData>{
+          title: 'Eingabe Personen-Code',
+          content: 'Für diesen Personen-Code liegen keine Informationen vor.',
+          type: MessageType.error
+        }
+      });
+    } else {
+      this.lds.personCode$.next(myCode);
+      this.lds.personToken$.next('');
+      this.showCodeForm = false;
+      this.showBookletButtons = true;
+      this.bookletlist = this.getStartButtonData(this.lds.allBooklets$.getValue());
     }
   }
 
   // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-  setTestselectButtons(): boolean {
-    let codeIsValid = true;
-    this.testlist = [];
-    if (Object.keys(this.sessiondata.booklets).length > 1) {
-      this.code = this.codeinputform.get('code').value;
-      codeIsValid = Object.keys(this.sessiondata.booklets).includes(this.code);
-    } else {
-      this.code = Object.keys(this.sessiondata.booklets)[0];
-    }
+  getStartButtonData(allBooklets: BookletDataList): StartButtonData[] {
+    const myreturn: StartButtonData[] = [];
+    const lt = this.loginToken;
+    const pt = this.lds.personToken$.getValue();
+    const code = this.lds.personCode$.getValue();
 
-    if (codeIsValid) {
-      const myBooklets = <BookletData[]>this.sessiondata.booklets[this.code];
+    if (pt.length > 0 || lt.length > 0) {
+      const myBooklets = allBooklets[this.lds.personCode$.getValue()];
       for (const booklet of myBooklets) {
         const myTest = new StartButtonData(booklet.name, booklet.title, booklet.filename);
-        this.testlist.push(myTest);
-        myTest.loadStatus(this.bs, this.gss, this.code);
-      }
-
-      if (this.testlist.length === 1) {
-        this.select_message = 'Bitte klicken Sie auf den Schalter unten, um den Test zu starten!';
-      } else {
-        this.select_message = 'Bitte klicken Sie auf einen der Schalter unten, um den Test auszuwählen und zu starten!';
-      }
-      if (this.sessiondata.mode === 'trial') {
-        this.select_message += ' Achtung: Dieser Test wird im Modus "trial" durchgeführt, d. h. es gelten keine ';
-        this.select_message += 'Zeitbeschränkungen, aber die Navigation ist so beschränkt wie im normalen Test.';
-      } else if (this.sessiondata.mode === 'review') {
-        this.select_message += ' Achtung: Dieser Test wird im Modus "review" durchgeführt, d. h. es gelten keine ';
-        this.select_message += 'Zeitbeschränkungen und die Navigation ist nicht beschränkt.';
-        this.select_message += ' Nutzen Sie das Menü oben rechts, um Kommentare zu vergeben!';
-      }
-    } else {
-
-      this.messsageDialog.open(MessageDialogComponent, {
-        width: '400px',
-        data: <MessageDialogData>{
-          title: 'Eingabe Kennwort für Test',
-          content: 'Für dieses Kennwort wurde kein Test gefunden.',
-          type: MessageType.error
+        if (pt.length > 0) {
+          myTest.getBookletStatusByPersonToken(this.bs, pt);
+        } else {
+          myTest.getBookletStatusByLoginToken(this.bs, lt, code);
         }
-      });
+        myreturn.push(myTest);
+      }
     }
-
-    return codeIsValid;
+    return myreturn;
   }
 
+  // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   buttonStartTest(event) {
     let myElement = event.target;
     do {
@@ -126,19 +216,60 @@ export class StartComponent implements OnInit {
     } while (myElement.localName !== 'button');
 
     const ButtonDataSplits = myElement.value.split('##');
+    const lt = this.loginToken;
+    const pt = this.lds.personToken$.getValue();
+    const code = this.lds.personCode$.getValue();
 
-    this.isError = false;
-    this.errorMessage = '';
-    this.bs.startSession(this.gss.loginToken, this.code, ButtonDataSplits[0]).subscribe(
-      (sessiontoken: string) => {
-        this.tss.updateSessionToken(sessiontoken);
-        this.tss.gotoFirstUnit(ButtonDataSplits[1]);
-      }, (errormsg: string) => {
-        this.tss.updateSessionToken('');
-        this.isError = true;
-        this.errorMessage = errormsg;
-      }
-    );
+    if (pt.length > 0 || lt.length > 0) {
+      if (pt.length > 0) {
+        this.bs.startBookletByPersonToken(pt, ButtonDataSplits[0]).subscribe(
+          bookletIdUntyped => {
+            if (bookletIdUntyped instanceof ServerError) {
+              const e = bookletIdUntyped as ServerError;
+              this.lds.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+            } else {
+              const bookletId = bookletIdUntyped as number;
+              if (bookletId > 0) {
+                this.lds.bookletDbId$.next(bookletId);
+                console.log('jippi: ' + bookletId.toString());
+                // ************************************************
+
+                // this.router.navigateByUrl('/u');
+
+                // ************************************************
+              } else {
+                this.lds.globalErrorMsg$.next('ungültige Anmeldung');
+              }
+            }
+          }
+        );
+      } else {
+        this.bs.startBookletByLoginToken(lt, code, ButtonDataSplits[0]).subscribe(
+          startDataUntyped => {
+            if (startDataUntyped instanceof ServerError) {
+              const e = startDataUntyped as ServerError;
+              this.lds.globalErrorMsg$.next(e.code.toString() + ': ' + e.label);
+            } else {
+              const startData = startDataUntyped as PersonTokenAndBookletId;
+              if (startData.bookletId > 0) {
+                this.lds.bookletDbId$.next(startData.bookletId);
+                this.lds.personToken$.next(startData.personToken);
+                console.log('jippi: ' + startData.bookletId.toString());
+                // ************************************************
+
+                // this.router.navigateByUrl('/u');
+
+                // ************************************************
+              } else {
+                this.lds.globalErrorMsg$.next('ungültige Anmeldung');
+              }
+            }
+          }
+        );
+          }
+    } else {
+      this.lds.globalErrorMsg$.next('ungültige Anmeldung');
+    }
   }
 }
 
@@ -153,7 +284,11 @@ export class StartButtonData {
   statustxt: string;
   filename_and_lastUnit: string;
 
-  constructor(name: string, title: string, filename: string) {
+  constructor(
+    name: string,
+    title: string,
+    filename: string
+  ) {
     this.name = name;
     this.title = title;
     this.filename = filename;
@@ -161,11 +296,31 @@ export class StartButtonData {
     this.statustxt = 'Bitte warten';
   }
 
-  loadStatus(bs: BackendService, gss: GlobalStoreService, code: string) {
-    bs.getBookletStatus(gss.loginToken, code, this.name).subscribe((respData: GetBookletResponseData) => {
-      this.statustxt = respData.statusLabel;
-      this.isEnabled = respData.canStart;
-      this.filename_and_lastUnit = this.filename + '##' + respData.lastUnit;
+  public getBookletStatusByLoginToken(bs: BackendService, loginToken: string, code: string) {
+    bs.getBookletStatusByNameAndLoginToken(loginToken, code, this.name).subscribe(respDataUntyped => {
+      if (respDataUntyped instanceof ServerError) {
+        const e = respDataUntyped as ServerError;
+        this.statustxt = e.code.toString() + ': ' + e.label;
+      } else {
+        const respData = respDataUntyped as BookletStatus;
+        this.statustxt = respData.statusLabel;
+        this.isEnabled = respData.canStart;
+        this.filename_and_lastUnit = this.filename + '##' + respData.lastUnit;
+      }
+    });
+  }
+
+  public getBookletStatusByPersonToken(bs: BackendService, personToken: string) {
+    bs.getBookletStatusByNameAndPersonToken(personToken, this.name).subscribe(respDataUntyped => {
+      if (respDataUntyped instanceof ServerError) {
+        const e = respDataUntyped as ServerError;
+        this.statustxt = e.code.toString() + ': ' + e.label;
+      } else {
+        const respData = respDataUntyped as BookletStatus;
+        this.statustxt = respData.statusLabel;
+        this.isEnabled = respData.canStart;
+        this.filename_and_lastUnit = this.filename + '##' + respData.lastUnit;
+      }
     });
   }
 }
diff --git a/src/app/test-controller/backend.service.spec.ts b/src/app/test-controller/backend.service.spec.ts
deleted file mode 100644
index c31039d7..00000000
--- a/src/app/test-controller/backend.service.spec.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TestBed, inject } from '@angular/core/testing';
-
-import { BackendService } from './backend.service';
-
-describe('BackendService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [BackendService]
-    });
-  });
-
-  it('should be created', inject([BackendService], (service: BackendService) => {
-    expect(service).toBeTruthy();
-  }));
-});
diff --git a/src/app/test-controller/backend.service.ts b/src/app/test-controller/backend.service.ts
deleted file mode 100644
index 29c024e8..00000000
--- a/src/app/test-controller/backend.service.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { Injectable, Inject } from '@angular/core';
-import { HttpClient, HttpParams, HttpHeaders, HttpEvent, HttpErrorResponse } from '@angular/common/http';
-import { ResponseContentType } from '@angular/http';
-import { BehaviorSubject ,  Observable, throwError } from 'rxjs';
-import { catchError, map, tap } from 'rxjs/operators';
-
-
-@Injectable()
-export class BackendService {
-
-  private unitCache: UnitData[] = [];
-  private lastBookletState = '';
-  private lastUnitResponses = '';
-  private lastUnitRestorePoint = '';
-
-  constructor(
-    @Inject('SERVER_URL') private serverUrl: string,
-    private http: HttpClient) { }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  getSessionData(sessiontoken: string): Observable<SessionData | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-      .post<SessionData>(this.serverUrl + 'getSessionData.php', {st: sessiontoken}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  setBookletStatus(sessiontoken: string, state: {}): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    if ((sessiontoken + JSON.stringify(state)) === this.lastBookletState) {
-      return new Observable(null);
-    } else {
-      this.lastBookletState = sessiontoken + JSON.stringify(state);
-      return this.http
-      .post<string>(this.serverUrl + 'setBookletStatus.php', {st: sessiontoken, state: state}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-    }
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  getUnit(sessiontoken: string, unitid: string): Observable<UnitData | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    const myUnitdata = this.unitCache[unitid];
-    if (typeof myUnitdata === 'undefined') {
-      return this.http
-      .post<UnitData>(this.serverUrl + 'getUnit.php', {st: sessiontoken, u: unitid}, httpOptions)
-        .pipe(
-          tap(r => this.unitCache[unitid] = r),
-          catchError(this.handleError)
-        );
-    } else {
-      return new Observable (observer => {
-        observer.next(myUnitdata);
-        observer.complete();
-      });
-    }
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  getUnitResource(sessiontoken: string, resId: string): Observable<string | ServerError> {
-    const myHttpOptions = {
-          headers: new HttpHeaders({
-            'Content-Type':  'application/json'
-          }),
-          responseType: 'arraybuffer' as 'json'
-      };
-
-    return this.http
-    .post<ArrayBuffer>(this.serverUrl + 'getUnitResource.php', {st: sessiontoken, r: resId}, myHttpOptions)
-      .pipe(
-        map((r: ArrayBuffer) => {
-          let str64 = '';
-          const alen = r.byteLength;
-          for (let i = 0; i < alen; i++) {
-            str64 += String.fromCharCode(r[i]);
-          }
-          return window.btoa(str64);
-        }),
-        catchError(this.handleError)
-    );
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  getUnitResource64(sessiontoken: string, resId: string): Observable<string | ServerError> {
-    const myHttpOptions = {
-          headers: new HttpHeaders({
-            'Content-Type':  'application/json'
-          }),
-          responseType: 'text' as 'json'
-      };
-
-      return this.http
-      .post<string>(this.serverUrl + 'getUnitResource64.php', {st: sessiontoken, r: resId}, myHttpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  getUnitResourceTxt(sessiontoken: string, resId: string): Observable<string | ServerError> {
-    const myHttpOptions = {
-          headers: new HttpHeaders({
-            'Content-Type':  'application/json'
-          }),
-          responseType: 'text' as 'json'
-      };
-
-      return this.http
-      .post<string>(this.serverUrl + 'getUnitResourceTxt.php', {st: sessiontoken, r: resId}, myHttpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  setUnitResponses(sessiontoken: string, unit: string, unitdata: string): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    if ((sessiontoken + unit + JSON.stringify(unitdata)) === this.lastUnitResponses) {
-      return new Observable(null);
-    } else {
-      this.lastUnitResponses = sessiontoken + unit + JSON.stringify(unitdata);
-      // todo: store the response for evaluation
-      return this.http
-      .post<string>(this.serverUrl + 'setUnitResponses.php', {st: sessiontoken, u: unit, responses: unitdata}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-    }
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  setUnitRestorePoint(sessiontoken: string, unit: string, unitdata: string): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    if ((sessiontoken + unit + JSON.stringify(unitdata)) === this.lastUnitRestorePoint) {
-      return new Observable(null);
-    } else {
-      this.lastUnitRestorePoint = sessiontoken + unit + JSON.stringify(unitdata);
-      const myUnitdata: UnitData = this.unitCache[unit];
-      if (typeof myUnitdata !== 'undefined') {
-        myUnitdata.restorepoint = unitdata;
-      }
-      return this.http
-      .post<string>(this.serverUrl + 'setUnitRestorePoint.php', {st: sessiontoken, u: unit, restorepoint: unitdata}, httpOptions)
-        .pipe(
-          catchError(this.handleError)
-        );
-    }
-  }
-
-  // 888888888888888888888888888888888888888888888888888888888888888888
-  setUnitLog(sessiontoken: string, unit: string, unitdata: {}): Observable<string | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
-    return this.http
-    .post<string>(this.serverUrl + 'setUnitLog.php', {st: sessiontoken, u: unit, log: unitdata}, httpOptions)
-      .pipe(
-        catchError(this.handleError)
-      );
-  }
-
-  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-  private handleError(errorObj: HttpErrorResponse): Observable<ServerError> {
-    const myreturn: ServerError = {
-      label: 'Fehler bei Datenübertragung',
-      code: errorObj.status
-    };
-    if (errorObj.status === 401) {
-      myreturn.label = 'Fehler: Zugriff verweigert - bitte (neu) anmelden!';
-    } else if (errorObj.status === 503) {
-      myreturn.label = 'Fehler: Server meldet Datenbankproblem.';
-    } else if (errorObj.error instanceof ErrorEvent) {
-      myreturn.label = 'Fehler: ' + (<ErrorEvent>errorObj.error).message;
-    } else {
-      myreturn.label = 'Fehler: ' + errorObj.message;
-    }
-
-    return Observable.throw(myreturn.label);
-  }
-}
-
-export interface SessionData {
-  xml: string;
-  locked: boolean;
-  u: number;
-}
-
-export interface UnitData {
-  xml: string;
-  restorepoint: string;
-  status: {};
-}
-
-export interface ServerError {
-  code: number;
-  label: string;
-}
diff --git a/src/app/test-controller/index.ts b/src/app/test-controller/index.ts
deleted file mode 100644
index 2193da2f..00000000
--- a/src/app/test-controller/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { TestControllerComponent } from './test-controller.component';
-export { TestControllerModule } from './test-controller.module';
-export { TestdataService } from './testdata.service';
-
diff --git a/src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.spec.ts b/src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.spec.ts
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.ts b/src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.ts
deleted file mode 100644
index 14a2a8ee..00000000
--- a/src/app/test-controller/resize-IFrameChild/resize-IFrameChild.directive.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Component, Directive, ElementRef, EventEmitter, HostListener,
-    Input, OnDestroy, OnInit, Output } from '@angular/core';
-
-
-  @Directive({
-    selector: 'div[iqbResizeIFrameChild]'
-  })
-  export class ResizeIFrameChildDirective  {
-
-
-    private _element: HTMLElement;
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    constructor(private element: ElementRef) {
-        this._element = this.element.nativeElement;
-    }
-
-
-    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    @HostListener('window:resize')
-    public onResize(): any {
-      const iFrameList = this._element.getElementsByTagName('iframe');
-      if (iFrameList.length > 0) {
-        let myIFrame: HTMLIFrameElement;
-        myIFrame = iFrameList[0];
-        const divHeight = this._element.clientHeight;
-        myIFrame.setAttribute('height', String(divHeight));
-      }
-    }
-  }
diff --git a/src/app/test-controller/test-controller-routing.module.ts b/src/app/test-controller/test-controller-routing.module.ts
deleted file mode 100644
index 8a3187c2..00000000
--- a/src/app/test-controller/test-controller-routing.module.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { UnitActivateGuard, UnitDeactivateGuard, UnitResolver } from './unithost/unit-routing';
-import { UnithostComponent } from './unithost/unithost.component';
-import { TestControllerComponent } from './test-controller.component';
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-
-
-const routes: Routes = [
-  {
-    path: 't',
-    component: TestControllerComponent,
-    children: [
-//      {path: '', redirectTo: 'u/0', pathMatch: 'full'},
-//      {path: 'u', redirectTo: 'u/0', pathMatch: 'full'},
-      {path: 'u/:u',
-        component: UnithostComponent,
-        // canActivate: [UnitActivateGuard],
-        // canDeactivate: [UnitDeactivateGuard],
-        resolve: {
-          unit: UnitResolver
-        }
-      }
-    ]
-  }];
-
-@NgModule({
-  imports: [RouterModule.forChild(routes)],
-  exports: [RouterModule]
-})
-export class TestControllerRoutingModule { }
diff --git a/src/app/test-controller/test-controller.component.spec.ts b/src/app/test-controller/test-controller.component.spec.ts
deleted file mode 100644
index 3e6a5082..00000000
--- a/src/app/test-controller/test-controller.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { TestControllerComponent } from './test-controller.component';
-
-describe('TestControllerComponent', () => {
-  let component: TestControllerComponent;
-  let fixture: ComponentFixture<TestControllerComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ TestControllerComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(TestControllerComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts
deleted file mode 100644
index 3b5ff62f..00000000
--- a/src/app/test-controller/test-controller.component.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
-  template: `<router-outlet></router-outlet>`,
-  styles: ['#testcontroller-main > ng-component:last-child { width: 100%;}']
-})
-export class TestControllerComponent { }
diff --git a/src/app/test-controller/test-controller.module.ts b/src/app/test-controller/test-controller.module.ts
deleted file mode 100644
index 48949f28..00000000
--- a/src/app/test-controller/test-controller.module.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { TestdataService } from './testdata.service';
-import { BackendService } from './backend.service';
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { TestControllerRoutingModule } from './test-controller-routing.module';
-import { UnithostComponent } from './unithost/unithost.component';
-import { MatProgressSpinnerModule } from '@angular/material';
-import { TestControllerComponent } from './test-controller.component';
-import { ResizeIFrameChildDirective } from './resize-IFrameChild/resize-IFrameChild.directive';
-import { routingProviders } from './unithost/unit-routing';
-
-
-@NgModule({
-  imports: [
-    CommonModule,
-    TestControllerRoutingModule,
-    MatProgressSpinnerModule
-  ],
-  declarations: [
-    UnithostComponent,
-    TestControllerComponent,
-    ResizeIFrameChildDirective
-  ],
-  providers: [
-    TestdataService,
-    BackendService,
-    routingProviders
-  ],
-  exports: [
-    TestControllerComponent
-  ]
-})
-export class TestControllerModule { }
diff --git a/src/app/test-controller/testdata.service.spec.ts b/src/app/test-controller/testdata.service.spec.ts
deleted file mode 100644
index 64bb3050..00000000
--- a/src/app/test-controller/testdata.service.spec.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TestBed, inject } from '@angular/core/testing';
-
-import { TestdataService } from './testdata.service';
-
-describe('TestdataService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [TestdataService]
-    });
-  });
-
-  it('should be created', inject([TestdataService], (service: TestdataService) => {
-    expect(service).toBeTruthy();
-  }));
-});
diff --git a/src/app/test-controller/testdata.service.ts b/src/app/test-controller/testdata.service.ts
deleted file mode 100644
index beaf8f65..00000000
--- a/src/app/test-controller/testdata.service.ts
+++ /dev/null
@@ -1,468 +0,0 @@
-import { BehaviorSubject ,  Observable } from 'rxjs';
-import { BackendService, SessionData, UnitData, ServerError } from './backend.service';
-import { Injectable, Component, Input, Output, EventEmitter, Pipe } from '@angular/core';
-import { Element } from '@angular/compiler';
-import { mergeAll, switchMap, map } from 'rxjs/operators';
-import { Router } from '@angular/router';
-
-@Injectable()
-export class TestdataService {
-  public pageTitle$ = new BehaviorSubject<string>('Lade Seite...');
-  public navPrevEnabled$ = new BehaviorSubject<boolean>(false);
-  public navNextEnabled$ = new BehaviorSubject<boolean>(false);
-  public isSession$ = new BehaviorSubject<boolean>(false);
-  public statusmessage$ = new BehaviorSubject<string>('Bitte warten!');
-  public bookletname$ = new BehaviorSubject<string>('-');
-  public unitname$ = new BehaviorSubject<string>('-');
-  public pendingItemDefinition$ = new BehaviorSubject<string>('');
-  public pendingItemRestorePoint$ = new BehaviorSubject<string>('');
-  public pendingItemResources$ = new BehaviorSubject<{[resourceID: string]: string}>(null);
-
-  get sessionToken(): string {
-    return this._sessionToken;
-  }
-
-
-  // .................................................................................
-  private _sessionToken = '';
-  private allUnits: UnitDef[] = [];
-  private currentUnitId$ = new BehaviorSubject<number>(0);
-
-  // ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
-  constructor(
-    private bs: BackendService,
-    private router: Router
-  ) {
-    this._sessionToken = localStorage.getItem('st');
-    if (this._sessionToken === null) {
-      this._sessionToken = '';
-    }
-    if (this._sessionToken === '') {
-      this.isSession$.next(false);
-    } else {
-      this.isSession$.next(true);
-    }
-
-    this.currentUnitId$.subscribe(myUnitId => {
-      this.navPrevEnabled$.next(myUnitId > 0);
-      this.navNextEnabled$.next((myUnitId >= 0) && (myUnitId < this.allUnits.length - 1));
-    });
-
-/*    this.isSession$.subscribe(isSession => {
-      if (isSession) {
-
-      } else {
-        this.updateBookletData('?', [], '', '');
-      }
-    }); */
-  }
-
-  getUnitAt (unitId: any): Observable<UnitDef | ServerError> {
-    const unitIdNumber = Number(unitId);
-    if (Number.isNaN(unitId) || (unitId < 0)) {
-      return new Observable(observer => {
-        observer.next(null);
-        observer.complete();
-      });
-    } else {
-      if (this.allUnits.length === 0) {
-
-        // first call at the beginning of test -> get booklet
-        return this.bs.getSessionData(this.sessionToken)
-          .pipe(
-            map((bdata: SessionData) => {
-
-            let myBookletName = '';
-
-            // Create Unit-List
-            const oParser = new DOMParser();
-            const oDOM = oParser.parseFromString(bdata.xml, 'text/xml');
-            if (oDOM.documentElement.nodeName === 'Booklet') {
-              // ________________________
-              const metadataElements = oDOM.documentElement.getElementsByTagName('Metadata');
-              if (metadataElements.length > 0) {
-                const metadataElement = metadataElements[0];
-                const NameElement = metadataElement.getElementsByTagName('Name')[0];
-                myBookletName = NameElement.textContent;
-              }
-
-              // ________________________
-              const unitsElements = oDOM.documentElement.getElementsByTagName('Units');
-              if (unitsElements.length > 0) {
-                const unitsElement = unitsElements[0];
-                const unitList = unitsElement.getElementsByTagName('Unit');
-                for (let i = 0; i < unitList.length; i++) {
-                  this.allUnits[i] = new UnitDef(unitList[i].getAttribute('name'), unitList[i].getAttribute('title'));
-                  this.allUnits[i].sequenceId = i;
-                }
-              }
-            }
-            return this.allUnits[unitId];
-          }));
-        } else {
-            // this.updateBookletData(myBookletName, myUnits, 'Bitte warten', bdata.status);
-        // }, (err: ServerError) => {
-            // this.updateBookletData('?', [], err.label, '');
-          return new Observable(observer => {
-            observer.next(this.allUnits[unitId]);
-            observer.complete();
-          });
-      }
-    }
-  }
-
-  // switchMap because current requests have to cancelled if new fetchUnitData-call arrives
-  fetchUnitData (myUnit: UnitDef): Observable<UnitDef> {
-    if (myUnit === null) {
-      return new Observable(observer => {
-        observer.next(null);
-        observer.complete();
-      });
-    } else {
-
-      return this.bs.getUnit(this.sessionToken, myUnit.name)
-        .pipe(
-          switchMap((udata: UnitData) => {
-            myUnit.restorePoint = udata.restorepoint;
-
-            const oParser = new DOMParser();
-            const oDOM = oParser.parseFromString(udata.xml, 'text/xml');
-            if (oDOM.documentElement.nodeName === 'Unit') {
-              // ________________________
-              const dataElements = oDOM.documentElement.getElementsByTagName('Data');
-              if (dataElements.length > 0) {
-                const dataElement = dataElements[0];
-                myUnit.dataForItemplayer = dataElement.textContent;
-              }
-
-              // ________________________
-              const resourcesElements = oDOM.documentElement.getElementsByTagName('Resources');
-              if (resourcesElements.length > 0) {
-                let ResourceFetchPromises: Promise<number>[];
-                ResourceFetchPromises = [];
-
-                // resources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                const resourcesElement = resourcesElements[0];
-                const rList = resourcesElement.getElementsByTagName('Resource');
-                for (let i = 0; i < rList.length; i++) {
-                  const myResource = new ResourceData(rList[i].textContent, rList[i].getAttribute('id'));
-                  myResource.type = rList[i].getAttribute('type');
-                  myUnit.resources.push(myResource);
-
-                  // prepare promise for each resource loading
-                  if (myResource.type === 'itemplayer_html') {
-                    ResourceFetchPromises.push(new Promise((resolve, reject) => {
-                      this.bs.getUnitResourceTxt(this.sessionToken, myResource.filename).subscribe(
-                        (fileAsTxt: string) => {
-                          myResource.dataString = fileAsTxt;
-                          resolve(myResource.dataString.length);
-                        }
-                      );
-                    }));
-                  } else {
-                    ResourceFetchPromises.push(new Promise((resolve, reject) => {
-                      this.bs.getUnitResource64(this.sessionToken, myResource.filename).subscribe(
-                        (fileAsBase64: string) => {
-                          myResource.dataString = fileAsBase64;
-                          resolve(myResource.dataString.length);
-                        }
-                      );
-                    }));
-                  }
-                }
-
-                // run all promises (i. e. resource loading requests)
-                return Promise.all(ResourceFetchPromises)
-                  .then(promisesReturnValues => {
-                    this.bs.setBookletStatus(this.sessionToken, {u: myUnit.sequenceId})
-                      .subscribe();
-                    return myUnit;
-                  });
-
-
-              } else {
-                return this.bs.setBookletStatus(this.sessionToken, {u: myUnit.sequenceId})
-                .pipe(
-                  map(d => myUnit)
-                );
-              }
-            } else {
-              return null;
-            }
-          }));
-        }
-  }
-
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  getUnitId(target: string): number {
-    let myUnitId = this.currentUnitId$.getValue();
-
-    if (this.allUnits.length > 0) {
-      switch (target) {
-        case 'next':
-          if (myUnitId < this.allUnits.length - 1) {
-            myUnitId = myUnitId + 1;
-          }
-          break;
-
-        case 'prev':
-          if (myUnitId > 0) {
-            myUnitId = myUnitId - 1;
-          }
-          break;
-
-        case 'first':
-          myUnitId = 0;
-          break;
-
-        case 'last':
-          myUnitId = this.allUnits.length - 1;
-          break;
-
-        default:
-          myUnitId = -1;
-          break;
-      }
-    } else {
-      myUnitId = 0;
-    }
-    return myUnitId;
-  }
-
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  public gotoPrevUnit() {
-    this.gotoUnit(this.getUnitId('prev'));
-  }
-
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  public gotoNextUnit() {
-    this.gotoUnit(this.getUnitId('next'));
-  }
-
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  public gotoFirstUnit(lastUnit?: number) {
-    if (lastUnit == null) {
-      this.gotoUnit(this.getUnitId('first'));
-    } else {
-      this.gotoUnit(lastUnit);
-    }
-  }
-
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  // + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-  private gotoUnit(newUnitId) {
-    this.router.navigateByUrl('/t/u/' + newUnitId, { skipLocationChange: false });
-  }
-
-  // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
-  // app.component.ngOnInit sets a listener on 'message'-event.
-  processMessagePost(postData: MessageEvent) {
-    const msgData = postData.data;
-    const msgType = msgData['type'];
-    if ((msgType !== undefined) || (msgType !== null)) {
-      if (msgType.substr(0, 7) === 'OpenCBA') {
-        // .........................................
-        const targetWindow = postData.source;
-        switch (msgType) {
-
-          // // // // // // //
-          case 'OpenCBA.stateChanged':
-            if (msgData['newState'] === 'readyToInitialize') {
-              let hasData = false;
-              const initParams = {};
-
-              const pendingSpec = this.pendingItemDefinition$.getValue();
-              if ((pendingSpec !== null) || (pendingSpec.length > 0)) {
-                initParams['itemSpecification'] = pendingSpec;
-                hasData = true;
-                this.pendingItemDefinition$.next(null);
-              }
-              const pendingRes = this.pendingItemResources$.getValue();
-              if ((pendingRes !== null) || (pendingRes !== {})) {
-                initParams['itemResources'] = pendingRes;
-                hasData = true;
-                this.pendingItemResources$.next({});
-              }
-              const pendingRP = this.pendingItemRestorePoint$.getValue();
-              if ((pendingRP !== null) || (pendingRP.length > 0)) {
-                initParams['restorePoint'] = pendingRP;
-                hasData = true;
-                this.pendingItemRestorePoint$.next(null);
-              }
-
-              if (hasData) {
-                targetWindow.postMessage({
-                  type: 'OpenCBA.initItemPlayer',
-                  initParameters: initParams
-                }, '*');
-              }
-            }
-            break;
-
-          // // // // // // //
-          case 'OpenCBA.newData':
-            const responseData = msgData['newResponses'];
-            if ((responseData !== undefined) || (responseData !== null)) {
-              this.bs.setUnitResponses(this.sessionToken, this.unitname$.getValue(), responseData)
-              .subscribe();
-            }
-
-            const restoreData = msgData['newRestorePoint'];
-            if ((restoreData !== undefined) || (restoreData !== null)) {
-              this.bs.setUnitRestorePoint(this.sessionToken, this.unitname$.getValue(), restoreData)
-              .subscribe();
-            }
-
-            const logData = msgData['newLogEntry'];
-            if ((restoreData !== undefined) || (restoreData !== null)) {
-              this.bs.setUnitLog(this.sessionToken, this.unitname$.getValue(), logData)
-              .subscribe();
-            }
-
-            break;
-
-          // // // // // // //
-          default:
-            console.log('processMessagePost unknown message type: ' + msgType);
-            break;
-        }
-
-
-        // .........................................
-      }
-    }
-  }
-  // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
-
-
-  updateSessionToken(newToken: string) {
-    this._sessionToken = newToken;
-    if ((newToken !== null) && (newToken.length > 0)) {
-      localStorage.setItem('st', newToken);
-      this.isSession$.next(true);
-    } else {
-      localStorage.removeItem('st');
-      this.isSession$.next(false);
-    }
-  }
-
-  updateBookletData(bookletname: string, units: UnitDef[], message: string, status: {}) {
-    this.allUnits = units;
-    this.bookletname$.next(bookletname);
-    this.statusmessage$.next(message);
-
-    if ((status === null) || (status['u'] === undefined)) {
-      this.gotoFirstUnit();
-    } else {
-      this.gotoUnit(status['u']);
-    }
-  }
-
-  updatePageTitle(newTitle: string) {
-    this.pageTitle$.next(newTitle);
-  }
-
-  updateUnitId(newUnitId: number) {
-    if ((newUnitId >= 0) && (newUnitId < this.allUnits.length)) {
-      this.currentUnitId$.next(newUnitId);
-    } else {
-      this.currentUnitId$.next(-1);
-    }
-  }
-}
-
-
-
-// .....................................................................
-export class Testlet {
-  private _testlets: Testlet[];
-  private _units: string;
-  constructor() {
-
-  }
-
-}
-
-// .....................................................................
-export interface NavigationPoint {
-  title: string;
-  unitId: number;
-  path: string;
-}
-
-// .....................................................................
-export class ResourceStore {
-
-}
-
-// .....................................................................
-export class ResourceData {
-  filename: string;
-  id: string;
-  type: string;
-  dataString: string;
-
-  constructor(filename: string, id: string) {
-    if ((typeof filename === 'undefined') || (filename == null)) {
-      filename = '';
-    }
-    if ((typeof id === 'undefined') || (id == null)) {
-      id = '';
-    }
-
-    if ((filename + id).length === 0) {
-      this.filename = '?';
-      this.id = '?';
-    } else {
-      if (filename.length === 0) {
-        this.filename = id;
-      } else {
-        this.filename = filename;
-      }
-      if (id.length === 0) {
-        this.id = filename;
-      } else {
-        this.id = id;
-      }
-    }
-  }
-}
-
-// .....................................................................
-export class UnitDef {
-  sequenceId: number;
-  name: string;
-  title: string;
-  resources: ResourceData[];
-  restorePoint: string;
-  dataForItemplayer: string;
-
-  constructor(name: string, title: string) {
-    this.name = name;
-    this.title = title;
-    this.resources = [];
-    this.restorePoint = '';
-    this.dataForItemplayer = '';
-  }
-
-  getItemplayerHtml() {
-    for (let i = 0; i < this.resources.length; i++) {
-      if (this.resources[i].type === 'itemplayer_html') {
-        if (this.resources[i].dataString.length > 0) {
-          return this.resources[i].dataString;
-        }
-      }
-    }
-    return null;
-  }
-
-  getResourcesAsDictionary(): {[resourceID: string]: string} {
-    const myResources = {};
-    for (let i = 0; i < this.resources.length; i++) {
-      if (this.resources[i].type !== 'itemplayer_html') {
-        myResources[this.resources[i].id] = this.resources[i].dataString;
-      }
-    }
-    return myResources;
-  }
-}
diff --git a/src/app/test-controller/unithost/unit-routing.spec.ts b/src/app/test-controller/unithost/unit-routing.spec.ts
deleted file mode 100644
index 2dbb0994..00000000
--- a/src/app/test-controller/unithost/unit-routing.spec.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { TestBed, async, inject } from '@angular/core/testing';
-
-import { UnitActivateGuard, UnitDeactivateGuard } from './unit-routing';
-
-describe('UnitActivateGuard', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [UnitActivateGuard]
-    });
-  });
-
-  it('should ...', inject([UnitActivateGuard], (guard: UnitActivateGuard) => {
-    expect(guard).toBeTruthy();
-  }));
-});
-
-
-describe('UnitDeactivateGuard', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [UnitDeactivateGuard]
-    });
-  });
-
-  it('should ...', inject([UnitDeactivateGuard], (guard: UnitDeactivateGuard) => {
-    expect(guard).toBeTruthy();
-  }));
-});
diff --git a/src/app/test-controller/unithost/unit-routing.ts b/src/app/test-controller/unithost/unit-routing.ts
deleted file mode 100644
index 6041850b..00000000
--- a/src/app/test-controller/unithost/unit-routing.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { switchMap, map } from 'rxjs/operators';
-import { ResourceData } from './../testdata.service';
-import { BackendService, ServerError } from './../backend.service';
-import { UnithostComponent } from './unithost.component';
-import { Injectable, Component } from '@angular/core';
-import { CanActivate, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, Resolve } from '@angular/router';
-import { Observable } from 'rxjs';
-
-import { UnitDef, TestdataService } from '../testdata.service';
-
-@Injectable()
-export class UnitActivateGuard implements CanActivate {
-  canActivate(
-    next: ActivatedRouteSnapshot,
-    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
-      console.log('UnitActivateGuard');
-    return true;
-  }
-}
-
-@Injectable()
-export class UnitDeactivateGuard implements CanDeactivate<UnithostComponent> {
-  canDeactivate(
-    component: UnithostComponent,
-    next: ActivatedRouteSnapshot,
-    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
-      console.log('UnitDeactivateGuard');
-    return true;
-  }
-}
-
-@Injectable()
-// enriches the routing data with unit data and resources:
-// places in data['unit'] the unit object
-export class UnitResolver implements Resolve<UnitDef> {
-  constructor(private tss: TestdataService,
-  private bs: BackendService) { }
-
-  resolve(next: ActivatedRouteSnapshot,
-    state: RouterStateSnapshot): Observable<UnitDef> {
-      if (this.tss.isSession$.getValue() === true) {
-        return this.tss.getUnitAt(next.params['u'])
-          .pipe(
-            switchMap((newUnit: UnitDef) => {
-              this.tss.unitname$.next(newUnit.name);
-              return this.tss.fetchUnitData(newUnit);
-            }));
-      } else {
-        this.tss.unitname$.next('');
-        return null;
-      }
-    }
-}
-
-
-export const routingProviders = [UnitActivateGuard, UnitDeactivateGuard, UnitResolver];
diff --git a/src/app/test-controller/unithost/unithost.component.css b/src/app/test-controller/unithost/unithost.component.css
deleted file mode 100644
index 5aebe20f..00000000
--- a/src/app/test-controller/unithost/unithost.component.css
+++ /dev/null
@@ -1,3 +0,0 @@
-#iFrameHost {
-  width: 100%;
-}
diff --git a/src/app/test-controller/unithost/unithost.component.html b/src/app/test-controller/unithost/unithost.component.html
deleted file mode 100644
index 6ea1e66e..00000000
--- a/src/app/test-controller/unithost/unithost.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!--  <p *ngIf="showMessage">{{ message }}</p>-->
-  <div id="iFrameHost" class="page-body" iqbResizeIFrameChild>
-  </div>
diff --git a/src/app/test-controller/unithost/unithost.component.spec.ts b/src/app/test-controller/unithost/unithost.component.spec.ts
deleted file mode 100644
index 7c5cf61a..00000000
--- a/src/app/test-controller/unithost/unithost.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { UnithostComponent } from './unithost.component';
-
-describe('UnithostComponent', () => {
-  let component: UnithostComponent;
-  let fixture: ComponentFixture<UnithostComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ UnithostComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(UnithostComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts
deleted file mode 100644
index c53a0eca..00000000
--- a/src/app/test-controller/unithost/unithost.component.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { Subscriber ,  Subscription } from 'rxjs';
-import { BackendService } from './../backend.service';
-import { TestdataService, UnitDef, ResourceData } from './../testdata.service';
-import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
-import { Location } from '@angular/common';
-
-@Component({
-  templateUrl: './unithost.component.html',
-  styleUrls: ['./unithost.component.css']
-})
-
-export class UnithostComponent implements OnInit, OnDestroy {
-  private message = '';
-
-  // public showIframe = false;
-  private iFrameHostElement: HTMLElement;
-  private iFrameItemplayer: HTMLIFrameElement;
-  private routingSubscription: Subscription;
-
-  constructor(
-    private tss: TestdataService,
-    private bs: BackendService,
-    private location: Location,
-    private route: ActivatedRoute
-  ) {
-    this.tss.statusmessage$.subscribe(s => {
-      this.message = s;
-    });
-  }
-
-  ngOnInit() {
-    this.iFrameHostElement = <HTMLElement>document.querySelector('#iFrameHost');
-
-    this.iFrameItemplayer = null;
-
-    this.routingSubscription = this.route.params.subscribe(
-      params => {
-        // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
-        while (this.iFrameHostElement.hasChildNodes()) {
-          this.iFrameHostElement.removeChild(this.iFrameHostElement.lastChild);
-        }
-        const newUnit: UnitDef = this.route.snapshot.data['unit'];
-
-        if ((newUnit === null) || (newUnit === undefined)) {
-          const messageElement = <HTMLElement>document.createElement('p');
-          messageElement.setAttribute('class', 'unitMessage');
-          messageElement.innerHTML = this.tss.statusmessage$.getValue();
-          this.iFrameHostElement.appendChild(messageElement);
-
-          this.tss.updatePageTitle('Problem?');
-          this.tss.updateUnitId(-1);
-        } else {
-          this.tss.updatePageTitle(newUnit.title);
-          this.tss.updateUnitId(newUnit.sequenceId);
-
-          this.iFrameItemplayer = <HTMLIFrameElement>document.createElement('iframe');
-          this.iFrameItemplayer.setAttribute('srcdoc', newUnit.getItemplayerHtml());
-          this.iFrameItemplayer.setAttribute('sandbox', 'allow-forms allow-scripts allow-same-origin');
-          this.iFrameItemplayer.setAttribute('class', 'unitHost');
-          this.iFrameItemplayer.setAttribute('height', String(this.iFrameHostElement.clientHeight));
-
-          this.tss.pendingItemDefinition$.next(newUnit.dataForItemplayer);
-          this.tss.pendingItemResources$.next(newUnit.getResourcesAsDictionary());
-          this.tss.pendingItemRestorePoint$.next(newUnit.restorePoint);
-
-          this.iFrameHostElement.appendChild(this.iFrameItemplayer);
-        }
-      });
-  }
-
-  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-  ngOnDestroy() {
-    this.routingSubscription.unsubscribe();
-  }
-}
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index d2df3ae3..b5d68c88 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -4,7 +4,7 @@
 
 export const environment = {
   production: false,
-  testcenterUrl: 'https://ocba2.iqb.hu-berlin.de/',
+  testcenterUrl: 'https://mdr2.iqb.hu-berlin.de/',
   appName: 'IQB-Testcenter',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
   appVersion: '0 (dev)'
-- 
GitLab