diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts
index 6e74d967cde10aacc4d6005d133e3a323adaafef..c78a255bef8153397338ec5b95e2f0bcf21702ce 100644
--- a/src/app/maindata.service.ts
+++ b/src/app/maindata.service.ts
@@ -97,6 +97,14 @@ export class MainDataService {
     this.setNewLoginData(myLoginData);
   }
 
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  endBooklet () {
+    const myLoginData = this.loginData$.getValue();
+    myLoginData.booklet = 0;
+    myLoginData.bookletlabel = '';
+    this.setNewLoginData(myLoginData);
+  }
+
   // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   getCode(): string {
     const myLoginData = this.loginData$.getValue();
diff --git a/src/app/test-controller/backend.service.ts b/src/app/test-controller/backend.service.ts
index 55339d80a8a1292d2a00e56e4622bde159681ec2..d2156e898f56f2b4e6306d071f6a9814761b4be9 100644
--- a/src/app/test-controller/backend.service.ts
+++ b/src/app/test-controller/backend.service.ts
@@ -78,70 +78,49 @@ export class BackendService {
   // 7777777777777777777777777777777777777777777777777777777777777777777777
   // send responses, status, logs
   // 7777777777777777777777777777777777777777777777777777777777777777777777
-  setBookletStatus(pToken: string, bookletDbId: number, 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', {au: pToken + '##' + bookletDbId.toString(), state: state}, httpOptions)
+  addBookletLog(bookletDbId: number, timestamp: number, entry: string): Observable<boolean | ServerError> {
+    return this.http
+      .post<boolean>(this.serverSlimUrl_POST + 'bookletlog', {b: bookletDbId, t: timestamp, e: entry})
         .pipe(
           catchError(this.handle)
         );
-    // }
   }
 
-  // ------------------------------
-  setUnitResponses(pToken: string, bookletDbId: number, unit: string,
-        unitdata: string, responseType: string): Observable<boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  setBookletState(bookletDbId: number, stateKey: string, state: string): Observable<boolean | ServerError> {
     return this.http
-    .post<boolean>(this.serverUrl + 'setUnitResponse.php',
-            {au: pToken + '##' + bookletDbId.toString(), u: unit, d: JSON.stringify(unitdata), rt: responseType}, httpOptions)
-      .pipe(
-        catchError(this.handle)
-      );
+      .post<boolean>(this.serverSlimUrl_POST + 'bookletstate', {b: bookletDbId, sk: stateKey, s: state})
+        .pipe(
+          catchError(this.handle)
+        );
   }
 
-  // ------------------------------
-  setUnitRestorePoint(pToken: string, bookletDbId: number, unit: string, unitdata: string): Observable<boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  addUnitLog(bookletDbId: number, timestamp: number, unitDbKey: string, entry: string): Observable<boolean | ServerError> {
     return this.http
-    .post<boolean>(this.serverUrl + 'setUnitRestorePoint.php',
-        {au: pToken + '##' + bookletDbId.toString(), u: unit, d: JSON.stringify(unitdata)}, httpOptions)
-      .pipe(
-        catchError(this.handle)
-      );
+      .post<boolean>(this.serverSlimUrl_POST + 'unitlog', {b: bookletDbId, u: unitDbKey, t: timestamp, e: entry})
+        .pipe(
+          catchError(this.handle)
+        );
   }
 
-  // ------------------------------
-  setUnitLog(pToken: string, bookletDbId: number, unit: string, unitdata: string[]): Observable<boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  newUnitResponse(bookletDbId: number, timestamp: number,
+            unitDbKey: string, response: string, responseType: string): Observable<boolean | ServerError> {
     return this.http
-    .post<boolean>(this.serverUrl + 'setUnitLog.php', {au: pToken + '##' + bookletDbId.toString(), u: unit, d: unitdata}, httpOptions)
-      .pipe(
-        catchError(this.handle)
-      );
+      .post<boolean>(this.serverSlimUrl_POST + 'response', {b: bookletDbId, u: unitDbKey, t: timestamp, r: response, rt: responseType})
+        .pipe(
+          catchError(this.handle)
+        );
+  }
+
+  newUnitRestorePoint(bookletDbId: number, unitDbKey: string, timestamp: number, restorePoint: string): Observable<boolean | ServerError> {
+    return this.http
+      .post<boolean>(this.serverSlimUrl_POST + 'restorepoint', {b: bookletDbId, u: unitDbKey, t: timestamp, r: restorePoint})
+        .pipe(
+          catchError(this.handle)
+        );
   }
 
 
+
   // 7777777777777777777777777777777777777777777777777777777777777777777777
   handle(errorObj: HttpErrorResponse): Observable<ServerError> {
     let myreturn: ServerError = null;
diff --git a/src/app/test-controller/test-controller.component.css b/src/app/test-controller/test-controller.component.css
index c67d5118b63cd208708035f23b6c6d490e176ae0..3bb1c1f85895b5881d6d82568792841a7d6a431d 100644
--- a/src/app/test-controller/test-controller.component.css
+++ b/src/app/test-controller/test-controller.component.css
@@ -26,19 +26,23 @@
   bottom: 0;
 }
 
-#reviewbutton .material-icons {
-  font-size: 2.0rem;
-}
-#reviewbutton .mat-button {
-  text-align: right;
-}
-#reviewbutton {
+/* --------------------------------------------- */
+#reviewButtonsContainer {
   position: absolute;
   right: 5px;
   top: 5px;  
   color: white;
 }
+#reviewButtonsContainer .material-icons {
+  font-size: 2.0rem;
+  padding: 2px;
+  min-width: 2px;
+}
+#reviewButtonsContainer .mat-button {
+  text-align: right;
+}
 
+/* --------------------------------------------- */
 #navButtonsContainer {
   position: fixed;
   z-index: 100;
diff --git a/src/app/test-controller/test-controller.component.html b/src/app/test-controller/test-controller.component.html
index a6c9dc420a0e7b347ff98360bbfdfcaaa7fbaebc..96f306e179e6fc65b6a165ab9ea6aeaf1b21b249 100644
--- a/src/app/test-controller/test-controller.component.html
+++ b/src/app/test-controller/test-controller.component.html
@@ -4,16 +4,21 @@
   </a>
 </div>
 <div id="navButtonsContainer" fxLayout="row">
-  <button mat-fab [disabled]="!tcs.unitPrevEnabled" color="accent" (click)="prevUnitNaviButtonClick()">
+  <button mat-fab [disabled]="!tcs.unitPrevEnabled" color="accent" (click)="tcs.setUnitNavigationRequest('#previous')" matTooltip="Zurück">
     <i class="material-icons">chevron_left</i>
   </button>
-  <button mat-fab [disabled]="!tcs.unitNextEnabled" color="accent" (click)="nextUnitNaviButtonClick()">
+  <button mat-fab [disabled]="!tcs.unitNextEnabled" color="accent" (click)="tcs.setUnitNavigationRequest('#next')" matTooltip="Weiter">
     <i class="material-icons">chevron_right</i>
   </button>
 </div>
-<button id="reviewbutton" mat-button *ngIf="tcs.mode === 'review'" (click)="showReviewDialog()">
-  <mat-icon>rate_review</mat-icon>
-</button>
+<div id="reviewButtonsContainer" *ngIf="tcs.mode === 'review'" fxLayout="row">
+  <button mat-button (click)="showReviewDialog()" matTooltip="Kommentar senden">
+    <mat-icon>rate_review</mat-icon>
+  </button>
+  <button mat-button (click)="tcs.setUnitNavigationRequest('#end')" matTooltip="Aktuelles Testheft beenden">
+    <mat-icon>exit_to_app</mat-icon>
+  </button>
+</div>
 <div class="spinner-container" *ngIf="dataLoading">
   <mat-spinner></mat-spinner>
 </div>
diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts
index 6e656a5a2cc1e1ce812665aa7cc22d250395a9cd..b544f1ebf3bd50986ca7b927f4e67a2038254195 100644
--- a/src/app/test-controller/test-controller.component.ts
+++ b/src/app/test-controller/test-controller.component.ts
@@ -19,7 +19,7 @@ import { switchMap } from 'rxjs/operators';
 })
 export class TestControllerComponent implements OnInit, OnDestroy {
   private loginDataSubscription: Subscription = null;
-  // private unitPosSubsription: Subscription = null;
+  private navigationRequestSubsription: Subscription = null;
 
   // private showUnitComponent = false;
   // private allUnits: UnitDef[] = [];
@@ -189,7 +189,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
             return of(false);
           } else {
             const myUnitData = myData as UnitData;
-            this.tcs.addUnitRestorePoint(sequenceId, myUnitData.restorepoint);
+            this.tcs.newUnitRestorePoint(myUnit.id, sequenceId, myUnitData.restorepoint, false);
             let playerId = '';
             let definitionRef = '';
 
@@ -254,11 +254,55 @@ export class TestControllerComponent implements OnInit, OnDestroy {
       );
   }
 
-  // ==========================================================
-  // ==========================================================
+  // #####################################################################################
+  // #####################################################################################
   ngOnInit() {
     this.router.navigateByUrl('/t');
 
+    // ==========================================================
+    // navigation between units and end booklet
+    this.navigationRequestSubsription = this.tcs.navigationRequest$.subscribe((navString: string) => {
+      if (this.tcs.rootTestlet === null) {
+        this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000});
+      } else {
+        switch (navString) {
+          case '#next':
+            if (this.tcs.rootTestlet !== null) {
+              this.router.navigateByUrl('/t/u/' + (this.tcs.currentUnitSequenceId + 1).toString());
+            }
+            break;
+          case '#previous':
+            if (this.tcs.rootTestlet !== null) {
+              this.router.navigateByUrl('/t/u/' + (this.tcs.currentUnitSequenceId - 1).toString());
+            }
+            break;
+          case '#first':
+            if (this.tcs.rootTestlet !== null) {
+              this.router.navigateByUrl('/t/u/1');
+            }
+            break;
+          case '#last':
+            if (this.tcs.rootTestlet !== null) {
+              this.router.navigateByUrl('/t/u/' + this.tcs.numberOfUnits.toString());
+            }
+            break;
+          case '#end':
+            this.mds.endBooklet();
+            break;
+
+          default:
+            if (this.tcs.rootTestlet !== null) {
+              this.router.navigateByUrl('/t/u/' + navString);
+            }
+            break;
+        }
+      }
+    });
+
+
+    // ==========================================================
+    // loading booklet data and all unit content
+    // navigation to first unit
     this.loginDataSubscription = this.mds.loginData$.subscribe(loginData => {
       this.tcs.resetDataStore();
       if ((loginData.persontoken.length > 0) && (loginData.booklet > 0)) {
@@ -299,11 +343,12 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                 }
 
                 if (loadingOk) {
-                  // =================================================
-
-                  this.goToUnitBySequenceId(1);
+                  // =====================
+                  this.tcs.bookletDbId = loginData.booklet;
+                  this.tcs.setBookletState('LASTUNIT', '1');
+                  this.tcs.setUnitNavigationRequest('#first');
 
-                  // =================================================
+                  // =====================
                 } else {
                   console.log('loading failed');
                   this.mds.globalErrorMsg$.next(new ServerError(0, 'Inhalte des Testheftes konnten nicht alle geladen werden.', ''));
@@ -313,22 +358,14 @@ export class TestControllerComponent implements OnInit, OnDestroy {
             }
           }
         });
+      } else {
+        this.router.navigateByUrl('/');
       }
     });
   }
 
 
-
-  // ==========================================================
-  goToUnitBySequenceId(sequenceId: number) {
-    if (this.tcs.rootTestlet !== null) {
-      this.router.navigateByUrl('/t/u/' + sequenceId.toString());
-    }
-  }
-
-
-
-  // ==========================================================
+  // #####################################################################################
   showReviewDialog() {
     if (this.tcs.rootTestlet === null) {
       this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000});
@@ -393,24 +430,39 @@ export class TestControllerComponent implements OnInit, OnDestroy {
     }
   }
 
-  // ==========================================================
-  nextUnitNaviButtonClick() {
-    if (this.tcs.rootTestlet !== null) {
-      this.router.navigateByUrl('/t/u/' + (this.tcs.currentUnitSequenceId + 1).toString());
-    }
-  }
 
-  // ==========================================================
-  prevUnitNaviButtonClick() {
-    if (this.tcs.rootTestlet !== null) {
-      this.router.navigateByUrl('/t/u/' + (this.tcs.currentUnitSequenceId - 1).toString());
-    }
-  }
 
   // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
   ngOnDestroy() {
     if (this.loginDataSubscription !== null) {
       this.loginDataSubscription.unsubscribe();
     }
+    if (this.navigationRequestSubsription !== null) {
+      this.navigationRequestSubsription.unsubscribe();
+    }
   }
 }
+  // // -- -- -- -- -- -- -- -- -- -- -- -- -- --
+  // this.log$.pipe(
+  //   bufferTime(500)
+  // ).subscribe((data: UnitLogData[]) => {
+  //   if (data.length > 0) {
+  //     const myLogs = {};
+  //     data.forEach(lg => {
+  //       if (lg !== null) {
+  //         if (lg.logEntry.length > 0) {
+  //           if (typeof myLogs[lg.unitDbKey] === 'undefined') {
+  //             myLogs[lg.unitDbKey] = [];
+  //           }
+  //           myLogs[lg.unitDbKey].push(JSON.stringify(lg.logEntry));
+  //         }
+  //       }
+  //     });
+  //     for (const unitName in myLogs) {
+  //       if (myLogs[unitName].length > 0) {
+  //         // ## this.bs.setUnitLog(this.lds.personToken$.getValue(),
+  //         // this.lds.bookletDbId$.getValue(), unitName, myLogs[unitName]).subscribe();
+  //       }
+  //     }
+  //   }
+  // });
diff --git a/src/app/test-controller/test-controller.interfaces.ts b/src/app/test-controller/test-controller.interfaces.ts
index 56e17ab476f23f0aee9d69e8144be388c028c2ba..7cb3b5571f338cec20ae33a1a056ccf0ab563d8a 100644
--- a/src/app/test-controller/test-controller.interfaces.ts
+++ b/src/app/test-controller/test-controller.interfaces.ts
@@ -1,55 +1,76 @@
-export interface UnitLogData {
-    unitDbKey: string;
-    logEntry: string;
+// used everywhere
+export interface TaggedString {
+    tag: string;
+    value: string;
 }
 
 export interface UnitResponseData {
+    bookletDbId: number;
     unitDbKey: string;
+    timestamp: number;
     response: string;
     responseType: string;
 }
 
 export interface UnitRestorePointData {
+    bookletDbId: number;
     unitDbKey: string;
     unitSequenceId: number;
+    timestamp: number;
     restorePoint: string;
 }
 
+// testcontroller restrictions +++++++++++++++++++++++++++++++++++
 export interface StartLockData {
     prompt: string;
     keyPreset: string;
 }
 
+export interface CodeInputData {
+    prompt: string;
+    code: string;
+    value: string;
+}
+
+// for backend ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+export interface KeyValuePair {
+    [K: string]: string;
+}
+
 export interface BookletData {
     xml: string;
     locked: boolean;
-    state: BookletState;
+    state: KeyValuePair[];
 }
 
 export interface UnitData {
     xml: string;
     restorepoint: string;
-    status: {};
+    state: KeyValuePair[];
 }
 
-export interface BookletState {
-    u: number;
-    responses: string;
-    presented: string;
-    status: string;
+// for testcontroller service ++++++++++++++++++++++++++++++++++++++++
+export interface BookletStateEntry {
+    bookletDbId: number;
+    timestamp: number;
+    entryKey: string;
+    entry: string;
 }
 
-export interface CodeInputData {
-    prompt: string;
-    code: string;
-    value: string;
+export interface BookletLogData {
+    bookletDbId: number;
+    timestamp: number;
+    entry: string;
 }
 
-export interface TaggedString {
-    tag: string;
-    value: string;
+export interface UnitLogData {
+    bookletDbId: number;
+    unitDbKey: string;
+    timestamp: number;
+    entry: string;
 }
 
+// for unithost ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 export interface PageData {
     index: number;
     id: string;
diff --git a/src/app/test-controller/test-controller.service.ts b/src/app/test-controller/test-controller.service.ts
index 0692c16df217ef5cd780618967164a585d096172..42a1ee2102017e5cceac98cb0554d77f7a1e8052 100644
--- a/src/app/test-controller/test-controller.service.ts
+++ b/src/app/test-controller/test-controller.service.ts
@@ -1,6 +1,11 @@
-import { BehaviorSubject, of, Observable } from 'rxjs';
+import { BehaviorSubject, of, Observable, Subject } from 'rxjs';
 import { Injectable } from '@angular/core';
 import { Testlet, BookletConfig } from './test-controller.classes';
+import { BookletLogData, UnitLogData, BookletStateEntry,
+  UnitResponseData, UnitRestorePointData } from './test-controller.interfaces';
+import { BackendService } from './backend.service';
+import { JsonpInterceptor } from '@angular/common/http';
+import { ServerError } from '../backend.service';
 
 @Injectable({
   providedIn: 'root'
@@ -11,11 +16,12 @@ export class TestControllerService {
   };
   public bookletConfig$ = new BehaviorSubject<BookletConfig>(this.standardBookletConfig);
   public rootTestlet: Testlet = null;
+  public bookletDbId = 0;
   public numberOfUnits = 0;
   public loginname = '';
   public mode = '';
 
-  public navigationRequest$ = new BehaviorSubject<string>('');
+  public navigationRequest$ = new Subject<string>();
 
   private _currentUnitSequenceId: number;
   public get currentUnitSequenceId(): number {
@@ -47,8 +53,14 @@ export class TestControllerService {
   private unitDefinitions: {[sequenceId: number]: string} = {};
   private unitRestorePoints: {[sequenceId: number]: string} = {};
 
+  constructor (
+    private bs: BackendService
+  ) { }
+
+  // 7777777777777777777777777777777777777777777777777777777777777777777777
   public resetDataStore() {
     this.bookletConfig$.next(this.standardBookletConfig);
+    this.bookletDbId = 0;
     this.players = {};
     this.unitDefinitions = {};
     this.unitRestorePoints = {};
@@ -163,9 +175,7 @@ export class TestControllerService {
   }
 
   // 7777777777777777777777777777777777777777777777777777777777777777777777
-  public addUnitRestorePoint (sequenceId: number, uRP: string) {
-    this.unitRestorePoints[sequenceId] = uRP;
-  }
+  // adding RestorePoint via newUnitRestorePoint below
   public hasUnitRestorePoint (sequenceId: number): boolean {
     return this.unitRestorePoints.hasOwnProperty(sequenceId);
   }
@@ -174,7 +184,75 @@ export class TestControllerService {
   }
 
   // 7777777777777777777777777777777777777777777777777777777777777777777777
-  public setUnitNavigationRequest(RequenstKey: string) {
-    this.navigationRequest$.next(RequenstKey);
+  public setUnitNavigationRequest(RequestKey: string) {
+    this.navigationRequest$.next(RequestKey);
+  }
+
+
+  // 7777777777777777777777777777777777777777777777777777777777777777777777
+  public addBookletLog(entry: string) {
+    this.bs.addBookletLog(this.bookletDbId, Date.now(), JSON.stringify(entry)).subscribe(ok => {
+      if (ok instanceof ServerError) {
+        console.log('((((((((((((((((addBookletLog');
+      }
+    });
+  }
+  public setBookletState(stateKey: string, state: string) {
+    this.bs.setBookletState(this.bookletDbId, stateKey, state).subscribe(ok => {
+      if (ok instanceof ServerError) {
+        console.log('((((((((((((((((setBookletState');
+      }
+    });
   }
+  public addUnitLog(unitDbKey: string, entry: string) {
+    this.bs.addUnitLog(this.bookletDbId, Date.now(), unitDbKey, JSON.stringify(entry)).subscribe(ok => {
+      if (ok instanceof ServerError) {
+        console.log('((((((((((((((((addUnitLog');
+      }
+    });
+  }
+  public newUnitResponse(unitDbKey: string, response: string, responseType) {
+    this.bs.newUnitResponse(this.bookletDbId, Date.now(), unitDbKey, JSON.stringify(response), responseType).subscribe(ok => {
+      if (ok instanceof ServerError) {
+        console.log('((((((((((((((((newUnitResponse');
+      }
+    });
+  }
+  public newUnitRestorePoint(unitDbKey: string, unitSequenceId: number, restorePoint: string, postToServer: boolean) {
+    this.unitRestorePoints[unitSequenceId] = restorePoint;
+    if (postToServer) {
+      this.bs.newUnitRestorePoint(this.bookletDbId, unitDbKey, Date.now(), JSON.stringify(restorePoint)).subscribe(ok => {
+        if (ok instanceof ServerError) {
+          console.log('((((((((((((((((newUnitRestorePoint');
+        }
+      });
+    }
+  }
+
+
+  // -- -- -- -- -- -- -- -- -- -- -- -- -- --
+      // this.log$.pipe(
+      //   bufferTime(500)
+      // ).subscribe((data: UnitLogData[]) => {
+      //   if (data.length > 0) {
+      //     const myLogs = {};
+      //     data.forEach(lg => {
+      //       if (lg !== null) {
+      //         if (lg.logEntry.length > 0) {
+      //           if (typeof myLogs[lg.unitDbKey] === 'undefined') {
+      //             myLogs[lg.unitDbKey] = [];
+      //           }
+      //           myLogs[lg.unitDbKey].push(JSON.stringify(lg.logEntry));
+      //         }
+      //       }
+      //     });
+      //     for (const unitName in myLogs) {
+      //       if (myLogs[unitName].length > 0) {
+      //         // ## this.bs.setUnitLog(this.lds.personToken$.getValue(),
+      //         // this.lds.bookletDbId$.getValue(), unitName, myLogs[unitName]).subscribe();
+      //       }
+      //     }
+      //   }
+      // });
+
 }
diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts
index 7a0f4ed8332f95c320d1d7395e76c1bcc9cdd8bd..8cd151541d76a8dd8308f2eeb4393fc419369445 100644
--- a/src/app/test-controller/unithost/unithost.component.ts
+++ b/src/app/test-controller/unithost/unithost.component.ts
@@ -1,8 +1,7 @@
 import { MainDataService } from './../../maindata.service';
 import { debounceTime, bufferTime, switchMap } from 'rxjs/operators';
 import { TestControllerService } from './../test-controller.service';
-import { Subscription, BehaviorSubject } from 'rxjs';
-import { BackendService } from './../backend.service';
+import { Subscription, Subject } from 'rxjs';
 import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
@@ -23,7 +22,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
   public leaveWarningText = 'Du hast den Hörtext noch nicht vollständig gehört. Nach dem ' +
           'Verlassen der Aufgabe wird der Hörtext nicht noch einmal gestartet. Trotzdem die Aufgabe verlassen?';
 
-  private myUnitNumber = -1;
+  private myUnitSequenceId = -1;
   private myUnitDbKey = '';
   private unitTitle = '';
 
@@ -40,19 +39,32 @@ export class UnithostComponent implements OnInit, OnDestroy {
   private pageList: PageData[] = [];
 
   // changed by itemplayer via postMessage, observed here to save (see below)
-  public restorePoint$ = new BehaviorSubject<UnitRestorePointData>(null);
-  public response$ = new BehaviorSubject<UnitResponseData>(null);
-  public log$ = new BehaviorSubject<UnitLogData>(null);
+  private restorePoint$ = new Subject<string>();
+  private restorePointSubscription: Subscription = null;
+  private response$ = new Subject<TaggedString>();
+  private responseSubscription: Subscription = null;
 
 
 
   constructor(
     private tcs: TestControllerService,
-    private bs: BackendService,
     private mds: MainDataService,
-    private location: Location,
     private route: ActivatedRoute
   ) {
+    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
+    this.restorePointSubscription = this.restorePoint$.pipe(
+      debounceTime(300)).subscribe(restorePoint => {
+        this.tcs.newUnitRestorePoint(this.myUnitDbKey, this.myUnitSequenceId, restorePoint, true);
+      }
+    );
+
+    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
+    this.responseSubscription = this.response$.pipe(
+      debounceTime(300)).subscribe(response => {
+        this.tcs.newUnitResponse(this.myUnitDbKey, response.value, response.tag);
+      }
+    );
+
     // -- -- -- -- -- -- -- -- -- -- -- -- -- --
     this.postMessageSubscription = this.mds.postMessage$.subscribe((m: MessageEvent) => {
       const msgData = m.data;
@@ -113,28 +125,17 @@ export class UnithostComponent implements OnInit, OnDestroy {
               this.setPageList(msgData['validPages'], msgData['currentPage']);
 
               const restorePoint = msgData['restorePoint'] as string;
-              if (restorePoint !== undefined) {
-                this.restorePoint$.next({
-                  unitDbKey: this.myUnitDbKey,
-                  unitSequenceId: this.myUnitNumber,
-                  restorePoint: restorePoint});
+              if (restorePoint) {
+                this.restorePoint$.next(restorePoint);
               }
               const response = msgData['response'] as string;
               if (response !== undefined) {
-                this.response$.next({unitDbKey: this.myUnitDbKey, response: response, responseType: msgData['responseType']});
+                this.response$.next({tag: msgData['responseType'], value: response});
               }
               const canLeaveChanged = msgData['canLeave'];
               if (canLeaveChanged !== undefined) {
                 this.leaveWarning = (canLeaveChanged as string === 'warning');
               }
-
-
-              // const logEntries = msgData['logEntries'] as string[];
-              // if ((logEntries !== undefined) && (logEntries.length > 0)) {
-              //   logEntries.forEach(log => {
-              //     this.log$.next({'unitName': this.myUnitName, 'msg': log});
-              //   });
-              // }
             }
             break;
 
@@ -152,55 +153,6 @@ export class UnithostComponent implements OnInit, OnDestroy {
         }
       }
     });
-
-    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
-    this.restorePoint$.pipe(
-      debounceTime(300)).subscribe(data => {
-        if (data !== null) {
-          this.tcs.addUnitRestorePoint(data.unitSequenceId, data.restorePoint);
-          // if (this.lds.loginMode$.getValue() !== 'review') {
-          //   this.bs.setUnitRestorePoint(this.lds.personToken$.getValue(),
-          //       this.lds.bookletDbId$.getValue(), data.unitName, data.restorePoint)
-          //   .subscribe();
-          // }
-        }
-    });
-
-    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
-    this.response$.pipe(
-      debounceTime(300)
-    ).subscribe(data => {
-        // if ((data !== null) && (this.lds.loginMode$.getValue() !== 'review')) {
-        //   this.bs.setUnitResponses(this.lds.personToken$.getValue(),
-        //       this.lds.bookletDbId$.getValue(), data.unitName, data.response, data.responseType)
-        //   .subscribe();
-      // }
-    });
-
-    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
-    this.log$.pipe(
-      bufferTime(500)
-    ).subscribe((data: UnitLogData[]) => {
-      if (data.length > 0) {
-        const myLogs = {};
-        data.forEach(lg => {
-          if (lg !== null) {
-            if (lg.logEntry.length > 0) {
-              if (typeof myLogs[lg.unitDbKey] === 'undefined') {
-                myLogs[lg.unitDbKey] = [];
-              }
-              myLogs[lg.unitDbKey].push(JSON.stringify(lg.logEntry));
-            }
-          }
-        });
-        for (const unitName in myLogs) {
-          if (myLogs[unitName].length > 0) {
-            // ## this.bs.setUnitLog(this.lds.personToken$.getValue(),
-            // this.lds.bookletDbId$.getValue(), unitName, myLogs[unitName]).subscribe();
-          }
-        }
-      }
-    });
   }
 
   // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
@@ -211,15 +163,15 @@ export class UnithostComponent implements OnInit, OnDestroy {
     this.leaveWarning = false;
 
     this.routingSubscription = this.route.params.subscribe(params => {
-      this.myUnitNumber = Number(params['u']);
-      this.tcs.currentUnitSequenceId = this.myUnitNumber;
+      this.myUnitSequenceId = Number(params['u']);
+      this.tcs.currentUnitSequenceId = this.myUnitSequenceId;
 
       while (this.iFrameHostElement.hasChildNodes()) {
         this.iFrameHostElement.removeChild(this.iFrameHostElement.lastChild);
       }
 
-      if ((this.myUnitNumber >= 1) && (this.myUnitNumber === this.myUnitNumber) && (this.tcs.rootTestlet !== null)) {
-        const currentUnit = this.tcs.rootTestlet.getUnitAt(this.myUnitNumber);
+      if ((this.myUnitSequenceId >= 1) && (this.myUnitSequenceId === this.myUnitSequenceId) && (this.tcs.rootTestlet !== null)) {
+        const currentUnit = this.tcs.rootTestlet.getUnitAt(this.myUnitSequenceId);
         this.unitTitle = currentUnit.unitDef.title; // (currentUnitId + 1).toString() + '. '
         this.myUnitDbKey = currentUnit.unitDef.alias;
         this.tcs.currentUnitDbKey = this.myUnitDbKey;
@@ -234,14 +186,14 @@ export class UnithostComponent implements OnInit, OnDestroy {
         this.iFrameItemplayer.setAttribute('class', 'unitHost');
         this.iFrameItemplayer.setAttribute('height', String(this.iFrameHostElement.clientHeight));
 
-        if (this.tcs.hasUnitDefinition(this.myUnitNumber)) {
-          this.pendingUnitDefinition = {tag: this.itemplayerSessionId, value: this.tcs.getUnitDefinition(this.myUnitNumber)};
+        if (this.tcs.hasUnitDefinition(this.myUnitSequenceId)) {
+          this.pendingUnitDefinition = {tag: this.itemplayerSessionId, value: this.tcs.getUnitDefinition(this.myUnitSequenceId)};
         } else {
           this.pendingUnitDefinition = null;
         }
 
-        if (this.tcs.hasUnitRestorePoint(this.myUnitNumber)) {
-          this.pendingUnitRestorePoint = {tag: this.itemplayerSessionId, value: this.tcs.getUnitRestorePoint(this.myUnitNumber)};
+        if (this.tcs.hasUnitRestorePoint(this.myUnitSequenceId)) {
+          this.pendingUnitRestorePoint = {tag: this.itemplayerSessionId, value: this.tcs.getUnitRestorePoint(this.myUnitSequenceId)};
         } else {
           this.pendingUnitRestorePoint = null;
         }
@@ -361,5 +313,11 @@ export class UnithostComponent implements OnInit, OnDestroy {
     if (this.postMessageSubscription !== null) {
       this.postMessageSubscription.unsubscribe();
     }
+    if (this.restorePointSubscription !== null) {
+      this.restorePointSubscription.unsubscribe();
+    }
+    if (this.responseSubscription !== null) {
+      this.responseSubscription.unsubscribe();
+    }
   }
 }