Browse Source

initial commit

hmt 2 years ago
commit
e92f4887fe
100 changed files with 19123 additions and 0 deletions
  1. 2 0
      .gitignore
  2. 3106 0
      api/ApiServer.ts
  3. 183 0
      api/ApiServerAlgorithmen.ts
  4. 197 0
      api/BaseApi.ts
  5. 21 0
      api/OpenApiError.ts
  6. 57 0
      core/Service.ts
  7. 471 0
      core/SprachendatenManager.ts
  8. 217 0
      core/abschluss/AbschlussManager.ts
  9. 98 0
      core/abschluss/AbschlussManagerBerufsbildend.ts
  10. 60 0
      core/abschluss/bk/a/BKAnlageA01Abschluss.ts
  11. 23 0
      core/abschluss/bk/a/BKAnlageAFach.ts
  12. 28 0
      core/abschluss/bk/a/BKAnlageAFaecher.ts
  13. 227 0
      core/abschluss/ge/AbschlussFaecherGruppe.ts
  14. 153 0
      core/abschluss/ge/AbschlussFaecherGruppen.ts
  15. 162 0
      core/abschluss/ge/ServiceAbschlussHA10.ts
  16. 163 0
      core/abschluss/ge/ServiceAbschlussHA9.ts
  17. 356 0
      core/abschluss/ge/ServiceAbschlussMSA.ts
  18. 288 0
      core/abschluss/ge/ServiceBerechtigungMSAQ.ts
  19. 121 0
      core/abschluss/ge/ServicePrognose.ts
  20. 1494 0
      core/abschluss/gost/AbiturdatenManager.ts
  21. 135 0
      core/abschluss/gost/GostBelegpruefung.ts
  22. 117 0
      core/abschluss/gost/GostBelegpruefungErgebnis.ts
  23. 95 0
      core/abschluss/gost/GostBelegpruefungErgebnisFehler.ts
  24. 58 0
      core/abschluss/gost/GostBelegpruefungsArt.ts
  25. 283 0
      core/abschluss/gost/GostBelegungsfehler.ts
  26. 58 0
      core/abschluss/gost/GostBelegungsfehlerArt.ts
  27. 132 0
      core/abschluss/gost/GostFachManager.ts
  28. 34 0
      core/abschluss/gost/abitur/services/AbiturBlockIMarkierAlgorithmus.ts
  29. 35 0
      core/abschluss/gost/abitur/services/AbiturBlockIMarkierPruefung.ts
  30. 200 0
      core/abschluss/gost/belegpruefung/AbiFaecher.ts
  31. 69 0
      core/abschluss/gost/belegpruefung/Allgemeines.ts
  32. 58 0
      core/abschluss/gost/belegpruefung/Deutsch.ts
  33. 486 0
      core/abschluss/gost/belegpruefung/Fremdsprachen.ts
  34. 287 0
      core/abschluss/gost/belegpruefung/GesellschaftswissenschaftenUndReligion.ts
  35. 490 0
      core/abschluss/gost/belegpruefung/KurszahlenUndWochenstunden.ts
  36. 58 0
      core/abschluss/gost/belegpruefung/Latinum.ts
  37. 72 0
      core/abschluss/gost/belegpruefung/LiterarischKuenstlerisch.ts
  38. 58 0
      core/abschluss/gost/belegpruefung/Mathematik.ts
  39. 88 0
      core/abschluss/gost/belegpruefung/Naturwissenschaften.ts
  40. 261 0
      core/abschluss/gost/belegpruefung/Projektkurse.ts
  41. 67 0
      core/abschluss/gost/belegpruefung/Schwerpunkt.ts
  42. 51 0
      core/abschluss/gost/belegpruefung/Sport.ts
  43. 644 0
      core/adt/collection/LinkedCollection.ts
  44. 59 0
      core/adt/collection/LinkedCollectionDescendingIterator.ts
  45. 93 0
      core/adt/collection/LinkedCollectionElement.ts
  46. 59 0
      core/adt/collection/LinkedCollectionIterator.ts
  47. 857 0
      core/adt/map/AVLMap.ts
  48. 47 0
      core/adt/map/AVLMapIntervall.ts
  49. 69 0
      core/adt/map/AVLMapNode.ts
  50. 110 0
      core/adt/map/AVLMapSubCollection.ts
  51. 56 0
      core/adt/map/AVLMapSubCollectionIterator.ts
  52. 109 0
      core/adt/map/AVLMapSubEntrySet.ts
  53. 57 0
      core/adt/map/AVLMapSubEntrySetIterator.ts
  54. 210 0
      core/adt/map/AVLMapSubKeySet.ts
  55. 57 0
      core/adt/map/AVLMapSubKeySetIterator.ts
  56. 491 0
      core/adt/map/AVLMapSubMap.ts
  57. 238 0
      core/adt/set/AVLSet.ts
  58. 546 0
      core/adt/tree/MinHeap.ts
  59. 60 0
      core/adt/tree/MinHeapIterator.ts
  60. 53 0
      core/data/BenutzerKennwort.ts
  61. 91 0
      core/data/Sprachbelegung.ts
  62. 116 0
      core/data/Sprachendaten.ts
  63. 136 0
      core/data/Sprachpruefung.ts
  64. 122 0
      core/data/abschluss/AbschlussErgebnis.ts
  65. 106 0
      core/data/abschluss/AbschlussErgebnisBerufsbildend.ts
  66. 91 0
      core/data/abschluss/GEAbschlussFach.ts
  67. 100 0
      core/data/abschluss/GEAbschlussFaecher.ts
  68. 102 0
      core/data/benutzer/BenutzerListeEintrag.ts
  69. 110 0
      core/data/betrieb/BetriebAnsprechpartner.ts
  70. 96 0
      core/data/betrieb/BetriebListeEintrag.ts
  71. 266 0
      core/data/betrieb/BetriebStammdaten.ts
  72. 55 0
      core/data/db/DBSchemaListeEintrag.ts
  73. 64 0
      core/data/db/SchemaListeEintrag.ts
  74. 174 0
      core/data/enm/ENMBKAbschluss.ts
  75. 128 0
      core/data/enm/ENMBKFach.ts
  76. 473 0
      core/data/enm/ENMDaten.ts
  77. 80 0
      core/data/enm/ENMFach.ts
  78. 75 0
      core/data/enm/ENMFloskel.ts
  79. 95 0
      core/data/enm/ENMFloskelgruppe.ts
  80. 53 0
      core/data/enm/ENMFoerderschwerpunkt.ts
  81. 85 0
      core/data/enm/ENMJahrgang.ts
  82. 106 0
      core/data/enm/ENMKlasse.ts
  83. 76 0
      core/data/enm/ENMLehrer.ts
  84. 143 0
      core/data/enm/ENMLeistung.ts
  85. 88 0
      core/data/enm/ENMLeistungBemerkungen.ts
  86. 83 0
      core/data/enm/ENMLernabschnitt.ts
  87. 139 0
      core/data/enm/ENMLerngruppe.ts
  88. 61 0
      core/data/enm/ENMNote.ts
  89. 215 0
      core/data/enm/ENMSchueler.ts
  90. 118 0
      core/data/enm/ENMSprachenfolge.ts
  91. 78 0
      core/data/enm/ENMTeilleistung.ts
  92. 71 0
      core/data/enm/ENMTeilleistungsart.ts
  93. 94 0
      core/data/enm/ENMZP10.ts
  94. 93 0
      core/data/erzieher/ErzieherListeEintrag.ts
  95. 164 0
      core/data/erzieher/ErzieherStammdaten.ts
  96. 54 0
      core/data/erzieher/Erzieherart.ts
  97. 69 0
      core/data/fach/FachDaten.ts
  98. 105 0
      core/data/fach/FaecherListeEintrag.ts
  99. 186 0
      core/data/gost/AbiturFachbelegung.ts
  100. 128 0
      core/data/gost/AbiturFachbelegungHalbjahr.ts

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+java
+node_modules

+ 3106 - 0
api/ApiServer.ts

@@ -0,0 +1,3106 @@
+import { BaseApi } from '../api/BaseApi';
+import { Abiturdaten, cast_de_nrw_schule_svws_core_data_gost_Abiturdaten } from '../core/data/gost/Abiturdaten';
+import { BenutzerListeEintrag, cast_de_nrw_schule_svws_core_data_benutzer_BenutzerListeEintrag } from '../core/data/benutzer/BenutzerListeEintrag';
+import { BetriebListeEintrag, cast_de_nrw_schule_svws_core_data_betrieb_BetriebListeEintrag } from '../core/data/betrieb/BetriebListeEintrag';
+import { BetriebStammdaten, cast_de_nrw_schule_svws_core_data_betrieb_BetriebStammdaten } from '../core/data/betrieb/BetriebStammdaten';
+import { DBSchemaListeEintrag, cast_de_nrw_schule_svws_core_data_db_DBSchemaListeEintrag } from '../core/data/db/DBSchemaListeEintrag';
+import { ENMDaten, cast_de_nrw_schule_svws_core_data_enm_ENMDaten } from '../core/data/enm/ENMDaten';
+import { Erzieherart, cast_de_nrw_schule_svws_core_data_erzieher_Erzieherart } from '../core/data/erzieher/Erzieherart';
+import { ErzieherListeEintrag, cast_de_nrw_schule_svws_core_data_erzieher_ErzieherListeEintrag } from '../core/data/erzieher/ErzieherListeEintrag';
+import { ErzieherStammdaten, cast_de_nrw_schule_svws_core_data_erzieher_ErzieherStammdaten } from '../core/data/erzieher/ErzieherStammdaten';
+import { FachDaten, cast_de_nrw_schule_svws_core_data_fach_FachDaten } from '../core/data/fach/FachDaten';
+import { FaecherListeEintrag, cast_de_nrw_schule_svws_core_data_fach_FaecherListeEintrag } from '../core/data/fach/FaecherListeEintrag';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../core/data/abschluss/GEAbschlussFaecher';
+import { GostBelegpruefungErgebnis, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnis } from '../core/abschluss/gost/GostBelegpruefungErgebnis';
+import { GostBlockungKurs, cast_de_nrw_schule_svws_core_data_gost_GostBlockungKurs } from '../core/data/gost/GostBlockungKurs';
+import { GostBlockungListeneintrag, cast_de_nrw_schule_svws_core_data_gost_GostBlockungListeneintrag } from '../core/data/gost/GostBlockungListeneintrag';
+import { GostBlockungRegel, cast_de_nrw_schule_svws_core_data_gost_GostBlockungRegel } from '../core/data/gost/GostBlockungRegel';
+import { GostBlockungSchiene, cast_de_nrw_schule_svws_core_data_gost_GostBlockungSchiene } from '../core/data/gost/GostBlockungSchiene';
+import { GostBlockungsdaten, cast_de_nrw_schule_svws_core_data_gost_GostBlockungsdaten } from '../core/data/gost/GostBlockungsdaten';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../core/data/gost/GostFach';
+import { GostJahrgang, cast_de_nrw_schule_svws_core_data_gost_GostJahrgang } from '../core/data/gost/GostJahrgang';
+import { GostJahrgangsdaten, cast_de_nrw_schule_svws_core_data_gost_GostJahrgangsdaten } from '../core/data/gost/GostJahrgangsdaten';
+import { GostLeistungen, cast_de_nrw_schule_svws_core_data_gost_GostLeistungen } from '../core/data/gost/GostLeistungen';
+import { GostSchuelerFachwahl, cast_de_nrw_schule_svws_core_data_gost_GostSchuelerFachwahl } from '../core/data/gost/GostSchuelerFachwahl';
+import { GostStatistikFachwahl, cast_de_nrw_schule_svws_core_data_gost_GostStatistikFachwahl } from '../core/data/gost/GostStatistikFachwahl';
+import { JavaInteger, cast_java_lang_Integer } from '../java/lang/JavaInteger';
+import { JahrgangsDaten, cast_de_nrw_schule_svws_core_data_jahrgang_JahrgangsDaten } from '../core/data/jahrgang/JahrgangsDaten';
+import { JahrgangsListeEintrag, cast_de_nrw_schule_svws_core_data_jahrgang_JahrgangsListeEintrag } from '../core/data/jahrgang/JahrgangsListeEintrag';
+import { KatalogEintrag, cast_de_nrw_schule_svws_core_data_kataloge_KatalogEintrag } from '../core/data/kataloge/KatalogEintrag';
+import { KatalogEintragStrassen, cast_de_nrw_schule_svws_core_data_kataloge_KatalogEintragStrassen } from '../core/data/kataloge/KatalogEintragStrassen';
+import { KlassenDaten, cast_de_nrw_schule_svws_core_data_klassen_KlassenDaten } from '../core/data/klassen/KlassenDaten';
+import { KlassenListeEintrag, cast_de_nrw_schule_svws_core_data_klassen_KlassenListeEintrag } from '../core/data/klassen/KlassenListeEintrag';
+import { KursDaten, cast_de_nrw_schule_svws_core_data_kurse_KursDaten } from '../core/data/kurse/KursDaten';
+import { KursListeEintrag, cast_de_nrw_schule_svws_core_data_kurse_KursListeEintrag } from '../core/data/kurse/KursListeEintrag';
+import { LehrerKatalogAbgangsgrundEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogAbgangsgrundEintrag } from '../core/data/lehrer/LehrerKatalogAbgangsgrundEintrag';
+import { LehrerKatalogAnrechnungsgrundEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogAnrechnungsgrundEintrag } from '../core/data/lehrer/LehrerKatalogAnrechnungsgrundEintrag';
+import { LehrerKatalogBeschaeftigungsartEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogBeschaeftigungsartEintrag } from '../core/data/lehrer/LehrerKatalogBeschaeftigungsartEintrag';
+import { LehrerKatalogEinsatzstatusEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogEinsatzstatusEintrag } from '../core/data/lehrer/LehrerKatalogEinsatzstatusEintrag';
+import { LehrerKatalogFachrichtungAnerkennungEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogFachrichtungAnerkennungEintrag } from '../core/data/lehrer/LehrerKatalogFachrichtungAnerkennungEintrag';
+import { LehrerKatalogFachrichtungEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogFachrichtungEintrag } from '../core/data/lehrer/LehrerKatalogFachrichtungEintrag';
+import { LehrerKatalogLehramtAnerkennungEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogLehramtAnerkennungEintrag } from '../core/data/lehrer/LehrerKatalogLehramtAnerkennungEintrag';
+import { LehrerKatalogLehramtEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogLehramtEintrag } from '../core/data/lehrer/LehrerKatalogLehramtEintrag';
+import { LehrerKatalogLehrbefaehigungAnerkennungEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogLehrbefaehigungAnerkennungEintrag } from '../core/data/lehrer/LehrerKatalogLehrbefaehigungAnerkennungEintrag';
+import { LehrerKatalogLehrbefaehigungEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogLehrbefaehigungEintrag } from '../core/data/lehrer/LehrerKatalogLehrbefaehigungEintrag';
+import { LehrerKatalogLeitungsfunktionEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogLeitungsfunktionEintrag } from '../core/data/lehrer/LehrerKatalogLeitungsfunktionEintrag';
+import { LehrerKatalogMehrleistungsartEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogMehrleistungsartEintrag } from '../core/data/lehrer/LehrerKatalogMehrleistungsartEintrag';
+import { LehrerKatalogMinderleistungsartEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogMinderleistungsartEintrag } from '../core/data/lehrer/LehrerKatalogMinderleistungsartEintrag';
+import { LehrerKatalogRechtsverhaeltnisEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogRechtsverhaeltnisEintrag } from '../core/data/lehrer/LehrerKatalogRechtsverhaeltnisEintrag';
+import { LehrerKatalogZugangsgrundEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerKatalogZugangsgrundEintrag } from '../core/data/lehrer/LehrerKatalogZugangsgrundEintrag';
+import { LehrerListeEintrag, cast_de_nrw_schule_svws_core_data_lehrer_LehrerListeEintrag } from '../core/data/lehrer/LehrerListeEintrag';
+import { LehrerPersonaldaten, cast_de_nrw_schule_svws_core_data_lehrer_LehrerPersonaldaten } from '../core/data/lehrer/LehrerPersonaldaten';
+import { LehrerStammdaten, cast_de_nrw_schule_svws_core_data_lehrer_LehrerStammdaten } from '../core/data/lehrer/LehrerStammdaten';
+import { List, cast_java_util_List } from '../java/util/List';
+import { JavaLong, cast_java_lang_Long } from '../java/lang/JavaLong';
+import { NationalitaetKatalogEintrag, cast_de_nrw_schule_svws_core_data_kataloge_NationalitaetKatalogEintrag } from '../core/data/kataloge/NationalitaetKatalogEintrag';
+import { OrtKatalogEintrag, cast_de_nrw_schule_svws_core_data_kataloge_OrtKatalogEintrag } from '../core/data/kataloge/OrtKatalogEintrag';
+import { OrtsteilKatalogEintrag, cast_de_nrw_schule_svws_core_data_kataloge_OrtsteilKatalogEintrag } from '../core/data/kataloge/OrtsteilKatalogEintrag';
+import { ReligionKatalogEintrag, cast_de_nrw_schule_svws_core_data_kataloge_ReligionKatalogEintrag } from '../core/data/kataloge/ReligionKatalogEintrag';
+import { SchuelerBetriebsdaten, cast_de_nrw_schule_svws_core_data_schueler_SchuelerBetriebsdaten } from '../core/data/schueler/SchuelerBetriebsdaten';
+import { SchuelerLernabschnittListeEintrag, cast_de_nrw_schule_svws_core_data_schueler_SchuelerLernabschnittListeEintrag } from '../core/data/schueler/SchuelerLernabschnittListeEintrag';
+import { SchuelerLernabschnittsdaten, cast_de_nrw_schule_svws_core_data_schueler_SchuelerLernabschnittsdaten } from '../core/data/schueler/SchuelerLernabschnittsdaten';
+import { SchuelerListeEintrag, cast_de_nrw_schule_svws_core_data_schueler_SchuelerListeEintrag } from '../core/data/schueler/SchuelerListeEintrag';
+import { SchuelerSchulbesuchsdaten, cast_de_nrw_schule_svws_core_data_schueler_SchuelerSchulbesuchsdaten } from '../core/data/schueler/SchuelerSchulbesuchsdaten';
+import { SchuelerStammdaten, cast_de_nrw_schule_svws_core_data_schueler_SchuelerStammdaten } from '../core/data/schueler/SchuelerStammdaten';
+import { SchuleStammdaten, cast_de_nrw_schule_svws_core_data_schule_SchuleStammdaten } from '../core/data/schule/SchuleStammdaten';
+import { Vector, cast_java_util_Vector } from '../java/util/Vector';
+
+export class ApiServer extends BaseApi {
+
+	/**
+	 *
+	 * Erstellt eine neue API mit der übergebenen Konfiguration.
+	 *
+	 * @param {string} url - die URL des Servers: Alle Pfadangaben sind relativ zu dieser URL
+	 * @param {string} username - der Benutzername für den API-Zugriff
+	 * @param {string} password - das Kennwort des Benutzers für den API-Zugriff
+	 */
+	public constructor(url : string, username : string, password : string) {
+		super(url, username, password);
+	}
+
+	/**
+	 * Implementierung der GET-Methode getConfigCertificate für den Zugriff auf die URL https://{hostname}/config/certificate
+	 * 
+	 * Gibt das Zertifikat des Server zurück.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Zertifikat des Servers
+	 *     - Mime-Type: text/plain
+	 *     - Rückgabe-Typ: String
+	 *   Code 500: Das Zertifikat wurde nicht gefunden
+	 * 
+	 * @returns Das Zertifikat des Servers
+	 */
+	public async getConfigCertificate() : Promise<String> {
+		let path : string = "/config/certificate";
+		const text : string = await super.getText(path);
+		return String(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getConfigCertificateBase64 für den Zugriff auf die URL https://{hostname}/config/certificate_base64
+	 * 
+	 * Gibt das Zertifikat des Server in Base64-Kodierung zurück.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Base-64-kodierte Zertifikat des Servers
+	 *     - Mime-Type: text/plain
+	 *     - Rückgabe-Typ: String
+	 *   Code 500: Das Zertifikat wurde nicht gefunden
+	 * 
+	 * @returns Das Base-64-kodierte Zertifikat des Servers
+	 */
+	public async getConfigCertificateBase64() : Promise<String> {
+		let path : string = "/config/certificate_base64";
+		const text : string = await super.getText(path);
+		return String(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getConfigDBSchemata für den Zugriff auf die URL https://{hostname}/config/db/schemata
+	 * 
+	 * Gibt eine sortierte Übersicht von allen konfigurierten DB-Schemata zurück.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von DB-Schema-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<DBSchemaListeEintrag>
+	 * 
+	 * @returns Eine Liste von DB-Schema-Listen-Einträgen
+	 */
+	public async getConfigDBSchemata() : Promise<List<DBSchemaListeEintrag>> {
+		let path : string = "/config/db/schemata";
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<DBSchemaListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(DBSchemaListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getConfigPublicKeyBase64 für den Zugriff auf die URL https://{hostname}/config/publickey_base64
+	 * 
+	 * Gibt den öffentlichen Schlüssel des Server in Base64-Kodierung zurück.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Base-64-kodierte, öffentliche Schlüssel des Servers
+	 *     - Mime-Type: text/plain
+	 *     - Rückgabe-Typ: String
+	 *   Code 500: Der öffentliche Schlüssel wurde nicht gefunden
+	 * 
+	 * @returns Der Base-64-kodierte, öffentliche Schlüssel des Servers
+	 */
+	public async getConfigPublicKeyBase64() : Promise<String> {
+		let path : string = "/config/publickey_base64";
+		const text : string = await super.getText(path);
+		return String(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getBenutzerliste für den Zugriff auf die URL https://{hostname}/db/{schema}/benutzer/
+	 * 
+	 * Erstellt eine Liste aller Benutzer unter Angabe.Es wird geprüft, ob der SVWS-Benutzer die notwendige Administrator-Berechtigung besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Benutzer-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<BenutzerListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten anzusehen.
+	 *   Code 404: Keine Schüler-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Benutzer-Einträgen
+	 */
+	public async getBenutzerliste(schema : string) : Promise<List<BenutzerListeEintrag>> {
+		let path : string = "/db/{schema}/benutzer/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<BenutzerListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(BenutzerListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getBetriebe für den Zugriff auf die URL https://{hostname}/db/{schema}/betriebe/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Betriebe unter Angabe der ID, der Betriebsart , des Betriebnamens, Kontaktdaten, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Betriebsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Betrieb-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<BetriebListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Betriebdaten anzusehen.
+	 *   Code 404: Keine Betrieb-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Betrieb-Listen-Einträgen
+	 */
+	public async getBetriebe(schema : string) : Promise<List<BetriebListeEintrag>> {
+		let path : string = "/db/{schema}/betriebe/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<BetriebListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(BetriebListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchSchuelerBetriebsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/betriebe/{id : \d+}/betrieb
+	 * 
+	 * Passt die Schüler-Betriebsdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Schülerbetreibsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Schüler-Betriebsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten zu ändern.
+	 *   Code 404: Kein Schülerbetrieb-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {SchuelerBetriebsdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchSchuelerBetriebsdaten(data : Partial<SchuelerBetriebsdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/betriebe/{id : \d+}/betrieb"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = SchuelerBetriebsdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerBetriebsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/betriebe/{id : \d+}/betrieb
+	 * 
+	 * Liest die Daten des Schülerbetriebs zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen vom Schülerbetriebbesitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Stammdaten des Schülerbetriebs.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<SchuelerBetriebsdaten>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerbetreibe anzusehen.
+	 *   Code 404: Kein Schülerbetrieb gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Stammdaten des Schülerbetriebs.
+	 */
+	public async getSchuelerBetriebsdaten(schema : string, id : number) : Promise<List<SchuelerBetriebsdaten>> {
+		let path : string = "/db/{schema}/betriebe/{id : \d+}/betrieb"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<SchuelerBetriebsdaten>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(SchuelerBetriebsdaten.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getBetriebStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/betriebe/{id : \d+}/stammdaten
+	 * 
+	 * Liest die Stammdaten des Betriebs zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Stammdaten eines Betriebs
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: BetriebStammdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Betriebsdaten anzusehen.
+	 *   Code 404: Kein Betrieb-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Stammdaten eines Betriebs
+	 */
+	public async getBetriebStammdaten(schema : string, id : number) : Promise<BetriebStammdaten> {
+		let path : string = "/db/{schema}/betriebe/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return BetriebStammdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchBetriebStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/betriebe/{id : \d+}/stammdaten
+	 * 
+	 * Passt die Betrieb-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Erzieherdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Betrieb-Stammdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Betriebdaten zu ändern.
+	 *   Code 404: Kein Betrieb-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {BetriebStammdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchBetriebStammdaten(data : Partial<BetriebStammdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/betriebe/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = BetriebStammdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der PUT-Methode setClientConfigGlobalKey für den Zugriff auf die URL https://{hostname}/db/{schema}/client/config/{app}/global/{key}
+	 * 
+	 * Schreibt den Konfigurationseintrag der angegebenen Anwendung für den angebenen Schlüsselwert in die globale Konfiguration. Dabei wird geprüft, ob der angemeldete Benutzer administrative Rechte hat.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Konfigurationseintrag wurde erfolgreich geschrieben
+	 * 
+	 * @param {String} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {string} app - der Pfad-Parameter app
+	 * @param {string} key - der Pfad-Parameter key
+	 */
+	public async setClientConfigGlobalKey(data : String, schema : string, app : string, key : string) : Promise<void> {
+		let path : string = "/db/{schema}/client/config/{app}/global/{key}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{app\s*(:[^}]+)?}/g, app)
+				.replace(/{key\s*(:[^}]+)?}/g, key);
+		let body : string = JSON.stringify(data);
+		return super.putJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getClientConfigUserKey für den Zugriff auf die URL https://{hostname}/db/{schema}/client/config/{app}/user/{key}
+	 * 
+	 * Liest den Schlüsselwert aus der Konfiguration für den Client aus. Ist sowohl ein globaler als auch eine benutzerspezifischer Konfigurationseintrag unter den Name vorhanden,so wird der benutzerspezifische Eintrag zurückgegeben. Die benutzerspezifische Konfiguration kann somit globale Einstellungen 'überschreiben'. Ist kein Wert vorhanden, so wird ein leerer String zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Wert des Konfigurationseintrags
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: String
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {string} app - der Pfad-Parameter app
+	 * @param {string} key - der Pfad-Parameter key
+	 * 
+	 * @returns Der Wert des Konfigurationseintrags
+	 */
+	public async getClientConfigUserKey(schema : string, app : string, key : string) : Promise<String> {
+		let path : string = "/db/{schema}/client/config/{app}/user/{key}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{app\s*(:[^}]+)?}/g, app)
+				.replace(/{key\s*(:[^}]+)?}/g, key);
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return JSON.parse(text).toString();
+	}
+
+
+	/**
+	 * Implementierung der PUT-Methode setClientConfigUserKey für den Zugriff auf die URL https://{hostname}/db/{schema}/client/config/{app}/user/{key}
+	 * 
+	 * Schreibt den Konfigurationseintrag der angegebenen Anwendung für den angebenen Schlüsselwert in die benutzerspezifische Konfiguration. 
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Konfigurationseintrag wurde erfolgreich geschrieben
+	 * 
+	 * @param {String} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {string} app - der Pfad-Parameter app
+	 * @param {string} key - der Pfad-Parameter key
+	 */
+	public async setClientConfigUserKey(data : String, schema : string, app : string, key : string) : Promise<void> {
+		let path : string = "/db/{schema}/client/config/{app}/user/{key}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{app\s*(:[^}]+)?}/g, app)
+				.replace(/{key\s*(:[^}]+)?}/g, key);
+		let body : string = JSON.stringify(data);
+		return super.putJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerENMDaten für den Zugriff auf die URL https://{hostname}/db/{schema}/enm/lehrer/{id : \d+}
+	 * 
+	 * Liest die Daten des Externen Notenmoduls (ENM) des Lehrers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Notendaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Externen Notenmoduls (ENM) des Lehrers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: ENMDaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Daten des ENM auszulesen.
+	 *   Code 404: Kein Lehrer-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Externen Notenmoduls (ENM) des Lehrers
+	 */
+	public async getLehrerENMDaten(schema : string, id : number) : Promise<ENMDaten> {
+		let path : string = "/db/{schema}/enm/lehrer/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return ENMDaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getErzieher für den Zugriff auf die URL https://{hostname}/db/{schema}/erzieher/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Erzieher unter Angabe der ID, des Kürzels, des Vor- und Nachnamens, Erzieherart, Kontaktdaten, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Erzieherdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Erzieher-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<ErzieherListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Erzieherdaten anzusehen.
+	 *   Code 404: Keine Erzieher-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Erzieher-Listen-Einträgen
+	 */
+	public async getErzieher(schema : string) : Promise<List<ErzieherListeEintrag>> {
+		let path : string = "/db/{schema}/erzieher/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<ErzieherListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(ErzieherListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getErzieherStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/erzieher/{id : \d+}/stammdaten
+	 * 
+	 * Liest die Stammdaten des Erziehers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Erzieherdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Stammdaten des Erziehers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: ErzieherStammdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Erzieherdaten anzusehen.
+	 *   Code 404: Kein Erzieher-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Stammdaten des Erziehers
+	 */
+	public async getErzieherStammdaten(schema : string, id : number) : Promise<ErzieherStammdaten> {
+		let path : string = "/db/{schema}/erzieher/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return ErzieherStammdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchErzieherStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/erzieher/{id : \d+}/stammdaten
+	 * 
+	 * Passt die Erzieher-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Erzieherdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Erzieher-Stammdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Erzieherdaten zu ändern.
+	 *   Code 404: Kein Erzieher-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {ErzieherStammdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchErzieherStammdaten(data : Partial<ErzieherStammdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/erzieher/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = ErzieherStammdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getErzieherArten für den Zugriff auf die URL https://{hostname}/db/{schema}/erzieher/arten
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Erzieherarten unter Angabe der ID, der Beschreibung, Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Erzieherarten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<Erzieherart>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalogdaten anzusehen.
+	 *   Code 404: Keine Erzieherart-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Erzieherarten
+	 */
+	public async getErzieherArten(schema : string) : Promise<List<Erzieherart>> {
+		let path : string = "/db/{schema}/erzieher/arten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<Erzieherart>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(Erzieherart.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getFaecher für den Zugriff auf die URL https://{hostname}/db/{schema}/faecher/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Fächer unter Angabe der ID, des Kürzels, des verwendeten Statistik-Kürzels, der Bezeichnung des Faches, ob es ein Fach der Oberstufe ist, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Fächerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Fächer-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<FaecherListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fächerdaten anzusehen.
+	 *   Code 404: Keine Fächer-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Fächer-Listen-Einträgen
+	 */
+	public async getFaecher(schema : string) : Promise<List<FaecherListeEintrag>> {
+		let path : string = "/db/{schema}/faecher/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<FaecherListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(FaecherListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getFach für den Zugriff auf die URL https://{hostname}/db/{schema}/faecher/{id : \d+}
+	 * 
+	 * Liest die Daten des Faches zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Fächerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Faches
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: FachDaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fächerdaten anzusehen.
+	 *   Code 404: Kein Fach-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Faches
+	 */
+	public async getFach(schema : string, id : number) : Promise<FachDaten> {
+		let path : string = "/db/{schema}/faecher/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return FachDaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGesamtschuleSchuelerPrognoseLeistungsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/gesamtschule/schueler/{id : \d+}/prognose_leistungsdaten
+	 * 
+	 * Liest die Leistungsdaten des aktuellen Lernabschnittes in Bezug auf die Prognose- bzw. Abschlussberechnung in der Sek I der Gesamtschule des Schülers mit der angegebene ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Leistungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Leistungsdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GEAbschlussFaecher
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Leistungsdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Leistungsdaten des Schülers
+	 */
+	public async getGesamtschuleSchuelerPrognoseLeistungsdaten(schema : string, id : number) : Promise<GEAbschlussFaecher> {
+		let path : string = "/db/{schema}/gesamtschule/schueler/{id : \d+}/prognose_leistungsdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GEAbschlussFaecher.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGesamtschuleSchuelerPrognosLeistungsdatenFuerAbschnitt für den Zugriff auf die URL https://{hostname}/db/{schema}/gesamtschule/schueler/{id : \d+}/prognose_leistungsdaten/abschnitt/{abschnittID : \d+}
+	 * 
+	 * Liest die Leistungsdaten des angegebenen Lernabschnittes in Bezug auf die Prognose- bzw. Abschlussberechnung in der Sek I der Gesamtschule des Schülers mit der angegebene ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Leistungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Leistungsdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GEAbschlussFaecher
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Leistungsdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * @param {number} abschnittID - der Pfad-Parameter abschnittID
+	 * 
+	 * @returns Die Leistungsdaten des Schülers
+	 */
+	public async getGesamtschuleSchuelerPrognosLeistungsdatenFuerAbschnitt(schema : string, id : number, abschnittID : number) : Promise<GEAbschlussFaecher> {
+		let path : string = "/db/{schema}/gesamtschule/schueler/{id : \d+}/prognose_leistungsdaten/abschnitt/{abschnittID : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString())
+				.replace(/{abschnittID\s*(:[^}]+)?}/g, abschnittID.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GEAbschlussFaecher.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGostAbiturBelegpruefungEF1 für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abitur/belegpruefung/EF1
+	 * 
+	 * Prüft anhand der übergeben Abiturdaten, ob die Belegung in den Abiturdaten korrekt ist oder nicht. Es werden ggf. auch Belegungsfehler und Hinweise zur Belegung zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBelegpruefungErgebnis
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Belegprüfung durchzuführen.
+	 *   Code 404: Es wurden keine Fächerdaten zur gymnasialen Oberstufe gefunden
+	 * 
+	 * @param {Abiturdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 */
+	public async getGostAbiturBelegpruefungEF1(data : Abiturdaten, schema : string) : Promise<GostBelegpruefungErgebnis> {
+		let path : string = "/db/{schema}/gost/abitur/belegpruefung/EF1"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		let body : string = Abiturdaten.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return GostBelegpruefungErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGostAbiturBelegpruefungGesamt für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abitur/belegpruefung/gesamt
+	 * 
+	 * Prüft anhand der übergeben Abiturdaten, ob die Belegung in den Abiturdaten korrekt ist oder nicht. Es werden ggf. auch Belegungsfehler und Hinweise zur Belegung zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBelegpruefungErgebnis
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Belegprüfung durchzuführen.
+	 *   Code 404: Es wurden keine Fächerdaten zur gymnasialen Oberstufe gefunden
+	 * 
+	 * @param {Abiturdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 */
+	public async getGostAbiturBelegpruefungGesamt(data : Abiturdaten, schema : string) : Promise<GostBelegpruefungErgebnis> {
+		let path : string = "/db/{schema}/gost/abitur/belegpruefung/gesamt"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		let body : string = Abiturdaten.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return GostBelegpruefungErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgaenge für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgaenge
+	 * 
+	 * Liefert eine Liste aller Abiturjahrgänge, welche in der Datenbank für die Laufbahnplanung angelegt sind.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen von Kataloginformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Liste der Abiturjahrgänge.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<GostJahrgang>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Liste der Abiturjahrgänge auszulesen.
+	 *   Code 404: Kein Abiturjahrgang gefunden oder keine gymnasiale Oberstufe bei der Schulform vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Die Liste der Abiturjahrgänge.
+	 */
+	public async getGostAbiturjahrgaenge(schema : string) : Promise<List<GostJahrgang>> {
+		let path : string = "/db/{schema}/gost/abiturjahrgaenge"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<GostJahrgang>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(GostJahrgang.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgang für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}
+	 * 
+	 * Liest die Grunddaten des Jahrgangs der gymnasialen Oberstufe zu dem Jahr, in welchem der Jahrgang Abitur machen wird, aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Jahrgangsinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Grunddaten des Jahrgangs der gymnasialen Oberstufe
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostJahrgangsdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Grunddaten der Gymnasialen Oberstufe anzusehen.
+	 *   Code 404: Kein Eintrag für einen Jahrgang der gymnasialen Oberstufe mit dem angegebenen Abiturjahr gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * 
+	 * @returns Die Grunddaten des Jahrgangs der gymnasialen Oberstufe
+	 */
+	public async getGostAbiturjahrgang(schema : string, abiturjahr : number) : Promise<GostJahrgangsdaten> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostJahrgangsdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostAbiturjahrgang für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}
+	 * 
+	 * Passt die Daten des Jahrganges der gymnasialen Oberstufe zu dem Jahr an, in welchem der Jahrgang Abitur machen wird. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen der Jahrgangsinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Jahrgangsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Jahrgangsdaten zu ändern.
+	 *   Code 404: Kein Abiturjahrgangs-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostJahrgangsdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 */
+	public async patchGostAbiturjahrgang(data : Partial<GostJahrgangsdaten>, schema : string, abiturjahr : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString());
+		let body : string = GostJahrgangsdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgangBlockungsliste für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/{halbjahr : \d+}/blockungen
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Blockungen der gymnasialen Oberstufe, welche für den angebenen Abitur-Jahrgang und das angegebene Halbjahr festgelegt wurden.. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Blockungs-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<GostBlockungListeneintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Blockungsdaten anzusehen.
+	 *   Code 404: Keine Blockungs-Einträge gefunden oder keine gymnasiale Oberstufe bei der Schulform vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * @param {number} halbjahr - der Pfad-Parameter halbjahr
+	 * 
+	 * @returns Eine Liste von Blockungs-Listen-Einträgen
+	 */
+	public async getGostAbiturjahrgangBlockungsliste(schema : string, abiturjahr : number, halbjahr : number) : Promise<List<GostBlockungListeneintrag>> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/{halbjahr : \d+}/blockungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString())
+				.replace(/{halbjahr\s*(:[^}]+)?}/g, halbjahr.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<GostBlockungListeneintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(GostBlockungListeneintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode createGostAbiturjahrgangBlockung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/{halbjahr : \d+}/blockungen/new/{name}
+	 * 
+	 * Erstellt eine neue Blockung und gibt die ID dieser Blockung zurück.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Erstellen der Fachwahlen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Blockung wurde erfolgreich angelegt.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Long
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um eine Blockung anzulegen.
+	 *   Code 404: Keine Fachwahlinformationen zum Anlegen einer Blockung gefunden
+	 *   Code 409: Die übergebenen Daten (Anzahl der Schienen) sind fehlerhaft, da eine Rahmenbedingung nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {Integer} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * @param {number} halbjahr - der Pfad-Parameter halbjahr
+	 * @param {string} name - der Pfad-Parameter name
+	 * 
+	 * @returns Die Blockung wurde erfolgreich angelegt.
+	 */
+	public async createGostAbiturjahrgangBlockung(data : Number, schema : string, abiturjahr : number, halbjahr : number, name : string) : Promise<Number> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/{halbjahr : \d+}/blockungen/new/{name}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString())
+				.replace(/{halbjahr\s*(:[^}]+)?}/g, halbjahr.toString())
+				.replace(/{name\s*(:[^}]+)?}/g, name);
+		let body : string = JSON.stringify(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return parseFloat(JSON.parse(text));
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgangFach für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fach/{id : \d+}
+	 * 
+	 * Liefert die Informationen bezüglich eines Abiturjahrgangs der gymnasialen Oberstufe zu dem Fach mit der angegebenen ID. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Fachinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Faches bezüglich eines Abiturjahrgangs der gymnasialen Oberstufe
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostFach
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Fachinformationen der Gymnasialen Oberstufe anzusehen.
+	 *   Code 404: Kein Eintrag für das Fach der gymnasialen Oberstufe mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Faches bezüglich eines Abiturjahrgangs der gymnasialen Oberstufe
+	 */
+	public async getGostAbiturjahrgangFach(schema : string, abiturjahr : number, id : number) : Promise<GostFach> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fach/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString())
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostFach.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostAbiturjahrgangFach für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fach/{id : \d+}
+	 * 
+	 * Passt die Daten eines Faches in Bezug auf den Abiturjahrgang der Gymnasiale Oberstufe an. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen der Fachinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Fachinformationen integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fachdaten zu ändern.
+	 *   Code 404: Kein Fach-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostFach} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchGostAbiturjahrgangFach(data : Partial<GostFach>, schema : string, abiturjahr : number, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fach/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString())
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = GostFach.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgangFachwahlen für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fachwahlen
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank für den angebenen Abitur-Jahrgang vorhanden Fachwahlen der gymnasialen Oberstufe. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Fächerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste der Fachwahlen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<GostStatistikFachwahl>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fachwahlen anzusehen.
+	 *   Code 404: Keine Fachwahlen gefunden oder keine gymnasiale Oberstufe bei der Schulform vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * 
+	 * @returns Eine Liste der Fachwahlen
+	 */
+	public async getGostAbiturjahrgangFachwahlen(schema : string, abiturjahr : number) : Promise<List<GostStatistikFachwahl>> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/fachwahlen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<GostStatistikFachwahl>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(GostStatistikFachwahl.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostAbiturjahrgangFaecher für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/faecher
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Fächer der gymnasialen Oberstufe, welche für den angebenen Abitur-Jahrgang festgelegt wurden.. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Fächerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Fächer-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<GostFach>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fächerdaten anzusehen.
+	 *   Code 404: Keine Fächer-Einträge gefunden oder keine gymnasiale Oberstufe bei der Schulform vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abiturjahr - der Pfad-Parameter abiturjahr
+	 * 
+	 * @returns Eine Liste von Fächer-Listen-Einträgen
+	 */
+	public async getGostAbiturjahrgangFaecher(schema : string, abiturjahr : number) : Promise<List<GostFach>> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/{abiturjahr : \d+}/faecher"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abiturjahr\s*(:[^}]+)?}/g, abiturjahr.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<GostFach>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(GostFach.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode createGostAbiturjahrgang für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/abiturjahrgang/new/{jahrgangid}
+	 * 
+	 * Erstellt einen neuen Abiturjahrgang und gibt das Abiturjahr zurück.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Erstellen eine Abiturjahrgangs besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Abiturjahrgang wurde erfolgreich angelegt.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Integer
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um einen Abiturjahrgang anzulegen.
+	 *   Code 404: Keine Daten beim angegebenen Jahrgang gefunden, um einen Abiturjahrgang anzulegen
+	 *   Code 409: Der Abiturjahrgang existiert bereits
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} jahrgangid - der Pfad-Parameter jahrgangid
+	 * 
+	 * @returns Der Abiturjahrgang wurde erfolgreich angelegt.
+	 */
+	public async createGostAbiturjahrgang(schema : string, jahrgangid : number) : Promise<Number> {
+		let path : string = "/db/{schema}/gost/abiturjahrgang/new/{jahrgangid}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{jahrgangid\s*(:[^}]+)?}/g, jahrgangid.toString());
+		const result : string = await super.postJSON(path, null);
+		const text = result;
+		return parseInt(JSON.parse(text));
+	}
+
+
+	/**
+	 * Implementierung der DELETE-Methode deleteGostBlockung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/{blockungsid : \d+}
+	 * 
+	 * Entfernt die angegebene Blockung der gymnasialen Oberstufe. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Entfernen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 204: Die Blockungsdaten der gymnasialen Oberstfue für die angegebene ID wurden erfolgreich gelöscht.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe zu löschen.
+	 *   Code 404: Keine Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} blockungsid - der Pfad-Parameter blockungsid
+	 */
+	public async deleteGostBlockung(schema : string, blockungsid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/blockungen/{blockungsid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{blockungsid\s*(:[^}]+)?}/g, blockungsid.toString());
+		return super.deleteJSON(path);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostBlockung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/{blockungsid : \d+}
+	 * 
+	 * Liest für die angegebene Blockung der gymnasialen Oberstufe die grundlegenden Daten aus. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Blockungsdaten der gymnasialen Oberstfue für die angegebene ID
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBlockungsdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe auszulesen.
+	 *   Code 404: Keine Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} blockungsid - der Pfad-Parameter blockungsid
+	 * 
+	 * @returns Die Blockungsdaten der gymnasialen Oberstfue für die angegebene ID
+	 */
+	public async getGostBlockung(schema : string, blockungsid : number) : Promise<GostBlockungsdaten> {
+		let path : string = "/db/{schema}/gost/blockungen/{blockungsid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{blockungsid\s*(:[^}]+)?}/g, blockungsid.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostBlockungsdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostBlockung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/{blockungsid : \d+}
+	 * 
+	 * Passt die Blockungsdaten der Gymnasiale Oberstufe mit der angegebenen ID an.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen der Fachwahlen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Blockungsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Blockungsdaten zu ändern.
+	 *   Code 404: Kein Blockungsdaten-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostBlockungsdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} blockungsid - der Pfad-Parameter blockungsid
+	 */
+	public async patchGostBlockung(data : Partial<GostBlockungsdaten>, schema : string, blockungsid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/blockungen/{blockungsid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{blockungsid\s*(:[^}]+)?}/g, blockungsid.toString());
+		let body : string = GostBlockungsdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode rechneGostBlockung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/{blockungsid : \d+}/rechne/{zeit : \d+}
+	 * 
+	 * Berechnet für die angegebene Blockung der gymnasialen Oberstufe Zwischenergebnisse und speichert diese in der DB. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Rechnen einer Blockung besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste der IDs der Zwischenergebnisse
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<Long>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe auf dem Server zu rechnen.
+	 *   Code 404: Keine Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} blockungsid - der Pfad-Parameter blockungsid
+	 * @param {number} zeit - der Pfad-Parameter zeit
+	 * 
+	 * @returns Eine Liste der IDs der Zwischenergebnisse
+	 */
+	public async rechneGostBlockung(schema : string, blockungsid : number, zeit : number) : Promise<List<Number>> {
+		let path : string = "/db/{schema}/gost/blockungen/{blockungsid : \d+}/rechne/{zeit : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{blockungsid\s*(:[^}]+)?}/g, blockungsid.toString())
+				.replace(/{zeit\s*(:[^}]+)?}/g, zeit.toString());
+		const result : string = await super.postJSON(path, null);
+		const obj = JSON.parse(result);
+		let ret = new Vector<Number>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(parseFloat(JSON.parse(text))); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostBlockungKurs für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/kurse/{kursid : \d+}
+	 * 
+	 * Liest den angegebenen Kurs einer Blockung der gymnasialen Oberstufe aus. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Kurs der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBlockungKurs
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe auszulesen.
+	 *   Code 404: Kein Kurs einer Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} kursid - der Pfad-Parameter kursid
+	 * 
+	 * @returns Der Kurs der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 */
+	public async getGostBlockungKurs(schema : string, kursid : number) : Promise<GostBlockungKurs> {
+		let path : string = "/db/{schema}/gost/blockungen/kurse/{kursid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{kursid\s*(:[^}]+)?}/g, kursid.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostBlockungKurs.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostBlockungKurs für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/kurse/{kursid : \d+}
+	 * 
+	 * Passt den angebenene Kurs der Gymnasiale Oberstufe mit der angegebenen ID an.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen von Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Blockungsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Blockungsdaten zu ändern.
+	 *   Code 404: Kein Kurs einer Blockung mit der angebenen ID gefunden.
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostBlockungKurs} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} kursid - der Pfad-Parameter kursid
+	 */
+	public async patchGostBlockungKurs(data : Partial<GostBlockungKurs>, schema : string, kursid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/blockungen/kurse/{kursid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{kursid\s*(:[^}]+)?}/g, kursid.toString());
+		let body : string = GostBlockungKurs.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostBlockungRegel für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/regeln/{regelid : \d+}
+	 * 
+	 * Liest die angegebene Regel einer Blockung der gymnasialen Oberstufe aus. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Regel der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBlockungRegel
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe auszulesen.
+	 *   Code 404: Keine Regel einer Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} regelid - der Pfad-Parameter regelid
+	 * 
+	 * @returns Die Regel der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 */
+	public async getGostBlockungRegel(schema : string, regelid : number) : Promise<GostBlockungRegel> {
+		let path : string = "/db/{schema}/gost/blockungen/regeln/{regelid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{regelid\s*(:[^}]+)?}/g, regelid.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostBlockungRegel.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostBlockungRegel für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/regeln/{regelid : \d+}
+	 * 
+	 * Passt die angegebene Regel der Gymnasiale Oberstufe mit der angegebenen ID an.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen von Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Blockungsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Blockungsdaten zu ändern.
+	 *   Code 404: Keine Regel einer Blockung mit der angebenen ID gefunden.
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostBlockungRegel} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} regelid - der Pfad-Parameter regelid
+	 */
+	public async patchGostBlockungRegel(data : Partial<GostBlockungRegel>, schema : string, regelid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/blockungen/regeln/{regelid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{regelid\s*(:[^}]+)?}/g, regelid.toString());
+		let body : string = GostBlockungRegel.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostBlockungSchiene für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/schiene/{schienenid : \d+}
+	 * 
+	 * Liest die angegebene Schiene einer Blockung der gymnasialen Oberstufe aus. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Schiene der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBlockungSchiene
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Blockungsdaten der Gymnasialen Oberstufe auszulesen.
+	 *   Code 404: Keine Schiene einer Blockung mit der angebenen ID gefunden.
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} schienenid - der Pfad-Parameter schienenid
+	 * 
+	 * @returns Die Schiene der Blockung der gymnasialen Oberstfue für die angegebene ID
+	 */
+	public async getGostBlockungSchiene(schema : string, schienenid : number) : Promise<GostBlockungSchiene> {
+		let path : string = "/db/{schema}/gost/blockungen/schiene/{schienenid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{schienenid\s*(:[^}]+)?}/g, schienenid.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostBlockungSchiene.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostBlockungSchiene für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/blockungen/schiene/{schienenid : \d+}
+	 * 
+	 * Passt die angegebene Schiene der Gymnasiale Oberstufe mit der angegebenen ID an.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen von Blockungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Blockungsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Blockungsdaten zu ändern.
+	 *   Code 404: Keine Schiene einer Blockung mit der angebenen ID gefunden.
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostBlockungSchiene} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} schienenid - der Pfad-Parameter schienenid
+	 */
+	public async patchGostBlockungSchiene(data : Partial<GostBlockungSchiene>, schema : string, schienenid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/blockungen/schiene/{schienenid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{schienenid\s*(:[^}]+)?}/g, schienenid.toString());
+		let body : string = GostBlockungSchiene.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostFach für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/fach/{id : \d+}
+	 * 
+	 * Liefert die Informationen bezüglich der gymnasialen Oberstufe zu dem Fach mit der angegebenen ID. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Fachinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Faches bezüglich der gymnasialen Oberstufe
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostFach
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Fachiformationen der Gymnasialen Oberstufe anzusehen.
+	 *   Code 404: Kein Eintrag für das Fach der gymnasialen Oberstufe mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Faches bezüglich der gymnasialen Oberstufe
+	 */
+	public async getGostFach(schema : string, id : number) : Promise<GostFach> {
+		let path : string = "/db/{schema}/gost/fach/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostFach.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostFach für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/fach/{id : \d+}
+	 * 
+	 * Passt die Daten eines Faches in Bezug auf die Gymnasiale Oberstufe an. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen der Fachinformationen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Fachinformationen integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fachdaten zu ändern.
+	 *   Code 404: Kein Fach-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostFach} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchGostFach(data : Partial<GostFach>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/fach/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = GostFach.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostFaecher für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/faecher
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Fächer der gymnasialen Oberstufe. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Fächerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Fächer-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<GostFach>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fächerdaten anzusehen.
+	 *   Code 404: Keine Fächer-Einträge gefunden oder keine gymnasiale Oberstufe bei der Schulform vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Fächer-Listen-Einträgen
+	 */
+	public async getGostFaecher(schema : string) : Promise<List<GostFach>> {
+		let path : string = "/db/{schema}/gost/faecher"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<GostFach>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(GostFach.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerAbiturdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{id : \d+}/abiturdaten
+	 * 
+	 * Liest die Abiturdaten aus den Abiturtabellen des Schülers mit der angegebene ID und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Leistungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Abiturdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Abiturdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Leistungsdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Abiturdaten des Schülers
+	 */
+	public async getGostSchuelerAbiturdaten(schema : string, id : number) : Promise<Abiturdaten> {
+		let path : string = "/db/{schema}/gost/schueler/{id : \d+}/abiturdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return Abiturdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerAbiturdatenAusLeistungsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{id : \d+}/abiturdatenAusLeistungsdaten
+	 * 
+	 * Liest die Abiturdaten aus den Leistungsdaten der gymnasiale Oberstufe des Schülers mit der angegebene ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Leistungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Abiturdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Abiturdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Leistungsdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Abiturdaten des Schülers
+	 */
+	public async getGostSchuelerAbiturdatenAusLeistungsdaten(schema : string, id : number) : Promise<Abiturdaten> {
+		let path : string = "/db/{schema}/gost/schueler/{id : \d+}/abiturdatenAusLeistungsdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return Abiturdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerLaufbahnplanung für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{id : \d+}/laufbahnplanung
+	 * 
+	 * Liest die Laufbahnplanungsdaten für die gymnasiale Oberstufe zu dem Schüler mit der angegebenen ID aus der Datenbank aus und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Laufbahnplanungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Laufbahnplanungsdaten der gymnasialen Oberstfue des angegebenen Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Abiturdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Laufbahnplanungsdaten der Gymnasialen Oberstufe eines Schülers auszulesen.
+	 *   Code 404: Kein Eintrag für einen Schüler mit Laufbahnplanungsdaten der gymnasialen Oberstufe für die angegebene ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Laufbahnplanungsdaten der gymnasialen Oberstfue des angegebenen Schülers
+	 */
+	public async getGostSchuelerLaufbahnplanung(schema : string, id : number) : Promise<Abiturdaten> {
+		let path : string = "/db/{schema}/gost/schueler/{id : \d+}/laufbahnplanung"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return Abiturdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerLeistungsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{id : \d+}/leistungsdaten
+	 * 
+	 * Liest die Leistungsdaten in Bezug auf die gymnasiale Oberstufe des Schülers mit der angegebene ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Leistungsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Leistungsdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostLeistungen
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Leistungsdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Leistungsdaten des Schülers
+	 */
+	public async getGostSchuelerLeistungsdaten(schema : string, id : number) : Promise<GostLeistungen> {
+		let path : string = "/db/{schema}/gost/schueler/{id : \d+}/leistungsdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return GostLeistungen.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerPDFWahlbogen für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{id : \d+}/wahlbogen
+	 * 
+	 * Erstellt den PDF-Wahlbogen für die gymnasiale Oberstufe zu dem Schüler mit der angegebenen ID. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Erstellen des Wahlbogens besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der PDF-Wahlbogen für die gymnasialen Oberstufe des angegebenen Schülers
+	 *     - Mime-Type: application/pdf
+	 *     - Rückgabe-Typ: Blob
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um den Wahlbogen für die Gymnasialen Oberstufe eines Schülers zu erstellen.
+	 *   Code 404: Kein Eintrag für einen Schüler mit Laufbahnplanungsdaten der gymnasialen Oberstufe für die angegebene ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Der PDF-Wahlbogen für die gymnasialen Oberstufe des angegebenen Schülers
+	 */
+	public async getGostSchuelerPDFWahlbogen(schema : string, id : number) : Promise<Blob> {
+		let path : string = "/db/{schema}/gost/schueler/{id : \d+}/wahlbogen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const data : Blob = await super.getPDF(path);
+		return data;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getGostSchuelerFachwahl für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{schuelerid : \d+}/fachwahl/{fachid : \d+}
+	 * 
+	 * Liest für die gymnasiale Oberstufe die Fachwahlen zu einem Fach von dem angegebenen Schüler aus. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Auslesen der Fachwahlen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Fachwahlen der gymnasialen Oberstfue für das angegebene Fach und den angegebenen Schüler
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Abiturdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Fachwahlen der Gymnasialen Oberstufe eines Schülers auszulesen.
+	 *   Code 404: Kein Eintrag für einen Schüler mit Laufbahnplanungsdaten der gymnasialen Oberstufe für die angegebene ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} schuelerid - der Pfad-Parameter schuelerid
+	 * @param {number} fachid - der Pfad-Parameter fachid
+	 * 
+	 * @returns Die Fachwahlen der gymnasialen Oberstfue für das angegebene Fach und den angegebenen Schüler
+	 */
+	public async getGostSchuelerFachwahl(schema : string, schuelerid : number, fachid : number) : Promise<Abiturdaten> {
+		let path : string = "/db/{schema}/gost/schueler/{schuelerid : \d+}/fachwahl/{fachid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{schuelerid\s*(:[^}]+)?}/g, schuelerid.toString())
+				.replace(/{fachid\s*(:[^}]+)?}/g, fachid.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return Abiturdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchGostSchuelerFachwahl für den Zugriff auf die URL https://{hostname}/db/{schema}/gost/schueler/{schuelerid : \d+}/fachwahl/{fachid : \d+}
+	 * 
+	 * Passt die Fachwahl eines Schüler in Bezug auf ein Fach der Gymnasiale Oberstufe an. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Anpassen der Fachwahlen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Fachwahlen integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Fachwahlen zu ändern.
+	 *   Code 404: Kein Schüler- oder Fach-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {GostSchuelerFachwahl} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} schuelerid - der Pfad-Parameter schuelerid
+	 * @param {number} fachid - der Pfad-Parameter fachid
+	 */
+	public async patchGostSchuelerFachwahl(data : Partial<GostSchuelerFachwahl>, schema : string, schuelerid : number, fachid : number) : Promise<void> {
+		let path : string = "/db/{schema}/gost/schueler/{schuelerid : \d+}/fachwahl/{fachid : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{schuelerid\s*(:[^}]+)?}/g, schuelerid.toString())
+				.replace(/{fachid\s*(:[^}]+)?}/g, fachid.toString());
+		let body : string = GostSchuelerFachwahl.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getJahrgaenge für den Zugriff auf die URL https://{hostname}/db/{schema}/jahrgaenge/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Jahrgänge unter Angabe der ID, des Kürzels, des verwendeten Statistik-Kürzels, der Bezeichnung des Jahrgangs, die Schulgliederung zu der der Jahrgang gehört, die ID eines Folgejahrgangs, sofern definiert, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Jahrgangsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Jahrgangs-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<JahrgangsListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Jahrgangsdaten anzusehen.
+	 *   Code 404: Keine Jahrgangs-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Jahrgangs-Listen-Einträgen
+	 */
+	public async getJahrgaenge(schema : string) : Promise<List<JahrgangsListeEintrag>> {
+		let path : string = "/db/{schema}/jahrgaenge/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<JahrgangsListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(JahrgangsListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getJahrgang für den Zugriff auf die URL https://{hostname}/db/{schema}/jahrgaenge/{id : \d+}
+	 * 
+	 * Liest die Daten des Jahrgangs zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Jahrgangsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Jahrgangs
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: JahrgangsDaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Jahrgangsdaten anzusehen.
+	 *   Code 404: Kein Jahrgangs-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Jahrgangs
+	 */
+	public async getJahrgang(schema : string, id : number) : Promise<JahrgangsDaten> {
+		let path : string = "/db/{schema}/jahrgaenge/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return JahrgangsDaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogBeschaeftigungsart für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/beschaeftigungsart
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhandenen Beschäftigungsarten unter Angabe der ID, eines Kürzels und der textuellen Beschreibung sowie der Information, ob der Eintrag in der Anwendung sichtbar bzw. änderbar sein soll, undgibt diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Katalog-Einträgen zu den Beschäftigungsarten.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Katalog-Einträgen zu den Beschäftigungsarten.
+	 */
+	public async getKatalogBeschaeftigungsart(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/beschaeftigungsart"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogBeschaeftigungsartmitID für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}
+	 * 
+	 * Liest die Daten der Beschäftigunsart zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Beschäftigungsartbesitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Katalog-Eintrag zu den Beschäftigungsarten.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Katalog-Eintrag zu den Beschäftigungsarten.
+	 */
+	public async getKatalogBeschaeftigungsartmitID(schema : string, id : number) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchBeschaeftigungsart für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}
+	 * 
+	 * Passt die Beschäftigungsart-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern der Daten der Beschäftigungsart besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Beschäftigungsart-Daten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Beschäftigungsart-Daten zu ändern.
+	 *   Code 404: Keine Beschäftigungsart mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {KatalogEintrag} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchBeschaeftigungsart(data : Partial<KatalogEintrag>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = KatalogEintrag.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogBetriebsartmitID für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}
+	 * 
+	 * Liest die Daten der Betriebsart zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Betriebsartenbesitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Katalog-Eintrag zu den Betriebsarten.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Katalog-Eintrag zu den Betriebsarten.
+	 */
+	public async getKatalogBetriebsartmitID(schema : string, id : number) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/beschaeftigungsart/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogBetriebsart für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/betriebsart
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhandenen Betriebsarten unter Angabe der ID, eines Kürzels und der textuellen Beschreibung sowie der Information, ob der Eintrag in der Anwendung sichtbar bzw. änderbar sein soll, undgibt diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Katalog-Einträgen zu den Betriebsarten.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Katalog-Einträgen zu den Betriebsarten.
+	 */
+	public async getKatalogBetriebsart(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/betriebsart"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchBetriebsart für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/betriebsart/{id : \d+}
+	 * 
+	 * Passt die Beschäftigungsart-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern der Daten der Betriebssart besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Beschäftigungsart-Daten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Beschäftigungsart-Daten zu ändern.
+	 *   Code 404: Keine Beschäftigungsart mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {KatalogEintrag} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchBetriebsart(data : Partial<KatalogEintrag>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/kataloge/betriebsart/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = KatalogEintrag.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogHaltestellen für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/haltestellen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Haltestellen unter Angabe der ID, eines Kürzels und der textuellen Beschreibung sowie der Information, ob der Eintrag in der Anwendung sichtbar bzw. änderbar sein soll, undgibt diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Katalog-Einträgen zu den Haltestellen.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Katalog-Einträgen zu den Haltestellen.
+	 */
+	public async getKatalogHaltestellen(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/haltestellen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogNationaelitaeten für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/nationalitaeten
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Nationalitäten unter Angabe der ID, des Landes, der Staatsangehörigkeit, einem Statistik-Kürzel, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Nationalitäten-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<NationalitaetKatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Nationalitäten-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Nationalitäten-Katalog-Einträgen
+	 */
+	public async getKatalogNationaelitaeten(schema : string) : Promise<List<NationalitaetKatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/nationalitaeten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<NationalitaetKatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(NationalitaetKatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogOrte für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/orte
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Orte unter Angabe der ID, der PLZ, des Ortes, ggf. des Kreises, dem Bundesland, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Orts-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<OrtKatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Ort-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Orts-Katalog-Einträgen
+	 */
+	public async getKatalogOrte(schema : string) : Promise<List<OrtKatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/orte"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<OrtKatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(OrtKatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogOrtsteile für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/ortsteile
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Ortsteile unter Angabe der ID, der zugehörigenOrt-ID, dem Namen des Ortsteils, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Ortsteil-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<OrtsteilKatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Ortsteil-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Ortsteil-Katalog-Einträgen
+	 */
+	public async getKatalogOrtsteile(schema : string) : Promise<List<OrtsteilKatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/ortsteile"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<OrtsteilKatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(OrtsteilKatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogReligionen für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/religionen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Religionen unter Angabe der ID, der Bezeichnung sowie der Bezeichnung, welche auf dem Zeugnis erscheint, einem Statistik-Kürzel, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Religion-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<ReligionKatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Religion-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Religion-Katalog-Einträgen
+	 */
+	public async getKatalogReligionen(schema : string) : Promise<List<ReligionKatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/religionen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<ReligionKatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(ReligionKatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogStrassen für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/strassen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhandenen Strassen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Straßen-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintragStrassen>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Straßen-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Straßen-Katalog-Einträgen
+	 */
+	public async getKatalogStrassen(schema : string) : Promise<List<KatalogEintragStrassen>> {
+		let path : string = "/db/{schema}/kataloge/strassen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintragStrassen>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintragStrassen.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKatalogVerkehrssprachen für den Zugriff auf die URL https://{hostname}/db/{schema}/kataloge/verkehrsprachen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Verkehrssprachen unter Angabe der ID, eines Kürzels und der textuellen Beschreibung sowie der Information, ob der Eintrag in der Anwendung sichtbar bzw. änderbar sein soll, undgibt diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Katalog-Einträgen zur Verkehrssprache.
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Katalog-Einträgen zur Verkehrssprache.
+	 */
+	public async getKatalogVerkehrssprachen(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/kataloge/verkehrsprachen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKlasse für den Zugriff auf die URL https://{hostname}/db/{schema}/klassen/{id : \d+}
+	 * 
+	 * Liest die Daten der Klasse zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Klassendaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten der Klasse
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: KlassenDaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Klassendaten anzusehen.
+	 *   Code 404: Kein Klassen-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten der Klasse
+	 */
+	public async getKlasse(schema : string, id : number) : Promise<KlassenDaten> {
+		let path : string = "/db/{schema}/klassen/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return KlassenDaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKlassenFuerAbschnitt für den Zugriff auf die URL https://{hostname}/db/{schema}/klassen/abschnitt/{abschnitt : \d+}
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Klassen unter Angabe der ID, des Kürzels, der Parallelität, der Kürzel des Klassenlehrers und des zweiten Klassenlehrers, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Klassendaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Klassen-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KlassenListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Klassendaten anzusehen.
+	 *   Code 404: Keine Klassen-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abschnitt - der Pfad-Parameter abschnitt
+	 * 
+	 * @returns Eine Liste von Klassen-Listen-Einträgen
+	 */
+	public async getKlassenFuerAbschnitt(schema : string, abschnitt : number) : Promise<List<KlassenListeEintrag>> {
+		let path : string = "/db/{schema}/klassen/abschnitt/{abschnitt : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abschnitt\s*(:[^}]+)?}/g, abschnitt.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KlassenListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KlassenListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKurse für den Zugriff auf die URL https://{hostname}/db/{schema}/kurse/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Kurse unter Angabe der ID, des Kürzels, der Parallelität, der Kürzel des Klassenlehrers und des zweiten Klassenlehrers, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Klassendaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Kurs-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KursListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Kursdaten anzusehen.
+	 *   Code 404: Keine Kurs-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Kurs-Listen-Einträgen
+	 */
+	public async getKurse(schema : string) : Promise<List<KursListeEintrag>> {
+		let path : string = "/db/{schema}/kurse/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KursListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KursListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKurs für den Zugriff auf die URL https://{hostname}/db/{schema}/kurse/{id : \d+}
+	 * 
+	 * Liest die Daten des Kurses zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Kursdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Daten des Kurses
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: KursDaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Kursdaten anzusehen.
+	 *   Code 404: Kein Kurs-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Daten des Kurses
+	 */
+	public async getKurs(schema : string, id : number) : Promise<KursDaten> {
+		let path : string = "/db/{schema}/kurse/{id : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return KursDaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getKurseFuerAbschnitt für den Zugriff auf die URL https://{hostname}/db/{schema}/kurse/abschnitt/{abschnitt : \d+}
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Kurse eines Schuljahresabschnittes unter Angabe der ID, des Kürzels, der Parallelität, der Kürzel des Klassenlehrers und des zweiten Klassenlehrers, einer Sortierreihenfolge und ob sie in der Anwendung sichtbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Klassendaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Kurs-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KursListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Kursdaten anzusehen.
+	 *   Code 404: Keine Kurs-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abschnitt - der Pfad-Parameter abschnitt
+	 * 
+	 * @returns Eine Liste von Kurs-Listen-Einträgen
+	 */
+	public async getKurseFuerAbschnitt(schema : string, abschnitt : number) : Promise<List<KursListeEintrag>> {
+		let path : string = "/db/{schema}/kurse/abschnitt/{abschnitt : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abschnitt\s*(:[^}]+)?}/g, abschnitt.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KursListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KursListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrer für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhanden Lehrer unter Angabe der ID, des Kürzels, des Vor- und Nachnamens, der sog. Personentyps, einer Sortierreihenfolge, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen sowie ob sie für die Schulstatistik relevant sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Lehrerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehrer-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Lehrerdaten anzusehen.
+	 *   Code 404: Keine Lehrer-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehrer-Listen-Einträgen
+	 */
+	public async getLehrer(schema : string) : Promise<List<LehrerListeEintrag>> {
+		let path : string = "/db/{schema}/lehrer/"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerPersonaldaten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/{id : \d+}/personaldaten
+	 * 
+	 * Liest die Personaldaten des Lehrers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Lehrerpersonaldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Personaldaten des Lehrers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: LehrerPersonaldaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Lehrerdaten anzusehen.
+	 *   Code 404: Kein Lehrer-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Personaldaten des Lehrers
+	 */
+	public async getLehrerPersonaldaten(schema : string, id : number) : Promise<LehrerPersonaldaten> {
+		let path : string = "/db/{schema}/lehrer/{id : \d+}/personaldaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return LehrerPersonaldaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchLehrerPersonaldaten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/{id : \d+}/personaldaten
+	 * 
+	 * Passt die Lehrer-Personaldaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Lehrer-Personaldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Lehrer-Personaldaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Lehrer-Personaldaten zu ändern.
+	 *   Code 404: Kein Lehrer-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {LehrerPersonaldaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchLehrerPersonaldaten(data : Partial<LehrerPersonaldaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/lehrer/{id : \d+}/personaldaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = LehrerPersonaldaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/{id : \d+}/stammdaten
+	 * 
+	 * Liest die Stammdaten des Lehrers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Lehrerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Stammdaten des Lehrers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: LehrerStammdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Lehrerdaten anzusehen.
+	 *   Code 404: Kein Lehrer-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Stammdaten des Lehrers
+	 */
+	public async getLehrerStammdaten(schema : string, id : number) : Promise<LehrerStammdaten> {
+		let path : string = "/db/{schema}/lehrer/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return LehrerStammdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchLehrerStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/{id : \d+}/stammdaten
+	 * 
+	 * Passt die Lehrer-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Lehrerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Lehrer-Stammdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Lehrerdaten zu ändern.
+	 *   Code 404: Kein Lehrer-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {LehrerStammdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchLehrerStammdaten(data : Partial<LehrerStammdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/lehrer/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = LehrerStammdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerAbgangsgruende für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/abgangsgruende
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Lehrerabgangsgründe unter Angabe der ID, der Bezeichnung und des Statistikschlüssels. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehrerabgangsgrund-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogAbgangsgrundEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Lehrerabgangsgrund-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehrerabgangsgrund-Katalog-Einträgen
+	 */
+	public async getLehrerAbgangsgruende(schema : string) : Promise<List<LehrerKatalogAbgangsgrundEintrag>> {
+		let path : string = "/db/{schema}/lehrer/abgangsgruende"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogAbgangsgrundEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogAbgangsgrundEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerAnrechnungsgruende für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/anrechnungsgruende
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Gründe für Anrechnungsstunden von Lehrern.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Einträgen für Gründe von Anrechnungsstunden von Lehrern
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogAnrechnungsgrundEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Einträgen für Gründe von Anrechnungsstunden von Lehrern
+	 */
+	public async getLehrerAnrechnungsgruende(schema : string) : Promise<List<LehrerKatalogAnrechnungsgrundEintrag>> {
+		let path : string = "/db/{schema}/lehrer/anrechnungsgruende"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogAnrechnungsgrundEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogAnrechnungsgrundEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerBeschaeftigungsarten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/beschaeftigungsarten
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Beschäftigungsarten unter Angabe der ID, eines Kürzels und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Beschäftigungsart-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogBeschaeftigungsartEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Beschäftigungsart-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Beschäftigungsart-Katalog-Einträgen
+	 */
+	public async getLehrerBeschaeftigungsarten(schema : string) : Promise<List<LehrerKatalogBeschaeftigungsartEintrag>> {
+		let path : string = "/db/{schema}/lehrer/beschaeftigungsarten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogBeschaeftigungsartEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogBeschaeftigungsartEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerEinsatzstatus für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/einsatzstatus
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Einsatzstatusarten unter Angabe der ID, eines Kürzels und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Einsatzstatus-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogEinsatzstatusEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Einsatzstatus-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Einsatzstatus-Katalog-Einträgen
+	 */
+	public async getLehrerEinsatzstatus(schema : string) : Promise<List<LehrerKatalogEinsatzstatusEintrag>> {
+		let path : string = "/db/{schema}/lehrer/einsatzstatus"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogEinsatzstatusEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogEinsatzstatusEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerFachrichtungen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/fachrichtungen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Fachrichtungen von Lehrern. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Fachrichtungens-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogFachrichtungEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Fachrichtungs-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Fachrichtungens-Katalog-Einträgen
+	 */
+	public async getLehrerFachrichtungen(schema : string) : Promise<List<LehrerKatalogFachrichtungEintrag>> {
+		let path : string = "/db/{schema}/lehrer/fachrichtungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogFachrichtungEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogFachrichtungEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerFachrichtungAnerkennungen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/fachrichtungen_anerkennungen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Anerkennungen von Fachrichtungen für Lehrer. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Anerkennungs-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogFachrichtungAnerkennungEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Anerkennungs-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Anerkennungs-Katalog-Einträgen
+	 */
+	public async getLehrerFachrichtungAnerkennungen(schema : string) : Promise<List<LehrerKatalogFachrichtungAnerkennungEintrag>> {
+		let path : string = "/db/{schema}/lehrer/fachrichtungen_anerkennungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogFachrichtungAnerkennungEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogFachrichtungAnerkennungEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerLehraemter für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/lehraemter
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Lehrämter. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehramt-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogLehramtEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Lehramt-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehramt-Katalog-Einträgen
+	 */
+	public async getLehrerLehraemter(schema : string) : Promise<List<LehrerKatalogLehramtEintrag>> {
+		let path : string = "/db/{schema}/lehrer/lehraemter"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogLehramtEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogLehramtEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerLehramtAnerkennungen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/lehraemter_anerkennungen
+	 * 
+	 * Erstellt eine Liste aller Anerkennungen von Lehrämtern. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Anerkennungs-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogLehramtAnerkennungEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Anerkennungs-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Anerkennungs-Katalog-Einträgen
+	 */
+	public async getLehrerLehramtAnerkennungen(schema : string) : Promise<List<LehrerKatalogLehramtAnerkennungEintrag>> {
+		let path : string = "/db/{schema}/lehrer/lehraemter_anerkennungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogLehramtAnerkennungEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogLehramtAnerkennungEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerLehrbefaehigungen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/lehrbefaehigungen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Lehrbefähigungen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehrbefähigung-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogLehrbefaehigungEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Lehrbefähigung-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehrbefähigung-Katalog-Einträgen
+	 */
+	public async getLehrerLehrbefaehigungen(schema : string) : Promise<List<LehrerKatalogLehrbefaehigungEintrag>> {
+		let path : string = "/db/{schema}/lehrer/lehrbefaehigungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogLehrbefaehigungEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogLehrbefaehigungEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerLehrbefaehigungenAnerkennungen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/lehrbefaehigungen_anerkennungen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Anerkennungen von Lehrbefähigungen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Einsatzstatus-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogLehrbefaehigungAnerkennungEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Anerkennungs-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Einsatzstatus-Katalog-Einträgen
+	 */
+	public async getLehrerLehrbefaehigungenAnerkennungen(schema : string) : Promise<List<LehrerKatalogLehrbefaehigungAnerkennungEintrag>> {
+		let path : string = "/db/{schema}/lehrer/lehrbefaehigungen_anerkennungen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogLehrbefaehigungAnerkennungEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogLehrbefaehigungAnerkennungEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerLeitungsfunktionen für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/leitungsfunktionen
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Lehrerleitungsfunktionen unter Angabe der ID und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehrerleitungsfunktion-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogLeitungsfunktionEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Lehrerleitungsfunktion-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehrerleitungsfunktion-Katalog-Einträgen
+	 */
+	public async getLehrerLeitungsfunktionen(schema : string) : Promise<List<LehrerKatalogLeitungsfunktionEintrag>> {
+		let path : string = "/db/{schema}/lehrer/leitungsfunktionen"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogLeitungsfunktionEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogLeitungsfunktionEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerMehrleistungsarten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/mehrleistungsarten
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden die Arten von Mehrleistungen durch Lehrer. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Mehrleistungsart-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogMehrleistungsartEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Mehrleistungsart-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Mehrleistungsart-Katalog-Einträgen
+	 */
+	public async getLehrerMehrleistungsarten(schema : string) : Promise<List<LehrerKatalogMehrleistungsartEintrag>> {
+		let path : string = "/db/{schema}/lehrer/mehrleistungsarten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogMehrleistungsartEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogMehrleistungsartEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerMinderleistungsarten für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/minderleistungsarten
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Arten von Minderleistungen durch Lehrer. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Minderleistungsart-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogMinderleistungsartEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Minderleistungsart-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Minderleistungsart-Katalog-Einträgen
+	 */
+	public async getLehrerMinderleistungsarten(schema : string) : Promise<List<LehrerKatalogMinderleistungsartEintrag>> {
+		let path : string = "/db/{schema}/lehrer/minderleistungsarten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogMinderleistungsartEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogMinderleistungsartEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerRechtsverhaeltnisse für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/rechtsverhaeltnisse
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Rechtsverhältnisse unter Angabe der ID, eines Kürzels und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Rechtsverhältnis-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogRechtsverhaeltnisEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Rechtsverhältnis-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Rechtsverhältnis-Katalog-Einträgen
+	 */
+	public async getLehrerRechtsverhaeltnisse(schema : string) : Promise<List<LehrerKatalogRechtsverhaeltnisEintrag>> {
+		let path : string = "/db/{schema}/lehrer/rechtsverhaeltnisse"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogRechtsverhaeltnisEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogRechtsverhaeltnisEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getLehrerZugangsgruende für den Zugriff auf die URL https://{hostname}/db/{schema}/lehrer/zugangsgruende
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Lehrerzugangsgründe unter Angabe der ID, der Bezeichnung und des Statistikschlüssels. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Lehrerzugangsgrund-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<LehrerKatalogZugangsgrundEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Lehrerzugangsgrund-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Lehrerzugangsgrund-Katalog-Einträgen
+	 */
+	public async getLehrerZugangsgruende(schema : string) : Promise<List<LehrerKatalogZugangsgrundEintrag>> {
+		let path : string = "/db/{schema}/lehrer/zugangsgruende"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<LehrerKatalogZugangsgrundEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(LehrerKatalogZugangsgrundEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerLernabschnittsdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/abschnitt/{abschnitt : \d+}/lernabschnittsdaten
+	 * 
+	 * Liest die Lernabschnittsdaten des Schülers zu der angegebenen ID und dem angegeben Schuljahresabschnitt aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Lernabschnittsdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: SchuelerLernabschnittsdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Schülerdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * @param {number} abschnitt - der Pfad-Parameter abschnitt
+	 * 
+	 * @returns Die Lernabschnittsdaten des Schülers
+	 */
+	public async getSchuelerLernabschnittsdaten(schema : string, id : number, abschnitt : number) : Promise<SchuelerLernabschnittsdaten> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/abschnitt/{abschnitt : \d+}/lernabschnittsdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString())
+				.replace(/{abschnitt\s*(:[^}]+)?}/g, abschnitt.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return SchuelerLernabschnittsdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerBetriebe für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/betriebe
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Betriebe unter Angabe der Schüler-IDdes Vor- und Nachnamens, Erzieherart, Kontaktdaten, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Betriebsdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Schülerbetrieben
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<SchuelerBetriebsdaten>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Erzieherdaten anzusehen.
+	 *   Code 404: Keine Erzieher-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Eine Liste von Schülerbetrieben
+	 */
+	public async getSchuelerBetriebe(schema : string, id : number) : Promise<List<SchuelerBetriebsdaten>> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/betriebe"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<SchuelerBetriebsdaten>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(SchuelerBetriebsdaten.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerBetriebsstammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/betriebsstammdaten
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Betriebe eines Schülers unter Angabe der ID,ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Betriebsdaten des Schülers besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von von Betriebsstammdaten eines Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<BetriebStammdaten>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Betriebdaten anzusehen.
+	 *   Code 404: Keine Betrieb-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Eine Liste von von Betriebsstammdaten eines Schülers
+	 */
+	public async getSchuelerBetriebsstammdaten(schema : string, id : number) : Promise<List<BetriebStammdaten>> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/betriebsstammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<BetriebStammdaten>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(BetriebStammdaten.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerErzieher für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/erzieher
+	 * 
+	 * Erstellt eine Liste aller in der Datenbank vorhandenen Erzieher unter Angabe der Schüler-IDdes Vor- und Nachnamens, Erzieherart, Kontaktdaten, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Erzieherdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Erzieherstammdaten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<ErzieherStammdaten>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Erzieherdaten anzusehen.
+	 *   Code 404: Keine Erzieher-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Eine Liste von Erzieherstammdaten
+	 */
+	public async getSchuelerErzieher(schema : string, id : number) : Promise<List<ErzieherStammdaten>> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/erzieher"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<ErzieherStammdaten>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(ErzieherStammdaten.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerLernabschnittsliste für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/lernabschnitte
+	 * 
+	 * Liest eine Lister der Lernabschnitte des Schülers zu der angegebenen ID aus der Datenbank und liefert diese zurück.Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Schüler-Lernabschnitt-Listeneinträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<SchuelerLernabschnittListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um die Schülerdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Eine Liste von Schüler-Lernabschnitt-Listeneinträgen
+	 */
+	public async getSchuelerLernabschnittsliste(schema : string, id : number) : Promise<List<SchuelerLernabschnittListeEintrag>> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/lernabschnitte"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<SchuelerLernabschnittListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(SchuelerLernabschnittListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerSchulbesuch für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/schulbesuch
+	 * 
+	 * Liest die Schulbesuchsdaten des Schülers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Schulbesuchsdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: SchuelerSchulbesuchsdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Schulbesuchsdaten des Schülers
+	 */
+	public async getSchuelerSchulbesuch(schema : string, id : number) : Promise<SchuelerSchulbesuchsdaten> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/schulbesuch"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return SchuelerSchulbesuchsdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchSchuelerSchulbesuch für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/schulbesuch
+	 * 
+	 * Passt die Schüler-Schulbesuchsdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Schüler-Schulbesuchsdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten zu ändern.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {SchuelerSchulbesuchsdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchSchuelerSchulbesuch(data : Partial<SchuelerSchulbesuchsdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/schulbesuch"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = SchuelerSchulbesuchsdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/stammdaten
+	 * 
+	 * Liest die Stammdaten des Schülers zu der angegebenen ID aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Stammdaten des Schülers
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: SchuelerStammdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten anzusehen.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 * 
+	 * @returns Die Stammdaten des Schülers
+	 */
+	public async getSchuelerStammdaten(schema : string, id : number) : Promise<SchuelerStammdaten> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return SchuelerStammdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchSchuelerStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/{id : \d+}/stammdaten
+	 * 
+	 * Passt die Schüler-Stammdaten zu der angegebenen ID an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Schülerstammdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten zu ändern.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {SchuelerStammdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} id - der Pfad-Parameter id
+	 */
+	public async patchSchuelerStammdaten(data : Partial<SchuelerStammdaten>, schema : string, id : number) : Promise<void> {
+		let path : string = "/db/{schema}/schueler/{id : \d+}/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{id\s*(:[^}]+)?}/g, id.toString());
+		let body : string = SchuelerStammdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerFuerAbschnitt für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/abschnitt/{abschnitt : \d+}
+	 * 
+	 * Erstellt eine Liste aller Schüler des angegebenen Schuljahresabschnitts unter Angabe der ID, des Vor- und Nachnamens, der Klasse, des Jahrgangs, sein Status (z.B. aktiv), einer Sortierreihenfolge, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Die schüler sind anhand der Klasse, des Nchnamens und des Vornamens sortiert.Es wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Schüler-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<SchuelerListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten anzusehen.
+	 *   Code 404: Keine Schüler-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * @param {number} abschnitt - der Pfad-Parameter abschnitt
+	 * 
+	 * @returns Eine Liste von Schüler-Listen-Einträgen
+	 */
+	public async getSchuelerFuerAbschnitt(schema : string, abschnitt : number) : Promise<List<SchuelerListeEintrag>> {
+		let path : string = "/db/{schema}/schueler/abschnitt/{abschnitt : \d+}"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema)
+				.replace(/{abschnitt\s*(:[^}]+)?}/g, abschnitt.toString());
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<SchuelerListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(SchuelerListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerAktuell für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/aktuell
+	 * 
+	 * Erstellt eine Liste aller im aktuellen Schuljahresabschnitt vorhanden Schüler unter Angabe der ID, des Vor- und Nachnamens, der Klasse, des Jahrgangs, sein Status (z.B. aktiv), einer Sortierreihenfolge, ob sie in der Anwendung sichtbar bzw. änderbar sein sollen. Die schüler sind anhand der Klasse, des Nachnamens und des Vornamens sortiert.Es wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schülerdaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Schüler-Listen-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<SchuelerListeEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schülerdaten anzusehen.
+	 *   Code 404: Keine Schüler-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Schüler-Listen-Einträgen
+	 */
+	public async getSchuelerAktuell(schema : string) : Promise<List<SchuelerListeEintrag>> {
+		let path : string = "/db/{schema}/schueler/aktuell"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<SchuelerListeEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(SchuelerListeEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerFahrschuelerarten für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/fahrschuelerarten
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Fahrschülerarten unter Angabe der ID, eines Kürzels und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Fahrschülerarten-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Fahrschülerart-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Fahrschülerarten-Katalog-Einträgen
+	 */
+	public async getSchuelerFahrschuelerarten(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/schueler/fahrschuelerarten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuelerFoerderschwerpunkte für den Zugriff auf die URL https://{hostname}/db/{schema}/schueler/foerderschwerpunkte
+	 * 
+	 * Erstellt eine Liste aller in dem Katalog vorhanden Förderschwerpunkte unter Angabe der ID, eines Kürzels und der Bezeichnung. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Katalogen besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Eine Liste von Förderschwerpunkte-Katalog-Einträgen
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: List<KatalogEintrag>
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Katalog-Einträge anzusehen.
+	 *   Code 404: Keine Förderschwerpunkt-Katalog-Einträge gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Eine Liste von Förderschwerpunkte-Katalog-Einträgen
+	 */
+	public async getSchuelerFoerderschwerpunkte(schema : string) : Promise<List<KatalogEintrag>> {
+		let path : string = "/db/{schema}/schueler/foerderschwerpunkte"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const obj = JSON.parse(result);
+		let ret = new Vector<KatalogEintrag>();
+		obj.forEach((elem: any) => { let text : string = JSON.stringify(elem); ret.add(KatalogEintrag.transpilerFromJSON(text)); });
+		return ret;
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchullogo für den Zugriff auf die URL https://{hostname}/db/{schema}/schule/logo
+	 * 
+	 * Liest das Logo der Schule zum angegebenen Schema aus der Datenbank und liefert dieses zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schuldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Logo der Schule
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: String
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schuldaten anzusehen.
+	 *   Code 404: Kein Eintrag mit dem angegebenen Schema gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Das Logo der Schule
+	 */
+	public async getSchullogo(schema : string) : Promise<String> {
+		let path : string = "/db/{schema}/schule/logo"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return JSON.parse(text).toString();
+	}
+
+
+	/**
+	 * Implementierung der PUT-Methode putSchullogo für den Zugriff auf die URL https://{hostname}/db/{schema}/schule/logo
+	 * 
+	 * Setzt das Logo der Schule. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schuldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Logo der Schule wurde gesetzt
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schuldaten zu ändern.
+	 *   Code 404: Kein Eintrag für die Schule gefunden
+	 * 
+	 * @param {String} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 */
+	public async putSchullogo(data : String, schema : string) : Promise<void> {
+		let path : string = "/db/{schema}/schule/logo"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		let body : string = JSON.stringify(data);
+		return super.putJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuleNummer für den Zugriff auf die URL https://{hostname}/db/{schema}/schule/nummer
+	 * 
+	 * Liefert die Schulnummer der Schule. Es wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen der Schuldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Schulnummer
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: Integer
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schuldaten anzusehen.
+	 *   Code 404: Keine Schule in der Datenbank vorhanden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Die Schulnummer
+	 */
+	public async getSchuleNummer(schema : string) : Promise<Number> {
+		let path : string = "/db/{schema}/schule/nummer"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return parseInt(JSON.parse(text));
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode getSchuleStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schule/stammdaten
+	 * 
+	 * Liest die Stammdaten der Schule zum angegebenen Schema aus der Datenbank und liefert diese zurück. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ansehen von Schuldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Die Stammdaten der Schule
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: SchuleStammdaten
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schuldaten anzusehen.
+	 *   Code 404: Kein Eintrag mit dem angegebenen Schema gefunden
+	 * 
+	 * @param {string} schema - der Pfad-Parameter schema
+	 * 
+	 * @returns Die Stammdaten der Schule
+	 */
+	public async getSchuleStammdaten(schema : string) : Promise<SchuleStammdaten> {
+		let path : string = "/db/{schema}/schule/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		const result : string = await super.getJSON(path);
+		const text = result;
+		return SchuleStammdaten.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der PATCH-Methode patchSchuleStammdaten für den Zugriff auf die URL https://{hostname}/db/{schema}/schule/stammdaten
+	 * 
+	 * Passt die Schul-Stammdaten an und speichert das Ergebnis in der Datenbank. Dabei wird geprüft, ob der SVWS-Benutzer die notwendige Berechtigung zum Ändern von Schuldaten besitzt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Patch wurde erfolgreich in die Schul-Stammdaten integriert.
+	 *   Code 400: Der Patch ist fehlerhaft aufgebaut.
+	 *   Code 403: Der SVWS-Benutzer hat keine Rechte, um Schuldaten zu ändern.
+	 *   Code 404: Kein Schüler-Eintrag mit der angegebenen ID gefunden
+	 *   Code 409: Der Patch ist fehlerhaft, da zumindest eine Rahmenbedingung für einen Wert nicht erfüllt wurde (z.B. eine negative ID)
+	 *   Code 500: Unspezifizierter Fehler (z.B. beim Datenbankzugriff)
+	 * 
+	 * @param {SchuleStammdaten} data - der Request-Body für die HTTP-Methode
+	 * @param {string} schema - der Pfad-Parameter schema
+	 */
+	public async patchSchuleStammdaten(data : Partial<SchuleStammdaten>, schema : string) : Promise<void> {
+		let path : string = "/db/{schema}/schule/stammdaten"
+				.replace(/{schema\s*(:[^}]+)?}/g, schema);
+		let body : string = SchuleStammdaten.transpilerToJSONPatch(data);
+		return super.patchJSON(path, body);
+	}
+
+
+	/**
+	 * Implementierung der GET-Methode isAlive für den Zugriff auf die URL https://{hostname}/status/alive
+	 * 
+	 * Eine Test-Methode zum Prüfen, ob der Server erreichbar ist.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Der Server ist erreichbar!
+	 *     - Mime-Type: text/plain
+	 *     - Rückgabe-Typ: String
+	 * 
+	 * @returns Der Server ist erreichbar!
+	 */
+	public async isAlive() : Promise<String> {
+		let path : string = "/status/alive";
+		const text : string = await super.getText(path);
+		return String(text);
+	}
+
+
+}

+ 183 - 0
api/ApiServerAlgorithmen.ts

@@ -0,0 +1,183 @@
+import { BaseApi } from '../api/BaseApi';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../core/data/abschluss/AbschlussErgebnis';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../core/data/abschluss/GEAbschlussFaecher';
+import { GostBelegpruefungErgebnis, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnis } from '../core/abschluss/gost/GostBelegpruefungErgebnis';
+import { GostBelegpruefungsdaten, cast_de_nrw_schule_svws_core_data_gost_GostBelegpruefungsdaten } from '../core/data/gost/GostBelegpruefungsdaten';
+
+export class ApiServerAlgorithmen extends BaseApi {
+
+	/**
+	 *
+	 * Erstellt eine neue API mit der übergebenen Konfiguration.
+	 *
+	 * @param {string} url - die URL des Servers: Alle Pfadangaben sind relativ zu dieser URL
+	 * @param {string} username - der Benutzername für den API-Zugriff
+	 * @param {string} password - das Kennwort des Benutzers für den API-Zugriff
+	 */
+	public constructor(url : string, username : string, password : string) {
+		super(url, username, password);
+	}
+
+	/**
+	 * Implementierung der POST-Methode getGesamtschuleAbschlussHA10 für den Zugriff auf die URL https://{hostname}/api/gesamtschule/abschluss/ha10
+	 * 
+	 * Prüft anhand der übergeben Fächerdaten, ob ein Hauptschulabschluss der Klasse 10 an einer Gesamtschule erreicht wird oder nicht. Im Falle, dass er nicht erreicht wird, werden ggf. Nachprüfungsfächer zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: AbschlussErgebnis
+	 * 
+	 * @param {GEAbschlussFaecher} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 */
+	public async getGesamtschuleAbschlussHA10(data : GEAbschlussFaecher) : Promise<AbschlussErgebnis> {
+		let path : string = "/api/gesamtschule/abschluss/ha10";
+		let body : string = GEAbschlussFaecher.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return AbschlussErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGesamtschuleAbschlussHA9 für den Zugriff auf die URL https://{hostname}/api/gesamtschule/abschluss/ha9
+	 * 
+	 * Prüft anhand der übergeben Fächerdaten, ob ein Hauptschulabschluss der Klasse 9 an einer Gesamtschule erreicht wird oder nicht. Im Falle, dass er nicht erreicht wird, werden ggf. Nachprüfungsfächer zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: AbschlussErgebnis
+	 *   Code 400: Es wurden ungültige Werte übergeben, so dass kein Abschluss berechnet werden kann.
+	 * 
+	 * @param {GEAbschlussFaecher} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 */
+	public async getGesamtschuleAbschlussHA9(data : GEAbschlussFaecher) : Promise<AbschlussErgebnis> {
+		let path : string = "/api/gesamtschule/abschluss/ha9";
+		let body : string = GEAbschlussFaecher.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return AbschlussErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGesamtschuleAbschlussMSA für den Zugriff auf die URL https://{hostname}/api/gesamtschule/abschluss/msa
+	 * 
+	 * Prüft anhand der übergeben Fächerdaten, ob ein Mittlerer Schulabschluss nach der Klasse 10 an einer Gesamtschule erreicht wird oder nicht. Im Falle, dass er nicht erreicht wird, werden ggf. Nachprüfungsfächer zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: AbschlussErgebnis
+	 * 
+	 * @param {GEAbschlussFaecher} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 */
+	public async getGesamtschuleAbschlussMSA(data : GEAbschlussFaecher) : Promise<AbschlussErgebnis> {
+		let path : string = "/api/gesamtschule/abschluss/msa";
+		let body : string = GEAbschlussFaecher.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return AbschlussErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGesamtschuleAbschlussMSAQ für den Zugriff auf die URL https://{hostname}/api/gesamtschule/abschluss/msaq
+	 * 
+	 * Prüft anhand der übergeben Fächerdaten, ob die Berechtigung zum Besuch der gymnasialen Oberstufe im Rahmen eines Mittlerer Schulabschlusses nach der Klasse 10 an einer Gesamtschule erreicht wird oder nicht.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: AbschlussErgebnis
+	 * 
+	 * @param {GEAbschlussFaecher} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Abschlussberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 */
+	public async getGesamtschuleAbschlussMSAQ(data : GEAbschlussFaecher) : Promise<AbschlussErgebnis> {
+		let path : string = "/api/gesamtschule/abschluss/msaq";
+		let body : string = GEAbschlussFaecher.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return AbschlussErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGesamtschuleAbschlussPrognose für den Zugriff auf die URL https://{hostname}/api/gesamtschule/abschluss/prognose
+	 * 
+	 * Führt anhand der übergeben Fächerdaten eine Abschlussprognose für den Gesamtschulabschluss nach Klasse 9 bzw. Klasse 10 durch.Wird der Jahrgang 10 angegeben, so findet keine Prüfung auf den HA9 statt.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Prognoseberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: AbschlussErgebnis
+	 * 
+	 * @param {GEAbschlussFaecher} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Prognoseberechnung, ggf. mit Nachprüfungsmöglichkeiten
+	 */
+	public async getGesamtschuleAbschlussPrognose(data : GEAbschlussFaecher) : Promise<AbschlussErgebnis> {
+		let path : string = "/api/gesamtschule/abschluss/prognose";
+		let body : string = GEAbschlussFaecher.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return AbschlussErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGostBelegpruefungEF1 für den Zugriff auf die URL https://{hostname}/api/gost/belegpruefung/EF1
+	 * 
+	 * Prüft anhand der übergeben Abiturdaten, ob die Belegung in den Abiturdaten korrekt ist oder nicht. Es werden ggf. auch Belegungsfehler und Hinweise zur Belegung zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBelegpruefungErgebnis
+	 * 
+	 * @param {GostBelegpruefungsdaten} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 */
+	public async getGostBelegpruefungEF1(data : GostBelegpruefungsdaten) : Promise<GostBelegpruefungErgebnis> {
+		let path : string = "/api/gost/belegpruefung/EF1";
+		let body : string = GostBelegpruefungsdaten.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return GostBelegpruefungErgebnis.transpilerFromJSON(text);
+	}
+
+
+	/**
+	 * Implementierung der POST-Methode getGostBelegpruefungGesamt für den Zugriff auf die URL https://{hostname}/api/gost/belegpruefung/gesamt
+	 * 
+	 * Prüft anhand der übergeben Abiturdaten, ob die Belegung in den Abiturdaten korrekt ist oder nicht. Es werden ggf. auch Belegungsfehler und Hinweise zur Belegung zurückgegeben.
+	 * 
+	 * Mögliche HTTP-Antworten: 
+	 *   Code 200: Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 *     - Mime-Type: application/json
+	 *     - Rückgabe-Typ: GostBelegpruefungErgebnis
+	 * 
+	 * @param {GostBelegpruefungsdaten} data - der Request-Body für die HTTP-Methode
+	 * 
+	 * @returns Das Ergebnis der Belegprüfung, ggf. mit Belegungsfehlern
+	 */
+	public async getGostBelegpruefungGesamt(data : GostBelegpruefungsdaten) : Promise<GostBelegpruefungErgebnis> {
+		let path : string = "/api/gost/belegpruefung/gesamt";
+		let body : string = GostBelegpruefungsdaten.transpilerToJSON(data);
+		const result : string = await super.postJSON(path, body);
+		const text = result;
+		return GostBelegpruefungErgebnis.transpilerFromJSON(text);
+	}
+
+
+}

+ 197 - 0
api/BaseApi.ts

@@ -0,0 +1,197 @@
+import { OpenApiError } from '../api/OpenApiError';
+
+export class BaseApi {
+
+    /** Die URL des Servers. Alle Pfadangaben sind relativ zu dieser URL. */
+    protected url : string;
+
+    /** Der Anmeldename beim Server */
+    protected username : string;
+
+    /** Der Default-RequestInit für einen Fetch */
+    #requestinit : RequestInit =  {
+        cache : 'no-cache',
+        credentials : 'same-origin'
+    }
+
+    /** Die Default-Header-Einträge */
+    #headers : Record<string, string> = {};
+
+    /**
+     * Erstellt eine neue API mit der übergebenen Konfiguration.
+     * 
+     * @param {string} url - die URL des Servers: Alle Pfadangaben sind relativ zu dieser URL
+     * @param {string} username - der Benutzername für den API-Zugriff
+     * @param {string} password - das Kennwort des Benutzers für den API-Zugriff
+     */
+    protected constructor(url : string, username : string, password : string) {
+        this.url = url;
+        this.username = username;
+        this.#headers["Authorization"] = "Basic " + btoa(username + ":" + password);
+    }
+
+
+    #getURL(path : string) : string {
+        return this.url + path;
+    }
+
+
+    async #getBinary(path : string, mimetype : string) : Promise<Blob> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Accept"] = mimetype;
+        requestInit.body = null;
+        requestInit.method = 'GET';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for GET: ' + path);
+            return await response.blob();
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for GET: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+
+    public getPDF(path : string) : Promise<Blob> {
+        return this.#getBinary(path, 'application/pdf');
+    }
+
+
+    async #getTextBased(path : string, mimetype : string) : Promise<string> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Accept"] = mimetype;
+        requestInit.body = null;
+        requestInit.method = 'GET';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for GET: ' + path);
+            return await response.text();
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for GET: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+    public getText(path : string) : Promise<string> {
+        return this.#getTextBased(path, 'text/plain');
+    }
+
+    public getJSON(path : string) : Promise<string> {
+        return this.#getTextBased(path, 'application/json');
+    }
+
+
+    async #postTextBased(path : string, mimetype_send : string, mimetype_receive : string, body : string | null) : Promise<string> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Content-Type"] = mimetype_send;
+        requestInit.headers["Accept"] = mimetype_receive;
+        requestInit.body = body;
+        requestInit.method = 'POST';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for POST: ' + path);
+            return await response.text();
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for POST: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+    public postText(path : string, body : string | null) : Promise<string> {
+        return this.#postTextBased(path, 'text/plain', 'text/plain', body);
+    }
+
+    public postJSON(path : string, body : string | null) : Promise<string> {
+        return this.#postTextBased(path, 'application/json', 'application/json', body);
+    }
+
+
+    async #patchTextBased(path : string, mimetype : string, body : string) : Promise<void> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Content-Type"] = mimetype;
+        requestInit.body = body;
+        requestInit.method = 'PATCH';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for PATCH: ' + path);
+            return;
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for PATCH: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+    public patchText(path : string, body : string) : Promise<void> {
+        return this.#patchTextBased(path, 'text/plain', body);
+    }
+
+    public patchJSON(path : string, body : string) : Promise<void> {
+        return this.#patchTextBased(path, 'application/json', body);
+    }
+
+
+    async #putTextBased(path : string, mimetype : string, body : string) : Promise<void> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Content-Type"] = mimetype;
+        requestInit.body = body;
+        requestInit.method = 'PUT';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for PUT: ' + path);
+            return;
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for PUT: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+    public putText(path : string, body : string) : Promise<void> {
+        return this.#putTextBased(path, 'text/plain', body);
+    }
+
+    public putJSON(path : string, body : string) : Promise<void> {
+        return this.#putTextBased(path, 'application/json', body);
+    }
+
+    async #deleteTextBased(path : string, mimetype : string) : Promise<void> {
+        let requestInit : RequestInit = { ...this.#requestinit };
+        requestInit.headers = { ...this.#headers };
+        requestInit.headers["Accept"] = mimetype;
+        requestInit.body = null;
+        requestInit.method = 'DELETE';
+        try {
+            const response = await fetch(this.#getURL(path), requestInit);
+            if (!response.ok)
+                throw new OpenApiError(response, 'Fetch failed for DELETE: ' + path);
+            return;
+        } catch (e) {
+            if (e instanceof Error)
+                throw (e instanceof OpenApiError) ? e : new OpenApiError(e, 'Fetch failed for DELETE: ' + path);
+            throw new Error("Unexpected Error: " + e);
+        }
+    }
+
+    public deleteText(path : string) : Promise<void> {
+        return this.#deleteTextBased(path, 'text/plain');
+    }
+
+    public deleteJSON(path : string) : Promise<void> {
+        return this.#deleteTextBased(path, 'application/json');
+    }
+
+}

+ 21 - 0
api/OpenApiError.ts

@@ -0,0 +1,21 @@
+
+export class OpenApiError extends Error {
+
+    _status : number | null;
+    _error : Error | null;
+
+    public constructor(value : Response | Error, message? : string) {
+        super(message);
+        this._status = (value instanceof Error) ? null : value.status;
+        this._error = (value instanceof Error) ? value : null;
+    }
+
+    public get status() : number | null {
+        return this._status;
+    }
+
+    public get error() : Error | null {
+        return this._error;
+    }
+
+}

+ 57 - 0
core/Service.ts

@@ -0,0 +1,57 @@
+import { JavaObject, cast_java_lang_Object } from '../java/lang/JavaObject';
+import { Logger, cast_de_nrw_schule_svws_logger_Logger } from '../logger/Logger';
+import { LogConsumerVector, cast_de_nrw_schule_svws_logger_LogConsumerVector } from '../logger/LogConsumerVector';
+
+export abstract class Service<T_IN, T_OUT> extends JavaObject {
+
+	protected logger : Logger = new Logger();
+
+	protected log : LogConsumerVector = new LogConsumerVector();
+
+
+	/**
+	 * Erstellt einen neuen Service, dessen Logger automatisch in einen Vector loggt. 
+	 */
+	protected constructor() {
+		super();
+		this.logger.addConsumer(this.log);
+	}
+
+	/**
+	 * Diese Methode muss von dem erbenden Service impelemntiert werden 
+	 * und handhabt das übergebene Input-Objekt und erzeugt das zugehörige
+	 * Output-Objekt.  
+	 *  
+	 * @param input   das Input-Objekt
+	 * 
+	 * @return das Output-Objekt
+	 */
+	public abstract handle(input : T_IN | null) : T_OUT | null;
+
+	/**
+	 * Gibt die Logger-Instanz von diesem Service zurück.  
+	 * 
+	 * @return die Logger-Instanz.
+	 */
+	public getLogger() : Logger {
+		return this.logger;
+	}
+
+	/**
+	 * Gibt das Log dieses Services zurück.
+	 * 
+	 * @return das Log dieses Services
+	 */
+	public getLog() : LogConsumerVector {
+		return this.log;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_Service<T_IN, T_OUT>(obj : unknown) : Service<T_IN, T_OUT> {
+	return obj as Service<T_IN, T_OUT>;
+}

+ 471 - 0
core/SprachendatenManager.ts

@@ -0,0 +1,471 @@
+import { JavaObject, cast_java_lang_Object } from '../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../java/lang/JavaInteger';
+import { Sprachbelegung, cast_de_nrw_schule_svws_core_data_Sprachbelegung } from '../core/data/Sprachbelegung';
+import { Sprachpruefung, cast_de_nrw_schule_svws_core_data_Sprachpruefung } from '../core/data/Sprachpruefung';
+import { Sprachpruefungniveau, cast_de_nrw_schule_svws_core_types_Sprachpruefungniveau } from '../core/types/Sprachpruefungniveau';
+import { NumberFormatException, cast_java_lang_NumberFormatException } from '../java/lang/NumberFormatException';
+import { JavaString, cast_java_lang_String } from '../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../java/util/Vector';
+import { Sprachendaten, cast_de_nrw_schule_svws_core_data_Sprachendaten } from '../core/data/Sprachendaten';
+import { HashSet, cast_java_util_HashSet } from '../java/util/HashSet';
+import { Comparator, cast_java_util_Comparator } from '../java/util/Comparator';
+
+export class SprachendatenManager extends JavaObject {
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Prüft, ob eine unterrichtliche Belegung der übergebenen Sprache existiert.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param sprache   das einstellige Kürzel der Sprache
+	 *
+	 * @return true, falls eine Belegung existiert und ansonsten false
+	 */
+	public static hatSprachbelegung(sprachendaten : Sprachendaten | null, sprache : String | null) : boolean {
+		if (sprachendaten === null || sprachendaten.belegungen === null || sprache === null || JavaObject.equalsTranspiler("", (sprache))) {
+			return false;
+		}
+		return SprachendatenManager.getSprachbelegung(sprachendaten, sprache) !== null;
+	}
+
+	/**
+	 * Prüft, ob eine unterrichtliche Belegung der übergebenen Sprache in der Sekundarstufe I existiert.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param sprache   das einstellige Kürzel der Sprache
+	 *
+	 * @return true, falls eine Belegung existiert und ansonsten false
+	 */
+	public static hatSprachbelegungInSekI(sprachendaten : Sprachendaten | null, sprache : String | null) : boolean {
+		if (sprachendaten === null || sprachendaten.belegungen === null || sprache === null || JavaObject.equalsTranspiler("", (sprache))) {
+			return false;
+		}
+		let belegung : Sprachbelegung | null = SprachendatenManager.getSprachbelegung(sprachendaten, sprache);
+		if (belegung !== null && SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungVonJahrgang) > 0) {
+			return SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungVonJahrgang) <= 10;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob eine unterrichtliche Belegung der übergebenen Sprache in der Sekundarstufe I mit der angegebenen Belegungsdauer existiert.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param sprache das einstellige Kürzel der Sprache
+	 * @param mindestBelegdauer Zulässig sind Werte 1 bis 5 für die minimale Dauer der Sprachbelegung, damit die Sprache berücksichtigt wird.
+	 *
+	 * @return true, falls eine Belegung existiert und ansonsten false
+	 */
+	public static hatSprachbelegungInSekIMitDauer(sprachendaten : Sprachendaten | null, sprache : String | null, mindestBelegdauer : Number | null) : boolean {
+		if (sprachendaten === null || sprachendaten.belegungen === null || sprache === null || JavaObject.equalsTranspiler("", (sprache)) || mindestBelegdauer === null || mindestBelegdauer <= 0) {
+			return false;
+		}
+		let belegung : Sprachbelegung | null = SprachendatenManager.getSprachbelegung(sprachendaten, sprache);
+		if (belegung === null) {
+			return false;
+		}
+		let belegtVonJahrgangNumerisch : number;
+		let belegtBisJahrgangNumerisch : number;
+		let letzterJahrgangSekI : number;
+		if (belegung.belegungVonJahrgang !== null) {
+			belegtVonJahrgangNumerisch = SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungVonJahrgang);
+			belegtBisJahrgangNumerisch = SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungBisJahrgang);
+			letzterJahrgangSekI = 10;
+			if (belegtVonJahrgangNumerisch === 6 || belegtVonJahrgangNumerisch === 8) {
+				letzterJahrgangSekI = 9;
+			}
+			if (0 < belegtVonJahrgangNumerisch && belegtVonJahrgangNumerisch <= 10) {
+				if (belegtBisJahrgangNumerisch === 0 || belegtBisJahrgangNumerisch > letzterJahrgangSekI) {
+					belegtBisJahrgangNumerisch = letzterJahrgangSekI;
+				}
+				return ((belegtBisJahrgangNumerisch - belegtVonJahrgangNumerisch + 1) >= mindestBelegdauer);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Gibt die zu der übergebenen Sprache gehörende Sprachbelegung zurück.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param sprache   das einstellige Kürzel der Sprache
+	 *
+	 * @return die Sprachbelegung oder null, falls keine existiert
+	 */
+	public static getSprachbelegung(sprachendaten : Sprachendaten | null, sprache : String | null) : Sprachbelegung | null {
+		if (sprachendaten === null || sprachendaten.belegungen === null || sprache === null || JavaObject.equalsTranspiler("", (sprache))) {
+			return null;
+		}
+		let belegungen : Vector<Sprachbelegung> = sprachendaten.belegungen;
+		for (let belegung of belegungen) {
+			if (JavaObject.equalsTranspiler(sprache, (belegung.sprache))) {
+				return belegung;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert die Sprachen aus der Sprachenfolge zurück, deren Beginn im angegebenen Zeitraum liegt und die angegebene Dauer besitzt.
+	 * Dabei wird davon ausgegangen, dass Sprachen ohne Ende der Belegung am Ende der Sekundarstufe I belegt wurden.
+	 * Bei einem Schüler der Sek-II wird auch nur die Dauer der Belegung in der Sek-I betrachtet.
+	 * Sprachprüfungen werden nicht berücksichtigt.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param belegungbeginnStart Es werden nur Sprachen berücksichtigt, deren Belegungsbeginn größer oder gleich dem angegebenen ASDJahrgang ist.
+	 * @param belegungbeginnEnde Es werden nur Sprachen berücksichtigt, deren Belegungsbeginn kleiner oder gleich dem angegebenen ASDJahrgang ist.
+	 * @param mindestBelegdauer Zulässig sind Werte 1 bis 5 für die minimale Dauer der Sprachbelegung, damit die Sprache berücksichtigt wird.
+	 *
+	 * @return Vector mit Sprachbelegungen, die die Kriterien erfüllen. Die Liste ist nach Belegungsbeginn aufsteigend sortiert
+	 */
+	public static getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten : Sprachendaten | null, belegungbeginnStart : String | null, belegungbeginnEnde : String | null, mindestBelegdauer : Number | null) : Vector<Sprachbelegung> {
+		let belegungen : Vector<Sprachbelegung> = new Vector();
+		if (sprachendaten !== null && sprachendaten.belegungen !== null && belegungbeginnStart !== null && !JavaObject.equalsTranspiler(belegungbeginnStart, ("")) && belegungbeginnEnde !== null && !JavaObject.equalsTranspiler(belegungbeginnEnde, ("")) && mindestBelegdauer !== null && mindestBelegdauer >= 0) {
+			let belegtVonJahrgangNumerisch : number;
+			let belegtBisJahrgangNumerisch : number;
+			let letzterJahrgangSekI : number;
+			let gefundeneSprachen : HashSet<String | null> | null = new HashSet();
+			let alleBelegungen : Vector<Sprachbelegung> = sprachendaten.belegungen;
+			for (let belegung of alleBelegungen) {
+				if (belegung.belegungVonJahrgang !== null) {
+					belegtVonJahrgangNumerisch = SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungVonJahrgang);
+					belegtBisJahrgangNumerisch = SprachendatenManager.ASDJahrgangNumerisch(belegung.belegungBisJahrgang);
+					letzterJahrgangSekI = 10;
+					if (belegtVonJahrgangNumerisch === 6 || belegtVonJahrgangNumerisch === 8) {
+						letzterJahrgangSekI = 9;
+					}
+					if (belegtVonJahrgangNumerisch > 0 && SprachendatenManager.ASDJahrgangNumerisch(belegungbeginnStart) <= belegtVonJahrgangNumerisch && belegtVonJahrgangNumerisch <= SprachendatenManager.ASDJahrgangNumerisch(belegungbeginnEnde)) {
+						if (belegtBisJahrgangNumerisch === 0 || belegtBisJahrgangNumerisch > letzterJahrgangSekI) {
+							belegtBisJahrgangNumerisch = letzterJahrgangSekI;
+						}
+						if ((belegtBisJahrgangNumerisch - belegtVonJahrgangNumerisch + 1) >= mindestBelegdauer) {
+							if (!gefundeneSprachen.contains(belegung.sprache)) {
+								belegungen.add(belegung);
+							}
+							gefundeneSprachen.add(belegung.sprache);
+						}
+					}
+				}
+			}
+		}
+		if (belegungen.size() > 0) {
+			let comparator : Comparator<Sprachbelegung> | null = { compare : (a: Sprachbelegung, b: Sprachbelegung) => JavaInteger.compare(SprachendatenManager.ASDJahrgangNumerisch(a.belegungVonJahrgang), SprachendatenManager.ASDJahrgangNumerisch(b.belegungVonJahrgang)) };
+			belegungen.sort(comparator);
+		}
+		return belegungen;
+	}
+
+	/**
+	 * Prüft, ob die übergebene Sprache als eine fortgeführte Fremdsprache in der gymnasialen Oberstufe
+	 * gemäß APO-GOSt ab EF belegt werden kann. Dazu zählen alle belegten Sprachen mit mind. 2 Jahren Belegung in Sek-I
+	 * sowie Sprachen aus bestimmten Sprachprüfungen.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 * @param sprache das einstellige Kürzel der Sprache
+	 *
+	 * @return true, falls die Sprache als fortgeführte Fremdsprache als EF belegt werden kann, andernfalls false
+	 */
+	public static istFortfuehrbareSpracheInGOSt(sprachendaten : Sprachendaten | null, sprache : String | null) : boolean {
+		if (sprachendaten === null || sprache === null || JavaObject.equalsTranspiler("", (sprache))) {
+			return false;
+		}
+		if (SprachendatenManager.hatSprachbelegungInSekIMitDauer(sprachendaten, sprache, 2)) {
+			return true;
+		}
+		let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+		if (pruefungen !== null) {
+			for (let pruefung of pruefungen) {
+				if (!JavaObject.equalsTranspiler(sprache, (pruefung.sprache)) && !JavaObject.equalsTranspiler(sprache, (pruefung.ersetzteSprache))) {
+					continue;
+				}
+				if (pruefung.istHKUPruefung && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+					return true;
+				}
+				if (pruefung.istFeststellungspruefung && (pruefung.note !== null) && (pruefung.note <= 4) && ((pruefung.kannBelegungAlsFortgefuehrteSpracheErlauben && pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) || ((pruefung.kannErstePflichtfremdspracheErsetzen || pruefung.kannZweitePflichtfremdspracheErsetzen || pruefung.kannWahlpflichtfremdspracheErsetzen) && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id)))) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Sammelt alle Sprachen, die in der GOSt als fortgeführte Sprachen belegt werden können, sei
+	 * es aufgrund einer Belegung von mindestens zwei Jahren oder aufgrund einer Sprachprüfung.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return Liste alle Sprachen, die in der GOSt fortgeführt werden können.
+	 */
+	public static getFortfuehrbareSprachenInGOSt(sprachendaten : Sprachendaten | null) : Vector<String> {
+		let sprachen : Vector<String> = new Vector();
+		if (sprachendaten !== null) {
+			let belegungen : Vector<Sprachbelegung> = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "05", "10", 2);
+			for (let belegung of belegungen) {
+				sprachen.add(belegung.sprache);
+			}
+			let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+			if (pruefungen !== null) {
+				for (let pruefung of pruefungen) {
+					if (pruefung.istHKUPruefung && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+						sprachen.add(pruefung.ersetzteSprache);
+					}
+					if (pruefung.istFeststellungspruefung && (pruefung.note !== null) && (pruefung.note <= 4) && ((pruefung.kannBelegungAlsFortgefuehrteSpracheErlauben && pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) || ((pruefung.kannErstePflichtfremdspracheErsetzen || pruefung.kannZweitePflichtfremdspracheErsetzen || pruefung.kannWahlpflichtfremdspracheErsetzen) && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id)))) {
+						sprachen.add(pruefung.ersetzteSprache);
+					}
+				}
+			}
+		}
+		return sprachen;
+	}
+
+	/**
+	 * Prüft für den Zeitpunkt Ende Sek-I, ob eine Fremdsprache im Umfang von mindestens 4 Jahren belegt wurde.
+	 * Dabei wird davon ausgegangen, dass Sprachen ohne Ende der Belegung am Ende der Sekundarstufe I belegt wurden.
+	 * Ist dies in der Sprachenfolge nicht der Fall, werden zusätzlich evtl. Sprachprüfungen herangezogen.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return true, falls der Nachweis gemäß der aktuellen Sprachdaten erfüllt ist, andernfalls false.
+	 */
+	public static hatEineSpracheMitMin4JahrenDauerEndeSekI(sprachendaten : Sprachendaten | null) : boolean {
+		if (sprachendaten === null) {
+			return false;
+		}
+		let anzahlSprachen : number = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "05", "07", 4).size();
+		if (anzahlSprachen >= 1) {
+			return true;
+		}
+		let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+		if (pruefungen !== null) {
+			for (let pruefung of pruefungen) {
+				if (pruefung.istFeststellungspruefung && (pruefung.kannErstePflichtfremdspracheErsetzen || pruefung.kannZweitePflichtfremdspracheErsetzen || pruefung.kannWahlpflichtfremdspracheErsetzen) && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft für den Zeitpunkt Ende Sek-I, ob eine zweite Fremdsprache im Umfang von mindestens 4 Jahren belegt wurde.
+	 * Dabei wird davon ausgegangen, dass Sprachen ohne Ende der Belegung am Ende der Sekundarstufe I belegt wurden.
+	 * Ist dies in der Sprachenfolge nicht der Fall, werden zusätzlich evtl. Sprachprüfungen herangezogen.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return true, falls der Nachweis gemäß der aktuellen Sprachdaten erfüllt ist, andernfalls false.
+	 */
+	public static hatZweiSprachenMitMin4JahrenDauerEndeSekI(sprachendaten : Sprachendaten | null) : boolean {
+		if (sprachendaten === null) {
+			return false;
+		}
+		let belegungen : Vector<Sprachbelegung> = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "05", "07", 4);
+		let anzahlSprachen : number = belegungen.size();
+		if (anzahlSprachen >= 2) {
+			return true;
+		}
+		if (anzahlSprachen === 1) {
+			let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+			if (pruefungen !== null) {
+				for (let pruefung of pruefungen) {
+					if (pruefung.istFeststellungspruefung && (pruefung.kannErstePflichtfremdspracheErsetzen || pruefung.kannZweitePflichtfremdspracheErsetzen || pruefung.kannWahlpflichtfremdspracheErsetzen) && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+						if (!JavaObject.equalsTranspiler(belegungen.get(0).sprache, (pruefung.sprache))) {
+							return true;
+						}
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft für den Zeitpunkt Ende Sek-I, ob eine Fremdsprache ab Kasse 8/9 im Umfang von mindestens 2 Jahren belegt wurde.
+	 * Dabei wird davon ausgegangen, dass Sprachen ohne Ende der Belegung am Ende der Sekundarstufe I belegt wurden.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return true, falls der Nachweis gemäß der aktuellen Sprachdaten erfüllt ist, andernfalls false.
+	 */
+	public static hatSpracheMit2JahrenDauerEndeSekI(sprachendaten : Sprachendaten | null) : boolean {
+		if (sprachendaten === null) {
+			return false;
+		}
+		let anzahlSprachen : number = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "08", "10", 2).size();
+		if (anzahlSprachen >= 1) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob eine Sprachfeststellungsprüfung auf dem Niveau der Einführungsphase (EF) der GOSt vorliegt.
+	 * Nach §11 (2) APO-GOSt setzt das eine Prüfung in der gleichen Sprache am Ende der Sek-I voraus
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return true, falls entsprechende Sprachprüfungen vorhanden sind, andernfalls false.
+	 */
+	public static hatSprachfeststellungspruefungAufEFNiveau(sprachendaten : Sprachendaten | null) : boolean {
+		if (sprachendaten === null) {
+			return false;
+		}
+		let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+		if (pruefungen !== null) {
+			for (let pruefungS1 of pruefungen) {
+				if (pruefungS1.istFeststellungspruefung && (pruefungS1.kannErstePflichtfremdspracheErsetzen || pruefungS1.kannZweitePflichtfremdspracheErsetzen || pruefungS1.kannWahlpflichtfremdspracheErsetzen) && (pruefungS1.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefungS1.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefungS1.note !== null) && (pruefungS1.note <= 4)) {
+					for (let pruefungEF of pruefungen) {
+						if (pruefungEF.istFeststellungspruefung && JavaObject.equalsTranspiler(pruefungEF.ersetzteSprache, (pruefungS1.ersetzteSprache)) && (pruefungEF.kannErstePflichtfremdspracheErsetzen || pruefungEF.kannZweitePflichtfremdspracheErsetzen || pruefungEF.kannWahlpflichtfremdspracheErsetzen) && pruefungEF.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_EF.id && (pruefungEF.note !== null) && (pruefungEF.note <= 4)) {
+							return true;
+						}
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Gibt die Fremdsprache zurück, die als erste Fremdsprache der Sekundarstufe I gewertet werden kann.
+	 * Im Falle einer Sprachprüfung als erste Pflichtfremdsprache wird diese mit der als Ersatz eingetragene Fremdsprache zurückgegeben.
+	 * Ist keine Sprachprüfung als erste Pflichtfremdsprache vorhanden, so wird die als erste Sprache in der Sekundarstufe I belegt
+	 * Sprache zurückgegeben, unabhängig von deren Belegdauer.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return Die erste belegte Sprache (gemäß Belegung oder Prüfung) oder null, falls keine existiert
+	 */
+	public static getErsteSpracheInSekI(sprachendaten : Sprachendaten | null) : String | null {
+		if (sprachendaten === null) {
+			return null;
+		}
+		let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+		if (pruefungen !== null) {
+			for (let pruefung of pruefungen) {
+				if (pruefung.istFeststellungspruefung && pruefung.kannErstePflichtfremdspracheErsetzen && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+					return pruefung.ersetzteSprache;
+				}
+			}
+		}
+		let belegungen : Vector<Sprachbelegung> = sprachendaten.belegungen;
+		if (belegungen !== null) {
+			let sprachbelegungen : Vector<Sprachbelegung> = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "05", "10", 0);
+			if (sprachbelegungen.size() > 0) {
+				return sprachbelegungen.get(0).sprache;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Gibt die Fremdsprache zurück, die als zweite Fremdsprache der Sekundarstufe I gewertet werden kann.
+	 * Im Falle einer Sprachprüfung als zweite Pflichtfremdsprache bzw. WP-Sprache wird diese mit der als Ersatz eingetragene Fremdsprache zurückgegeben.
+	 * Ist keine Sprachprüfung als zweite Pflichtfremdsprache bzw. WP-Sprache vorhanden, so wird die als zweite Sprache in der Sekundarstufe I belegt
+	 * Sprache zurückgegeben, unabhängig von deren Belegdauer.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return Die zweite belegte Sprache (gemäß Belegung oder Prüfung) oder null, falls keine existiert
+	 */
+	public static getZweiteSpracheInSekI(sprachendaten : Sprachendaten | null) : String | null {
+		if (sprachendaten === null) {
+			return null;
+		}
+		let pruefungErsteSprache : String | null = "";
+		let pruefungZweiteSprache : String | null = "";
+		let pruefungen : Vector<Sprachpruefung> = sprachendaten.pruefungen;
+		if (pruefungen !== null) {
+			for (let pruefung of pruefungen) {
+				if (pruefung.istFeststellungspruefung && pruefung.kannErstePflichtfremdspracheErsetzen && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+					pruefungErsteSprache = pruefung.ersetzteSprache;
+				}
+				if (pruefung.istFeststellungspruefung && (pruefung.kannZweitePflichtfremdspracheErsetzen || pruefung.kannWahlpflichtfremdspracheErsetzen) && (pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_HA10.id || pruefung.anspruchsniveauId === Sprachpruefungniveau.NIVEAU_MSA.id) && (pruefung.note !== null) && (pruefung.note <= 4)) {
+					pruefungZweiteSprache = pruefung.ersetzteSprache;
+				}
+			}
+		}
+		if (!JavaObject.equalsTranspiler(pruefungZweiteSprache, (""))) {
+			return pruefungZweiteSprache;
+		}
+		let belegungen : Vector<Sprachbelegung> = sprachendaten.belegungen;
+		if (belegungen !== null) {
+			let sprachbelegungen : Vector<Sprachbelegung> = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "05", "10", 0);
+			if (!JavaObject.equalsTranspiler(pruefungErsteSprache, (""))) {
+				for (let sprachbelegung of sprachbelegungen) {
+					if (!JavaObject.equalsTranspiler(sprachbelegung.sprache, (pruefungErsteSprache))) {
+						return sprachbelegung.sprache;
+					}
+				}
+			} else {
+				if (sprachbelegungen.size() > 1) {
+					return sprachbelegungen.get(1).sprache;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Ermittelt, ob eine Fremdsprache ab Kasse 8/9 im Umfang von mindestens 2 Jahren belegt wurde und gibt sie zurück
+	 * Dabei wird davon ausgegangen, dass Sprachen ohne Ende der Belegung am Ende der Sekundarstufe I belegt wurden.
+	 *
+	 * @param sprachendaten die Sprachendaten mit Sprachbelegungen und Sprachprüfungen
+	 *
+	 * @return Sprache, falls eine Belegung vorhanden ist, sonst null
+	 */
+	public static getSpracheMit2JahrenDauerEndeSekI(sprachendaten : Sprachendaten | null) : String | null {
+		if (sprachendaten === null) {
+			return null;
+		}
+		let belegungen : Vector<Sprachbelegung> = sprachendaten.belegungen;
+		if (belegungen !== null) {
+			let sprachbelegungen : Vector<Sprachbelegung> = SprachendatenManager.getSprachlegungenNachBeginnUndDauerEndeSekI(sprachendaten, "08", "10", 2);
+			if (sprachbelegungen.size() > 0) {
+				return sprachbelegungen.get(0).sprache;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Hilfsfunktion, die einen ASDJahrgang nach APO-SI und APO-GOSt und in einen numerischen Wert für Vergleiche umwandelt.
+	 * Dabei wird EF zu 11, Q1 zu 12 und Q2 zu 13. Die übrigen Stufen werden gemäß ihrer numerischen Stufenangaben umgewandelt. 
+	 *
+	 * @param ASDJahrgang Der in den mumerischen Wert umzuwandelnde ASDJahrgang.
+	 *
+	 * @return Wert des ASDJahrgangs zwischen 5 und 13, wenn dieser nicht bestimmt werden kann, wird der Wert 0 zurückgegeben.
+	 */
+	private static ASDJahrgangNumerisch(ASDJahrgang : String | null) : number {
+		if (ASDJahrgang === null || JavaObject.equalsTranspiler(ASDJahrgang, (""))) {
+			return 0;
+		}
+		switch (ASDJahrgang) {
+			case "EF": 
+				return 11;
+			case "Q1": 
+				return 12;
+			case "Q2": 
+				return 13;
+			default: 
+				try {
+					return JavaInteger.parseInt(ASDJahrgang);
+				} catch(e) {
+					return 0;
+				}
+		}
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.SprachendatenManager'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_SprachendatenManager(obj : unknown) : SprachendatenManager {
+	return obj as SprachendatenManager;
+}

+ 217 - 0
core/abschluss/AbschlussManager.ts

@@ -0,0 +1,217 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../core/data/abschluss/GEAbschlussFach';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../core/data/abschluss/AbschlussErgebnis';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../core/data/abschluss/GEAbschlussFaecher';
+import { StringBuilder, cast_java_lang_StringBuilder } from '../../java/lang/StringBuilder';
+import { List, cast_java_util_List } from '../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../java/lang/JavaString';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../core/types/Abschluss';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../java/lang/JavaBoolean';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { Vector, cast_java_util_Vector } from '../../java/util/Vector';
+import { HashSet, cast_java_util_HashSet } from '../../java/util/HashSet';
+
+export class AbschlussManager extends JavaObject {
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Erzeugt ein Ergebnis der Abschlussberechnung unter Angabe, ob dieser erworben 
+	 * wurde. Die Liste der Nachprüfungsfächer ist leer und ein Log ist nicht zugeordnet.
+	 * Sollten Nachprüfungsmöglichkeiten bestehen so ist die Methode 
+	 * {@link AbschlussManager#getErgebnisNachpruefung} zu nutzen.
+	 * und ob dieser erworben wurde. 
+	 *  
+	 * @param abschluss   der Abschluss für den das Ergebnis erzeugt wird 
+	 * @param erworben    true, falls der Abschluss erworben wurde, sonst false
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung 
+	 */
+	public static getErgebnis(abschluss : Abschluss | null, erworben : boolean) : AbschlussErgebnis {
+		let ergebnis : AbschlussErgebnis = new AbschlussErgebnis();
+		ergebnis.abschluss = abschluss === null ? null : abschluss.toString();
+		ergebnis.erworben = erworben;
+		ergebnis.npFaecher = null;
+		ergebnis.log = null;
+		return ergebnis;
+	}
+
+	/**
+	 * Erzeugt ein Ergebnis der Abschlussberechnung, wo der Abschluss nicht erreicht wurde, aber ggf. 
+	 * noch durch Nachprüfungen erreicht werden kann. Ein log wird nicht zugeordnet.
+	 * 
+	 * @param abschluss    der Abschluss für den das Ergebnis erzeugt wird 
+	 * @param np_faecher   eine Liste von Nachprüfungsfächern, falls eine Nachprüfung möglich ist, 
+	 *                     ansonsten null oder eine leere Liste
+	 *
+	 * @return das Ergebnis der Abschlussberechnung 
+	 */
+	public static getErgebnisNachpruefung(abschluss : Abschluss | null, np_faecher : List<String> | null) : AbschlussErgebnis {
+		let ergebnis : AbschlussErgebnis = new AbschlussErgebnis();
+		ergebnis.abschluss = abschluss === null ? null : abschluss.toString();
+		ergebnis.erworben = false;
+		if ((np_faecher === null) || (np_faecher.size() === 0)) 
+			ergebnis.npFaecher = null; else 
+			ergebnis.npFaecher = np_faecher;
+		ergebnis.log = null;
+		return ergebnis;
+	}
+
+	/**
+	 * Gibt an, ob für einen Abschluss eine Nachprüfungsmöglichkeit besteht.
+	 * 
+	 * @param ergebnis   das Abschluss-Ergebnis bei dem auf eine Nachprüfungsmöglichkeit 
+	 *                   geprüft werden soll. 
+	 * 
+	 * @return true, falls eine Nachprüfungsmöglichkeit besteht, sonst false
+	 */
+	public static hatNachpruefungsmoeglichkeit(ergebnis : AbschlussErgebnis) : boolean {
+		return (ergebnis.npFaecher !== null) && ergebnis.npFaecher.size() > 0;
+	}
+
+	/**
+	 * Gibt die Nachprüfungsfächer als Komma-separierten String zurück.
+	 * 
+	 * @param ergebnis   das Abschluss-Ergebnis bei dem die Nachprüfungsmöglichkeiten 
+	 *                   ausgegeben werden sollen
+	 *                    
+	 * @return die Nachprüfungsfächer als Komma-separierten String
+	 */
+	public static getNPFaecherString(ergebnis : AbschlussErgebnis) : String {
+		if (ergebnis.npFaecher === null) 
+			return "";
+		let sb : StringBuilder | null = new StringBuilder();
+		for (let fach of ergebnis.npFaecher) {
+			if (sb.length() > 0) 
+				sb.append(", ");
+			sb.append(fach);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Vergleicht die beiden Abschlüsse, ob sie identisch sind. Ein
+	 * Übergabewert null wird als {@link Abschluss#OHNE_ABSCHLUSS}
+	 * interpretiert.
+	 *  
+	 * @param a   der eine Abschluss
+	 * @param b   der andere Abschluss
+	 * 
+	 * @return true, falls sie identisch sind und ansonsten false
+	 */
+	public static equalsAbschluesse(a : String | null, b : String | null) : boolean {
+		if ((a === null) || (Abschluss.OHNE_ABSCHLUSS.is(a))) 
+			return (b === null) || (Abschluss.OHNE_ABSCHLUSS.is(b));
+		return JavaObject.equalsTranspiler(a, (b));
+	}
+
+	/**
+	 * Gibt den Abschluss zurück. Im Falle das kein Abschluss angegeben ist
+	 * wird Abschluss.OHNE_ABSCHLUSS zurückgegeben.
+	 * 
+	 * @param ergebnis   das Ergebnis 
+	 * 
+	 * @return der Abschluss
+	 */
+	public static getAbschluss(ergebnis : AbschlussErgebnis) : String {
+		return ergebnis.abschluss === null ? Abschluss.OHNE_ABSCHLUSS.toString() : ergebnis.abschluss;
+	}
+
+	/**
+	 * Die Methode dient dem Erzeugen eines Faches für die Abschlussberechnung.
+	 * 
+	 * @param kuerzel           das Kürzel des Faches
+	 * @param bezeichnung       die Bezeichnung des Faches
+	 * @param note              die Note, die in dem Fach erteilt wurde
+	 * @param kursart           gibt die Kursart Faches an: leistungsdifferenzierter (E-Kurs, G-Kurs) oder sonstiger Kurs
+	 * @param istFremdsprache   gibt an, ob es sich bei dem Fach um eine Fremdsprache handelt oder nicht
+	 * 
+	 * @return das Abschlussfach 
+	 */
+	public static erstelleAbschlussFach(kuerzel : String, bezeichnung : String | null, note : number, kursart : GELeistungsdifferenzierteKursart, istFremdsprache : Boolean | null) : GEAbschlussFach {
+		let fach : GEAbschlussFach = new GEAbschlussFach();
+		fach.kuerzel = kuerzel;
+		fach.bezeichnung = (bezeichnung === null || JavaObject.equalsTranspiler("", (bezeichnung))) ? "---" : bezeichnung;
+		fach.note = note;
+		fach.kursart = kursart.kuerzel;
+		fach.istFremdsprache = istFremdsprache === null ? false : istFremdsprache;
+		return fach;
+	}
+
+	/**
+	 * Liefert eine List mit den Fachkürzeln aus der übergebenen Liste mit Abschlussfächern.
+	 * 
+	 * @param faecher   die Liste mit Abschlussfächern
+	 * 
+	 * @return die Liste mit den Fachkürzeln
+	 */
+	public static getKuerzel(faecher : List<GEAbschlussFach>) : List<String> {
+		let result : Vector<String> = new Vector();
+		for (let i : number = 0; i < faecher.size(); i++){
+			let fach : GEAbschlussFach = faecher.get(i);
+			if ((fach === null) || fach.kuerzel === null) 
+				continue;
+			if (result.contains(fach.kuerzel)) 
+				continue;
+			result.add(fach.kuerzel);
+		}
+		return result;
+	}
+
+	/**
+	 * Prüft, ob vier leistungsdifferenzierte Fächer belegt wurden. Dabei wird nicht geprüft, ob 
+	 * es sich um G oder E-Kurse handelt.
+	 * 
+	 * @param abschluss_faecher   die Abschlussfächer 
+	 * 
+	 * @return true, falls vier leistungsdifferenzierte Fächer belegt wurden, sonst false
+	 */
+	public static pruefeHat4LeistungsdifferenzierteFaecher(abschluss_faecher : GEAbschlussFaecher) : boolean {
+		if (abschluss_faecher.faecher === null) 
+			return false;
+		let count : number = 0;
+		let faecher : List<GEAbschlussFach> = abschluss_faecher.faecher;
+		for (let fach of faecher) {
+			if (fach === null) 
+				continue;
+			let kursart : GELeistungsdifferenzierteKursart = GELeistungsdifferenzierteKursart.from(fach.kursart);
+			if ((kursart as unknown === GELeistungsdifferenzierteKursart.E as unknown) || (kursart as unknown === GELeistungsdifferenzierteKursart.G as unknown)) 
+				count++;
+		}
+		return (count === 4);
+	}
+
+	/**
+	 * Prüft, ob Duplikate bei den Kürzeln der Fächer vorkommen. Dies darf zur korrekten
+	 * Ausführung des Abschlussalgorithmus nicht vorkommen.
+	 * 
+	 * @param abschluss_faecher   die Abschlussfächer 
+	 * 
+	 * @return true, falls keine Duplikate vorkommen, sonst false
+	 */
+	public static pruefeKuerzelDuplikate(abschluss_faecher : GEAbschlussFaecher) : boolean {
+		if (abschluss_faecher.faecher === null) 
+			return true;
+		let kuerzel : HashSet<String> = new HashSet();
+		let faecher : List<GEAbschlussFach> = abschluss_faecher.faecher;
+		for (let fach of faecher) {
+			if ((fach === null) || (fach.kuerzel === null)) 
+				continue;
+			if (!kuerzel.add(fach.kuerzel)) 
+				return false;
+		}
+		return true;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.AbschlussManager'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_AbschlussManager(obj : unknown) : AbschlussManager {
+	return obj as AbschlussManager;
+}

+ 98 - 0
core/abschluss/AbschlussManagerBerufsbildend.ts

@@ -0,0 +1,98 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../java/lang/JavaBoolean';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../core/types/Abschluss';
+import { BKAnlageAFach, cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFach } from '../../core/abschluss/bk/a/BKAnlageAFach';
+import { AbschlussErgebnisBerufsbildend, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnisBerufsbildend } from '../../core/data/abschluss/AbschlussErgebnisBerufsbildend';
+import { JavaDouble, cast_java_lang_Double } from '../../java/lang/JavaDouble';
+import { BKAnlageAFaecher, cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFaecher } from '../../core/abschluss/bk/a/BKAnlageAFaecher';
+
+export class AbschlussManagerBerufsbildend extends JavaObject {
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Erzeugt ein Ergebnis der Abschlussberechnung unter Angabe, ob dieser erworben 
+	 * wurde. Die Liste der Nachprüfungsfächer ist leer und ein Log ist nicht zugeordnet.
+	 *  
+	 * @param hatBSA                      ist der Berufsschulabschluss erreicht
+	 * @param note                        Note des Abschlusses
+	 * @param hatBA                       ist der Berufsabschluss erreicht
+	 * @param abschlussAllgemeinbildend   der allgemeinbildende Abschluss
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung 
+	 */
+	public static getErgebnis(hatBSA : boolean, note : number, hatBA : Boolean | null, abschlussAllgemeinbildend : Abschluss | null) : AbschlussErgebnisBerufsbildend {
+		let ergebnis : AbschlussErgebnisBerufsbildend = new AbschlussErgebnisBerufsbildend();
+		ergebnis.hatBSA = hatBSA;
+		ergebnis.note = note;
+		ergebnis.hatBA = hatBA;
+		ergebnis.abschlussAllgemeinbildend = (abschlussAllgemeinbildend === null) ? null : abschlussAllgemeinbildend.toString();
+		ergebnis.log = null;
+		return ergebnis;
+	}
+
+	/**
+	 * Berechnet den Notendurchschnitt aller Fächer
+	 * 
+	 * @param abschluss_faecher   die Fächer für die Abschlussberechnung
+	 * 
+	 * @return der Notendurchschnitt oder NaN im Fehlerfall
+	 */
+	public static getDurchschnitt(abschluss_faecher : BKAnlageAFaecher) : number {
+		if ((abschluss_faecher.faecher === null) || (abschluss_faecher.faecher.size() === 0)) 
+			return NaN;
+		let sum : number = 0;
+		for (let fach of abschluss_faecher.faecher) {
+			sum += fach.note;
+		}
+		return (sum as number) / abschluss_faecher.faecher.size();
+	}
+
+	/**
+	 * Berechnet die Anzahl der Defizite 
+	 * 
+	 * @param abschluss_faecher   die Fächer für die Abschlussberechnung
+	 * 
+	 * @return die Anzahl der Defizite oder -1 im Fehlerfall
+	 */
+	public static getAnzahlDefizite(abschluss_faecher : BKAnlageAFaecher) : number {
+		if ((abschluss_faecher.faecher === null) || (abschluss_faecher.faecher.size() === 0)) 
+			return -1;
+		let sum : number = 0;
+		for (let fach of abschluss_faecher.faecher) {
+			if (fach.note >= 5) 
+				sum++;
+		}
+		return sum;
+	}
+
+	/**
+	 * Berechnet die Anzahl der Note Ungenügend 
+	 * 
+	 * @param abschluss_faecher   die Fächer für die Abschlussberechnung
+	 * 
+	 * @return die Anzahl der Note Ungenügend oder -1 im Fehlerfall
+	 */
+	public static getAnzahlUngenuegend(abschluss_faecher : BKAnlageAFaecher) : number {
+		if ((abschluss_faecher.faecher === null) || (abschluss_faecher.faecher.size() === 0)) 
+			return -1;
+		let sum : number = 0;
+		for (let fach of abschluss_faecher.faecher) {
+			if (fach.note >= 6) 
+				sum++;
+		}
+		return sum;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.AbschlussManagerBerufsbildend'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_AbschlussManagerBerufsbildend(obj : unknown) : AbschlussManagerBerufsbildend {
+	return obj as AbschlussManagerBerufsbildend;
+}

+ 60 - 0
core/abschluss/bk/a/BKAnlageA01Abschluss.ts

@@ -0,0 +1,60 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { AbschlussManagerBerufsbildend, cast_de_nrw_schule_svws_core_abschluss_AbschlussManagerBerufsbildend } from '../../../../core/abschluss/AbschlussManagerBerufsbildend';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../../core/Service';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../../core/types/Abschluss';
+import { Sprachreferenzniveau, cast_de_nrw_schule_svws_core_types_Sprachreferenzniveau } from '../../../../core/types/Sprachreferenzniveau';
+import { AbschlussErgebnisBerufsbildend, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnisBerufsbildend } from '../../../../core/data/abschluss/AbschlussErgebnisBerufsbildend';
+import { BKAnlageAFaecher, cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFaecher } from '../../../../core/abschluss/bk/a/BKAnlageAFaecher';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../../logger/LogLevel';
+
+export class BKAnlageA01Abschluss extends Service<BKAnlageAFaecher, AbschlussErgebnisBerufsbildend> {
+
+
+	public constructor() {
+		super();
+	}
+
+	public handle(input : BKAnlageAFaecher) : AbschlussErgebnisBerufsbildend {
+		this.logger.log(LogLevel.INFO, "Prüfe BSA:");
+		if (AbschlussManagerBerufsbildend.getAnzahlUngenuegend(input) > 0) {
+			this.logger.logLn(LogLevel.INFO, " nicht erreicht (kein ungenügend erlaubt, insgesamt " + AbschlussManagerBerufsbildend.getAnzahlUngenuegend(input) + ").");
+			return AbschlussManagerBerufsbildend.getErgebnis(false, AbschlussManagerBerufsbildend.getDurchschnitt(input), false, Abschluss.OHNE_ABSCHLUSS);
+		} else 
+			if (AbschlussManagerBerufsbildend.getAnzahlDefizite(input) > 1) {
+				this.logger.logLn(LogLevel.INFO, " nicht erreicht (mehr als 1 Defizit, insgesamt " + AbschlussManagerBerufsbildend.getAnzahlDefizite(input) + ").");
+				return AbschlussManagerBerufsbildend.getErgebnis(false, AbschlussManagerBerufsbildend.getDurchschnitt(input), false, Abschluss.OHNE_ABSCHLUSS);
+			}
+		this.logger.logLn(LogLevel.INFO, " erreicht.");
+		if ((input.englischGeR === null) || (Sprachreferenzniveau.B1.compareTo(input.englischGeR) < 0)) {
+			if (input.englischGeR === null) {
+				this.logger.logLn(LogLevel.INFO, "Das Sprachreferenzniveau in Englisch wurde nicht angegeben. Eine Prüfung auf MSA ist daher nicht möglich.");
+			} else {
+				this.logger.logLn(LogLevel.INFO, "Das Sprachreferenzniveau in Englisch ist für den MSA nicht ausreichend.");
+			}
+			this.logger.logLn(LogLevel.INFO, "HSA10 wurde erreicht.");
+			return AbschlussManagerBerufsbildend.getErgebnis(true, AbschlussManagerBerufsbildend.getDurchschnitt(input), input.hatBestandenBerufsAbschlussPruefung, Abschluss.HA10);
+		}
+		if (AbschlussManagerBerufsbildend.getDurchschnitt(input) <= 2.5) {
+			this.logger.logLn(LogLevel.INFO, "Die Durschnittsnote ist besser als oder gleich 2,5.");
+			this.logger.logLn(LogLevel.INFO, "MSA-Q wurde erreicht.");
+			return AbschlussManagerBerufsbildend.getErgebnis(false, AbschlussManagerBerufsbildend.getDurchschnitt(input), input.hatBestandenBerufsAbschlussPruefung, Abschluss.MSA_Q);
+		} else 
+			if (AbschlussManagerBerufsbildend.getDurchschnitt(input) <= 3.5) {
+				this.logger.logLn(LogLevel.INFO, "Die Durschnittsnote ist besser als oder gleich 3,5, aber schlechter als 2,5.");
+				this.logger.logLn(LogLevel.INFO, "MSA wurde erreicht.");
+				return AbschlussManagerBerufsbildend.getErgebnis(false, AbschlussManagerBerufsbildend.getDurchschnitt(input), input.hatBestandenBerufsAbschlussPruefung, Abschluss.MSA);
+			}
+		this.logger.logLn(LogLevel.INFO, "Die Durschnittsnote ist schlechter als 3,5.");
+		this.logger.logLn(LogLevel.INFO, "HSA10 wurde erreicht.");
+		return AbschlussManagerBerufsbildend.getErgebnis(false, AbschlussManagerBerufsbildend.getDurchschnitt(input), input.hatBestandenBerufsAbschlussPruefung, Abschluss.HA10);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.bk.a.BKAnlageA01Abschluss'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageA01Abschluss(obj : unknown) : BKAnlageA01Abschluss {
+	return obj as BKAnlageA01Abschluss;
+}

+ 23 - 0
core/abschluss/bk/a/BKAnlageAFach.ts

@@ -0,0 +1,23 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../../java/lang/JavaString';
+
+export class BKAnlageAFach extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public note : number = -1;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.bk.a.BKAnlageAFach'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFach(obj : unknown) : BKAnlageAFach {
+	return obj as BKAnlageAFach;
+}

+ 28 - 0
core/abschluss/bk/a/BKAnlageAFaecher.ts

@@ -0,0 +1,28 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../../java/lang/JavaString';
+import { BKAnlageAFach, cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFach } from '../../../../core/abschluss/bk/a/BKAnlageAFach';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../../java/lang/JavaBoolean';
+
+export class BKAnlageAFaecher extends JavaObject {
+
+	public faecher : List<BKAnlageAFach> | null = null;
+
+	public hatBestandenBerufsAbschlussPruefung : Boolean | null = null;
+
+	public englischGeR : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.bk.a.BKAnlageAFaecher'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_bk_a_BKAnlageAFaecher(obj : unknown) : BKAnlageAFaecher {
+	return obj as BKAnlageAFaecher;
+}

+ 227 - 0
core/abschluss/ge/AbschlussFaecherGruppe.ts

@@ -0,0 +1,227 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { StringBuilder, cast_java_lang_StringBuilder } from '../../../java/lang/StringBuilder';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+
+export class AbschlussFaecherGruppe extends JavaObject {
+
+	private readonly faecher : Vector<GEAbschlussFach> = new Vector();
+
+
+	/**
+	 * Erzeugt eine Fächergruppe aus den angegebenen Fächern und den vorgegebenen Kriterien.
+	 *
+	 * @param faecherAlle       eine Liste aller vorhandenen Leistungen
+	 * @param faecherNutzen     nur die gelisteten Fächer nutzen, null bedeutet grundsätzlich alle benoteten Fächer nutzen (außer den gefilterten)
+	 * @param faecherFiltern    null bedeutet keinen Filter verwenden, ansonsten werden die gelisteten Fächer gefiltert
+	 */
+	public constructor(faecherAlle : List<GEAbschlussFach>, faecherNutzen : List<String> | null, faecherFiltern : List<String> | null) {
+		super();
+		if (faecherAlle === null) 
+			return;
+		for (let i : number = 0; i < faecherAlle.size(); i++){
+			let fach : GEAbschlussFach = faecherAlle.get(i);
+			if (fach.kuerzel === null) 
+				continue;
+			if ((faecherFiltern !== null) && faecherFiltern.contains(fach.kuerzel)) 
+				continue;
+			if ((faecherNutzen !== null) && !faecherNutzen.contains(fach.kuerzel)) 
+				continue;
+			this.faecher.add(AbschlussManager.erstelleAbschlussFach(fach.kuerzel, fach.bezeichnung, fach.note, GELeistungsdifferenzierteKursart.from(fach.kursart), fach.istFremdsprache));
+		}
+	}
+
+	/**
+	 * Prüft, ob die gelisteten Fächer in der Fächergruppe sind und nur diese.
+	 * 
+	 * @param faecherAbgleich   die Fächer, welche in der Fächergruppe sein sollen.
+	 * 
+	 * @return true, falls die angegebenen Fächer und nur diese in der Fächergruppe sind, ansonsten false.
+	 */
+	public istVollstaendig(faecherAbgleich : List<String> | null) : boolean {
+		if (faecherAbgleich === null) 
+			return true;
+		if (this.isEmpty()) 
+			return false;
+		for (let kuerzel of faecherAbgleich) {
+			if (!this.contains(kuerzel)) 
+				return false;
+		}
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (!faecherAbgleich.contains(fach.kuerzel)) 
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Gibt zurück, ob die Fächergruppe leer ist oder mindestens ein Fach beinhaltet.
+	 *  
+	 * @return true, falls die Fächergruppe leer ist, ansonsten false
+	 */
+	public isEmpty() : boolean {
+		return (this.faecher === null) || (this.faecher.isEmpty());
+	}
+
+	/**
+	 * Prüft, ob das Fach mit dem angegebenen Fachkürzel in der Fächergruppe enthalten ist
+	 * oder nicht.
+	 * 
+	 * @param kuerzel   das Kürzel des Faches, welches geprüft werden soll.
+	 * 
+	 * @return true, falls das Fach vorhanden ist, und ansonsten false
+	 */
+	public contains(kuerzel : String | null) : boolean {
+		if (kuerzel === null) 
+			return false;
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if ((fach !== null) && (JavaObject.equalsTranspiler(fach.kuerzel, (kuerzel)))) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Entfernt alle Fächer aus der Fächergruppe, die dem übergebenen Filter entsprechen.
+	 * 
+	 * @param filter   die Funktion, um die zu entfernenden Fächer zu bestimmen
+	 * 
+	 * @return die Liste der tatsächlich entfernten Fächer
+	 */
+	public entferneFaecher(filter : Predicate<GEAbschlussFach>) : List<GEAbschlussFach> {
+		let selected : Vector<GEAbschlussFach> = new Vector();
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach)) 
+				selected.add(fach);
+		}
+		this.faecher.removeAll(selected);
+		return selected;
+	}
+
+	/**
+	 * Bestimmt das Fach, welches dem übergebenen Filter entspricht. Entsprechen
+	 * mehrere Fächer dem Filterkriterium, so wird nur das erste Fach 
+	 * der internen Liste zurückgegeben.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für das gesuchte Fach angibt.
+	 * 
+	 * @return das Fach, sofern eines gefunden wurde, ansonsten false
+	 */
+	public getFach(filter : Predicate<GEAbschlussFach>) : GEAbschlussFach | null {
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach)) 
+				return fach;
+		}
+		return null;
+	}
+
+	/**
+	 * Bestimmt alle Fächer, welche dem übergebenen Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return eine Liste der Fächer, die dem Filterkriterium entsprechen
+	 */
+	public getFaecher(filter : Predicate<GEAbschlussFach>) : List<GEAbschlussFach> {
+		let result : Vector<GEAbschlussFach> = new Vector();
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach)) 
+				result.add(fach);
+		}
+		return result;
+	}
+
+	/**
+	 * Gibt die Anzahl der Fächer zurück, welche dem übergebenen Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return die Anzahl der Fächer
+	 */
+	public getFaecherAnzahl(filter : Predicate<GEAbschlussFach>) : number {
+		let count : number = 0;
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach)) 
+				count++;
+		}
+		return count;
+	}
+
+	/**
+	 * Bestimmt die Kürzel aller Fächer, welche dem übergebenen Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return eine Liste der Kürzel der Fächer, die dem Filterkriterium entsprechen
+	 */
+	public getKuerzel(filter : Predicate<GEAbschlussFach>) : List<String> {
+		let result : Vector<String> = new Vector();
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach) && (fach.kuerzel !== null)) 
+				result.add(fach.kuerzel);
+		}
+		return result;
+	}
+
+	/**
+	 * Erstellt eine Zeichenkette mit einer Komma-separierten Liste der Kürzel aller Fächer, 
+	 * welche dem übergebenen Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return die Zeichenkette mit einer Komma-separierten Liste der Fächerkürzel
+	 */
+	public getKuerzelListe(filter : Predicate<GEAbschlussFach>) : String {
+		let sb : StringBuilder = new StringBuilder();
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (filter.test(fach)) {
+				if (sb.length() > 0) 
+					sb.append(", ");
+				sb.append(fach.kuerzel);
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Gibt eine Komma-separierte Liste, der Abschlussfächer aus. Dabei wird
+	 * die toString Methode der Klasse AbschlussFach verwendet.
+	 */
+	public toString() : String {
+		let sb : StringBuilder = new StringBuilder();
+		for (let i : number = 0; i < this.faecher.size(); i++){
+			let fach : GEAbschlussFach = this.faecher.get(i);
+			if (sb.length() > 0) 
+				sb.append(", ");
+			let diffkursinfo : String = "";
+			if ((fach.kursart === null) || (fach.kuerzel === null)) 
+				continue;
+			if (!GELeistungsdifferenzierteKursart.Sonstige.hat(fach.kursart)) 
+				diffkursinfo += fach.kursart + ",";
+			sb.append(fach.kuerzel + "(" + diffkursinfo.valueOf() + fach.note + ")");
+		}
+		return sb.toString();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.ge.AbschlussFaecherGruppe'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppe(obj : unknown) : AbschlussFaecherGruppe {
+	return obj as AbschlussFaecherGruppe;
+}

+ 153 - 0
core/abschluss/ge/AbschlussFaecherGruppen.ts

@@ -0,0 +1,153 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { StringBuilder, cast_java_lang_StringBuilder } from '../../../java/lang/StringBuilder';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { AbschlussFaecherGruppe, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppe } from '../../../core/abschluss/ge/AbschlussFaecherGruppe';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+
+export class AbschlussFaecherGruppen extends JavaObject {
+
+	public readonly fg1 : AbschlussFaecherGruppe;
+
+	public readonly fg2 : AbschlussFaecherGruppe;
+
+
+	/**
+	 * Erzeugt eine neues Objekt AbschlussFaecherGruppen
+	 *  
+	 * @param fg1   die Fächergruppe 1
+	 * @param fg2   die Fächergruppe 2
+	 */
+	public constructor(fg1 : AbschlussFaecherGruppe, fg2 : AbschlussFaecherGruppe) {
+		super();
+		this.fg1 = fg1;
+		this.fg2 = fg2;
+	}
+
+	/**
+	 * Prüft, ob eine der beiden Fächergruppen leer ist.
+	 * 
+	 * @return true, falls eine der beiden Fächergruppen leer ist.
+	 */
+	public isEmpty() : boolean {
+		return this.fg1 === null || this.fg2 === null || this.fg1.isEmpty() || this.fg2.isEmpty();
+	}
+
+	/**
+	 * Prüft, ob das Fach mit dem angegebenen Fachkürzel in einer der beiden 
+	 * Fächergruppen enthalten ist oder nicht.
+	 * 
+	 * @param kuerzel   das Kürzel des Faches, welches geprüft werden soll.
+	 * 
+	 * @return true, falls das Fach vorhanden ist, und ansonsten false
+	 */
+	public contains(kuerzel : String | null) : boolean {
+		return this.fg1.contains(kuerzel) || this.fg2.contains(kuerzel);
+	}
+
+	/**
+	 * Bestimmt alle Fächer beider Fächergruppen, welche dem übergebenen 
+	 * Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return eine Liste der Fächer, die dem Filterkriterium entsprechen
+	 */
+	public getFaecher(filter : Predicate<GEAbschlussFach>) : List<GEAbschlussFach> {
+		let faecher : List<GEAbschlussFach> = this.fg1.getFaecher(filter);
+		faecher.addAll(this.fg2.getFaecher(filter));
+		return faecher;
+	}
+
+	/**
+	 * Gibt die Anzahl der Fächer beider Fächergruppen zurück, welche dem übergebenen 
+	 * Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return die Anzahl der Fächer
+	 */
+	public getFaecherAnzahl(filter : Predicate<GEAbschlussFach>) : number {
+		return this.fg1.getFaecherAnzahl(filter) + this.fg2.getFaecherAnzahl(filter);
+	}
+
+	/**
+	 * Bestimmt die Kürzel aller Fächer beider Fächergruppen, welche dem übergebenen 
+	 * Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return eine Liste der Kürzel der Fächer, die dem Filterkriterium entsprechen
+	 */
+	public getKuerzel(filter : Predicate<GEAbschlussFach>) : List<String> {
+		let faecher : List<String> = this.fg1.getKuerzel(filter);
+		faecher.addAll(this.fg2.getKuerzel(filter));
+		return faecher;
+	}
+
+	/**
+	 * Erstellt eine Zeichenkette mit einer Komma-separierten Liste der Kürzel aller Fächer
+	 * beider Fächergruppen, welche dem übergebenen Filterkriterium entsprechen.
+	 * 
+	 * @param filter   die Funktion, die das Kriterium für die gesuchten Fächer angibt.
+	 * 
+	 * @return die Zeichenkette mit einer Komma-separierten Liste der Fächerkürzel
+	 */
+	public getKuerzelListe(filter : Predicate<GEAbschlussFach>) : String;
+
+	/**
+	 * Erstellt eine Zeichenkette mit einer Komma-separierten Liste der Kürzel aller Fächer
+	 * beider Fächergruppen, welche dem übergebenen Filterkriterium entsprechen. Dabei
+	 * werden für die Fächergruppen jedoch unterschiedliche Filterkriterien angewendet.
+	 * 
+	 * @param filterFG1   die Funktion, die das Kriterium für die gesuchten Fächer der Fächergruppe 1 angibt.
+	 * @param filterFG2   die Funktion, die das Kriterium für die gesuchten Fächer der Fächergruppe 2 angibt.
+	 * 
+	 * @return die Zeichenkette mit einer Komma-separierten Liste der Fächerkürzel
+	 */
+	public getKuerzelListe(filterFG1 : Predicate<GEAbschlussFach>, filterFG2 : Predicate<GEAbschlussFach>) : String;
+
+	/**
+	 * Implementation for method overloads of 'getKuerzelListe'
+	 */
+	public getKuerzelListe(__param0 : Predicate<GEAbschlussFach>, __param1? : Predicate<GEAbschlussFach>) : String {
+		if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('test' in __param0) && (typeof __param0.test === 'function')) || (__param0 === null)) && (typeof __param1 === "undefined")) {
+			let filter : Predicate<GEAbschlussFach> = cast_java_util_function_Predicate(__param0);
+			let sb : StringBuilder = new StringBuilder();
+			let faecher : List<String> = this.getKuerzel(filter);
+			for (let fach of faecher) {
+				if (sb.length() > 0) 
+					sb.append(", ");
+				sb.append(fach);
+			}
+			return sb.toString();
+		} else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('test' in __param0) && (typeof __param0.test === 'function')) || (__param0 === null)) && ((typeof __param1 !== "undefined") && ((typeof __param1 !== 'undefined') && (__param1 instanceof Object) && (__param1 !== null) && ('test' in __param1) && (typeof __param1.test === 'function')) || (__param1 === null))) {
+			let filterFG1 : Predicate<GEAbschlussFach> = cast_java_util_function_Predicate(__param0);
+			let filterFG2 : Predicate<GEAbschlussFach> = cast_java_util_function_Predicate(__param1);
+			let sb : StringBuilder = new StringBuilder();
+			let faecherFG1 : List<String> = this.fg1.getKuerzel(filterFG1);
+			let faecherFG2 : List<String> = this.fg2.getKuerzel(filterFG2);
+			for (let fach of faecherFG1) {
+				if (sb.length() > 0) 
+					sb.append(", ");
+				sb.append(fach);
+			}
+			for (let fach of faecherFG2) {
+				if (sb.length() > 0) 
+					sb.append(", ");
+				sb.append(fach);
+			}
+			return sb.toString();
+		} else throw new Error('invalid method overload');
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.ge.AbschlussFaecherGruppen'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppen(obj : unknown) : AbschlussFaecherGruppen {
+	return obj as AbschlussFaecherGruppen;
+}

+ 162 - 0
core/abschluss/ge/ServiceAbschlussHA10.ts

@@ -0,0 +1,162 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../core/Service';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../logger/LogLevel';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+import { AbschlussFaecherGruppe, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppe } from '../../../core/abschluss/ge/AbschlussFaecherGruppe';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../../core/data/abschluss/GEAbschlussFaecher';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../../core/data/abschluss/AbschlussErgebnis';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../core/types/Abschluss';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { AbschlussFaecherGruppen, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppen } from '../../../core/abschluss/ge/AbschlussFaecherGruppen';
+
+export class ServiceAbschlussHA10 extends Service<GEAbschlussFaecher, AbschlussErgebnis> {
+
+	filterDefizit : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note > 4 && (!f.ausgeglichen) };
+
+	filterMangelhaft : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note === 5 };
+
+	filterMangelhaftOhneZP10Faecher : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note === 5) && (!JavaObject.equalsTranspiler("D", (f.kuerzel))) && (!JavaObject.equalsTranspiler("E", (f.kuerzel))) && (!JavaObject.equalsTranspiler("M", (f.kuerzel))) };
+
+	filterUngenuegend : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note === 6 };
+
+	filterEKurse : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (GELeistungsdifferenzierteKursart.E.hat(f.kursart)) };
+
+	filterWeitereFremdsprachen : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (!JavaObject.equalsTranspiler("E", (f.kuerzel)) && (f.istFremdsprache !== null) && (f.istFremdsprache === true)) };
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Führt die Abschlussberechnung anhand der übergebenen Abschlussfächer durch
+	 * und gibt das Berechnungsergebnis zurück.
+	 * 
+	 * @param input    die Abschlussfächer
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung
+	 */
+	public handle(input : GEAbschlussFaecher) : AbschlussErgebnis {
+		this.logger.logLn(LogLevel.INFO, "Prüfe HA10:");
+		this.logger.logLn(LogLevel.DEBUG, "==========");
+		if ((input.faecher === null) || (!AbschlussManager.pruefeHat4LeistungsdifferenzierteFaecher(input))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht genügend leistungsdiffernzierte Fächer gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (!AbschlussManager.pruefeKuerzelDuplikate(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden Fächer mit dem gleichen Kürzel zur Abschlussprüfung übergeben. Dies ist nicht zulässig.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let faecher : AbschlussFaecherGruppen = new AbschlussFaecherGruppen(new AbschlussFaecherGruppe(input.faecher, Arrays.asList("D", "M", "LBNW", "LBAL"), null), new AbschlussFaecherGruppe(input.faecher, null, Arrays.asList("D", "M", "LBNW", "LBAL", "BI", "PH", "CH", "AT", "AW", "AH")));
+		if (!faecher.fg1.istVollstaendig(Arrays.asList("D", "M", "LBNW", "LBAL"))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht alle nötigen Leistungen für die Fächergruppe 1 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (faecher.fg2.isEmpty()) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Keine Leistungen für die Fächergruppe 2 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let weitereFS : List<GEAbschlussFach> = faecher.fg2.entferneFaecher(this.filterWeitereFremdsprachen);
+		if (weitereFS.size() > 0) {
+			for (let fs of weitereFS) {
+				if (fs.bezeichnung === null) 
+					continue;
+				this.logger.logLn(LogLevel.DEBUG, " -> Ignoriere weitere Fremdsprache: " + fs.bezeichnung + "(" + fs.note + ")");
+			}
+		}
+		this.logger.logLn(LogLevel.DEBUG, " - ggf. Verbessern der E-Kurs-Noten für die Defizitberechnung:");
+		let tmpFaecher : List<GEAbschlussFach> = faecher.getFaecher(this.filterEKurse);
+		for (let f of tmpFaecher) {
+			if (f.kuerzel === null) 
+				continue;
+			let note : number = f.note;
+			let note_neu : number = (note === 1) ? 1 : note - 1;
+			this.logger.logLn(LogLevel.DEBUG, "   " + f.kuerzel + "(E):" + note + "->" + note_neu);
+			f.note = note_neu;
+		}
+		this.logger.logLn(LogLevel.DEBUG, " -> FG1: Fächer " + faecher.fg1.toString().valueOf());
+		this.logger.logLn(LogLevel.DEBUG, " -> FG2: Fächer " + faecher.fg2.toString().valueOf());
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeDefizite(faecher, "");
+		if (abschlussergebnis.erworben) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => HA 10: APO-SI §41 (1)");
+		} else 
+			if (AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis)) {
+				this.logger.logLn(LogLevel.INFO, " => kein HA10 - Nachprüfungsmöglichkeite(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf());
+			} else {
+				this.logger.logLn(LogLevel.INFO, " => kein HA10 - KEINE Nachprüfungsmöglichkeiten!");
+			}
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Prüft in Bezug auf Defizite, ob der Abschluss erworben wurde.
+	 * 
+	 * @param faecher      die Asbchlussfächer nach Fächergruppen sortiert
+	 * @param log_indent   die Einrückung für das Logging
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug die Defizitberechnung
+	 */
+	private pruefeDefizite(faecher : AbschlussFaecherGruppen, log_indent : String) : AbschlussErgebnis {
+		let fg1_defizite : number = faecher.fg1.getFaecherAnzahl(this.filterDefizit);
+		let fg2_defizite : number = faecher.fg2.getFaecherAnzahl(this.filterDefizit);
+		let ges_defizite : number = fg1_defizite + fg2_defizite;
+		let fg1_mangelhaft : number = faecher.fg1.getFaecherAnzahl(this.filterMangelhaft);
+		let fg1_ungenuegend : number = faecher.fg1.getFaecherAnzahl(this.filterUngenuegend);
+		let fg2_ungenuegend : number = faecher.fg2.getFaecherAnzahl(this.filterUngenuegend);
+		if (fg1_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG1: Defizit" + (fg1_defizite > 1 ? "e" : "") + ": " + faecher.fg1.getKuerzelListe(this.filterDefizit).valueOf());
+		if (fg2_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG2: Defizit" + (fg2_defizite > 1 ? "e" : "") + ": " + faecher.fg2.getKuerzelListe(this.filterDefizit).valueOf());
+		if ((fg1_ungenuegend > 0) || (fg2_ungenuegend > 1)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu oft ungenügend (6) - 0x6 in FG1 und max. 1x6 in FG2 erlaubt.");
+			return AbschlussManager.getErgebnis(Abschluss.HA10, false);
+		}
+		this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> " + ((fg2_ungenuegend === 1) ? "1x6 in FG2 erlaubt" : "0x6 in FG1 und FG2") + " -> prüfe weitere Defizite");
+		if (fg1_mangelhaft > 2) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: Mehr als 2x5 in FG1");
+			return AbschlussManager.getErgebnis(Abschluss.HA10, false);
+		}
+		if ((fg1_mangelhaft === 2) && (fg2_defizite > 1)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: 2x5 in FG1 und mind. ein weiteres Defizit in FG2");
+			return AbschlussManager.getErgebnis(Abschluss.HA10, false);
+		}
+		if (ges_defizite > 3) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: Insgesamt mehr als 3 Defizite");
+			return AbschlussManager.getErgebnis(Abschluss.HA10, false);
+		}
+		let hatNP : boolean = (fg1_mangelhaft === 2) || (ges_defizite === 3);
+		if (hatNP) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: " + ((fg1_mangelhaft === 2) ? "2x5 in FG1, aber kein weiteres Defizit in FG2" : "3 Defizite nicht erlaubt"));
+			this.logger.logLn(LogLevel.INFO, " -> Hinweis: Nachprüfungen in ZP10-Fächern nicht möglich");
+			let np_faecher : List<String> = (fg1_mangelhaft === 2) ? faecher.fg1.getKuerzel(this.filterMangelhaftOhneZP10Faecher) : faecher.getKuerzel(this.filterMangelhaftOhneZP10Faecher);
+			let abschlussergebnis : AbschlussErgebnis = AbschlussManager.getErgebnisNachpruefung(Abschluss.HA10, np_faecher);
+			this.logger.logLn(LogLevel.INFO, AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis) ? (" -> Nachprüfungsmöglichkeit(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf()) : " -> also: kein Nachprüfungsmöglichkeit.");
+			return abschlussergebnis;
+		}
+		if ((fg1_defizite === 0) && (fg2_defizite === 0)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> keine Defizite in FG1 und FG2");
+			return AbschlussManager.getErgebnis(Abschluss.HA10, true);
+		}
+		this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zwei Defizite erlaubt (solange nicht beide in FG1)");
+		return AbschlussManager.getErgebnis(Abschluss.HA10, true);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.ge.ServiceAbschlussHA10'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussHA10(obj : unknown) : ServiceAbschlussHA10 {
+	return obj as ServiceAbschlussHA10;
+}

+ 163 - 0
core/abschluss/ge/ServiceAbschlussHA9.ts

@@ -0,0 +1,163 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../core/Service';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../logger/LogLevel';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+import { AbschlussFaecherGruppe, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppe } from '../../../core/abschluss/ge/AbschlussFaecherGruppe';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../../core/data/abschluss/GEAbschlussFaecher';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../../core/data/abschluss/AbschlussErgebnis';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../core/types/Abschluss';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { AbschlussFaecherGruppen, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppen } from '../../../core/abschluss/ge/AbschlussFaecherGruppen';
+
+export class ServiceAbschlussHA9 extends Service<GEAbschlussFaecher, AbschlussErgebnis> {
+
+	filterDefizit : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note > 4 && (!f.ausgeglichen) };
+
+	filterMangelhaft : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note === 5 };
+
+	filterUngenuegend : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => f.note === 6 };
+
+	filterEKurse : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (GELeistungsdifferenzierteKursart.E.hat(f.kursart)) };
+
+	filterWeitereFremdsprachen : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (!JavaObject.equalsTranspiler("E", (f.kuerzel)) && (f.istFremdsprache !== null) && (f.istFremdsprache === true)) };
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Führt die Abschlussberechnung anhand der übergebenen Abschlussfächer durch
+	 * und gibt das Berechnungsergebnis zurück.
+	 * 
+	 * @param input    die Abschlussfächer
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung
+	 */
+	public handle(input : GEAbschlussFaecher) : AbschlussErgebnis {
+		if (JavaObject.equalsTranspiler("10", (input.jahrgang))) {
+			this.logger.logLn(LogLevel.INFO, "Im Jahrgang 10 gibt es keinen HA9-Abschluss mehr.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		this.logger.logLn(LogLevel.INFO, "Prüfe HA9:");
+		this.logger.logLn(LogLevel.DEBUG, "==========");
+		if ((input.faecher === null) || (!AbschlussManager.pruefeHat4LeistungsdifferenzierteFaecher(input))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht genügend leistungsdiffernzierte Fächer gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (!AbschlussManager.pruefeKuerzelDuplikate(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden Fächer mit dem gleichen Kürzel zur Abschlussprüfung übergeben. Dies ist nicht zulässig.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let faecher : AbschlussFaecherGruppen = new AbschlussFaecherGruppen(new AbschlussFaecherGruppe(input.faecher, Arrays.asList("D", "M"), null), new AbschlussFaecherGruppe(input.faecher, null, Arrays.asList("D", "M", "LBNW", "LBAL")));
+		if (!faecher.fg1.istVollstaendig(Arrays.asList("D", "M"))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht alle nötigen Leistungen für die Fächergruppe 1 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (faecher.fg2.isEmpty()) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Keine Leistungen für die Fächergruppe 2 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let weitereFS : List<GEAbschlussFach> = faecher.fg2.entferneFaecher(this.filterWeitereFremdsprachen);
+		if (weitereFS.size() > 0) {
+			for (let fs of weitereFS) {
+				if (fs.bezeichnung === null) 
+					continue;
+				this.logger.logLn(LogLevel.DEBUG, " -> Ignoriere weitere Fremdsprache: " + fs.bezeichnung + "(" + fs.note + ")");
+			}
+		}
+		this.logger.logLn(LogLevel.DEBUG, " - ggf. Verbessern der E-Kurs-Noten für die Defizitberechnung:");
+		let tmpFaecher : List<GEAbschlussFach> = faecher.getFaecher(this.filterEKurse);
+		for (let f of tmpFaecher) {
+			if (f.kuerzel === null) 
+				continue;
+			let note : number = f.note;
+			let note_neu : number = (note === 1) ? 1 : note - 1;
+			this.logger.logLn(LogLevel.DEBUG, "   " + f.kuerzel + "(E):" + note + "->" + note_neu);
+			f.note = note_neu;
+		}
+		this.logger.logLn(LogLevel.DEBUG, " -> FG1: Fächer " + faecher.fg1.toString().valueOf());
+		this.logger.logLn(LogLevel.DEBUG, " -> FG2: Fächer " + faecher.fg2.toString().valueOf());
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeDefizite(faecher, "");
+		if (abschlussergebnis.erworben) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => HA 9: APO-SI §40 (3)");
+		} else 
+			if (AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis)) {
+				this.logger.logLn(LogLevel.INFO, " => kein HA9 - Nachprüfungsmöglichkeite(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf());
+			} else {
+				this.logger.logLn(LogLevel.INFO, " => kein HA9 - KEINE Nachprüfungsmöglichkeiten!");
+			}
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Prüft in Bezug auf Defizite, ob der Abschluss erworben wurde.
+	 * 
+	 * @param faecher      die Asbchlussfächer nach Fächergruppen sortiert
+	 * @param log_indent   die Einrückung für das Logging
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug die Defizitberechnung
+	 */
+	private pruefeDefizite(faecher : AbschlussFaecherGruppen, log_indent : String) : AbschlussErgebnis {
+		let fg1_defizite : number = faecher.fg1.getFaecherAnzahl(this.filterDefizit);
+		let fg2_defizite : number = faecher.fg2.getFaecherAnzahl(this.filterDefizit);
+		let ges_defizite : number = fg1_defizite + fg2_defizite;
+		let fg1_mangelhaft : number = faecher.fg1.getFaecherAnzahl(this.filterMangelhaft);
+		let fg1_ungenuegend : number = faecher.fg1.getFaecherAnzahl(this.filterUngenuegend);
+		let fg2_ungenuegend : number = faecher.fg2.getFaecherAnzahl(this.filterUngenuegend);
+		if (fg1_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG1: Defizit" + (fg1_defizite > 1 ? "e" : "") + ": " + faecher.fg1.getKuerzelListe(this.filterDefizit).valueOf());
+		if (fg2_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG2: Defizit" + (fg2_defizite > 1 ? "e" : "") + ": " + faecher.fg2.getKuerzelListe(this.filterDefizit).valueOf());
+		if ((fg1_ungenuegend > 0) || (fg2_ungenuegend > 1)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu oft ungenügend (6) - 0x6 in FG1 und max. 1x6 in FG2 erlaubt.");
+			return AbschlussManager.getErgebnis(Abschluss.HA9, false);
+		}
+		this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> " + ((fg2_ungenuegend === 1) ? "1x6 in FG2 erlaubt" : "0x6 in FG1 und FG2") + " -> prüfe weitere Defizite");
+		if (fg1_mangelhaft > 2) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: Mehr als 2x5 in FG1");
+			return AbschlussManager.getErgebnis(Abschluss.HA9, false);
+		}
+		if ((fg1_mangelhaft === 2) && (fg2_defizite > 1)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: 2x5 in FG1 und mind. ein weiteres Defizit in FG2");
+			return AbschlussManager.getErgebnis(Abschluss.HA9, false);
+		}
+		if (ges_defizite > 3) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: Insgesamt mehr als 3 Defizite");
+			return AbschlussManager.getErgebnis(Abschluss.HA9, false);
+		}
+		let hatNP : boolean = (fg1_mangelhaft === 2) || (ges_defizite === 3);
+		if (hatNP) {
+			let np_faecher : List<String> = (fg1_mangelhaft === 2) ? faecher.fg1.getKuerzel(this.filterMangelhaft) : faecher.getKuerzel(this.filterMangelhaft);
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite: " + ((fg1_mangelhaft === 2) ? "2x5 in FG1, aber kein weiteres Defizit in FG2" : "3 Defizite nicht erlaubt"));
+			let abschlussergebnis : AbschlussErgebnis = AbschlussManager.getErgebnisNachpruefung(Abschluss.HA9, np_faecher);
+			this.logger.logLn(LogLevel.INFO, " -> Nachprüfungsmöglichkeit(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf());
+			return abschlussergebnis;
+		}
+		if ((fg1_defizite === 0) && (fg2_defizite === 0)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> keine Defizite in FG1 und FG2");
+			return AbschlussManager.getErgebnis(Abschluss.HA9, true);
+		}
+		this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zwei Defizite erlaubt (solange nicht beide in FG1)");
+		return AbschlussManager.getErgebnis(Abschluss.HA9, true);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.ge.ServiceAbschlussHA9'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussHA9(obj : unknown) : ServiceAbschlussHA9 {
+	return obj as ServiceAbschlussHA9;
+}

+ 356 - 0
core/abschluss/ge/ServiceAbschlussMSA.ts

@@ -0,0 +1,356 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../core/Service';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../logger/LogLevel';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+import { AbschlussFaecherGruppe, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppe } from '../../../core/abschluss/ge/AbschlussFaecherGruppe';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../../core/data/abschluss/GEAbschlussFaecher';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../../core/data/abschluss/AbschlussErgebnis';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../core/types/Abschluss';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { AbschlussFaecherGruppen, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppen } from '../../../core/abschluss/ge/AbschlussFaecherGruppen';
+
+export class ServiceAbschlussMSA extends Service<GEAbschlussFaecher, AbschlussErgebnis> {
+
+	private filterDefizite : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && ((f.note > 4) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 3))) };
+
+	private filterDefizite1NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && (((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 5)) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 4))) };
+
+	private filterDefizite2NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && (((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 6)) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 5))) };
+
+	private filterDefiziteMehrAls1NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && (((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 6)) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note >= 5))) };
+
+	private filterDefiziteMehrAls2NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 6)) };
+
+	private filterDefiziteMitNPOption : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && ((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 5)) };
+
+	private filterDefizitWP : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && (f.note > 4) && JavaString.equalsIgnoreCase("WP", f.kuerzel) };
+
+	private filterDefizitNichtWP : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgeglichen && (f.note > 4) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 3)) && !JavaString.equalsIgnoreCase("WP", f.kuerzel) };
+
+	private filterBenoetigte3er : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgleich && (f.note <= 3) && (GELeistungsdifferenzierteKursart.Sonstige.hat(f.kursart)) };
+
+	private filterDefiziteBenoetigte3erMitNPOption : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgleich && (f.note === 4) && (GELeistungsdifferenzierteKursart.Sonstige.hat(f.kursart)) };
+
+	private filterAusgleiche : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgleich && ((f.note < 3) || ((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note < 4))) };
+
+	private filterAusgleiche3er : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgleich && (f.note < 3) };
+
+	private filterEKurse : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (GELeistungsdifferenzierteKursart.E.hat(f.kursart)) };
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Bestimmt anhand der übergebenen Fächer die Zuordnung zu den beiden Fäächergruppen.
+	 * 
+	 * @param input   die Abschlussfächer
+	 * 
+	 * @return die Zuordnung der Abschlussfächer zu beiden Fachgruppen 1 und 2
+	 */
+	public static getFaechergruppen(input : List<GEAbschlussFach>) : AbschlussFaecherGruppen {
+		let faecher : AbschlussFaecherGruppen = new AbschlussFaecherGruppen(new AbschlussFaecherGruppe(input, Arrays.asList("D", "M", "E", "WP"), null), new AbschlussFaecherGruppe(input, null, Arrays.asList("D", "M", "E", "WP", "LBNW", "LBAL")));
+		return faecher;
+	}
+
+	/**
+	 * Führt die Abschlussberechnung anhand der übergebenen Abschlussfächer durch
+	 * und gibt das Berechnungsergebnis zurück.
+	 * 
+	 * @param input    die Abschlussfächer
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung
+	 */
+	public handle(input : GEAbschlussFaecher) : AbschlussErgebnis {
+		this.logger.logLn(LogLevel.INFO, "Prüfe MSA:");
+		this.logger.logLn(LogLevel.DEBUG, "==========");
+		if ((input.faecher === null) || (!AbschlussManager.pruefeHat4LeistungsdifferenzierteFaecher(input))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht genügend leistungsdiffernzierte Fächer gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (!AbschlussManager.pruefeKuerzelDuplikate(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden Fächer mit dem gleichen Kürzel zur Abschlussprüfung übergeben. Dies ist nicht zulässig.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let faecher : AbschlussFaecherGruppen = ServiceAbschlussMSA.getFaechergruppen(input.faecher);
+		if (!faecher.fg1.istVollstaendig(Arrays.asList("D", "M", "E", "WP"))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht alle nötigen Leistungen für die Fächergruppe 1 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (faecher.fg2.isEmpty()) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Keine Leistungen für die Fächergruppe 2 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let anzahlEKurse : number = faecher.getFaecherAnzahl(this.filterEKurse);
+		if (anzahlEKurse < 2) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => kein MSA (FOR) - nicht genügend E-Kurse belegt");
+			return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+		} else 
+			if (anzahlEKurse > 2) {
+				let zuviel : number = anzahlEKurse - 2;
+				let eKursFG2 : GEAbschlussFach | null = faecher.fg2.getFach(this.filterEKurse);
+				if (eKursFG2 !== null) {
+					let note : number = eKursFG2.note;
+					let note_neu : number = (note === 1) ? 1 : note - 1;
+					this.logger.logLn(LogLevel.DEBUG, "   " + eKursFG2.kuerzel + ":(E)" + note + "->(G)" + note_neu);
+					eKursFG2.note = note_neu;
+					eKursFG2.kursart = GELeistungsdifferenzierteKursart.G.kuerzel;
+					zuviel--;
+				}
+				while (zuviel > 0) {
+					let eKursFG1 : GEAbschlussFach | null = faecher.fg1.getFach(this.filterEKurse);
+					if (eKursFG1 !== null) {
+						let note : number = eKursFG1.note;
+						let note_neu : number = (note === 1) ? 1 : note - 1;
+						this.logger.logLn(LogLevel.DEBUG, "   " + eKursFG1.kuerzel + ":(E)" + note + "->(G)" + note_neu);
+						eKursFG1.note = note_neu;
+						eKursFG1.kursart = GELeistungsdifferenzierteKursart.G.kuerzel;
+						zuviel--;
+					}
+					zuviel--;
+				}
+			}
+		this.logger.logLn(LogLevel.DEBUG, " -> FG1: Fächer " + faecher.fg1.toString().valueOf());
+		this.logger.logLn(LogLevel.DEBUG, " -> FG2: Fächer " + faecher.fg2.toString().valueOf());
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeDefizite(faecher, "");
+		if (abschlussergebnis.erworben) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => MSA (FOR): APO-SI §42 (3)");
+		} else 
+			if (AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis)) {
+				this.logger.logLn(LogLevel.INFO, " => kein MSA (FOR) - Nachprüfungsmöglichkeite(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf());
+			} else {
+				this.logger.logLn(LogLevel.INFO, " => kein MSA (FOR) - KEINE Nachprüfungsmöglichkeiten!");
+			}
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Prüft in Bezug auf Defizite, ob der Abschluss erworben wurde.
+	 * 
+	 * @param faecher      die Asbchlussfächer nach Fächergruppen sortiert
+	 * @param log_indent   die Einrückung für das Logging
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug die Defizitberechnung
+	 */
+	private pruefeDefizite(faecher : AbschlussFaecherGruppen, log_indent : String) : AbschlussErgebnis {
+		let ignorieren_genutzt : boolean = false;
+		let ausgleich_genutzt : boolean = false;
+		let nachpruefung_genutzt : boolean = false;
+		let npFaecher : List<GEAbschlussFach> = new Vector();
+		let fg1_defizite : number = faecher.fg1.getFaecherAnzahl(this.filterDefizite);
+		let fg2_defizite : number = faecher.fg2.getFaecherAnzahl(this.filterDefizite);
+		let fg1_anzahlAusgleiche : number = faecher.fg1.getFaecherAnzahl(this.filterAusgleiche);
+		if (fg1_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG1: Defizit" + (fg1_defizite > 1 ? "e" : "") + ": " + faecher.fg1.getKuerzelListe(this.filterDefizite).valueOf());
+		if (fg2_defizite > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG2: Defizit" + (fg2_defizite > 1 ? "e" : "") + ": " + faecher.fg2.getKuerzelListe(this.filterDefizite).valueOf());
+		if (faecher.fg1.getFaecherAnzahl(this.filterDefiziteMehrAls1NS) > 0) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> in FG1 unzulässig: mind. 1x6 oder bei einem G-Kurs 1x5");
+			return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+		}
+		if (faecher.fg2.getFaecherAnzahl(this.filterDefiziteMehrAls2NS) > 0) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> in FG2 unzulässig: in einem G-Kurs 1x6");
+			return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+		}
+		let sonstige_ungenuegend : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite2NS);
+		if (sonstige_ungenuegend.size() > 1) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite, kann nicht mehr als eine Note mit 6 (bzw. 5 bei einem G-Kurs) in FG2 unberücksichtigt lassen");
+			return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+		} else 
+			if (sonstige_ungenuegend.size() === 1) {
+				let defizitFach : GEAbschlussFach = sonstige_ungenuegend.get(0);
+				if (GELeistungsdifferenzierteKursart.Sonstige.hat(defizitFach.kursart)) {
+					defizitFach.ausgeglichen = true;
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> unberücksichtigt: Defizit in " + defizitFach.kuerzel + " (2 Notenstufen)");
+					ignorieren_genutzt = true;
+				} else 
+					if ((GELeistungsdifferenzierteKursart.E.hat(defizitFach.kursart)) && (defizitFach.note === 6)) {
+						this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> Ein ungenügend in dem E-Kurs " + defizitFach.kuerzel + " kann nicht ausgelichen werden und eine Nachprüfung ist nicht zulässig!");
+						return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+					} else {
+						this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> Nachprüfung muss falls möglich in " + defizitFach.kuerzel + " stattfinden!");
+						nachpruefung_genutzt = true;
+						npFaecher.add(defizitFach);
+						defizitFach.note--;
+					}
+			}
+		let wp_defizit : GEAbschlussFach | null = faecher.fg1.getFach(this.filterDefizitWP);
+		if ((fg1_defizite > 2) || ((fg1_defizite === 2) && (wp_defizit === null)) || ((fg1_defizite === 2) && (fg1_anzahlAusgleiche === 0)) || ((fg1_defizite === 1) && (wp_defizit === null) && (fg1_anzahlAusgleiche === 0))) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG1");
+			return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+		}
+		if ((fg1_defizite === 2) && (wp_defizit !== null)) {
+			if (nachpruefung_genutzt) {
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG1, eine Nachprüfung in mehreren Fächern (WP, " + sonstige_ungenuegend.get(0).kuerzel + ") ist nicht möglich!");
+				return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+			}
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> WP-Defizite in FG1, eine Nachprüfung ist, sofern möglich, in WP nötig!");
+			npFaecher.add(wp_defizit);
+			nachpruefung_genutzt = true;
+		}
+		if ((fg1_defizite === 2) || ((fg1_defizite === 1) && (wp_defizit === null))) {
+			ausgleich_genutzt = true;
+			let defizitFach : GEAbschlussFach | null = faecher.fg1.getFach(this.filterDefizitNichtWP);
+			if (defizitFach === null) 
+				throw new NullPointerException()
+			defizitFach.ausgeglichen = true;
+			let ausgleichsFach : GEAbschlussFach | null = faecher.fg1.getFach(this.filterAusgleiche);
+			if (ausgleichsFach === null) 
+				throw new NullPointerException()
+			ausgleichsFach.ausgleich = true;
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Gleiche das Defizit (FG1) in " + defizitFach.kuerzel + " mit " + ausgleichsFach.kuerzel + " (FG1) aus.");
+		}
+		if (((fg1_defizite === 1) && (wp_defizit !== null))) {
+			let defizitFach : GEAbschlussFach = wp_defizit;
+			let ausgleichsFach : GEAbschlussFach | null = faecher.fg1.getFach(this.filterAusgleiche);
+			if (ausgleichsFach !== null) {
+				ausgleich_genutzt = true;
+				defizitFach.ausgeglichen = true;
+				ausgleichsFach.ausgleich = true;
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe mit Ausgleich: Gleiche das Defizit (FG1) in " + defizitFach.kuerzel + " mit " + ausgleichsFach.kuerzel + " (FG1) aus. " + defizitFach.kuerzel + " alternativ als Nachprüfungsfach denkbar.");
+				let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, 2, ignorieren_genutzt, ausgleich_genutzt, nachpruefung_genutzt);
+				if (!abschlussergebnis.erworben && abschlussergebnis.npFaecher !== null && AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis) && wp_defizit.kuerzel !== null) 
+					abschlussergebnis.npFaecher.add(wp_defizit.kuerzel);
+				return abschlussergebnis;
+			}
+			if ((sonstige_ungenuegend.size() === 1) && (!sonstige_ungenuegend.get(0).ausgeglichen)) {
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> das Defizit in WP kann nicht ausgeglichen werden und eine Nachprüfung in mehreren Fächern (WP, " + sonstige_ungenuegend.get(0).kuerzel + ") ist nicht möglich!");
+				return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+			}
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> WP-Defizite in FG1 ohne Ausgleichsmöglichkeit, eine Nachprüfung ist, sofern möglich, in WP nötig!");
+			npFaecher.add(wp_defizit);
+			nachpruefung_genutzt = true;
+		}
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent, npFaecher, 2, ignorieren_genutzt, ausgleich_genutzt, nachpruefung_genutzt);
+		if ((nachpruefung_genutzt) && abschlussergebnis.erworben) 
+			return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA, AbschlussManager.getKuerzel(npFaecher));
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Führt eine Detailprüfung in der Fächergruppe 2 durch. Diese Methode wird ggf. mehrfach - auch rekursiv - aufgerufen. 
+	 * 
+	 * @param faecher                die Abschlussfächer nach Fächergruppen sortiert
+	 * @param log_indent             die Einrückung für das Logging
+	 * @param npFaecher              die Liste der Nachprüfungsfächer, die bisher schon feststehen
+	 * @param benoetige3er           die Anzahl der 3er, die noch in FG2 benötigt werden
+	 * @param ignorieren_genutzt     gibt an, ob die Möglichkeit eine defizitäre Leistung in FG2 zu ignorieren schon genutzt wurde 
+	 * @param ausgleich_genutzt      gibt an, ob die Möglichkeit des Ausgleichs über ein anderes Fach schon genutzt wurde
+	 * @param nachpruefung_genutzt   gibt an, ob die Nachprüfungsmöglichkeit bereits eingesetzt werden musste
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug auf den Stand dieser Detailprüfung
+	 */
+	private pruefeFG2(faecher : AbschlussFaecherGruppen, log_indent : String, npFaecher : List<GEAbschlussFach>, benoetige3er : number, ignorieren_genutzt : boolean, ausgleich_genutzt : boolean, nachpruefung_genutzt : boolean) : AbschlussErgebnis {
+		let defizite : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite);
+		let mangelhaft : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite1NS);
+		let hat_defizit : boolean = defizite.size() > 0;
+		let hat_defizit_sonstige_3er : boolean = faecher.fg2.getFaecherAnzahl(this.filterBenoetigte3er) < benoetige3er;
+		if ((!hat_defizit) && (!hat_defizit_sonstige_3er)) 
+			return AbschlussManager.getErgebnis(Abschluss.MSA, true);
+		if (!ignorieren_genutzt) {
+			for (let defizitFach of mangelhaft) {
+				if (!GELeistungsdifferenzierteKursart.Sonstige.hat(defizitFach.kursart)) 
+					continue;
+				defizitFach.ausgeglichen = true;
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe: Defizit unberücksichtigt in " + defizitFach.kuerzel);
+				let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, benoetige3er, true, ausgleich_genutzt, nachpruefung_genutzt);
+				if (abschlussergebnis.erworben) 
+					return abschlussergebnis;
+				defizitFach.ausgeglichen = false;
+			}
+		}
+		if (!ausgleich_genutzt) {
+			if (hat_defizit_sonstige_3er) {
+				let ausgleichsFach : GEAbschlussFach | null = faecher.fg2.getFach(this.filterAusgleiche3er);
+				if (ausgleichsFach === null) {
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Kein Ausgleich für eine fehlende 3 vorhanden. ");
+				} else {
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe: Ausgleich einer fehlende 3 durch " + ausgleichsFach.kuerzel);
+					ausgleichsFach.ausgleich = true;
+					let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, benoetige3er - 1, ignorieren_genutzt, true, nachpruefung_genutzt);
+					if (abschlussergebnis.erworben) 
+						return abschlussergebnis;
+					ausgleichsFach.ausgleich = false;
+				}
+			} else {
+				let ausgleichsFaecher : List<GEAbschlussFach> = faecher.getFaecher(this.filterAusgleiche);
+				if (ausgleichsFaecher.size() <= benoetige3er) {
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> kann Ausgleichsregelung nicht nutzen, da nicht genügend 3er-Fächer vorhanden sind.");
+				} else {
+					let anzahlSonstigeFaecherMind3 : number = faecher.fg2.getFaecherAnzahl(this.filterBenoetigte3er);
+					for (let defizitFach of defizite) {
+						for (let ausgleichsFach of ausgleichsFaecher) {
+							this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe: Ausgleich von " + defizitFach.kuerzel + " durch " + ausgleichsFach.kuerzel);
+							if ((GELeistungsdifferenzierteKursart.Sonstige.hat(ausgleichsFach.kursart)) && (anzahlSonstigeFaecherMind3 <= benoetige3er)) {
+								this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> " + ausgleichsFach.kuerzel + " nicht als Ausgleich möglich, da für die Mindestanforderung mind. " + benoetige3er + "x3 benötigt wird, aber nur " + anzahlSonstigeFaecherMind3 + "x3 zur Verfügung steht.");
+							} else {
+								defizitFach.ausgeglichen = true;
+								ausgleichsFach.ausgleich = true;
+								let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, benoetige3er, ignorieren_genutzt, true, nachpruefung_genutzt);
+								if (abschlussergebnis.erworben) 
+									return abschlussergebnis;
+								defizitFach.ausgeglichen = false;
+								ausgleichsFach.ausgleich = false;
+							}
+						}
+					}
+				}
+			}
+		}
+		if (!nachpruefung_genutzt) {
+			if (hat_defizit_sonstige_3er) {
+				let npKandidaten : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefiziteBenoetigte3erMitNPOption);
+				for (let defizitFach of npKandidaten) {
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe: Nachprüfung in " + defizitFach.kuerzel + " auf befriedigend möglich?");
+					defizitFach.ausgeglichen = true;
+					defizitFach.note--;
+					let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, benoetige3er, ignorieren_genutzt, ausgleich_genutzt, true);
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + (abschlussergebnis.erworben ? "   -> Ja!" : "   -> Nein!"));
+					if (abschlussergebnis.erworben) 
+						npFaecher.add(defizitFach);
+					defizitFach.note++;
+					defizitFach.ausgeglichen = false;
+				}
+			} else {
+				let npKandidaten : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefiziteMitNPOption);
+				for (let defizitFach of npKandidaten) {
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe: Nachprüfung in " + defizitFach.kuerzel + " möglich?");
+					defizitFach.ausgeglichen = true;
+					defizitFach.note--;
+					let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, benoetige3er, ignorieren_genutzt, ausgleich_genutzt, true);
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + (abschlussergebnis.erworben ? "   -> Ja!" : "   -> Nein!"));
+					if (abschlussergebnis.erworben) 
+						npFaecher.add(defizitFach);
+					defizitFach.note++;
+					defizitFach.ausgeglichen = false;
+				}
+			}
+		}
+		if ((!nachpruefung_genutzt) && (npFaecher.size() > 0)) 
+			return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA, AbschlussManager.getKuerzel(npFaecher));
+		return AbschlussManager.getErgebnis(Abschluss.MSA, false);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.ge.ServiceAbschlussMSA', 'de.nrw.schule.svws.core.Service'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussMSA(obj : unknown) : ServiceAbschlussMSA {
+	return obj as ServiceAbschlussMSA;
+}

+ 288 - 0
core/abschluss/ge/ServiceBerechtigungMSAQ.ts

@@ -0,0 +1,288 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../core/Service';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GELeistungsdifferenzierteKursart, cast_de_nrw_schule_svws_core_types_ge_GELeistungsdifferenzierteKursart } from '../../../core/types/ge/GELeistungsdifferenzierteKursart';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../logger/LogLevel';
+import { Predicate, cast_java_util_function_Predicate } from '../../../java/util/function/Predicate';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../../core/data/abschluss/GEAbschlussFaecher';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../../core/data/abschluss/AbschlussErgebnis';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
+import { ServiceAbschlussMSA, cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussMSA } from '../../../core/abschluss/ge/ServiceAbschlussMSA';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../core/types/Abschluss';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { AbschlussFaecherGruppen, cast_de_nrw_schule_svws_core_abschluss_ge_AbschlussFaecherGruppen } from '../../../core/abschluss/ge/AbschlussFaecherGruppen';
+
+export class ServiceBerechtigungMSAQ extends Service<GEAbschlussFaecher, AbschlussErgebnis> {
+
+	private filterDefizite : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note > 3) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 2)) };
+
+	private filterDefizite1NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => ((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 4)) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 3)) };
+
+	private filterDefizite2NS : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => ((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 5)) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note === 4)) };
+
+	private filterDefizitWP : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note > 3) && JavaString.equalsIgnoreCase("WP", f.kuerzel) };
+
+	private filterDefizitNichtWP : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note > 3) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 2)) && !JavaString.equalsIgnoreCase("WP", f.kuerzel) };
+
+	private filterFG1NichtAusgleichbar : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note > 4) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 3)) };
+
+	private filterFG2NichtAusgleichbar : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (f.note > 5) || ((GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note > 3)) };
+
+	private filterAusgleiche : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => !f.ausgleich && ((f.note < 2) || ((!GELeistungsdifferenzierteKursart.G.hat(f.kursart)) && (f.note < 3))) };
+
+	private filterEKurse : Predicate<GEAbschlussFach> = { test : (f: GEAbschlussFach) => (GELeistungsdifferenzierteKursart.E.hat(f.kursart)) };
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Führt die Abschlussberechnung (bzw. Berechtigungsberechnung) anhand der übergebenen 
+	 * Abschlussfächer durch und gibt das Berechnungsergebnis zurück.
+	 * 
+	 * @param input    die Abschlussfächer
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung
+	 */
+	public handle(input : GEAbschlussFaecher) : AbschlussErgebnis {
+		this.logger.logLn(LogLevel.INFO, "Prüfe MSA-Q:");
+		this.logger.logLn(LogLevel.DEBUG, "============");
+		if ((input.faecher === null) || (!AbschlussManager.pruefeHat4LeistungsdifferenzierteFaecher(input))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht genügend leistungsdifferenzierte Fächer gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (!AbschlussManager.pruefeKuerzelDuplikate(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden Fächer mit dem gleichen Kürzel zur Abschlussprüfung übergeben. Dies ist nicht zulässig.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let faecher : AbschlussFaecherGruppen = ServiceAbschlussMSA.getFaechergruppen(input.faecher);
+		if (!faecher.fg1.istVollstaendig(Arrays.asList("D", "M", "E", "WP"))) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Es wurden nicht alle nötigen Leistungen für die Fächergruppe 1 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		if (faecher.fg2.isEmpty()) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.DEBUG, " => Fehler: Keine Leistungen für die Fächergruppe 2 gefunden.");
+			return AbschlussManager.getErgebnis(null, false);
+		}
+		let anzahlEKurse : number = faecher.getFaecherAnzahl(this.filterEKurse);
+		if (anzahlEKurse < 3) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => kein MSA-Q (FOR-Q) - nicht genügend E-Kurse belegt");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+		} else 
+			if (anzahlEKurse > 3) {
+				this.logger.logLn(LogLevel.DEBUG, " - Verbessern der E-Kurs-Noten für die Defizitberechnung, falls mehr als 3 E-Kurse vorhanden sind:");
+				let tmpFaecher : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterEKurse);
+				for (let f of tmpFaecher) {
+					let note : number = f.note;
+					let note_neu : number = (note === 1) ? 1 : note - 1;
+					this.logger.logLn(LogLevel.DEBUG, "   " + f.kuerzel + ":(E)" + note + "->(G)" + note_neu);
+					f.note = note_neu;
+					f.kursart = GELeistungsdifferenzierteKursart.G.kuerzel;
+				}
+			}
+		this.logger.logLn(LogLevel.DEBUG, " -> FG1: Fächer " + faecher.fg1.toString().valueOf());
+		this.logger.logLn(LogLevel.DEBUG, " -> FG2: Fächer " + faecher.fg2.toString().valueOf());
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeDefizite(faecher, "");
+		if (abschlussergebnis.erworben) {
+			this.logger.logLn(LogLevel.DEBUG, "______________________________");
+			this.logger.logLn(LogLevel.INFO, " => MSA-Q (FOR-Q): APO-SI §43 (4)");
+		} else 
+			if (AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis)) {
+				this.logger.logLn(LogLevel.INFO, " => kein MSA-Q (FOR-Q) - Nachprüfungsmöglichkeite(en) in " + AbschlussManager.getNPFaecherString(abschlussergebnis).valueOf());
+			} else {
+				this.logger.logLn(LogLevel.INFO, " => kein MSA-Q (FOR-Q) - KEINE Nachprüfungsmöglichkeiten!");
+			}
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Prüft in Bezug auf Defizite, ob der Abschluss erworben wurde.
+	 * 
+	 * @param faecher      die Asbchlussfächer nach Fächergruppen sortiert
+	 * @param log_indent   die Einrückung für das Logging
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug die Defizitberechnung
+	 */
+	private pruefeDefizite(faecher : AbschlussFaecherGruppen, log_indent : String) : AbschlussErgebnis {
+		let fg1_defizite : List<GEAbschlussFach> = faecher.fg1.getFaecher(this.filterDefizite);
+		let fg2_defizite : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite);
+		if (fg1_defizite.size() > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG1: Defizit" + (fg1_defizite.size() > 1 ? "e" : "") + ": " + faecher.fg1.getKuerzelListe(this.filterDefizite).valueOf());
+		if (fg2_defizite.size() > 0) 
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> FG2: Defizit" + (fg2_defizite.size() > 1 ? "e" : "") + ": " + faecher.fg2.getKuerzelListe(this.filterDefizite).valueOf());
+		let nachpruefung_genutzt : boolean = false;
+		let npFaecher : List<GEAbschlussFach> = new Vector();
+		let fg1_nicht_ausgleichbar : List<GEAbschlussFach> = faecher.fg1.getFaecher(this.filterFG1NichtAusgleichbar);
+		let fg2_nicht_ausgleichbar : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterFG2NichtAusgleichbar);
+		if ((fg1_nicht_ausgleichbar.size() > 0) || (fg2_nicht_ausgleichbar.size() > 0)) {
+			let str_faecher : String = faecher.getKuerzelListe(this.filterFG1NichtAusgleichbar, this.filterFG2NichtAusgleichbar);
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Defizit(e) in " + str_faecher.valueOf() + " aufgrund zu hoher Abweichungen nicht ausgleichbar.");
+			if ((fg1_nicht_ausgleichbar.size() === 0) && (fg2_nicht_ausgleichbar.size() === 1) && (GELeistungsdifferenzierteKursart.G.hat(fg2_nicht_ausgleichbar.get(0).kursart)) && (fg2_nicht_ausgleichbar.get(0).note === 4)) {
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> Nachprüfung muss falls möglich in " + fg2_nicht_ausgleichbar.get(0).kuerzel + " stattfinden!");
+				nachpruefung_genutzt = true;
+				npFaecher.add(fg2_nicht_ausgleichbar.get(0));
+			} else {
+				return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+			}
+		}
+		let fg1_ausgleichsfaecher : List<GEAbschlussFach> = faecher.fg1.getFaecher(this.filterAusgleiche);
+		let wp_defizit : GEAbschlussFach | null = faecher.fg1.getFach(this.filterDefizitWP);
+		if ((fg1_defizite.size() > 2) || ((fg1_defizite.size() === 2) && (wp_defizit === null))) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG1");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+		} else 
+			if ((fg1_defizite.size() === 2) && (wp_defizit !== null) && (fg1_ausgleichsfaecher.size() === 0)) {
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG1 - kein Ausgleich möglich");
+				return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+			} else 
+				if ((fg1_defizite.size() === 2) && (wp_defizit !== null) && (fg1_ausgleichsfaecher.size() > 0) && (!nachpruefung_genutzt)) {
+					let defizitFach : GEAbschlussFach | null = faecher.fg1.getFach(this.filterDefizitNichtWP);
+					if (defizitFach === null) 
+						throw new NullPointerException()
+					let ausgleichsFach : GEAbschlussFach = fg1_ausgleichsfaecher.get(0);
+					defizitFach.ausgeglichen = true;
+					ausgleichsFach.ausgleich = true;
+					this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Ausgleich von " + defizitFach.kuerzel + " durch " + ausgleichsFach.kuerzel);
+					nachpruefung_genutzt = true;
+					npFaecher.add(wp_defizit);
+					let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent, npFaecher, nachpruefung_genutzt);
+					if (abschlussergebnis.erworben) {
+						return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA_Q, AbschlussManager.getKuerzel(npFaecher));
+					}
+					return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+				}
+		if ((fg1_defizite.size() === 1) && (wp_defizit === null) && (fg1_ausgleichsfaecher.size() === 0)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> kein Defizit-Ausgleich in FG1");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+		}
+		if ((fg1_defizite.size() === 1) && (wp_defizit === null)) {
+			let defizitFach : GEAbschlussFach | null = faecher.fg1.getFach(this.filterDefizitNichtWP);
+			if (defizitFach === null) 
+				throw new NullPointerException()
+			let ausgleichsFach : GEAbschlussFach = fg1_ausgleichsfaecher.get(0);
+			defizitFach.ausgeglichen = true;
+			ausgleichsFach.ausgleich = true;
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Ausgleich von " + defizitFach.kuerzel + " durch " + ausgleichsFach.kuerzel);
+		}
+		if ((fg1_defizite.size() === 1) && (wp_defizit !== null)) {
+			if ((fg1_ausgleichsfaecher.size() > 0)) {
+				let defizitFach : GEAbschlussFach = wp_defizit;
+				let ausgleichsFach : GEAbschlussFach = fg1_ausgleichsfaecher.get(0);
+				defizitFach.ausgeglichen = true;
+				ausgleichsFach.ausgleich = true;
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe FG2 mit der Option Ausgleich von " + defizitFach.kuerzel + " durch " + ausgleichsFach.kuerzel);
+				let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, nachpruefung_genutzt);
+				if (abschlussergebnis.erworben) 
+					return abschlussergebnis;
+				defizitFach.ausgeglichen = false;
+				ausgleichsFach.ausgleich = false;
+			}
+			if (nachpruefung_genutzt) {
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Eine Nachprüfung im WP-Fach und in dem leistungsdifferenzierten Fach der FG2 ist nicht gleichzeitig möglich.");
+				return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+			}
+			wp_defizit.ausgleich = true;
+			wp_defizit.note--;
+			let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent, npFaecher, true);
+			wp_defizit.note++;
+			wp_defizit.ausgleich = false;
+			if (abschlussergebnis.erworben) {
+				nachpruefung_genutzt = true;
+				npFaecher.add(wp_defizit);
+			}
+			return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA_Q, AbschlussManager.getKuerzel(npFaecher));
+		}
+		let log_fg2_indent : String = log_indent;
+		if (fg2_nicht_ausgleichbar.size() === 1) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe FG2 mit Nachprüfung in " + fg2_nicht_ausgleichbar.get(0).kuerzel);
+			log_fg2_indent += "  ";
+		}
+		let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_fg2_indent, npFaecher, nachpruefung_genutzt);
+		if (((fg2_nicht_ausgleichbar.size() === 1) && abschlussergebnis.erworben) || ((!abschlussergebnis.erworben) && (AbschlussManager.hatNachpruefungsmoeglichkeit(abschlussergebnis)))) {
+			return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA_Q, AbschlussManager.getKuerzel(npFaecher));
+		}
+		return abschlussergebnis;
+	}
+
+	/**
+	 * Führt eine Detailprüfung in der Fächergruppe 2 durch. Diese Methode wird ggf. mehrfach - auch rekursiv - aufgerufen. 
+	 * 
+	 * @param faecher                die Abschlussfächer nach Fächergruppen sortiert
+	 * @param log_indent             die Einrückung für das Logging
+	 * @param npFaecher              die Liste der Nachprüfungsfächer, die bisher schon feststehen
+	 * @param nachpruefung_genutzt   gibt an, ob die Nachprüfungsmöglichkeit bereits eingesetzt werden musste
+	 * 
+	 * @return das Ergebnis der Abschlussberechnung in Bezug auf den Stand dieser Detailprüfung
+	 */
+	private pruefeFG2(faecher : AbschlussFaecherGruppen, log_indent : String, npFaecher : List<GEAbschlussFach>, nachpruefung_genutzt : boolean) : AbschlussErgebnis {
+		let ges_ausgleichsfaecher : List<GEAbschlussFach> = faecher.getFaecher(this.filterAusgleiche);
+		let fg2_defizite_1NS : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite1NS);
+		let fg2_defizite_2NS : List<GEAbschlussFach> = faecher.fg2.getFaecher(this.filterDefizite2NS);
+		let fg2_defizit_anzahl : number = fg2_defizite_1NS.size() + fg2_defizite_2NS.size();
+		if (fg2_defizit_anzahl === 0) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> keine Defizite in FG2");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, true);
+		}
+		if ((fg2_defizite_2NS.size() > 2) || (fg2_defizit_anzahl > (nachpruefung_genutzt ? 3 : 4))) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG2 - mit Ausgleich und Nachprüfung kein Abschluss möglich");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+		}
+		if (ges_ausgleichsfaecher.size() < fg2_defizit_anzahl - (nachpruefung_genutzt ? 0 : 1)) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> zu viele Defizite in FG2 - nicht genügend Ausgleichsfächer vorhanden");
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, false);
+		}
+		if (fg2_defizite_2NS.size() === 2) {
+			for (let defizitFach of fg2_defizite_2NS) {
+				defizitFach.ausgeglichen = true;
+				defizitFach.ausgleich = true;
+				defizitFach.note--;
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe erneut mit Nachprüfung in " + defizitFach.kuerzel);
+				let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, true);
+				this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> Nachprüfung in " + defizitFach.kuerzel + (abschlussergebnis.erworben ? " möglich" : " nicht möglich"));
+				if (abschlussergebnis.erworben) 
+					npFaecher.add(defizitFach);
+				defizitFach.ausgeglichen = true;
+				defizitFach.ausgleich = true;
+				defizitFach.note++;
+			}
+			return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA_Q, AbschlussManager.getKuerzel(npFaecher));
+		}
+		if (ges_ausgleichsfaecher.size() >= fg2_defizit_anzahl) {
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> genug Ausgleichsfächer vorhanden." + (nachpruefung_genutzt ? "" : " Nachprüfung nicht nötig."));
+			return AbschlussManager.getErgebnis(Abschluss.MSA_Q, true);
+		}
+		for (let defizitFach of fg2_defizite_1NS) {
+			defizitFach.ausgeglichen = true;
+			defizitFach.ausgleich = true;
+			defizitFach.note--;
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + " -> Prüfe erneut mit Nachprüfung in " + defizitFach.kuerzel);
+			let abschlussergebnis : AbschlussErgebnis = this.pruefeFG2(faecher, log_indent.valueOf() + "  ", npFaecher, true);
+			this.logger.logLn(LogLevel.DEBUG, log_indent.valueOf() + "   -> Nachprüfung in " + defizitFach.kuerzel + (abschlussergebnis.erworben ? " möglich" : " nicht möglich"));
+			if (abschlussergebnis.erworben) 
+				npFaecher.add(defizitFach);
+			defizitFach.ausgeglichen = true;
+			defizitFach.ausgleich = true;
+			defizitFach.note++;
+		}
+		return AbschlussManager.getErgebnisNachpruefung(Abschluss.MSA_Q, AbschlussManager.getKuerzel(npFaecher));
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.ge.ServiceBerechtigungMSAQ'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_ServiceBerechtigungMSAQ(obj : unknown) : ServiceBerechtigungMSAQ {
+	return obj as ServiceBerechtigungMSAQ;
+}

+ 121 - 0
core/abschluss/ge/ServicePrognose.ts

@@ -0,0 +1,121 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { ServiceAbschlussHA10, cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussHA10 } from '../../../core/abschluss/ge/ServiceAbschlussHA10';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../core/Service';
+import { ServiceBerechtigungMSAQ, cast_de_nrw_schule_svws_core_abschluss_ge_ServiceBerechtigungMSAQ } from '../../../core/abschluss/ge/ServiceBerechtigungMSAQ';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../logger/LogLevel';
+import { GEAbschlussFaecher, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher } from '../../../core/data/abschluss/GEAbschlussFaecher';
+import { AbschlussErgebnis, cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis } from '../../../core/data/abschluss/AbschlussErgebnis';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { ServiceAbschlussMSA, cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussMSA } from '../../../core/abschluss/ge/ServiceAbschlussMSA';
+import { Abschluss, cast_de_nrw_schule_svws_core_types_Abschluss } from '../../../core/types/Abschluss';
+import { AbschlussManager, cast_de_nrw_schule_svws_core_abschluss_AbschlussManager } from '../../../core/abschluss/AbschlussManager';
+import { ServiceAbschlussHA9, cast_de_nrw_schule_svws_core_abschluss_ge_ServiceAbschlussHA9 } from '../../../core/abschluss/ge/ServiceAbschlussHA9';
+
+export class ServicePrognose extends Service<GEAbschlussFaecher, AbschlussErgebnis> {
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Prüft, ob Lernbereichsnoten bei den Sbchlussfächern zur Verfügung stehen oder nicht.
+	 * 
+	 * @param faecher   die Abschlussfächer
+	 * 
+	 * @return true, falls die Lernbereichsnoten vorhanden sind, ansonsten false
+	 */
+	private static hatLernbereichsnoten(faecher : GEAbschlussFaecher) : boolean {
+		let hatLBNW : boolean = false;
+		let hatLBAL : boolean = false;
+		if (faecher.faecher === null) 
+			return false;
+		let tmp : List<GEAbschlussFach> = faecher.faecher;
+		for (let fach of tmp) {
+			if (fach === null) 
+				continue;
+			hatLBNW = hatLBNW || JavaObject.equalsTranspiler("LBNW", (fach.kuerzel));
+			hatLBAL = hatLBAL || JavaObject.equalsTranspiler("LBAL", (fach.kuerzel));
+		}
+		return hatLBNW && hatLBAL;
+	}
+
+	/**
+	 * Führt die Prognoseberechnung anhand der übergebenen Abschlussfächer durch
+	 * und gibt das Berechnungsergebnis zurück.
+	 * 
+	 * @param input    die Abschlussfächer
+	 * 
+	 * @return das Ergebnis der Prognoseberechnung
+	 */
+	public handle(input : GEAbschlussFaecher) : AbschlussErgebnis {
+		if (!AbschlussManager.pruefeHat4LeistungsdifferenzierteFaecher(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "Fehler: Es wurden nicht genügend leistungsdiffernzierte Fächer gefunden.");
+			let prognose : AbschlussErgebnis = AbschlussManager.getErgebnis(null, false);
+			prognose.log = this.log.getStrings();
+			return prognose;
+		}
+		if (!AbschlussManager.pruefeKuerzelDuplikate(input)) {
+			this.logger.logLn(LogLevel.DEBUG, "Fehler: Es wurden Fächer mit dem gleichen Kürzel zur Abschlussprüfung übergeben. Dies ist nicht zulässig.");
+			let prognose : AbschlussErgebnis = AbschlussManager.getErgebnis(null, false);
+			prognose.log = this.log.getStrings();
+			return prognose;
+		}
+		let abschluss : Abschluss = Abschluss.OHNE_ABSCHLUSS;
+		let np_faecher : List<String> | null = null;
+		if (!JavaObject.equalsTranspiler("10", (input.jahrgang))) {
+			let ha9 : ServiceAbschlussHA9 = new ServiceAbschlussHA9();
+			let ha9output : AbschlussErgebnis = ha9.handle(input);
+			np_faecher = ha9output.npFaecher;
+			if (ha9output.erworben) 
+				abschluss = Abschluss.HA9;
+			this.log.append(ha9.getLog());
+			this.logger.logLn(LogLevel.INFO, "");
+		} else 
+			if (JavaObject.equalsTranspiler("10", (input.jahrgang))) {
+				abschluss = Abschluss.HA9;
+			}
+		let ha10 : ServiceAbschlussHA10 = new ServiceAbschlussHA10();
+		let ha10output : AbschlussErgebnis = ha10.handle(input);
+		if (ha10output.erworben) 
+			abschluss = Abschluss.HA10; else 
+			if (JavaObject.equalsTranspiler("10", (input.jahrgang)) || (JavaObject.equalsTranspiler(Abschluss.HA9, (abschluss)))) 
+				np_faecher = ha10output.npFaecher;
+		this.log.append(ha10.getLog());
+		if ((!JavaObject.equalsTranspiler(Abschluss.OHNE_ABSCHLUSS, (abschluss))) || (!ServicePrognose.hatLernbereichsnoten(input))) {
+			let msa : ServiceAbschlussMSA = new ServiceAbschlussMSA();
+			let msaOutput : AbschlussErgebnis = msa.handle(input);
+			this.logger.logLn(LogLevel.INFO, "");
+			this.log.append(msa.getLog());
+			if (msaOutput.erworben) {
+				abschluss = Abschluss.MSA;
+				let msaq : ServiceBerechtigungMSAQ = new ServiceBerechtigungMSAQ();
+				let msaqOutput : AbschlussErgebnis = msaq.handle(input);
+				if (msaqOutput.erworben) {
+					abschluss = Abschluss.MSA_Q;
+				} else {
+					np_faecher = msaqOutput.npFaecher;
+				}
+				this.logger.logLn(LogLevel.INFO, "");
+				this.log.append(msaq.getLog());
+			} else {
+				np_faecher = msaOutput.npFaecher;
+			}
+		}
+		let prognose : AbschlussErgebnis = AbschlussManager.getErgebnisNachpruefung(abschluss, np_faecher);
+		prognose.erworben = (!JavaObject.equalsTranspiler(Abschluss.OHNE_ABSCHLUSS, (abschluss)));
+		prognose.log = this.log.getStrings();
+		return prognose;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.ge.ServicePrognose'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_ge_ServicePrognose(obj : unknown) : ServicePrognose {
+	return obj as ServicePrognose;
+}

+ 1494 - 0
core/abschluss/gost/AbiturdatenManager.ts

@@ -0,0 +1,1494 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { Naturwissenschaften, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Naturwissenschaften } from '../../../core/abschluss/gost/belegpruefung/Naturwissenschaften';
+import { SprachendatenManager, cast_de_nrw_schule_svws_core_SprachendatenManager } from '../../../core/SprachendatenManager';
+import { Schwerpunkt, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Schwerpunkt } from '../../../core/abschluss/gost/belegpruefung/Schwerpunkt';
+import { HashMap, cast_java_util_HashMap } from '../../../java/util/HashMap';
+import { KurszahlenUndWochenstunden, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_KurszahlenUndWochenstunden } from '../../../core/abschluss/gost/belegpruefung/KurszahlenUndWochenstunden';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { AbiturFachbelegungHalbjahr, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr } from '../../../core/data/gost/AbiturFachbelegungHalbjahr';
+import { GostBesondereLernleistung, cast_de_nrw_schule_svws_core_types_gost_GostBesondereLernleistung } from '../../../core/types/gost/GostBesondereLernleistung';
+import { GostBelegpruefungErgebnis, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnis } from '../../../core/abschluss/gost/GostBelegpruefungErgebnis';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GostKursart, cast_de_nrw_schule_svws_core_types_gost_GostKursart } from '../../../core/types/gost/GostKursart';
+import { Latinum, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Latinum } from '../../../core/abschluss/gost/belegpruefung/Latinum';
+import { Sprachendaten, cast_de_nrw_schule_svws_core_data_Sprachendaten } from '../../../core/data/Sprachendaten';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../core/types/gost/GostFachbereich';
+import { Allgemeines, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Allgemeines } from '../../../core/abschluss/gost/belegpruefung/Allgemeines';
+import { Sport, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Sport } from '../../../core/abschluss/gost/belegpruefung/Sport';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../core/types/gost/GostHalbjahr';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../core/types/gost/GostSchriftlichkeit';
+import { ZulaessigesFach, cast_de_nrw_schule_svws_core_types_statkue_ZulaessigesFach } from '../../../core/types/statkue/ZulaessigesFach';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+import { Collections, cast_java_util_Collections } from '../../../java/util/Collections';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { GesellschaftswissenschaftenUndReligion, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_GesellschaftswissenschaftenUndReligion } from '../../../core/abschluss/gost/belegpruefung/GesellschaftswissenschaftenUndReligion';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../core/abschluss/gost/GostBelegungsfehler';
+import { AbiFaecher, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_AbiFaecher } from '../../../core/abschluss/gost/belegpruefung/AbiFaecher';
+import { HashSet, cast_java_util_HashSet } from '../../../java/util/HashSet';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../core/data/gost/GostFach';
+import { LiterarischKuenstlerisch, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_LiterarischKuenstlerisch } from '../../../core/abschluss/gost/belegpruefung/LiterarischKuenstlerisch';
+import { GostAbiturFach, cast_de_nrw_schule_svws_core_types_gost_GostAbiturFach } from '../../../core/types/gost/GostAbiturFach';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../core/abschluss/gost/GostBelegpruefung';
+import { GostFachManager, cast_de_nrw_schule_svws_core_abschluss_gost_GostFachManager } from '../../../core/abschluss/gost/GostFachManager';
+import { Abiturdaten, cast_de_nrw_schule_svws_core_data_gost_Abiturdaten } from '../../../core/data/gost/Abiturdaten';
+import { Projektkurse, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Projektkurse } from '../../../core/abschluss/gost/belegpruefung/Projektkurse';
+import { Deutsch, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Deutsch } from '../../../core/abschluss/gost/belegpruefung/Deutsch';
+import { Fremdsprachen, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Fremdsprachen } from '../../../core/abschluss/gost/belegpruefung/Fremdsprachen';
+import { GostBelegpruefungErgebnisFehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnisFehler } from '../../../core/abschluss/gost/GostBelegpruefungErgebnisFehler';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { Mathematik, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Mathematik } from '../../../core/abschluss/gost/belegpruefung/Mathematik';
+
+export class AbiturdatenManager extends JavaObject {
+
+	private readonly abidaten : Abiturdaten;
+
+	private readonly gostFaecher : HashMap<Number, GostFach>;
+
+	private readonly pruefungsArt : GostBelegpruefungsArt;
+
+	private readonly mapFachbereiche : HashMap<GostFachbereich, Vector<AbiturFachbelegung>> = new HashMap();
+
+	private belegpruefungen : Vector<GostBelegpruefung> = new Vector();
+
+	private belegpruefungsfehler : Vector<GostBelegungsfehler> = new Vector();
+
+	private belegpruefungErfolgreich : boolean = false;
+
+
+	/**
+	 * Erstellt ein neues Manager-Objekt, welches mit den übergebenen Abiturdaten verknüpft wird.
+	 * 
+	 * @param abidaten       die Abiturdaten
+	 * @param gostFaecher    die Fächer der Gymnasialen Oberstufe, die bei dem Abiturjahrgang zur Verfügung stehen. 
+	 * @param pruefungsArt   die Art der Belegpruefung (z.B. EF1 oder GESAMT)
+	 */
+	public constructor(abidaten : Abiturdaten, gostFaecher : List<GostFach>, pruefungsArt : GostBelegpruefungsArt) {
+		super();
+		this.abidaten = abidaten;
+		this.gostFaecher = new HashMap();
+		for (let i : number = 0; i < gostFaecher.size(); i++){
+			let fach : GostFach | null = gostFaecher.get(i);
+			if (fach !== null) 
+				this.gostFaecher.put(fach.id, fach);
+		}
+		this.pruefungsArt = pruefungsArt;
+		this.init();
+	}
+
+	/**
+	 * Führt die Belegprüfung der Art pruefungs_art für einen Schüler durch, dessen Abiturdaten mit dem angegebenen 
+	 * Manager verwaltet werden.
+	 * 
+	 * @param pruefungs_art    die Art der Prüfung, die durchgeführt wird
+	 * 
+	 * @return eine Liste mit den durchgefuehrten Belegpruefungen
+	 */
+	public getPruefungen(pruefungs_art : GostBelegpruefungsArt) : Vector<GostBelegpruefung> {
+		let pruefungen : Vector<GostBelegpruefung> = new Vector();
+		pruefungen.add(new Deutsch(this, pruefungs_art));
+		let pruefungFremdsprachen : Fremdsprachen = new Fremdsprachen(this, pruefungs_art);
+		pruefungen.add(pruefungFremdsprachen);
+		pruefungen.add(new Latinum(this, pruefungs_art));
+		pruefungen.add(new LiterarischKuenstlerisch(this, pruefungs_art));
+		pruefungen.add(new GesellschaftswissenschaftenUndReligion(this, pruefungs_art));
+		pruefungen.add(new Mathematik(this, pruefungs_art));
+		let pruefungNaturwissenschaften : Naturwissenschaften = new Naturwissenschaften(this, pruefungs_art);
+		pruefungen.add(pruefungNaturwissenschaften);
+		pruefungen.add(new Sport(this, pruefungs_art));
+		let pruefungProjektkurse : Projektkurse = new Projektkurse(this, pruefungs_art);
+		pruefungen.add(pruefungProjektkurse);
+		pruefungen.add(new Schwerpunkt(this, pruefungs_art, pruefungFremdsprachen, pruefungNaturwissenschaften));
+		pruefungen.add(new AbiFaecher(this, pruefungs_art));
+		pruefungen.add(new KurszahlenUndWochenstunden(this, pruefungs_art, pruefungProjektkurse));
+		pruefungen.add(new Allgemeines(this, pruefungs_art));
+		return pruefungen;
+	}
+
+	/**
+	 * Initialisiert bzw. reinitialisert die Datenstrukturen, die für den schnellen Zugriff auf die Daten
+	 * eingerichtet werden. 
+	 */
+	public init() : void {
+		if (this.abidaten === null) 
+			return;
+		this.initMapFachbereiche();
+		this.belegpruefungen = this.getPruefungen(this.pruefungsArt);
+		for (let i : number = 0; i < this.belegpruefungen.size(); i++){
+			let belegpruefung : GostBelegpruefung = this.belegpruefungen.get(i);
+			belegpruefung.pruefe();
+		}
+		this.belegpruefungsfehler = GostBelegpruefung.getBelegungsfehlerAlle(this.belegpruefungen);
+		this.belegpruefungErfolgreich = GostBelegpruefung.istErfolgreich(this.belegpruefungsfehler);
+	}
+
+	/**
+	 * Initialisiert bzw. reinitialisiert die Map für den schnellen Zugriff auf Fachbelegungen
+	 * anhand des Fachbereichs. 
+	 */
+	private initMapFachbereiche() : void {
+		this.mapFachbereiche.clear();
+		let fachbereiche : List<GostFachbereich> = GostFachbereich.values();
+		for (let fachbereich of fachbereiche) {
+			this.mapFachbereiche.put(fachbereich, new Vector<AbiturFachbelegung>());
+		}
+		let fachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.zaehleBelegung(fachbelegung) > 0) {
+				fachbereiche = GostFachbereich.getBereiche(this.getFach(fachbelegung));
+				for (let fachbereich of fachbereiche) {
+					let listFachbelegungen : Vector<AbiturFachbelegung> | null = this.mapFachbereiche.get(fachbereich);
+					if (listFachbelegungen === null) 
+						continue;
+					listFachbelegungen.add(fachbelegung);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Liefert die in den Abiturdaten enthaltenen Sprachendaten.
+	 *
+	 * @return Die Sprachendaten (siehe {@link Sprachendaten})
+	 */
+	public getSprachendaten() : Sprachendaten | null {
+		return this.abidaten.sprachendaten;
+	}
+
+	/**
+	 * Berechnet die Wochenstunden, welche von dem Schüler in den einzelnen 
+	 * Halbjahren der gymnasialen Oberstufe für das Abitur relevant belegt wurden.
+	 * 
+	 * @return ein Array mit den Wochenstunden für die sechs Halbjahre 
+	 */
+	public getWochenstunden() : Array<number> | null {
+		let stunden : Array<number> | null = [0, 0, 0, 0, 0, 0];
+		for (let i : number = 0; i < 6; i++){
+			for (let fb of this.abidaten.fachbelegungen) {
+				let hjb : AbiturFachbelegungHalbjahr | null = fb.belegungen[i];
+				if ((hjb === null) || (JavaObject.equalsTranspiler("AT", (hjb.kursartKuerzel)))) 
+					continue;
+				stunden[i] += hjb.wochenstunden;
+			}
+		}
+		return stunden;
+	}
+
+	/**
+	 * Berechnet die Anzahl der anrechenbaren Kurse, welche von dem Schüler in den einzelnen 
+	 * Halbjahren der gymnasialen Oberstufe für das Abitur belegt wurden.
+	 * 
+	 * @return ein Array mit den anrechenbaren Kursen für die sechs Halbjahre 
+	 */
+	public getAnrechenbareKurse() : Array<number> | null {
+		let anzahl : Array<number> | null = [0, 0, 0, 0, 0, 0];
+		let bll : GostBesondereLernleistung | null = GostBesondereLernleistung.fromKuerzel(this.abidaten.besondereLernleistung);
+		for (let i : number = 0; i < 6; i++){
+			for (let fb of this.abidaten.fachbelegungen) {
+				let hjb : AbiturFachbelegungHalbjahr | null = fb.belegungen[i];
+				if ((hjb === null) || (JavaObject.equalsTranspiler("AT", (hjb.kursartKuerzel)))) 
+					continue;
+				let kursart : GostKursart | null = GostKursart.fromKuerzel(hjb.kursartKuerzel);
+				if ((kursart as unknown !== GostKursart.VTF as unknown) && (!((kursart as unknown === GostKursart.PJK as unknown) && (bll as unknown === GostBesondereLernleistung.PROJEKTKURS as unknown)))) 
+					anzahl[i]++;
+			}
+		}
+		return anzahl;
+	}
+
+	/**
+	 * Liefert das Fach der gymnasialen Oberstufe für die angegeben Abiturfachbelegung.
+	 * 
+	 * @param belegung   die Fachbelegung (siehe {@link AbiturFachbelegung})
+	 * 
+	 * @return das Fach der gymnasialen Oberstufe (siehe {@link GostFach}) 
+	 */
+	public getFach(belegung : AbiturFachbelegung | null) : GostFach | null {
+		if (belegung === null) 
+			return null;
+		return this.gostFaecher.get(belegung.fachID);
+	}
+
+	/**
+	 * Prüft, ob das Faches in allen angegebenen Halbjahren belegt wurde.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachbelegung
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls das Fach in den Halbjahren belegt wurde, sonst false 
+	 */
+	public pruefeBelegung(fachbelegung : AbiturFachbelegung | null, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if ((belegungHalbjahr === null) || (belegungHalbjahr.kursartKuerzel === null)) 
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Bestimmt die Anzahl der Fachbelegungen, die dem Fach zugeordnet sind.
+	 * Wird keine gültige Fachbelegung übergeben, so wird 0 zurückgegeben.
+	 *  
+	 * @param fachbelegung   die Fachbelegung 
+	 * 
+	 * @return die Anzahl der Belegungen des Faches
+	 */
+	public zaehleBelegung(fachbelegung : AbiturFachbelegung | null) : number {
+		if (fachbelegung === null) 
+			return 0;
+		let anzahl : number = 0;
+		for (let i : number = 0; i < GostHalbjahr.maxHalbjahre; i++){
+			if (fachbelegung.belegungen[i] !== null) 
+				anzahl++;
+		}
+		return anzahl;
+	}
+
+	/**
+	 * Zählt die Anzahl der Belegungen für die angegebenen Fachbelegungen in den angegeben Halbjahren.
+	 * Ist die Fachbelegung null, so wird 0 zurückgegeben. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so wird ebenfalls 0 zurückgegeben.
+	 * 
+	 * @param fachbelegungen      die Fachbelegungen
+	 * @param halbjahre           die Halbjahre 
+	 * 
+	 * @return die Anzahl der Belegungen in den Halbjahren und den Fächern 
+	 */
+	public zaehleBelegungInHalbjahren(fachbelegungen : List<AbiturFachbelegung> | null, ...halbjahre : Array<GostHalbjahr>) : number {
+		if (fachbelegungen === null) 
+			return 0;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return 0;
+		let anzahl : number = 0;
+		for (let fachbelegung of fachbelegungen) 
+			for (let halbjahr of halbjahre) 
+				if (fachbelegung.belegungen[halbjahr.id] !== null) 
+					anzahl++;
+		return anzahl;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Kursart entspricht.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param kursart           die zu prüfende Kursart 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungMitKursart(fachbelegung : AbiturFachbelegung | null, kursart : GostKursart, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if ((belegungHalbjahr === null) || (kursart as unknown !== GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel) as unknown)) 
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Prüft, ob eine Fachbelegung existiert, welche in den angegebenen Halbjahren der angegebenen Kursart 
+	 * entspricht.
+	 * Ist keine Fachbelegung angegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen 
+	 * Fachbelegung kein Halbjahr angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param kursart           die zu prüfende Kursart 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungExistiertMitKursart(fachbelegungen : List<AbiturFachbelegung> | null, kursart : GostKursart, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if ((fachbelegungen === null) || (fachbelegungen.size() <= 0)) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungMitKursart(fachbelegung, kursart, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren mindestens einmal die angegebenen Kursart hat.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Kursart nicht
+	 * einmal existiert.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param kursart           die zu prüfende Kursart 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Kursart mindestens einmal in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungHatMindestensEinmalKursart(fachbelegung : AbiturFachbelegung | null, kursart : GostKursart, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return false;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if (belegungHalbjahr === null) 
+				continue;
+			if (kursart as unknown === GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel) as unknown) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in dem angegebenen Halbjahr der angegebenen Schriftlichkeit entspricht.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. 
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahr          das zu prüfende Halbjahr 
+	 * 
+	 * @return true, falls die Schriftlichkeit in dem Halbjahr gegeben ist, sonst false 
+	 */
+	public pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, halbjahr : GostHalbjahr) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+		if ((belegungHalbjahr === null) || (belegungHalbjahr.schriftlich === null) || ((schriftlichkeit as unknown !== GostSchriftlichkeit.BELIEBIG as unknown) && (((schriftlichkeit as unknown === GostSchriftlichkeit.SCHRIFTLICH as unknown) && (!belegungHalbjahr.schriftlich)) || ((schriftlichkeit as unknown === GostSchriftlichkeit.MUENDLICH as unknown) && (belegungHalbjahr.schriftlich))))) 
+			return false;
+		return true;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungMitSchriftlichkeit(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let halbjahr of halbjahre) 
+			if (!this.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, schriftlichkeit, halbjahr)) 
+				return false;
+		return true;
+	}
+
+	/**
+	 * Prüft, ob eine Belegung des Faches in den angegebenen Halbjahren nicht der angegebenen Schriftlichkeit entspricht.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren nicht gegeben ist, sonst false 
+	 */
+	public pruefeBelegungErfuelltNicht(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if ((belegungHalbjahr === null) || ((schriftlichkeit as unknown !== GostSchriftlichkeit.BELIEBIG as unknown) && (((schriftlichkeit as unknown === GostSchriftlichkeit.SCHRIFTLICH as unknown) && (!belegungHalbjahr.schriftlich)) || ((schriftlichkeit as unknown === GostSchriftlichkeit.MUENDLICH as unknown) && (belegungHalbjahr.schriftlich))))) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob eine Belegung des Faches in den angegebenen Halbjahren nicht der angegebenen Schriftlichkeit entspricht,
+	 * sofern es in dem Halbjahr überhaupt belegt wurde..
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren nicht gegeben ist, sonst false 
+	 */
+	public pruefeBelegungErfuelltNichtFallsBelegt(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if (belegungHalbjahr === null) 
+				continue;
+			let schriftlich : Boolean = belegungHalbjahr.schriftlich === null ? false : belegungHalbjahr.schriftlich;
+			if (((schriftlichkeit as unknown !== GostSchriftlichkeit.BELIEBIG as unknown) && (((schriftlichkeit as unknown === GostSchriftlichkeit.SCHRIFTLICH as unknown) && (!schriftlich)) || ((schriftlichkeit as unknown === GostSchriftlichkeit.MUENDLICH as unknown) && (schriftlich))))) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren mindestens einmal die angegebene Schritflichkeit hat.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Schriftlichkeit nicht
+	 * einmal existiert.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die angegebene Schriftlichkeit mindestens einmal in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungHatMindestensEinmalSchriftlichkeit(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return false;
+		for (let halbjahr of halbjahre) {
+			let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+			if (belegungHalbjahr === null) 
+				continue;
+			if ((schriftlichkeit.istSchriftlich === null) || (schriftlichkeit.istSchriftlich as unknown === belegungHalbjahr.schriftlich as unknown)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob eine Fachbelegung existiert, welche in den angegebenen Halbjahren mindestens einmal die angegebene 
+	 * Schritflichkeit hat.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Schriftlichkeit nicht
+	 * einmal existiert.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die angegebene Schriftlichkeit bei einer Fachbelegung mindestens einmal in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungExistiertHatMindestensEinmalSchriftlichkeit(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if ((fachbelegungen === null) || (fachbelegungen.size() <= 0)) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return false;
+		for (let fachbelegung of fachbelegungen) 
+			if (this.pruefeBelegungHatMindestensEinmalSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre)) 
+				return true;
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer mit den angegebenen Halbjahren existiert.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche 
+	 * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist z.B. bei bilingualen
+	 * Fächern nötig oder bei der Unterscheidung von Sport-Profilen.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls eine Fachbelegung mit den Halbjahren existiert, sonst false 
+	 */
+	public pruefeBelegungExistiert(fachbelegungen : List<AbiturFachbelegung> | null, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return true;
+		for (let fachbelegung of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fachbelegung.fachID);
+			if (fach === null) 
+				continue;
+			let alleBelegungen : List<AbiturFachbelegung> | null = this.getFachbelegungByFachkuerzel(fach.kuerzel);
+			if ((alleBelegungen === null) || (alleBelegungen.size() === 0)) 
+				continue;
+			let hatBelegung : boolean = true;
+			for (let halbjahr of halbjahre) {
+				let hatHalbjahresBelegung : boolean = false;
+				for (let aktFachbelegung of alleBelegungen) {
+					if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
+						hatHalbjahresBelegung = true;
+						break;
+					}
+				}
+				if (!hatHalbjahresBelegung) {
+					hatBelegung = false;
+					break;
+				}
+			}
+			if (hatBelegung) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer mit dem angegebenen Halbjahr existiert.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. 
+	 * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche 
+	 * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist z.B. bei bilingualen
+	 * Fächern nötig oder bei der Unterscheidung von Sport-Profilen.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param halbjahr          das zu prüfende Halbjahr 
+	 * 
+	 * @return true, falls eine Fachbelegung mit dem Halbjahr existiert, sonst false 
+	 */
+	public pruefeBelegungExistiertEinzeln(fachbelegungen : List<AbiturFachbelegung> | null, halbjahr : GostHalbjahr) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fachbelegung.fachID);
+			if (fach === null) 
+				continue;
+			let alleBelegungen : List<AbiturFachbelegung> | null = this.getFachbelegungByFachkuerzel(fach.kuerzel);
+			if ((alleBelegungen === null) || (alleBelegungen.size() === 0)) 
+				continue;
+			for (let aktFachbelegung of alleBelegungen) 
+				if (aktFachbelegung.belegungen[halbjahr.id] !== null) 
+					return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer mit einer durchgängigen Belegung existiert,
+	 * die zumindest in der Q1 und der Q2.1 schriftlich ist.
+	 * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche 
+	 * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist bei bilingualen
+	 * Fächern nötig.   
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * 
+	 * @return true, falls eine durchgehend schriftliche Fachbelegung existiert, sonst false 
+	 */
+	public pruefeBelegungExistiertDurchgehendSchriftlich(fachbelegungen : List<AbiturFachbelegung> | null) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fachbelegung.fachID);
+			if (fach === null) 
+				continue;
+			let alleBelegungen : List<AbiturFachbelegung> | null = this.getFachbelegungByFachkuerzel(fach.kuerzel);
+			if ((alleBelegungen === null) || (alleBelegungen.size() === 0)) 
+				continue;
+			let hatBelegung : boolean = true;
+			for (let halbjahr of GostHalbjahr.values()) {
+				let hatHalbjahresBelegung : boolean = false;
+				for (let aktFachbelegung of alleBelegungen) {
+					if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
+						let belegungHalbjahr : AbiturFachbelegungHalbjahr | null = aktFachbelegung.belegungen[halbjahr.id];
+						if (((halbjahr as unknown !== GostHalbjahr.Q11 as unknown) && (halbjahr as unknown !== GostHalbjahr.Q12 as unknown) && (halbjahr as unknown !== GostHalbjahr.Q21 as unknown)) || ((belegungHalbjahr !== null) && (belegungHalbjahr.schriftlich !== null) && (belegungHalbjahr.schriftlich))) 
+							hatHalbjahresBelegung = true;
+					}
+				}
+				if (!hatHalbjahresBelegung) {
+					hatBelegung = false;
+					break;
+				}
+			}
+			if (hatBelegung) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in dem angegebenen Halbjahr der angegebenen Schriftlichkeit entspricht.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. 
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahr          das zu prüfende Halbjahr 
+	 * 
+	 * @return true, falls bei einer Fachbelegung die Schriftlichkeit in dem Halbjahr gegeben ist, sonst false 
+	 */
+	public pruefeBelegungExistiertMitSchriftlichkeitEinzeln(fachbelegungen : List<AbiturFachbelegung | null> | null, schriftlichkeit : GostSchriftlichkeit, halbjahr : GostHalbjahr) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, schriftlichkeit, halbjahr)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls bei einer Fachbelegung die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungExistiertMitSchriftlichkeit(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren mindestens einmal die angegebene Kursart 
+	 * hat. Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param kursart           die zu prüfende Kursart 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Kursart bei einer Fachbelegung mindestens einmal in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungExistiertHatMindestensEinmalKursart(fachbelegungen : List<AbiturFachbelegung> | null, kursart : GostKursart, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungHatMindestensEinmalKursart(fachbelegung, kursart, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren existiert,
+	 * bei welchem in mind. einem der Halbjahren die angebene Schriftlichkeit nicht gegeben ist.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true oder false (siehe oben) 
+	 */
+	public pruefeBelegungExistiertErfuelltNicht(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungErfuelltNicht(fachbelegung, schriftlichkeit, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren existiert,
+	 * bei welchem in mind. einem der Halbjahren die angebene Schriftlichkeit nicht gegeben ist, sofern
+	 * das Fach überhaupt belegt wurde.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true oder false (siehe oben) 
+	 */
+	public pruefeBelegungExistiertErfuelltNichtFallsBelegt(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungErfuelltNichtFallsBelegt(fachbelegung, schriftlichkeit, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
+	 * und das Fach durchgehend belegbar ist.
+	 * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegung      die zu prüfende Fachnbelegung
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungDurchgehendBelegbar(fachbelegung : AbiturFachbelegung | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		if (!GostFachManager.istDurchgehendBelegbarBisQ22(this.getFach(fachbelegung))) 
+			return false;
+		return this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre);
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
+	 * und das Fach durchgängig belegbar ist.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls bei einer Fachbelegung die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungDurchgehendBelegbarExistiert(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegungDurchgehendBelegbar(fachbelegung, schriftlichkeit, ...halbjahre)) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
+	 * und das Fach durchgängig belegt ist.
+	 * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
+	 * angegeben, so ist die Prüfung erfolgreich sofern das Fach durchgängig belegt wurde, da kein Halbjahr auf die 
+	 * Schriftlichkeit geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu prüfenden Fachnbelegungen
+	 * @param schriftlichkeit   die zu prüfende Schriftlichkeit 
+	 * @param halbjahre         die zu prüfenden Halbjahre 
+	 * 
+	 * @return true, falls bei eine Fachbelegung durchgängig belegt wurde und die Schriftlichkeit in den Halbjahren gegeben ist, sonst false 
+	 */
+	public pruefeBelegungDurchgehendBelegtExistiert(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : boolean {
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeBelegung(fachbelegung, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+				if (this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre)) 
+					return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft, ob die Fachbelegung in mindestens einem der Halbjahre die angegebene Kursart aufweist.
+	 * Existiert die Fachbelegung nicht (null), so kommt die Kursart auch nicht vor.
+	 *  
+	 * @param fachbelegung   die Fachbelegung
+	 * @param kursart        die Kursart
+	 * 
+	 * @return true, falls mindestens einmal die Kursart belegt wurde, sonst false
+	 */
+	public pruefeAufKursart(fachbelegung : AbiturFachbelegung | null, kursart : GostKursart) : boolean {
+		if (fachbelegung === null) 
+			return false;
+		for (let belegunghalbjahr of fachbelegung.belegungen) {
+			if ((belegunghalbjahr !== null) && GostKursart.fromKuerzel(belegunghalbjahr.kursartKuerzel) as unknown === kursart as unknown) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen und gibt nur die Fachbelegungen zurück, bei denen die 
+	 * Kursart existiert.
+	 * Wird keine Fachbelegung übergeben (null oder leere Liste), so kommt auch keine 
+	 * Belegung mit der Kursart vor.
+	 *  
+	 * @param fachbelegungen   die Fachbelegungen
+	 * @param kursart          die Kursart
+	 * 
+	 * @return eine Liste mit den Fachbelegungen, welche die kursart haben
+	 */
+	public filterBelegungKursartExistiert(fachbelegungen : List<AbiturFachbelegung> | null, kursart : GostKursart) : List<AbiturFachbelegung> {
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		if ((fachbelegungen === null) || (fachbelegungen.size() <= 0)) 
+			return result;
+		for (let fachbelegung of fachbelegungen) {
+			if (this.pruefeAufKursart(fachbelegung, kursart)) 
+				result.add(fachbelegung);
+		}
+		return result;
+	}
+
+	/**
+	 * Prüft, ob die Fachbelegung eine durchgängige Belegung hat. Zusatzkurse können nicht für eine
+	 * durchgängige Belegung zählen.
+	 * 
+	 * @param fachbelegung   die zu prüfende Fachbelegung
+	 * 
+	 * @return true, wenn die Belegung durchgängig ist.
+	 */
+	public pruefeDurchgaengigkeit(fachbelegung : AbiturFachbelegung | null) : boolean {
+		if ((fachbelegung === null) || (this.pruefeAufKursart(fachbelegung, GostKursart.ZK))) 
+			return false;
+		return this.pruefeBelegung(fachbelegung, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22);
+	}
+
+	/**
+	 * Zählt die Fachbelegungen, welche eine durchgängige Belegung aufweisen. Zusatzkurse zählen
+	 * nicht für eine durchgängige Belegung.
+	 * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche 
+	 * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist bei bilingualen
+	 * Fächern nötig.   
+	 * 
+	 * @param fachbelegungen   die zu überprüfenden Fachbelegungen
+	 * 
+	 * @return die Anzahl der durchgängigen Belegungen
+	 */
+	public zaehleDurchgaengigeBelegungen(fachbelegungen : List<AbiturFachbelegung> | null) : number {
+		if (fachbelegungen === null) 
+			return 0;
+		let anzahl : number = 0;
+		for (let fachbelegung of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fachbelegung.fachID);
+			if (fach === null) 
+				continue;
+			if (fachbelegung.belegungen[GostHalbjahr.EF1.id] === null) 
+				continue;
+			let alleBelegungen : List<AbiturFachbelegung> | null = this.getFachbelegungByFachkuerzel(fach.kuerzel);
+			if ((alleBelegungen === null) || (alleBelegungen.size() === 0)) 
+				continue;
+			let hatBelegung : boolean = true;
+			let halbjahre : Array<GostHalbjahr> = [GostHalbjahr.EF1, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22];
+			for (let halbjahr of halbjahre) {
+				let hatHalbjahresBelegung : boolean = false;
+				for (let aktFachbelegung of alleBelegungen) {
+					if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
+						hatHalbjahresBelegung = true;
+						break;
+					}
+				}
+				if (!hatHalbjahresBelegung) {
+					hatBelegung = false;
+					break;
+				}
+			}
+			if (hatBelegung) 
+				anzahl++;
+		}
+		return anzahl;
+	}
+
+	/**
+	 * Prüft, ob die Fachbelegung eine durchgängige Belegung hat und prüft die Schriftlichkeit
+	 * in der Qualifikationsphase. Ein Fach in der Qualifikationsphase gilt als Schriftlich belegt,
+	 * sofern die ersten 3 Halbjahre der Qualifikationsphase schriftlich belegt wurden. 
+	 * - Zusatzkurse können nicht für eine durchgängige Belegung zählen.
+	 * 
+	 * @param fachbelegung   die zu prüfende die zu überprüfenden Fachbelegung
+	 * 
+	 * @return true, wenn die Belegung durchgängig ist und die Schriftlichkeit den Anforderungen genügt.
+	 */
+	public pruefeDurchgaengigkeitSchriftlich(fachbelegung : AbiturFachbelegung | null) : boolean {
+		if (!this.pruefeDurchgaengigkeit(fachbelegung)) 
+			return false;
+		return this.pruefeBelegungMitSchriftlichkeit(fachbelegung, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21);
+	}
+
+	/**
+	 * Prüft, ob unter den angegebenen Fachbelegungen ein Fach als Abiturfach von einem der angegebenen Arten 
+	 * gewählt wurde. Wird keine Art angebeben, so wird jede Fachbelegung akzeptiert und true zurückgegeben.
+	 * 
+	 * @param fachbelegungen   die Fachbelegungen
+	 * @param arten            die Arten der Abiturfächer
+	 *  
+	 * @return true, falls unter den Fachbelegungen mindestens ein Fach als Abiturfach von einem der 
+	 *         angegebenen Arten gewählt wurde und false sonst
+	 */
+	public pruefeExistiertAbiFach(fachbelegungen : List<AbiturFachbelegung> | null, ...arten : Array<GostAbiturFach>) : boolean {
+		if ((arten === null) || (arten.length === 0)) 
+			return true;
+		if (fachbelegungen === null) 
+			return false;
+		for (let fachbelegung of fachbelegungen) 
+			for (let art of arten) {
+				let abiturFach : GostAbiturFach | null = GostAbiturFach.fromID(fachbelegung.abiturFach);
+				if (abiturFach as unknown === art as unknown) 
+					return true;
+			}
+		return false;
+	}
+
+	/**
+	 * Prüft anhand des Statistik-Kürzels, ob in dem angegebenen Halbjahr eine doppelte Fachbelegung 
+	 * vorliegt oder nicht. Bei den Fremdsprachen werden nur unterschiedliche Fremdsprachen in einem Halbjahr 
+	 * akzeptiert und es dürfen mehrere Vertiefungsfächer (VX) in einem Halbjahr vorkommen.   
+	 * 
+	 * @param halbjahr   das zu prüfende Halbjahr
+	 * 
+	 * @return true, falls eine doppelte Belegung vorliegt, sonst false
+	 */
+	public hatDoppelteFachbelegungInHalbjahr(halbjahr : GostHalbjahr) : boolean {
+		let set : HashSet<String> = new HashSet();
+		let fachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if (fach === null) 
+				continue;
+			let belegung : AbiturFachbelegungHalbjahr | null = this.getBelegungHalbjahr(fb, halbjahr, GostSchriftlichkeit.BELIEBIG);
+			if (belegung === null) 
+				continue;
+			let kuerzel : String | null = GostFachManager.getFremdsprache(fach);
+			if (kuerzel === null) 
+				kuerzel = fach.kuerzel === null ? "" : fach.kuerzel;
+			if (!set.add(kuerzel) && (!JavaObject.equalsTranspiler("VX", (kuerzel)))) 
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft anhand des Statistik-Kürzels, ob in einem der angegebenen Halbjahre eine doppelte Fachbelegung 
+	 * vorliegt oder nicht. Bei den Fremdsprachen werden nur unterschiedliche Fremdsprachen in einem Halbjahr 
+	 * akzeptiert und es dürfen mehrere Vertiefungsfächer (VX) in einem Halbjahr vorkommen.   
+	 * 
+	 * @param halbjahre   die zu prüfenden Halbjahre
+	 * 
+	 * @return true, falls eine doppelte Belegung vorliegt, sonst false
+	 */
+	public hatDoppelteFachbelegung(...halbjahre : Array<GostHalbjahr>) : boolean {
+		if ((halbjahre === null) || (halbjahre.length === 0)) 
+			return false;
+		for (let halbjahr of halbjahre) 
+			if (this.hatDoppelteFachbelegungInHalbjahr(halbjahr)) 
+				return true;
+		return false;
+	}
+
+	/**
+	 * Gibt zurück, ob der Projektkurs als besondere Lernleistung verwendet wird.
+	 * 
+	 * @return true, falls der Projektkurs als besondere Lernleistung verwendet wird
+	 */
+	public istProjektKursBesondereLernleistung() : boolean {
+		return (GostBesondereLernleistung.PROJEKTKURS.is(this.abidaten.besondereLernleistung));
+	}
+
+	/**
+	 * Bestimmt die erste Fachbelegung mit dem angegebenen Statistik-Kürzel
+	 * 
+	 * @param kuerzel          das Kürzel des Faches, kann null sein (dann wird auch null zurückgegeben)
+	 * 
+	 * @return die Fachbelegung oder null, falls keine vorhanden ist
+	 */
+	public getFachbelegungByKuerzel(kuerzel : String | null) : AbiturFachbelegung | null {
+		if ((kuerzel === null) || (JavaObject.equalsTranspiler("", (kuerzel)))) 
+			return null;
+		let fachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if ((fach !== null) && (JavaObject.equalsTranspiler(kuerzel, (fach.kuerzel)))) 
+				return fb;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert alle Fachbelegungen der Abiturdaten, welche den angegebenen Fachbereichen zuzuordnen sind.
+	 * Wird kein Fachbereich angegeben, so werden alle Fachbelegungen der Abiturdaten zurückgegeben.
+	 * 
+	 * @param fachbereiche   die Fachbereiche 
+	 * 
+	 * @return eine Liste der Fachbelegungen aus den Fachbereichen
+	 */
+	public getFachbelegungen(...fachbereiche : Array<GostFachbereich>) : List<AbiturFachbelegung> {
+		if ((fachbereiche === null) || (fachbereiche.length === 0)) 
+			return this.abidaten.fachbelegungen;
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		for (let fachbereich of fachbereiche) {
+			let fachbelegungen : List<AbiturFachbelegung> | null = this.mapFachbereiche.get(fachbereich);
+			if (fachbelegungen === null) 
+				continue;
+			result.addAll(fachbelegungen);
+		}
+		return result;
+	}
+
+	/**
+	 * Liefert alle Fachbelegungen, die bilingual unterrichtet wurden.
+	 * 
+	 * @return eine Liste der Fachbelegungen
+	 */
+	public getFachbelegungenBilingual() : List<AbiturFachbelegung> {
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		let fachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fb of fachbelegungen) {
+			if (this.zaehleBelegung(fb) <= 0) 
+				continue;
+			let fach : GostFach | null = this.getFach(fb);
+			if ((fach !== null) && (!GostFachbereich.FREMDSPRACHE.hat(fach)) && (!GostFachbereich.DEUTSCH.hat(fach)) && (fach.biliSprache !== null) && (!JavaObject.equalsTranspiler("D", (fach.biliSprache)))) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen auf neu einsetzende Fremdsprachen.
+	 * 
+	 * @param fachbelegungen   die zu filternden Fachbelegungen
+	 * 
+	 * @return die gefilterten Fachbelegungen
+	 */
+	public filterFremdspracheNeuEinsetzend(fachbelegungen : List<AbiturFachbelegung> | null) : List<AbiturFachbelegung> {
+		if (fachbelegungen === null) 
+			return Collections.emptyList();
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if ((fach !== null) && fach.istFremdsprache && fach.istFremdSpracheNeuEinsetzend) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen auf fortgeführte Fremdsprachen.
+	 * 
+	 * @param fachbelegungen   die zu filternden Fachbelegungen
+	 * 
+	 * @return die gefilterten Fachbelegungen
+	 */
+	public filterFremdspracheFortgefuehrt(fachbelegungen : List<AbiturFachbelegung> | null) : List<AbiturFachbelegung> {
+		if (fachbelegungen === null) 
+			return Collections.emptyList();
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if ((fach !== null) && fach.istFremdsprache && !fach.istFremdSpracheNeuEinsetzend) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen danach, ob sie durchgehend belegbar sind
+	 * 
+	 * @param fachbelegungen   die zu filternden Fachbelegungen
+	 * 
+	 * @return die gefilterten Fachbelegungen
+	 */
+	public filterDurchgehendBelegbar(fachbelegungen : List<AbiturFachbelegung> | null) : List<AbiturFachbelegung> {
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		if (fachbelegungen === null) 
+			return result;
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if (GostFachManager.istDurchgehendBelegbarBisQ22(fach)) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen. Es werden nur Fachbelegungen behalten, die in den angegebenen Halbjahren eine Belegung aufweisen.
+	 * Wird kein Halbjahr angegeben, so wird nichts gefiltert, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu filternden Fachbelegungen 
+	 * @param halbjahre         die Halbjahre, die belegt sein müssen
+	 * 
+	 * @return die gefilterten Fachbelegungen
+	 */
+	public filterBelegungen(fachbelegungen : List<AbiturFachbelegung> | null, ...halbjahre : Array<GostHalbjahr>) : List<AbiturFachbelegung> {
+		if (fachbelegungen === null) 
+			return Collections.emptyList();
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		for (let fb of fachbelegungen) {
+			if (this.pruefeBelegung(fb, ...halbjahre)) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Diese Methode zählt die Anzahl der angegebenen Fachbelegungen, welche in allen 
+	 * Halbjahren belegt sind. Dabei werden Fachbelegungen, welche dem gleichem Statistik-Fach
+	 * zuzuordnen sind zusammengefasst. Dies ist bei der Abwahl von bilingualen Sachfächern
+	 * relevant.
+	 *   
+	 * @param fachbelegungen   die zu zählenden Fachbelegungen
+	 * 
+	 * @return die Anzahl der Fachbelegungen
+	 */
+	public zaehleBelegungenDurchgaengig(fachbelegungen : List<AbiturFachbelegung> | null) : number {
+		if (fachbelegungen === null) 
+			return 0;
+		let faecher : HashSet<ZulaessigesFach> = new HashSet();
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fb.fachID);
+			if (fach === null) 
+				continue;
+			let zulFach : ZulaessigesFach = ZulaessigesFach.getByKuerzelASD(fach.kuerzel);
+			if (zulFach as unknown !== ZulaessigesFach.DEFAULT as unknown) 
+				faecher.add(zulFach);
+		}
+		let count : number = 0;
+		for (let zulFach of faecher) {
+			let vorhanden : boolean = true;
+			for (let halbjahr of GostHalbjahr.values()) {
+				let belegung_vorhanden : boolean = false;
+				for (let fb of fachbelegungen) {
+					let fbFach : GostFach | null = this.gostFaecher.get(fb.fachID);
+					if (fbFach === null) 
+						continue;
+					let fbZulFach : ZulaessigesFach = ZulaessigesFach.getByKuerzelASD(fbFach.kuerzel);
+					if ((zulFach as unknown === fbZulFach as unknown) && (fb.belegungen[halbjahr.id] !== null)) {
+						belegung_vorhanden = true;
+						break;
+					}
+				}
+				if (!belegung_vorhanden) {
+					vorhanden = false;
+					break;
+				}
+			}
+			if (vorhanden) 
+				count++;
+		}
+		return count;
+	}
+
+	/**
+	 * Diese Methode zählt die Anzahl der angegebenen Fachbelegungen, welche in allen 
+	 * Halbjahren belegt sind. Dabei werden Fachbelegungen, welche dem gleichem Statistik-Fach
+	 * zuzuordnen sind zusammengefasst. Dies ist bei der Abwahl von bilingualen Sachfächern
+	 * relevant.
+	 *   
+	 * @param fachbelegungen   die zu zählenden Fachbelegungen
+	 * 
+	 * @return die Anzahl der Fachbelegungen
+	 */
+	public zaehleBelegungenDurchgaengigSchriftlichInQPhase(fachbelegungen : List<AbiturFachbelegung> | null) : number {
+		if (fachbelegungen === null) 
+			return 0;
+		let faecher : HashSet<ZulaessigesFach> = new HashSet();
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fb.fachID);
+			if (fach === null) 
+				continue;
+			let zulFach : ZulaessigesFach = ZulaessigesFach.getByKuerzelASD(fach.kuerzel);
+			if (zulFach as unknown !== ZulaessigesFach.DEFAULT as unknown) 
+				faecher.add(zulFach);
+		}
+		let count : number = 0;
+		for (let zulFach of faecher) {
+			let vorhanden : boolean = true;
+			for (let halbjahr of GostHalbjahr.values()) {
+				let belegung_vorhanden : boolean = false;
+				for (let fb of fachbelegungen) {
+					let fbFach : GostFach | null = this.gostFaecher.get(fb.fachID);
+					if (fbFach === null) 
+						continue;
+					let fbZulFach : ZulaessigesFach = ZulaessigesFach.getByKuerzelASD(fbFach.kuerzel);
+					if (zulFach as unknown === fbZulFach as unknown) {
+						let belegung : AbiturFachbelegungHalbjahr | null = fb.belegungen[halbjahr.id];
+						if (belegung !== null) {
+							let istSchriftlichkeitOK : boolean = true;
+							if (((halbjahr as unknown === GostHalbjahr.Q11 as unknown) || (halbjahr as unknown === GostHalbjahr.Q12 as unknown) || (halbjahr as unknown === GostHalbjahr.Q21 as unknown)) && ((belegung.schriftlich === null) || (!belegung.schriftlich))) 
+								istSchriftlichkeitOK = false;
+							if (istSchriftlichkeitOK) {
+								belegung_vorhanden = true;
+								break;
+							}
+						}
+					}
+				}
+				if (!belegung_vorhanden) {
+					vorhanden = false;
+					break;
+				}
+			}
+			if (vorhanden) 
+				count++;
+		}
+		return count;
+	}
+
+	/**
+	 * Filtert die Fachbelegungen. Es werden nur Belegungen behalten, die in den angegebenen Halbjahren die geforderte Schriftlichkeit aufweisen.
+	 * Wird kein Halbjahr angegeben, so wird nichts gefiltert, da kein Halbjahr geprüft werden muss.
+	 * 
+	 * @param fachbelegungen    die zu filternden Fachbelegungen 
+	 * @param schriftlichkeit   die geforderte Schriftlichkeit
+	 * @param halbjahre         die Halbjahre, die belegt sein müssen
+	 * 
+	 * @return die gefilterten Fachbelegungen
+	 */
+	public filterBelegungenMitSchriftlichkeit(fachbelegungen : List<AbiturFachbelegung> | null, schriftlichkeit : GostSchriftlichkeit, ...halbjahre : Array<GostHalbjahr>) : List<AbiturFachbelegung> {
+		if (fachbelegungen === null) 
+			return Collections.emptyList();
+		let result : Vector<AbiturFachbelegung> = new Vector();
+		for (let fb of fachbelegungen) {
+			if (this.pruefeBelegungMitSchriftlichkeit(fb, schriftlichkeit, ...halbjahre)) 
+				result.add(fb);
+		}
+		return result;
+	}
+
+	/**
+	 * Liefert die erste Fachbelegung für den Fachbereich - sofern eine existiert
+	 * 
+	 * @param fachbereich   der Fachbereich
+	 * 
+	 * @return die Fachbelegung oder null
+	 */
+	public getFachbelegung(fachbereich : GostFachbereich) : AbiturFachbelegung | null {
+		let faecher : Vector<AbiturFachbelegung | null> | null = this.mapFachbereiche.get(fachbereich);
+		if ((faecher === null) || (faecher.size() === 0)) 
+			return null;
+		return faecher.get(0);
+	}
+
+	/**
+	 * Liefert alle Fachbelegungen mit dem angegebenen Statistk-Kürzel des Faches 
+	 * 
+	 * @param kuerzel   das Kürzel des Faches
+	 * 
+	 * @return eine Liste mit den Fachbelegungen
+	 */
+	public getFachbelegungByFachkuerzel(kuerzel : String | null) : List<AbiturFachbelegung> {
+		let fachbelegungen : Vector<AbiturFachbelegung> = new Vector();
+		if (kuerzel === null) 
+			return fachbelegungen;
+		let tmpFachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fachbelegung of tmpFachbelegungen) {
+			let fach : GostFach | null = this.gostFaecher.get(fachbelegung.fachID);
+			if ((fach === null) || (!JavaObject.equalsTranspiler(kuerzel, (fach.kuerzel)))) 
+				continue;
+			fachbelegungen.add(fachbelegung);
+		}
+		return fachbelegungen;
+	}
+
+	/**
+	 * Prüft, ob der Kurs in dem angegebenen Halbjahr mit der angegebenen Schriftlichkeit belegt ist 
+	 * und gibt ggf. die Belegung zurück.
+	 *  
+	 * @param fachbelegung   die Abiturfachbelegung aus welcher die Belegungsinformationen für das Halbjahr entnommen wird 
+	 * @param halbjahr       das Halbjahr, in welchem die Belegung gesucht wird.
+	 * @param schriftlich    gibt an, ob das Fach schriftlich oder mündlich belegt sein muss
+	 * 
+	 * @return die Belegungsinformationen zu dem Fach
+	 */
+	public getBelegungHalbjahr(fachbelegung : AbiturFachbelegung, halbjahr : GostHalbjahr, schriftlich : GostSchriftlichkeit) : AbiturFachbelegungHalbjahr | null {
+		let belegung : AbiturFachbelegungHalbjahr | null = fachbelegung.belegungen[halbjahr.id];
+		return ((belegung !== null) && ((schriftlich as unknown === GostSchriftlichkeit.BELIEBIG as unknown) || ((schriftlich as unknown === GostSchriftlichkeit.SCHRIFTLICH as unknown) && (belegung.schriftlich)) || ((schriftlich as unknown === GostSchriftlichkeit.MUENDLICH as unknown) && (!belegung.schriftlich)))) ? belegung : null;
+	}
+
+	/**
+	 * Liefert die erste Sprachbelegung - sofern eine existiert
+	 * 
+	 * @param sprache   das einstellige Kürzel der Sprache
+	 * 
+	 * @return die Fachbelegung für die Sprache
+	 */
+	public getSprachbelegung(sprache : String | null) : AbiturFachbelegung | null {
+		if (sprache === null) 
+			return null;
+		let fachbelegungen : Vector<AbiturFachbelegung> = this.abidaten.fachbelegungen;
+		for (let fb of fachbelegungen) {
+			let fach : GostFach | null = this.getFach(fb);
+			if ((fach === null) || (!GostFachManager.istFremdsprachenfach(fach, sprache))) 
+				continue;
+			if (JavaObject.equalsTranspiler(sprache, (GostFachManager.getFremdsprache(fach)))) 
+				return fb;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert für die übergebene Fachbelegung die Halbjahre, in denen das Fach mit einer der angebenen 
+	 * Kursarten belegt wurde. Ist keine Kursart angegeben, so werden die Halbjahre aller Belegungen
+	 * zurückgegeben. Ist keine Fachbelegung angegeben, so wird eine leere Liste zurückgegeben.
+	 *  
+	 * @param fachbelegung   die Fachbelegung
+	 * @param kursarten      die Kursarten
+	 * 
+	 * @return eine Liste der Halbjahre in den das Fach mit einer der Kursarten belegt wurde
+	 */
+	public getHalbjahreKursart(fachbelegung : AbiturFachbelegung | null, ...kursarten : Array<GostKursart>) : Vector<GostHalbjahr> {
+		let halbjahre : Vector<GostHalbjahr> = new Vector();
+		if (fachbelegung !== null) {
+			for (let belegungHalbjahr of fachbelegung.belegungen) {
+				if (belegungHalbjahr === null) 
+					continue;
+				let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegungHalbjahr.halbjahrKuerzel);
+				if (halbjahr === null) 
+					continue;
+				if ((kursarten === null) || (kursarten.length === 0)) {
+					halbjahre.add(halbjahr);
+					continue;
+				}
+				for (let kursart of kursarten) {
+					if (JavaObject.equalsTranspiler(kursart, (GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel)))) {
+						halbjahre.add(halbjahr);
+						break;
+					}
+				}
+			}
+		}
+		return halbjahre;
+	}
+
+	/**
+	 * Gibt die Sprache des bilingualen Bildungsgang zurück oder null, falls keiner gewählt wurde.
+	 * 
+	 * @return die Sprache des bilingualen Bildungsgang oder null
+	 */
+	public getBiligualenBildungsgang() : String | null {
+		return this.abidaten.bilingualeSprache;
+	}
+
+	/**
+	 * Prüft bei der Sprachenfolge, ob eine laut Sprachenfolge fortgeführte
+	 * Fremdsprache fehlerhafterweise als neu einsetzende Fremdsprache belegt wurde.
+	 * Übergebene Fachbelegungen, die keine Fremdsprachen sind werden ignoriert.  
+	 * 
+	 * @param fremdsprachen   die zu prüfenden Fachbelegungen
+	 *  
+	 * @return true, falls eine fortgeführte Fremdsprache bei den übergebenen 
+	 *         Fachbelegungen existiert, ansonsten false 
+	 */
+	public hatFortgefuehrteFremdspracheInSprachendaten(fremdsprachen : List<AbiturFachbelegung> | null) : boolean {
+		if (fremdsprachen === null) 
+			return false;
+		if (this.abidaten.sprachendaten === null) 
+			return false;
+		for (let fs of fremdsprachen) {
+			let fach : GostFach | null = this.getFach(fs);
+			if ((fach === null) || (!fach.istFremdsprache)) 
+				continue;
+			if (SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.abidaten.sprachendaten, GostFachManager.getFremdsprache(fach))) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Prüft bei der Sprachenfolge, ob für eine laut Sprachenfolge neu einsetzende
+	 * Fremdsprache fehlerhafterweise ein Kurs in einer fortgeführten Fremdsprache belegt wurde.
+	 * Übergebene Fachbelegungen, die keine Fremdsprachen sind werden ignoriert.  
+	 * 
+	 * @param fremdsprachen   die zu prüfenden Fachbelegungen
+	 *  
+	 * @return true, falls eine neu einsetzende Fremdsprache bei den übergebenen 
+	 *         Fachbelegungen existiert, ansonsten false 
+	 */
+	public hatNeuEinsetzendeFremdspracheInSprachendaten(fremdsprachen : List<AbiturFachbelegung> | null) : boolean {
+		if (fremdsprachen === null) 
+			return false;
+		if (this.abidaten.sprachendaten === null) 
+			return false;
+		for (let fs of fremdsprachen) {
+			let fach : GostFach | null = this.getFach(fs);
+			if ((fach === null) || (!fach.istFremdsprache)) 
+				continue;
+			if (!SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.abidaten.sprachendaten, GostFachManager.getFremdsprache(fach))) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Gibt an, ob am Ende der EF eine Muttersprachenprüfung geplant bzw. erfolgt ist.
+	 * 
+	 * @return true, falls eine Muttersprachenprüfung am Ende der EF vorliegt, sonst false
+	 */
+	public hatMuttersprachenPruefungEndeEF() : boolean {
+		return this.abidaten.muttersprachenpruefungEndeEF;
+	}
+
+	/**
+	 * Gibt an, ob die zweite Fremdsprache in der Sekundarstufe manuell erfolgreich 
+	 * geprüft wurde und dort eine entsprechende Belegung existiert.
+	 * 
+	 * @return true, falls in der Sek I eine zweite Fremdsprache belegt wurde
+	 */
+	public istSekIZweiteFremdspracheManuellGeprueft() : boolean {
+		return this.abidaten.sek1Fremdsprache2ManuellGeprueft;
+	}
+
+	/**
+	 * Prüft, ob die Belegung seit der EF1 vorhanden ist. Hierbei werden
+	 * Zusatz-, Vertiefungs- und Projektkurse auch als später einsetzend akzeptiert.
+	 * Dies gilt auch für Literatur, instrumental- und vokalpraktische Kurse sowie 
+	 * für Religion und Philosophie.
+	 * 
+	 * @param fachbelegung   die Abiturfachbelegungen, die geprüft werden
+	 * 
+	 * @return true, falls das Fach seit EF1 durchgängig belegt wurde oder eine der Ausnahmen zutrifft, sonsta false 
+	 */
+	public istBelegtSeitEF(fachbelegung : AbiturFachbelegung) : boolean {
+		let fach : GostFach | null = this.getFach(fachbelegung);
+		if (fach === null) 
+			return false;
+		if (GostFachbereich.LITERARISCH_KUENSTLERISCH_ERSATZ.hat(fach)) 
+			return true;
+		if (GostFachbereich.RELIGION.hat(fach)) 
+			return true;
+		if (JavaObject.equalsTranspiler("PL", (fach.kuerzel))) 
+			return true;
+		for (let belegung of fachbelegung.belegungen) {
+			if (belegung === null) 
+				continue;
+			let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegung.halbjahrKuerzel);
+			let kursart : GostKursart | null = GostKursart.fromKuerzel(belegung.kursartKuerzel);
+			if ((halbjahr === null) || (kursart === null)) 
+				continue;
+			if ((kursart as unknown === GostKursart.ZK as unknown) || (kursart as unknown === GostKursart.PJK as unknown) || (kursart as unknown === GostKursart.VTF as unknown)) 
+				continue;
+			let prevHalbjahr : GostHalbjahr | null = halbjahr.previous();
+			if (prevHalbjahr === null) 
+				continue;
+			if (fachbelegung.belegungen[prevHalbjahr.id] === null) {
+				let alleBelegungen : List<AbiturFachbelegung> | null = this.getFachbelegungByFachkuerzel(fach.kuerzel);
+				if ((alleBelegungen === null) || (alleBelegungen.size() <= 1)) 
+					return false;
+				if (!this.pruefeBelegungExistiert(alleBelegungen, prevHalbjahr)) 
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Gibt das Ergebnis der Belegprüfung zurück. Dieses enthält eine Liste der Fehler, die bei der Belegprüfung 
+	 * festgestellt wurden und ob diese erfolgreich gewesen ist oder nicht.
+	 * 
+	 * @return das Ergebnis der Belegprüfung
+	 */
+	public getBelegpruefungErgebnis() : GostBelegpruefungErgebnis {
+		let ergebnis : GostBelegpruefungErgebnis = new GostBelegpruefungErgebnis();
+		ergebnis.erfolgreich = this.belegpruefungErfolgreich;
+		for (let i : number = 0; i < this.belegpruefungsfehler.size(); i++){
+			let fehler : GostBelegungsfehler = this.belegpruefungsfehler.get(i);
+			ergebnis.fehlercodes.add(new GostBelegpruefungErgebnisFehler(fehler, this.pruefungsArt));
+		}
+		return ergebnis;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.AbiturdatenManager'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager(obj : unknown) : AbiturdatenManager {
+	return obj as AbiturdatenManager;
+}

+ 135 - 0
core/abschluss/gost/GostBelegpruefung.ts

@@ -0,0 +1,135 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../core/abschluss/gost/AbiturdatenManager';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../core/abschluss/gost/GostBelegungsfehler';
+
+export abstract class GostBelegpruefung extends JavaObject {
+
+	protected readonly pruefungen_vorher : Array<GostBelegpruefung>;
+
+	protected readonly manager : AbiturdatenManager;
+
+	protected readonly pruefungs_art : GostBelegpruefungsArt;
+
+	private readonly belegungsfehler : Vector<GostBelegungsfehler> = new Vector();
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung, welche den angegebenen Daten-Manager verwendet.
+	 * 
+	 * @param manager           der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art     die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 * @param pruefungen_vorher   eine vorher durchgeführte Abiturprüfung
+	 */
+	protected constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt, ...pruefungen_vorher : Array<GostBelegpruefung>) {
+		super();
+		this.pruefungen_vorher = pruefungen_vorher;
+		this.manager = manager;
+		this.pruefungs_art = pruefungs_art;
+	}
+
+	/**
+	 * Führt eine Belegprüfung durch.
+	 */
+	public pruefe() : void {
+		this.init();
+		if (this.pruefungs_art as unknown === GostBelegpruefungsArt.EF1 as unknown) 
+			this.pruefeEF1(); else 
+			if (this.pruefungs_art as unknown === GostBelegpruefungsArt.GESAMT as unknown) 
+				this.pruefeGesamt();
+	}
+
+	/**
+	 * Fügt einen Belegungsfehler zu der Belegprüfung hinzu. Diese Methode wird von den Sub-Klassen
+	 * aufgerufen, wenn dort ein Belegungsfehler erkannt wird.
+	 * 
+	 * @param fehler   der hinzuzufügende Belegungsfehler
+	 */
+	protected addFehler(fehler : GostBelegungsfehler) : void {
+		if (!this.belegungsfehler.contains(fehler)) 
+			this.belegungsfehler.add(fehler);
+	}
+
+	/**
+	 * Gibt die Belegungsfehler zurück, welche bei der Gesamtprüfung aufgetreten sind.
+	 * 
+	 * @return die Belegungsfehler
+	 */
+	public getBelegungsfehler() : Vector<GostBelegungsfehler> {
+		return this.belegungsfehler;
+	}
+
+	/**
+	 * Git zurück, ob ein "echter" Belegungsfehler vorliegt und nicht nur eine Warnung oder ein Hinweis.
+	 * 
+	 * @return true, falls ein "echter" Belegungsfehler vorliegt.
+	 */
+	public hatBelegungsfehler() : boolean {
+		for (let i : number = 0; i < this.belegungsfehler.size(); i++){
+			let fehler : GostBelegungsfehler = this.belegungsfehler.get(i);
+			if (!fehler.istInfo()) 
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Initialisiert die Daten für die Belegprüfungen mithilfe des Abiturdaten-Managers
+	 */
+	protected abstract init() : void;
+
+	/**
+	 * Führt alle Belegprüfungen für die EF.1 durch.
+	 */
+	protected abstract pruefeEF1() : void;
+
+	/**
+	 * Führt alle Belegprüfungen für die gesamte Oberstufe durch.
+	 */
+	protected abstract pruefeGesamt() : void;
+
+	/**
+	 * Gibt zurück, ob die angegebenen Belegprüfungsfehler einen "echten" Fehler beinhalten 
+	 * und nicht nur einen Hinweise / eine Information.
+	 * 
+	 * @param alle_fehler   die Belegprüfungsfehler und -informationen der durchgeführten Belegprüfungen
+	 * 
+	 * @return true, falls kein "echter" Belegprüfungsfehler aufgetreten ist, sonst false
+	 */
+	public static istErfolgreich(alle_fehler : Vector<GostBelegungsfehler>) : boolean {
+		for (let i : number = 0; i < alle_fehler.size(); i++){
+			let fehler : GostBelegungsfehler = alle_fehler.get(i);
+			if (!fehler.istInfo()) 
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Liefert alle Belegprüfungsfehler der übergebenen Teil-Belegprüfungen zurück.
+	 * Doppelte Fehler werden dabei nur einfach zurückgegeben (Set).
+	 *  
+	 * @param pruefungen   die durchgeführten Belegprüfungen, deren fehler zurückgegeben werden sollen.
+	 * 
+	 * @return die Menge der Belegprüfungsfehler
+	 */
+	public static getBelegungsfehlerAlle(pruefungen : List<GostBelegpruefung>) : Vector<GostBelegungsfehler> {
+		let fehler : Vector<GostBelegungsfehler> = new Vector();
+		for (let i : number = 0; i < pruefungen.size(); i++){
+			let pruefung : GostBelegpruefung = pruefungen.get(i);
+			fehler.addAll(pruefung.getBelegungsfehler());
+		}
+		return fehler;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung(obj : unknown) : GostBelegpruefung {
+	return obj as GostBelegpruefung;
+}

+ 117 - 0
core/abschluss/gost/GostBelegpruefungErgebnis.ts

@@ -0,0 +1,117 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GostBelegpruefungErgebnisFehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnisFehler } from '../../../core/abschluss/gost/GostBelegpruefungErgebnisFehler';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class GostBelegpruefungErgebnis extends JavaObject {
+
+	public erfolgreich : boolean = false;
+
+	public fehlercodes : Vector<GostBelegpruefungErgebnisFehler> = new Vector();
+
+	public log : List<String> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefungErgebnis'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): GostBelegpruefungErgebnis {
+		const obj = JSON.parse(json);
+		const result = new GostBelegpruefungErgebnis();
+		if (typeof obj.erfolgreich === "undefined")
+			 throw new Error('invalid json format, missing attribute erfolgreich');
+		result.erfolgreich = obj.erfolgreich;
+		if (!!obj.fehlercodes) {
+			for (let elem of obj.fehlercodes) {
+				result.fehlercodes?.add(GostBelegpruefungErgebnisFehler.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.log) {
+			for (let elem of obj.log) {
+				result.log?.add(elem);
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : GostBelegpruefungErgebnis) : string {
+		let result = '{';
+		result += '"erfolgreich" : ' + obj.erfolgreich + ',';
+		if (!obj.fehlercodes) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.fehlercodes.size(); i++) {
+				let elem = obj.fehlercodes.get(i);
+				result += GostBelegpruefungErgebnisFehler.transpilerToJSON(elem);
+				if (i < obj.fehlercodes.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.log) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.log.size(); i++) {
+				let elem = obj.log.get(i);
+				result += '"' + elem + '"';
+				if (i < obj.log.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<GostBelegpruefungErgebnis>) : string {
+		let result = '{';
+		if (typeof obj.erfolgreich !== "undefined") {
+			result += '"erfolgreich" : ' + obj.erfolgreich + ',';
+		}
+		if (typeof obj.fehlercodes !== "undefined") {
+			if (!obj.fehlercodes) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.fehlercodes.size(); i++) {
+					let elem = obj.fehlercodes.get(i);
+					result += GostBelegpruefungErgebnisFehler.transpilerToJSON(elem);
+					if (i < obj.fehlercodes.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.log !== "undefined") {
+			if (!obj.log) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.log.size(); i++) {
+					let elem = obj.log.get(i);
+					result += '"' + elem + '"';
+					if (i < obj.log.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnis(obj : unknown) : GostBelegpruefungErgebnis {
+	return obj as GostBelegpruefungErgebnis;
+}

+ 95 - 0
core/abschluss/gost/GostBelegpruefungErgebnisFehler.ts

@@ -0,0 +1,95 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class GostBelegpruefungErgebnisFehler extends JavaObject {
+
+	public code : String = "";
+
+	public art : String = "";
+
+	public beschreibung : String = "";
+
+
+	/**
+	 * Erzeugt eine neue Instanz eines Fehlers beim Ergebnis der Belegprüfung.
+	 * 
+	 * @param f           der Typ des Belegungsfehlers (siehe {@link GostBelegungsfehler})
+	 * @param pruef_art   die Art der durchgeführtern Belegungprüfung (siehe {@link GostBelegpruefungsArt}), um 
+	 *                    die konkrete Ausprägung des Textinformationen bestimmen zu können.
+	 */
+	public constructor(f : GostBelegungsfehler, pruef_art : GostBelegpruefungsArt);
+
+	/**
+	 * Erzeugt eine neue Instanz eines Fehlers beim Ergebnis der Belegprüfung.
+	 * Dieser Konstruktor dient als Default-Konstruktor für die Serialisierung / Deserialisierung
+	 * aus JSON-Dateien.
+	 */
+	public constructor();
+
+	/**
+	 * Implementation for method overloads of 'constructor'
+	 */
+	public constructor(__param0? : GostBelegungsfehler, __param1? : GostBelegpruefungsArt) {
+		super();
+		if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.abschluss.gost.GostBelegungsfehler')))) && ((typeof __param1 !== "undefined") && ((__param1 instanceof JavaObject) && (__param1.isTranspiledInstanceOf('de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefungsArt'))))) {
+			let f : GostBelegungsfehler = cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler(__param0);
+			let pruef_art : GostBelegpruefungsArt = cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt(__param1);
+			this.code = f.toString();
+			this.art = f.getArt().kuerzel;
+			this.beschreibung = f.getText(pruef_art);
+		} else if ((typeof __param0 === "undefined") && (typeof __param1 === "undefined")) {
+			} else throw new Error('invalid method overload');
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefungErgebnisFehler'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): GostBelegpruefungErgebnisFehler {
+		const obj = JSON.parse(json);
+		const result = new GostBelegpruefungErgebnisFehler();
+		if (typeof obj.code === "undefined")
+			 throw new Error('invalid json format, missing attribute code');
+		result.code = obj.code;
+		if (typeof obj.art === "undefined")
+			 throw new Error('invalid json format, missing attribute art');
+		result.art = obj.art;
+		if (typeof obj.beschreibung === "undefined")
+			 throw new Error('invalid json format, missing attribute beschreibung');
+		result.beschreibung = obj.beschreibung;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : GostBelegpruefungErgebnisFehler) : string {
+		let result = '{';
+		result += '"code" : ' + '"' + obj.code.valueOf() + '"' + ',';
+		result += '"art" : ' + '"' + obj.art.valueOf() + '"' + ',';
+		result += '"beschreibung" : ' + '"' + obj.beschreibung.valueOf() + '"' + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<GostBelegpruefungErgebnisFehler>) : string {
+		let result = '{';
+		if (typeof obj.code !== "undefined") {
+			result += '"code" : ' + '"' + obj.code.valueOf() + '"' + ',';
+		}
+		if (typeof obj.art !== "undefined") {
+			result += '"art" : ' + '"' + obj.art.valueOf() + '"' + ',';
+		}
+		if (typeof obj.beschreibung !== "undefined") {
+			result += '"beschreibung" : ' + '"' + obj.beschreibung.valueOf() + '"' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungErgebnisFehler(obj : unknown) : GostBelegpruefungErgebnisFehler {
+	return obj as GostBelegpruefungErgebnisFehler;
+}

+ 58 - 0
core/abschluss/gost/GostBelegpruefungsArt.ts

@@ -0,0 +1,58 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class GostBelegpruefungsArt extends JavaObject {
+
+	public static readonly EF1 : GostBelegpruefungsArt = new GostBelegpruefungsArt("EF.1", "nur EF.1");
+
+	public static readonly GESAMT : GostBelegpruefungsArt = new GostBelegpruefungsArt("Gesamt", "die gesamte Oberstufe");
+
+	public readonly kuerzel : String;
+
+	public readonly beschreibung : String;
+
+
+	/**
+	 * Erzeugt ein neues Abitur-Belegungsart-Objekt
+	 * 
+	 * @param kuerzel        das der Kurs-Belegungsart
+	 * @param beschreibung   die textuelle Beschreibung der Kurs-Belegungsart
+	 */
+	private constructor(kuerzel : String, beschreibung : String) {
+		super();
+		this.kuerzel = kuerzel;
+		this.beschreibung = beschreibung;
+	}
+
+	/**
+	 * Gibt die Art der Belegprüfung anhand des übergebenen Kürzels zurück.
+	 *
+	 * @param kuerzel    das Kürzel der Art der Belegprüfung
+	 *  
+	 * @return die Art der Belegprüfung
+	 */
+	public static fromKuerzel(kuerzel : String | null) : GostBelegpruefungsArt | null {
+		if (kuerzel === null) 
+			return null;
+		switch (kuerzel) {
+			case "EF.1": 
+				return GostBelegpruefungsArt.EF1;
+			case "Gesamt": 
+				return GostBelegpruefungsArt.GESAMT;
+		}
+		return null;
+	}
+
+	public toString() : String {
+		return this.kuerzel;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefungsArt'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt(obj : unknown) : GostBelegpruefungsArt {
+	return obj as GostBelegpruefungsArt;
+}

+ 283 - 0
core/abschluss/gost/GostBelegungsfehler.ts

@@ -0,0 +1,283 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { GostBelegungsfehlerArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehlerArt } from '../../../core/abschluss/gost/GostBelegungsfehlerArt';
+
+export class GostBelegungsfehler extends JavaObject {
+
+	public static readonly ABI_10 : GostBelegungsfehler = new GostBelegungsfehler("ABI_10", GostBelegungsfehlerArt.BELEGUNG, "Unter den vier Abiturfächern müssen zwei der Fächer Deutsch, Mathematik oder Fremdsprache sein.", null);
+
+	public static readonly ABI_11 : GostBelegungsfehler = new GostBelegungsfehler("ABI_11", GostBelegungsfehlerArt.BELEGUNG, "Religionslehre und Sport dürfen nicht gleichzeitig Abiturfächer sein.", null);
+
+	public static readonly ABI_12 : GostBelegungsfehler = new GostBelegungsfehler("ABI_12", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "In Q2.2 muss das 3. Abiturfach schriftlich belegt sein.", null);
+
+	public static readonly ABI_13 : GostBelegungsfehler = new GostBelegungsfehler("ABI_13", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "In Q2.2 muss das 4. Abiturfach mündlich belegt sein.", null);
+
+	public static readonly ABI_15 : GostBelegungsfehler = new GostBelegungsfehler("ABI_15", GostBelegungsfehlerArt.BELEGUNG, "Sport kann nur als 2. oder als 4. Abiturfach gewählt werden.", null);
+
+	public static readonly ABI_16 : GostBelegungsfehler = new GostBelegungsfehler("ABI_16", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Fächer, die keine Abiturfächer sind, müssen in Q2.2 mündlich belegt werden.", null);
+
+	public static readonly ABI_17 : GostBelegungsfehler = new GostBelegungsfehler("ABI_17", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Das 3. Abiturfach muss von Q1.1 bis Q2.2 schriftlich belegt sein.", null);
+
+	public static readonly ABI_18 : GostBelegungsfehler = new GostBelegungsfehler("ABI_18", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Das 4. Abiturfach muss von Q1.1 bis Q2.1 schriftlich belegt sein.", null);
+
+	public static readonly ABI_19 : GostBelegungsfehler = new GostBelegungsfehler("ABI_19", GostBelegungsfehlerArt.BELEGUNG, "Unter den vier Abiturfächern müssen zwei der Fächer Deutsch, Mathematik oder Fremdsprache sein. Dies kann nicht durch zwei Fremdsprachen erfüllt werden.", null);
+
+	public static readonly ABI_21 : GostBelegungsfehler = new GostBelegungsfehler("ABI_21", GostBelegungsfehlerArt.BELEGUNG, "Es kann nur ein Fach 1. Abiturfach sein.", null);
+
+	public static readonly ABI_22 : GostBelegungsfehler = new GostBelegungsfehler("ABI_22", GostBelegungsfehlerArt.BELEGUNG, "Es kann nur ein Fach 2. Abiturfach sein.", null);
+
+	public static readonly ABI_23 : GostBelegungsfehler = new GostBelegungsfehler("ABI_23", GostBelegungsfehlerArt.BELEGUNG, "Es kann nur ein Fach 3. Abiturfach sein.", null);
+
+	public static readonly ABI_24 : GostBelegungsfehler = new GostBelegungsfehler("ABI_24", GostBelegungsfehlerArt.BELEGUNG, "Es kann nur ein Fach 4. Abiturfach sein.", null);
+
+	public static readonly ANZ_10 : GostBelegungsfehler = new GostBelegungsfehler("ANZ_10", GostBelegungsfehlerArt.BELEGUNG, "In der Einführungsphase müssen in jedem Halbjahr mindestens 10 Fächer belegt werden. Vertiefungskurse werden bei der Zählung nicht berücksichtigt.", "In EF.1 müssen mindestens 10 Kurse belegt werden. Bei der Kurszählung werden Vertiefungskurse nicht mitgezählt.");
+
+	public static readonly ANZ_11_INFO : GostBelegungsfehler = new GostBelegungsfehler("ANZ_11_INFO", GostBelegungsfehlerArt.HINWEIS, "Die Stundenbandbreite sollte pro Halbjahr 32 bis 36 Stunden betragen, um eine gleichmäßige Stundenbelastung zu gewährleisten.", "Die Gesamtstundenzahl sollte 32 bis 36 Stunden betragen, um eine gleichmäßige Stundenbelastung in der Oberstufe zu gewährleisten.");
+
+	public static readonly ANZ_12 : GostBelegungsfehler = new GostBelegungsfehler("ANZ_12", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase müssen mindestens 38 anrechenbare Kurse belegt werden.", null);
+
+	public static readonly ANZ_13 : GostBelegungsfehler = new GostBelegungsfehler("ANZ_13", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase müssen mindestens 32 anrechenbare Kurse belegt werden.", null);
+
+	public static readonly BIL_4_INFO : GostBelegungsfehler = new GostBelegungsfehler("BIL_4_INFO", GostBelegungsfehlerArt.HINWEIS, "Programmfehler: Dieser Hinweis ist für eine Gesamtbelegprüfung der Sek II nicht vorgesehen!", "Soll ein bilinguales Sachfach zum Sprachenschwerpunkt beitragen, so muss es schriftlich belegt werden.");
+
+	public static readonly BIL_10 : GostBelegungsfehler = new GostBelegungsfehler("BIL_10", GostBelegungsfehlerArt.BELEGUNG, "Im bilingualen Bildungsgang muss die bilinguale Fremdsprache in EF.1 und EF.2 schriftlich und in Q1.1 bis Q2.2 als Leistungskurs belegt werden.", "Im bilingualen Bildungsgang muss die bilinguale Fremdsprache schriftlich belegt werden.");
+
+	public static readonly BIL_11_INFO : GostBelegungsfehler = new GostBelegungsfehler("BIL_11_INFO", GostBelegungsfehlerArt.HINWEIS, "Im bilingualen Bildungsgang werden in EF.1 und EF.2 in der Regel zwei bilinguale Sachfächer belegt.", "Im bilingualen Bildungsgang sollten zwei bilinguale Sachfächer belegt werden.");
+
+	public static readonly BIL_12 : GostBelegungsfehler = new GostBelegungsfehler("BIL_12", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Im bilingualen Bildungsgang muss ein bilinguales Sachfach durchgehend von Q1.1 bis Q2.1 schriftlich belegt werden.", null);
+
+	public static readonly BIL_13 : GostBelegungsfehler = new GostBelegungsfehler("BIL_13", GostBelegungsfehlerArt.BELEGUNG, "Ein bilinguales Sachfach muss unter den Abiturfächern sein.", null);
+
+	public static readonly BIL_14 : GostBelegungsfehler = new GostBelegungsfehler("BIL_14", GostBelegungsfehlerArt.BELEGUNG, "Es können nur bilinguale Sachfächer belegt werden, deren Sprache in der Sekundarstufe erlernt wurde.", "Es können nur bilinguale Sachfächer belegt werden, deren Sprache in der Sekundarstufe erlernt wurde.");
+
+	public static readonly BIL_15 : GostBelegungsfehler = new GostBelegungsfehler("BIL_15", GostBelegungsfehlerArt.BELEGUNG, "Im bilingualen Bildungsgang muss in EF.1 und EF.2 mindestens ein bilinguales Sachfach belegt werden.", "Im bilingualen Bildungsgang muss mindestens ein bilinguales Sachfach belegt werden.");
+
+	public static readonly D_10 : GostBelegungsfehler = new GostBelegungsfehler("D_10", GostBelegungsfehlerArt.BELEGUNG, "Deutsch muss von EF.1 bis Q2.2 belegt werden.", "Deutsch muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly D_11 : GostBelegungsfehler = new GostBelegungsfehler("D_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Deutsch muss von EF.1 bis wenigstens Q2.1 schriftlich belegt werden.", "Deutsch muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly E1BEL_10 : GostBelegungsfehler = new GostBelegungsfehler("E1BEL_10", GostBelegungsfehlerArt.BELEGUNG, "Bis auf Literatur, vokal- und instrumentalpraktische Kurse, Zusatzkurse, Vertiefungsfächer und Projektkurse können keine Fächer hinzugewählt werden, die nicht schon ab EF.1 belegt wurden.", null);
+
+	public static readonly FS_10 : GostBelegungsfehler = new GostBelegungsfehler("FS_10", GostBelegungsfehlerArt.BELEGUNG, "Mindestens eine Fremdsprache muss von EF.1 bis Q2.2 durchgehend belegt werden. Handelt es sich hierbei um eine neu einsetzende Fremdsprache, so muss zusätzlich mindestens eine aus der SI fortgeführte Fremdsprache von EF.1 bis EF.2 belegt werden.", "Da die gewählte Fremdsprache in der Oberstufe nicht durchgehend angeboten wird, muss entweder zusätzliche eine neu einsetzende Fremdsprache, oder eine andere in der Sekundarstufe I begonnene Fremdsprache belegt werden.");
+
+	public static readonly FS_11 : GostBelegungsfehler = new GostBelegungsfehler("FS_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Mindestens eine durchgehend belegte Fremdsprache muss von EF.1 bis Q2.1 schriftlich belegt sein.", "Mindestens eine Fremdsprache muss in EF.1 schriftlich belegt werden. Die zu wählende Fremdsprache muss durchgehend angeboten werden.");
+
+	public static readonly FS_12 : GostBelegungsfehler = new GostBelegungsfehler("FS_12", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "In EF.1 und EF.2 müssen alle gewählten Fremdsprachenfächer schriftlich belegt werden.", "In EF.1 müssen alle belegten Fremdsprachen schriftlich belegt werden.");
+
+	public static readonly FS_13 : GostBelegungsfehler = new GostBelegungsfehler("FS_13", GostBelegungsfehlerArt.BELEGUNG, "Bei unvollendeter 2. Fremdsprache, muss die in der Sekundarstufe 1 begonnene 2. Fremdsprache in EF schriftlich oder eine neu einsetzende Fremdsprache durchgehend schriftlich belegt werden.", "Wurde die 2. Fremdsprache erst ab Klasse 8 erlernt, muss die in der Sekundarstufe 1 begonnene 2. Fremdsprache oder eine neu einsetzende Fremdsprache schriftlich in EF.1 belegt werden.");
+
+	public static readonly FS_14 : GostBelegungsfehler = new GostBelegungsfehler("FS_14", GostBelegungsfehlerArt.BELEGUNG, "Bei fehlender 2. Fremdsprache muss eine neu einsetzende Fremdsprache durchgehend schriftlich belegt werden.", "Wurde bisher keine 2. Fremdsprache erlernt, muss eine neu einsetzende Fremdsprache in EF.1 schriftlich belegt werden.");
+
+	public static readonly FS_15 : GostBelegungsfehler = new GostBelegungsfehler("FS_15", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Kurse in neu einsetzenden Fremdsprachen müssen schriftlich belegt werden.", null);
+
+	public static readonly FS_16 : GostBelegungsfehler = new GostBelegungsfehler("FS_16", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Mindestens eine fortgeführte Fremdsprache muss in EF.1 und EF.2 schriftlich belegt werden.", "Mindestens eine in der Sekundarstufe I begonnene Fremdsprache muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly FS_17 : GostBelegungsfehler = new GostBelegungsfehler("FS_17", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Neu einsetzende Fremdsprachen dürfen nicht als Leistungskurs belegt werden.", null);
+
+	public static readonly FS_18 : GostBelegungsfehler = new GostBelegungsfehler("FS_18", GostBelegungsfehlerArt.BELEGUNG, "Mindestens eine Fremdsprache muss von EF.1 bis Q2.2 belegt werden.", "Mindestens eine in der Sekundarstufe I begonnene Fremdsprache muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly FS_19_INFO : GostBelegungsfehler = new GostBelegungsfehler("FS_19_INFO", GostBelegungsfehlerArt.HINWEIS, "Eine erfolgreiche Feststellungsprüfung in der Muttersprache am Ende der Sekundarstufe I und am Ende von EF.2 ist notwendig, um die Fremdsprachenbedingungen zu erfüllen.", "Eine erfolgreiche Feststellungsprüfung in der Muttersprache am Ende der Sekundarstufe I und am Ende von EF.2 ist notwendig, um die Fremdsprachenbedingungen zu erfüllen.");
+
+	public static readonly FS_20 : GostBelegungsfehler = new GostBelegungsfehler("FS_20", GostBelegungsfehlerArt.BELEGUNG, "Eine neu einsetzende Fremdsprache kann nur gewählt werden, wenn diese nicht zuvor in der Sekundarstaufe I belegt wurde. Die Sprachenfolge ist fehlerhaft.", "Eine neu einsetzende Fremdsprache kann nur gewählt werden, wenn diese nicht zuvor in der Sekundarstaufe I belegt wurde. Die Sprachenfolge ist fehlerhaft.");
+
+	public static readonly FS_21 : GostBelegungsfehler = new GostBelegungsfehler("FS_21", GostBelegungsfehlerArt.BELEGUNG, "Eine fortgeführte Fremdsprache wurde in der Sprachenfolge als neu einsetzend eingetragen. Die Sprachenfolge ist fehlerhaft.", "Eine fortgeführte Fremdsprache wurde in der Sprachenfolge als neu einsetzend eingetragen. Die Sprachenfolge ist fehlerhaft.");
+
+	public static readonly FS_22_INFO : GostBelegungsfehler = new GostBelegungsfehler("FS_22_INFO", GostBelegungsfehlerArt.HINWEIS, "Englisch wurde nicht in der Sprachenfolge eingetragen. Bitte Prüfen Sie die Sprachenfolge auf Korrektheit.", "Englisch wurde nicht in der Sprachenfolge eingetragen. Bitte Prüfen Sie die Sprachenfolge auf Korrektheit.");
+
+	public static readonly FS_23 : GostBelegungsfehler = new GostBelegungsfehler("FS_23", GostBelegungsfehlerArt.BELEGUNG, "Es wird das Fach einer fortgeführten Fremdsprache belegt, zu dem es keine entsprechende Eintragung einer Belegung oder Sprachprüfung in der Sekundarstufe I gibt. Bitte die Sprachenfolge und Sprachprüfungen prüfen.", "Es wird das Fach einer fortgeführten Fremdsprache belegt, zu dem es keine entsprechende Eintragung einer Belegung oder Sprachprüfung in der Sekundarstufe I gibt. Bitte die Sprachenfolge und Sprachprüfungen prüfen.");
+
+	public static readonly FS_24 : GostBelegungsfehler = new GostBelegungsfehler("FS_24", GostBelegungsfehlerArt.BELEGUNG, "Ist die Bedingungen für die Belegung einer zweiten Fremdsprache in der Sekundarstufe I noch nicht erfüllt worden, so müssen in der Einführungsphase zwei Fremdsprachen belegt werden.", "Ist die Bedingungen für die Belegung einer zweiten Fremdsprache in der Sekundarstufe I noch nicht erfüllt worden, so müssen in der Einführungsphase zwei Fremdsprachen belegt werden.");
+
+	public static readonly FS_25 : GostBelegungsfehler = new GostBelegungsfehler("FS_25", GostBelegungsfehlerArt.BELEGUNG, "Es wurde keine fortführbare Fremdsprache in der Sprachbelegung gefunden. Bitte prüfen Sie die Sprachenfolge.", "Es wurde keine fortführbare Fremdsprache in der Sprachbelegung gefunden. Bitte prüfen Sie die Sprachenfolge.");
+
+	public static readonly GE_1_INFO : GostBelegungsfehler = new GostBelegungsfehler("GE_1_INFO", GostBelegungsfehlerArt.HINWEIS, "Programmfehler: Dieser Hinweis ist für eine Gesamtbelegprüfung der Sek II nicht vorgesehen!", "Wird Geschichte nicht in EF.1 belegt, so muss Geschichte in der Qualifikationsphase als Zusatzkurs gewählt werden.");
+
+	public static readonly GE_10 : GostBelegungsfehler = new GostBelegungsfehler("GE_10", GostBelegungsfehlerArt.BELEGUNG, "Geschichte muss von EF.1 bis wenigstens Q1.2 oder als Zusatzkurs (in der Regel von Q2.1 bis Q2.2) belegt werden.", null);
+
+	public static readonly GKS_10 : GostBelegungsfehler = new GostBelegungsfehler("GKS_10", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase sind pro Halbjahr mindestens 7 Fächer in Grundkursen zu wählen.", null);
+
+	public static readonly GKS_11 : GostBelegungsfehler = new GostBelegungsfehler("GKS_11", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase sind pro Halbjahr mindestens 6 Fächer in Grundkursen zu wählen.", null);
+
+	public static readonly GW_10 : GostBelegungsfehler = new GostBelegungsfehler("GW_10", GostBelegungsfehlerArt.BELEGUNG, "Mindestens eine Gesellschaftswissenschaft muss von Q1.1 bis Q2.2 durchgehend belegt werden.", "Mindestens eine Gesellschaftswissenschaft muss in EF.1 belegt werden und durchgängig belegbar sein.");
+
+	public static readonly GW_11 : GostBelegungsfehler = new GostBelegungsfehler("GW_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "In EF.1 und EF.2 muss mindestens eine Gesellschaftswissenschaft schriftlich belegt sein.", "Mindestens eine Gesellschaftswissenschaft muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly GW_12 : GostBelegungsfehler = new GostBelegungsfehler("GW_12", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Mindestens eine Gesellschaftswissenschaft oder Religionslehre muss von Q1.1 bis wenigstens Q2.1 schriftlich belegt werden.", null);
+
+	public static readonly IGF_10 : GostBelegungsfehler = new GostBelegungsfehler("IGF_10", GostBelegungsfehlerArt.BELEGUNG, "Inhaltsgleiche Fächer und Projektkurse dürfen in jedem Halbjahr nur einmal belegt werden.", "Inhaltsgleiche Fächer dürfen nur einmal belegt werden.");
+
+	public static readonly KU_MU_10 : GostBelegungsfehler = new GostBelegungsfehler("KU_MU_10", GostBelegungsfehlerArt.BELEGUNG, "Mindestens eines der Fächer Kunst oder Musik muss von EF.1 bis wenigstens Q1.2 durchgehend belegt werden. In der Qualifikationsphase kann auch alternativ Literatur, ein vokalpraktisches oder ein instrumentalpraktisches Fach mit zwei Kursen belegt werden.", "Mindestens eines der Fächer Kunst oder Musik muss in EF.1 belegt werden");
+
+	public static readonly L_10_INFO : GostBelegungsfehler = new GostBelegungsfehler("L_10_INFO", GostBelegungsfehlerArt.HINWEIS, "Um das Latinum zu erlangen muss Latein in EF.1 und EF.2 belegt werden.", "Um das Latinum zu erlangen muss Latein in EF.1 schriftlich fortgeführt werden.");
+
+	public static readonly L_11_INFO : GostBelegungsfehler = new GostBelegungsfehler("L_11_INFO", GostBelegungsfehlerArt.HINWEIS, "Um das Latinum zu erlangen muss Latein mindestens bis Q1.2, je nach Stundenvolumen sogar bis Q2.2 belegt werden.", null);
+
+	public static readonly L_12_INFO : GostBelegungsfehler = new GostBelegungsfehler("L_12_INFO", GostBelegungsfehlerArt.HINWEIS, "Um das Latinum zu erlangen muss Latein mindestens bis EF.2, je nach Beginn und Stundenvolumen sogar bis Q2.2 belegt werden.", null);
+
+	public static readonly LI_IV_10 : GostBelegungsfehler = new GostBelegungsfehler("LI_IV_10", GostBelegungsfehlerArt.BELEGUNG, "Die Fächer Literatur, instrumentalpraktischer bzw. vokalpraktischer Grundkurs dürfen maximal in zwei aufeinanderfolgenden Halbjahren belegt werden.", null);
+
+	public static readonly LI_IV_11 : GostBelegungsfehler = new GostBelegungsfehler("LI_IV_11", GostBelegungsfehlerArt.BELEGUNG, "Es darf nur eins der Fächer Literatur, IP oder VP belegt werden. (Schulen mit genehmigtem musisch-künstlerischem Schwerpunkt müssen betroffene Schüler in SchILD-NRW manuell zulassen).", null);
+
+	public static readonly LK_10 : GostBelegungsfehler = new GostBelegungsfehler("LK_10", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase müssen zwei Fächer durchgehend in Leistungskursen belegt werden.", null);
+
+	public static readonly LK_11 : GostBelegungsfehler = new GostBelegungsfehler("LK_11", GostBelegungsfehlerArt.BELEGUNG, "Es dürfen nicht mehr als zwei Fächer als Leistungskurse belegt werden.", null);
+
+	public static readonly LK1_10 : GostBelegungsfehler = new GostBelegungsfehler("LK1_10", GostBelegungsfehlerArt.BELEGUNG, "Erstes Abiturfach nicht eindeutig identifizierbar.", null);
+
+	public static readonly LK1_11 : GostBelegungsfehler = new GostBelegungsfehler("LK1_11", GostBelegungsfehlerArt.BELEGUNG, "Das erste Leistungskursfach muss eine fortgeführte Fremdsprache, Mathematik, eine klassische Naturwissenschaft oder Deutsch sein.", null);
+
+	public static readonly LK1_12 : GostBelegungsfehler = new GostBelegungsfehler("LK1_12", GostBelegungsfehlerArt.BELEGUNG, "Ist Deutsch erstes Leistungskursfach, muss Mathematik oder eine Fremdsprache unter den vier Abiturfächern sein.", null);
+
+	public static readonly LK1_13 : GostBelegungsfehler = new GostBelegungsfehler("LK1_13", GostBelegungsfehlerArt.BELEGUNG, "Die Abiturfächer müssen alle drei Aufgabenfelder abdecken. Insgesamt sind vier Abiturfächer zu belegen.", null);
+
+	public static readonly M_10 : GostBelegungsfehler = new GostBelegungsfehler("M_10", GostBelegungsfehlerArt.BELEGUNG, "Mathematik muss von EF.1 bis Q2.2 belegt werden.", "Mathematik muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly M_11 : GostBelegungsfehler = new GostBelegungsfehler("M_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Mathematik muss von EF.1 bis wenigstens Q2.1 schriftlich belegt werden.", "Mathematik muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly NW_10 : GostBelegungsfehler = new GostBelegungsfehler("NW_10", GostBelegungsfehlerArt.BELEGUNG, "Mindestens eine klassische Naturwissenschaft (Physik, Biologie, Chemie) muss durchgehend von Q1.1 bis Q2.2 belegt werden.", "Mindestens eines der Fächer Physik, Chemie oder Biologie muss in EF.1 belegt werden und durchgängig belegbar sein.");
+
+	public static readonly NW_11 : GostBelegungsfehler = new GostBelegungsfehler("NW_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "In EF.1 und EF.2 muss mindestens eine klassische Naturwissenschaft schriftlich belegt sein.", "Mindestens eines der Fächer Physik, Chemie oder Biologie muss in EF.1 schriftlich belegt werden.");
+
+	public static readonly NW_FS_10 : GostBelegungsfehler = new GostBelegungsfehler("NW_FS_10", GostBelegungsfehlerArt.BELEGUNG, "Von EF.1 bis Q2.2 müssen entweder zwei Naturwissenschaften oder zwei Fremdsprachen durchgehend gewählt werden. Hierbei ist eine Naturwissenschaft oder sind zwei Fremdsprachen schriftlich zu belegen. Zu den Fremdsprachen zählen auch in einer weiteren Fremdsprache unterrichtete Sachfächer.", "In EF.1 müssen entweder zwei Naturwissenschaften oder zwei Fremdsprachen belegt werden. Hierbei ist eine Naturwissenschaft oder sind zwei Fremdsprachen schriftlich zu belegen. Zu den Fremdsprachen zählen auch in einer weiteren Fremdsprache unterrichtete Sachfächer.");
+
+	public static readonly NW_FS_11 : GostBelegungsfehler = new GostBelegungsfehler("NW_FS_11", GostBelegungsfehlerArt.SCHRIFTLICHKEIT, "Zwei Fremdsprachen oder eines von mindestens zwei naturwissenschaftlichen Fächern muss von Q1.1 bis wenigstens Q2.1 schriftlich belegt werden.", null);
+
+	public static readonly NW_FS_12_INFO : GostBelegungsfehler = new GostBelegungsfehler("NW_FS_12_INFO", GostBelegungsfehlerArt.HINWEIS, "Da von EF.1 bis Q2.2 weniger als zwei naturwissenschaftliche Fächer durchgehend belegt wurden, oder kein naturwissenschaftliches Fach schriftlich belegt wurde, liegt ausschließlich ein Sprachenschwerpunkt vor.", "Da in EF.1 weniger als zwei Naturwissenschaften belegt, oder keine schriftlich belegt wurden, müssen zwei Fremdsprachen bis Q2.2 durchgehend schriftlich belegt werden.");
+
+	public static readonly NW_FS_13_INFO : GostBelegungsfehler = new GostBelegungsfehler("NW_FS_13_INFO", GostBelegungsfehlerArt.HINWEIS, "Da von EF.1 bis Q2.2 weniger als zwei Fremdsprachen schriftlich belegt wurden, liegt ausschließlich ein naturwissenschaftlicher Schwerpunkt vor.", "Da in EF.1 weniger als zwei Fremdsprachen schriftlich belegt wurden, müssen zwei Naturwissenschaften bis Q2.2 belegt, davon mindestens eine schriftlich belegt werden.");
+
+	public static readonly PF_10 : GostBelegungsfehler = new GostBelegungsfehler("PF_10", GostBelegungsfehlerArt.BELEGUNG, "In der Einführungsphase können keine Projektkurse belegt werden.", "In EF.1 können keine Projektkurse belegt werden.");
+
+	public static readonly PF_11 : GostBelegungsfehler = new GostBelegungsfehler("PF_11", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase kann maximal ein Projektkurs belegt werden.", null);
+
+	public static readonly PF_12 : GostBelegungsfehler = new GostBelegungsfehler("PF_12", GostBelegungsfehlerArt.BELEGUNG, "Projektkurse können nur dann belegt werden, wenn gleichzeitig oder maximal zwei Halbjahre vorher auch das Leitfach im gleichem Umfang belegt wurde.", null);
+
+	public static readonly PF_13 : GostBelegungsfehler = new GostBelegungsfehler("PF_13", GostBelegungsfehlerArt.BELEGUNG, "Ein Projektkurs kann nur belegt werden, wenn in der Qualifikationsphase zeitgleich oder vorab auch sein Leitfach zwei Halbjahre lang belegt wurde.", null);
+
+	public static readonly PF_14 : GostBelegungsfehler = new GostBelegungsfehler("PF_14", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase kann maximal ein Projektkurs in zwei aufeinanderfolgenden Halbjahren belegt werden.", null);
+
+	public static readonly PF_15 : GostBelegungsfehler = new GostBelegungsfehler("PF_15", GostBelegungsfehlerArt.BELEGUNG, "Es existiert kein Projektkurs, der als besondere Lernleistung eingebracht werden kann.", null);
+
+	public static readonly PF_16_INFO : GostBelegungsfehler = new GostBelegungsfehler("PF_16_INFO", GostBelegungsfehlerArt.HINWEIS, "Wird der Projektkurs als besondere Lernleistung in das Abitur eingebracht, so zählt er nicht mehr zu den einbringungsfähigen Kursen in Block I.", null);
+
+	public static readonly PF_17_INFO : GostBelegungsfehler = new GostBelegungsfehler("PF_17_INFO", GostBelegungsfehlerArt.HINWEIS, "Ein Projektkurs soll nur im Ausnahmefall abgewählt werden. Bei einem abgewählten Projektkurs werden lediglich die Wochenstunden auf die Laufbahn angerechnet.", null);
+
+	public static readonly PF_18 : GostBelegungsfehler = new GostBelegungsfehler("PF_18", GostBelegungsfehlerArt.BELEGUNG, "Ein Projektkurs kann nicht in der Q2.2 beginnen.", null);
+
+	public static readonly RE_10 : GostBelegungsfehler = new GostBelegungsfehler("RE_10", GostBelegungsfehlerArt.BELEGUNG, "Religionslehre muss wenigstens von EF.1-Q1.2 durchgehend belegt werden. Als Ersatz kann Philosophie dienen, sofern Philosophie nicht die einzige von EF.1 bis Q2.2 durchgehend belegte Gesellschaftswissenschaft ist. In diesen Fällen muss ein weiteres Fach der Gesellschaftswissenschaften als Religionsersatz dienen.", "Ein Religionskurs muss in EF.1 belegt werden. Als Ersatz kann Philosophie belegt werden, sofern eine weitere Gesellschaftswissenschaft bis zum Abitur belegt wird.");
+
+	public static readonly RE_11 : GostBelegungsfehler = new GostBelegungsfehler("RE_11", GostBelegungsfehlerArt.BELEGUNG, "Philosophie darf nicht die einzige durchgehend von Q1.1 bis Q2.2 belegte Geisteswissenschaft sein.", null);
+
+	public static readonly SP_10 : GostBelegungsfehler = new GostBelegungsfehler("SP_10", GostBelegungsfehlerArt.BELEGUNG, "Sport muss von EF.1 bis Q2.2 belegt werden.", "Sport muss in EF.1 belegt werden.");
+
+	public static readonly STD_10 : GostBelegungsfehler = new GostBelegungsfehler("STD_10", GostBelegungsfehlerArt.BELEGUNG, "Der Pflichtunterricht darf 102 Stunden nicht unterschreiten.", null);
+
+	public static readonly STD_11_INFO : GostBelegungsfehler = new GostBelegungsfehler("STD_11_INFO", GostBelegungsfehlerArt.HINWEIS, "Der Pflichtunterricht darf nur in begründeten Ausnahmefällen 102 Stunden unterschreiten.", null);
+
+	public static readonly SW_1_INFO : GostBelegungsfehler = new GostBelegungsfehler("SW_1_INFO", GostBelegungsfehlerArt.HINWEIS, "Programmfehler: Dieser Hinweis ist für eine Gesamtbelegprüfung der Sek II nicht vorgesehen!", "Wird Sozialwissenschaften nicht in EF.1 belegt, so muss Sozialwissenschaften in der Qualifikationsphase als Zusatzkurs gewählt werden.");
+
+	public static readonly SW_10 : GostBelegungsfehler = new GostBelegungsfehler("SW_10", GostBelegungsfehlerArt.BELEGUNG, "Sozialwissenschaften muss von EF.1 bis wenigstens Q1.2 oder als Zusatzkurs (in der Regel von Q2.1 bis Q2.2) belegt werden.", null);
+
+	public static readonly VF_10 : GostBelegungsfehler = new GostBelegungsfehler("VF_10", GostBelegungsfehlerArt.BELEGUNG, "In der Einführungsphase können maximal vier Vertiefungskurse belegt werden.", null);
+
+	public static readonly VF_11 : GostBelegungsfehler = new GostBelegungsfehler("VF_11", GostBelegungsfehlerArt.BELEGUNG, "In der Qualifikationsphase können maximal zwei Vertiefungskurse belegt werden.", null);
+
+	public static readonly WST_10 : GostBelegungsfehler = new GostBelegungsfehler("WST_10", GostBelegungsfehlerArt.BELEGUNG, "Die Summe der durchschnittlichen Jahreskursstunden von EF.1 bis Q2.2 darf 100 nicht unterschreiten.", null);
+
+	public static readonly WST_20 : GostBelegungsfehler = new GostBelegungsfehler("WST_20", GostBelegungsfehlerArt.BELEGUNG, "Die durchschnittliche Wochenstundenzahl muss in der Einführungsphase mindestens 34 Stunden betragen.", null);
+
+	public static readonly WST_21 : GostBelegungsfehler = new GostBelegungsfehler("WST_21", GostBelegungsfehlerArt.BELEGUNG, "Die durchschnittliche Wochenstundenzahl muss in der Qualifikationsphase mindestens 34 Stunden betragen.", null);
+
+	public static readonly ZK_10 : GostBelegungsfehler = new GostBelegungsfehler("ZK_10", GostBelegungsfehlerArt.BELEGUNG, "Ein Zusatzkurs in Geschichte oder Sozialwissenschaften kann nur angewählt werden, wenn das Fach im vorangegangenen Halbjahr nicht belegt wurde.", null);
+
+	public static readonly ZK_11 : GostBelegungsfehler = new GostBelegungsfehler("ZK_11", GostBelegungsfehlerArt.BELEGUNG, "Ein Zusatzkurs in Geschichte oder Sozialwissenschaften muss in zwei aufeinanderfolgenden Halbjahren belegt werden.", null);
+
+	public static readonly ZK_12 : GostBelegungsfehler = new GostBelegungsfehler("ZK_12", GostBelegungsfehlerArt.BELEGUNG, "Zusatzkurse dürfen maximal in zwei aufeinanderfolgenden Halbjahren belegt werden.", null);
+
+	public static readonly ZK_13 : GostBelegungsfehler = new GostBelegungsfehler("ZK_13", GostBelegungsfehlerArt.BELEGUNG, "Zusatzkurse dürfen nur einmal pro Fach belegt werden und können nicht in einem bilingualen Fach gewählt werden.", null);
+
+	public readonly code : String;
+
+	public readonly art : GostBelegungsfehlerArt;
+
+	public readonly textGESAMT : String;
+
+	public readonly textEF1 : String;
+
+
+	/**
+	 * Erstellt einen neuen Belegungsfehlerfür die Aufzählung (s.o.). Dabei wird ein
+	 * Text für die Gesamtprüfung und die EF.1-Prüfung angegeben.    
+	 * 
+	 * @param code         der eindeutige Code des Belegungsfehlers
+	 * @param art          die Fehlerart (Belegungsfehler, Schriftlichkeit oder Information)
+	 * @param textGESAMT   der zugeordnete Text für die Gesamtbelegprüfung oder null
+	 * @param textEF1      der zugeordnete Text für die EF.1-Prüfung oder null
+	 */
+	private constructor(code : String, art : GostBelegungsfehlerArt, textGESAMT : String | null, textEF1 : String | null) {
+		super();
+		this.code = code;
+		this.art = art;
+		this.textGESAMT = textGESAMT !== null ? textGESAMT : "Programmfehler: Diese Belegungsfehlerart ist für eine Gesamt-Prüfung nicht vorgesehen!";
+		this.textEF1 = (textEF1 !== null) ? textEF1 : "Programmfehler: Diese Belegungsfehlerart ist für eine Prüfung eingeschränkt auf die EF.1 nicht vorgesehen!";
+	}
+
+	/**
+	 * Gibt zurück, ob es sich bei dem Belegungsfehler nur um eine Information
+	 * und nicht um einen "echten" Fehler handelt.
+	 *   
+	 * @return true, falls es sich nur um eine Information handelt, sonst false
+	 */
+	public istInfo() : boolean {
+		return (this.art as unknown === GostBelegungsfehlerArt.HINWEIS as unknown);
+	}
+
+	/**
+	 * Gibt zurück, ob es sich bei dem Belegungsfehler um einen "echten" Fehler handelt
+	 * und nicht nur um eine Information.
+	 * 
+	 * @return true, falls es sich um einen "echten" Fehler handelt, sonst false
+	 */
+	public istFehler() : boolean {
+		return (this.art as unknown !== GostBelegungsfehlerArt.HINWEIS as unknown);
+	}
+
+	/**
+	 * Gibt die Art des Belegungsfehlers zurück.
+	 * 
+	 * @return die Art des Belegungsfehlers
+	 */
+	public getArt() : GostBelegungsfehlerArt {
+		return this.art;
+	}
+
+	/**
+	 * Gibt je nach angegebenener Belegprüfungsart den zugehörigen Text für den Belegungsfehler 
+	 * zurück.
+	 * 
+	 * @param pruef_art   die Belegprüfungsart
+	 * 
+	 * @return der zugehörige Text des Belegungsfehlers
+	 */
+	public getText(pruef_art : GostBelegpruefungsArt) : String {
+		if (pruef_art as unknown === GostBelegpruefungsArt.EF1 as unknown) 
+			return this.textEF1;
+		if (pruef_art as unknown === GostBelegpruefungsArt.GESAMT as unknown) 
+			return this.textGESAMT;
+		return this.textGESAMT;
+	}
+
+	public toString() : String {
+		return this.code;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegungsfehler'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler(obj : unknown) : GostBelegungsfehler {
+	return obj as GostBelegungsfehler;
+}

+ 58 - 0
core/abschluss/gost/GostBelegungsfehlerArt.ts

@@ -0,0 +1,58 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class GostBelegungsfehlerArt extends JavaObject {
+
+	public static readonly BELEGUNG : GostBelegungsfehlerArt = new GostBelegungsfehlerArt("BELEGUNG");
+
+	public static readonly SCHRIFTLICHKEIT : GostBelegungsfehlerArt = new GostBelegungsfehlerArt("SCHRIFTLICHKEIT");
+
+	public static readonly HINWEIS : GostBelegungsfehlerArt = new GostBelegungsfehlerArt("HINWEIS");
+
+	public readonly kuerzel : String;
+
+
+	/**
+	 * Erzeugt ein neues Abitur-Belegungsfehler-Objekt
+	 * 
+	 * @param kuerzel        das Kürzel der Fehler-Art
+	 */
+	private constructor(kuerzel : String) {
+		super();
+		this.kuerzel = kuerzel;
+	}
+
+	/**
+	 * Gibt die Belegungsfehler-Art anhand des übergebenen Kürzels zurück.
+	 *
+	 * @param kuerzel    das Kürzel der Belegungsfehler-Art
+	 *  
+	 * @return die Belegungsfehler-Art
+	 */
+	public static fromKuerzel(kuerzel : String | null) : GostBelegungsfehlerArt | null {
+		if (kuerzel === null) 
+			return null;
+		switch (kuerzel) {
+			case "BELEGUNG": 
+				return GostBelegungsfehlerArt.BELEGUNG;
+			case "SCHRIFTLICHKEIT": 
+				return GostBelegungsfehlerArt.SCHRIFTLICHKEIT;
+			case "HINWEIS": 
+				return GostBelegungsfehlerArt.HINWEIS;
+		}
+		return null;
+	}
+
+	public toString() : String {
+		return this.kuerzel;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegungsfehlerArt'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehlerArt(obj : unknown) : GostBelegungsfehlerArt {
+	return obj as GostBelegungsfehlerArt;
+}

+ 132 - 0
core/abschluss/gost/GostFachManager.ts

@@ -0,0 +1,132 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../core/types/gost/GostFachbereich';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../core/data/gost/GostFach';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../core/types/gost/GostHalbjahr';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class GostFachManager extends JavaObject {
+
+
+	public constructor() {
+		super();
+	}
+
+	/**
+	 * Gibt an, ob es sich bei dem Fach um ein Projektkursfach handelt.
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return true, falls es sich um ein Projektkursfach handelt
+	 */
+	public static istProjektkurs(fach : GostFach) : boolean {
+		return JavaObject.equalsTranspiler("PX", (fach.kuerzel));
+	}
+
+	/**
+	 * Gibt an, ob es sich bei dem Fach um ein Vertiefungskursfach handelt.
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return true, falls es sich um ein Vertiefungskursfach handelt
+	 */
+	public static istVertiefungskurs(fach : GostFach) : boolean {
+		return JavaObject.equalsTranspiler("VX", (fach.kuerzel));
+	}
+
+	/**
+	 * Gibt an, ob das Fach durchgehend von EF.1 bis Q2.2 belegbar ist;
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return true, falls es so belegbar ist, sonst false
+	 */
+	public static istDurchgehendBelegbarBisQ22(fach : GostFach | null) : boolean {
+		if (fach === null) 
+			return false;
+		return fach.istMoeglichEF1 && fach.istMoeglichEF2 && fach.istMoeglichQ11 && fach.istMoeglichQ12 && fach.istMoeglichQ21 && fach.istMoeglichQ22;
+	}
+
+	/**
+	 * Gibt an, ob das Fach durchgehend von EF.1 bis EF.2 belegbar ist;
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return true, falls es so belegbar ist, sonst false
+	 */
+	public static istBelegbarBisEF2(fach : GostFach) : boolean {
+		return fach.istMoeglichEF1 && fach.istMoeglichEF2;
+	}
+
+	/**
+	 * Prüft, ob das Fach zu der angegebenen Sprache gehört
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * @param sprache   das Kürzel der Sprache (1. Zeichen ohne Jahrgang!)
+	 * 
+	 * @return true, falls das Fach zu der angegebenen Sprache passt, sonst false 
+	 */
+	public static istFremdsprachenfach(fach : GostFach | null, sprache : String | null) : boolean {
+		if ((fach === null) || (fach.kuerzel === null) || (JavaObject.equalsTranspiler("", (fach.kuerzel))) || !GostFachbereich.FREMDSPRACHE.hat(fach) || (sprache === null)) 
+			return false;
+		return (JavaString.compareToIgnoreCase(sprache, fach.kuerzel.substring(0, 1)) === 0);
+	}
+
+	/**
+	 * Liefert das Kürzel der Sprache (ohne Jahrgang) zurück, falls es sich um eine Sprache handelt.
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return das Kürzel der Sprache oder null
+	 */
+	public static getFremdsprache(fach : GostFach) : String | null {
+		if ((fach.kuerzel === null) || (JavaObject.equalsTranspiler("", (fach.kuerzel))) || !GostFachbereich.FREMDSPRACHE.hat(fach)) 
+			return null;
+		return fach.kuerzel.substring(0, 1).toUpperCase();
+	}
+
+	/**
+	 * Prüft, ob das Fach bilingual unterrichtet wird oder nicht.
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * 
+	 * @return true, falls das Fach bilingual unterrichtet wird.
+	 */
+	public static istBilingual(fach : GostFach) : boolean {
+		return ((fach.biliSprache !== null) && (!JavaObject.equalsTranspiler("", (fach.biliSprache))) && (!JavaObject.equalsTranspiler("D", (fach.biliSprache))));
+	}
+
+	/**
+	 * Gibt zurück, ob das Fach in dem angegebenen Halbjahr wählbar ist oder nicht.
+	 * 
+	 * @param fach   das Fach der gymnasialen Oberstufe 
+	 * @param halbjahr   das zu prüfende Halbjahr
+	 * 
+	 * @return true, falls das Fach in dem Halbjahr wählbar ist, sonst false
+	 */
+	public static istWaehlbar(fach : GostFach | null, halbjahr : GostHalbjahr) : boolean {
+		if (fach === null) 
+			return false;
+		if (halbjahr as unknown === GostHalbjahr.EF1 as unknown) 
+			return fach.istMoeglichEF1;
+		if (halbjahr as unknown === GostHalbjahr.EF2 as unknown) 
+			return fach.istMoeglichEF2;
+		if (halbjahr as unknown === GostHalbjahr.Q11 as unknown) 
+			return fach.istMoeglichQ11;
+		if (halbjahr as unknown === GostHalbjahr.Q12 as unknown) 
+			return fach.istMoeglichQ12;
+		if (halbjahr as unknown === GostHalbjahr.Q21 as unknown) 
+			return fach.istMoeglichQ21;
+		if (halbjahr as unknown === GostHalbjahr.Q22 as unknown) 
+			return fach.istMoeglichQ22;
+		return false;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostFachManager'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_GostFachManager(obj : unknown) : GostFachManager {
+	return obj as GostFachManager;
+}

+ 34 - 0
core/abschluss/gost/abitur/services/AbiturBlockIMarkierAlgorithmus.ts

@@ -0,0 +1,34 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../../java/lang/JavaObject';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../../../core/Service';
+import { Abiturdaten, cast_de_nrw_schule_svws_core_data_gost_Abiturdaten } from '../../../../../core/data/gost/Abiturdaten';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../../../logger/LogLevel';
+
+export class AbiturBlockIMarkierAlgorithmus extends Service<Abiturdaten | null, Abiturdaten | null> {
+
+
+	/**
+	 * Erzeugt einen Markierungs-Dienst zur Markierung der Kurse aus dem Block I der Abiturdaten, welche
+	 * in die Punktewertung für die Abiturzulassung und in das Abitur einfliessen. 
+	 */
+	public constructor() {
+		super();
+	}
+
+	public handle(abidaten : Abiturdaten | null) : Abiturdaten | null {
+		if (abidaten === null) {
+			this.logger.logLn(LogLevel.ERROR, "Der Dienst " + this.getClass().getSimpleName().valueOf() + " hat keine gültigen Abiturdaten erhalten.");
+			return null;
+		}
+		this.logger.logLn(LogLevel.ERROR, "Der Dienst " + this.getClass().getSimpleName().valueOf() + " ist noch nicht fertig programmiert...");
+		return abidaten;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.gost.abitur.services.AbiturBlockIMarkierAlgorithmus'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_abitur_services_AbiturBlockIMarkierAlgorithmus(obj : unknown) : AbiturBlockIMarkierAlgorithmus {
+	return obj as AbiturBlockIMarkierAlgorithmus;
+}

+ 35 - 0
core/abschluss/gost/abitur/services/AbiturBlockIMarkierPruefung.ts

@@ -0,0 +1,35 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../../java/lang/JavaObject';
+import { Service, cast_de_nrw_schule_svws_core_Service } from '../../../../../core/Service';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../../../java/lang/JavaBoolean';
+import { Abiturdaten, cast_de_nrw_schule_svws_core_data_gost_Abiturdaten } from '../../../../../core/data/gost/Abiturdaten';
+import { LogLevel, cast_de_nrw_schule_svws_logger_LogLevel } from '../../../../../logger/LogLevel';
+
+export class AbiturBlockIMarkierPruefung extends Service<Abiturdaten | null, Boolean | null> {
+
+
+	/**
+	 * TODO
+	 */
+	public constructor() {
+		super();
+	}
+
+	public handle(abidaten : Abiturdaten | null) : Boolean | null {
+		if (abidaten === null) {
+			this.logger.logLn(LogLevel.ERROR, "Der Dienst " + this.getClass().getSimpleName().valueOf() + " hat keine gültigen Abiturdaten erhalten.");
+			return null;
+		}
+		let ergebnis : boolean = false;
+		this.logger.logLn(LogLevel.ERROR, "Der Dienst " + this.getClass().getSimpleName().valueOf() + " ist noch nicht fertig programmiert...");
+		return ergebnis;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.Service', 'de.nrw.schule.svws.core.abschluss.gost.abitur.services.AbiturBlockIMarkierPruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_abitur_services_AbiturBlockIMarkierPruefung(obj : unknown) : AbiturBlockIMarkierPruefung {
+	return obj as AbiturBlockIMarkierPruefung;
+}

+ 200 - 0
core/abschluss/gost/belegpruefung/AbiFaecher.ts

@@ -0,0 +1,200 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../../core/data/gost/GostFach';
+import { GostAbiturFach, cast_de_nrw_schule_svws_core_types_gost_GostAbiturFach } from '../../../../core/types/gost/GostAbiturFach';
+import { HashMap, cast_java_util_HashMap } from '../../../../java/util/HashMap';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+import { HashSet, cast_java_util_HashSet } from '../../../../java/util/HashSet';
+
+export class AbiFaecher extends GostBelegpruefung {
+
+	private mapAbiturFachbelegungen : HashMap<GostAbiturFach, AbiturFachbelegung> | null = null;
+
+	private anzahlAbiFaecher : number = 0;
+
+	private anzahlDeutschMatheFremdsprache : number = 0;
+
+	private anzahlFremdsprachen : number = 0;
+
+	private anzahlSportReligion : number = 0;
+
+	private hatAufgabenfeldI : boolean = false;
+
+	private hatAufgabenfeldII : boolean = false;
+
+	private hatAufgabenfeldIII : boolean = false;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für die Projektkurse.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.mapAbiturFachbelegungen = new HashMap();
+		this.anzahlAbiFaecher = 0;
+		this.anzahlDeutschMatheFremdsprache = 0;
+		this.anzahlFremdsprachen = 0;
+		this.anzahlSportReligion = 0;
+		this.hatAufgabenfeldI = false;
+		this.hatAufgabenfeldII = false;
+		this.hatAufgabenfeldIII = false;
+		let alleFachbelegungen : List<AbiturFachbelegung> = this.manager.getFachbelegungen();
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			let abiturFach : GostAbiturFach | null = GostAbiturFach.fromID(fachbelegung.abiturFach);
+			if (abiturFach === null) 
+				continue;
+			this.mapAbiturFachbelegungen.put(abiturFach, fachbelegung);
+			this.anzahlAbiFaecher++;
+			let fach : GostFach | null = this.manager.getFach(fachbelegung);
+			if (fach === null) 
+				continue;
+			if (GostFachbereich.FREMDSPRACHE.hat(fach) || GostFachbereich.DEUTSCH.hat(fach)) 
+				this.hatAufgabenfeldI = true;
+			if (GostFachbereich.GESELLSCHAFTSWISSENSCHAFTLICH_MIT_RELIGION.hat(fach)) 
+				this.hatAufgabenfeldII = true;
+			if (GostFachbereich.MATHEMATISCH_NATURWISSENSCHAFTLICH.hat(fach)) 
+				this.hatAufgabenfeldIII = true;
+			if (GostFachbereich.FREMDSPRACHE.hat(fach) || GostFachbereich.DEUTSCH.hat(fach) || GostFachbereich.MATHEMATIK.hat(fach)) 
+				this.anzahlDeutschMatheFremdsprache++;
+			if (GostFachbereich.FREMDSPRACHE.hat(fach)) 
+				this.anzahlFremdsprachen++;
+			if (GostFachbereich.SPORT.hat(fach) || GostFachbereich.RELIGION.hat(fach)) 
+				this.anzahlSportReligion++;
+		}
+	}
+
+	protected pruefeEF1() : void {
+	}
+
+	protected pruefeGesamt() : void {
+		this.pruefeLK1();
+		this.pruefeAnzahlUndAufgabenfelderAbiFaecher();
+		this.pruefeMehrfacheAbiturfaecher();
+		this.pruefeSchriftlichkeitAB3undAB4();
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 70:
+	 * Prüfe, ob der erste LK eine fortgeführte Fremdsprache, eine klassische Naturwissenschaft, Mathematik oder Deutsch ist
+	 */
+	private pruefeLK1() : void {
+		let lk1 : AbiturFachbelegung | null = this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(GostAbiturFach.LK1);
+		let lk1fach : GostFach | null = this.manager.getFach(lk1);
+		if ((lk1 === null) || (lk1fach === null) || !((GostFachbereich.DEUTSCH.hat(lk1fach)) || (GostFachbereich.FREMDSPRACHE.hat(lk1fach) && !lk1.istFSNeu) || (GostFachbereich.MATHEMATIK.hat(lk1fach)) || (GostFachbereich.NATURWISSENSCHAFTLICH_KLASSISCH.hat(lk1fach)))) 
+			this.addFehler(GostBelegungsfehler.LK1_11);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 71-74:
+	 * Prüfe, ob die Zahl der Abiturfächer 4 ist und diese alle Aufgabenfelder abdecken
+	 *    und ob mindestens 2 Fächer im Bereich Deutsch, Fremdsprache, Mathematik liegen
+	 *    und ob maximale 1 Fach im Bereich Sport und Religion liegt
+	 *    und ob Sport nicht als erstes oder drittes Abiturfach gewählt wurde 
+	 */
+	private pruefeAnzahlUndAufgabenfelderAbiFaecher() : void {
+		if ((this.anzahlAbiFaecher !== 4) || (!this.hatAufgabenfeldI) || (!this.hatAufgabenfeldII) || (!this.hatAufgabenfeldIII)) 
+			this.addFehler(GostBelegungsfehler.LK1_13);
+		if (this.anzahlDeutschMatheFremdsprache < 2) 
+			this.addFehler(GostBelegungsfehler.ABI_10);
+		if ((this.anzahlDeutschMatheFremdsprache < 3) && (this.anzahlFremdsprachen > 1)) 
+			this.addFehler(GostBelegungsfehler.ABI_19);
+		if (this.anzahlSportReligion > 1) 
+			this.addFehler(GostBelegungsfehler.ABI_11);
+		let lk1 : AbiturFachbelegung | null = this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(GostAbiturFach.LK1);
+		let lk1fach : GostFach | null = this.manager.getFach(lk1);
+		let ab3 : AbiturFachbelegung | null = this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(GostAbiturFach.AB3);
+		let ab3fach : GostFach | null = this.manager.getFach(ab3);
+		if (((lk1fach !== null) && (GostFachbereich.SPORT.hat(lk1fach.kuerzel))) || ((ab3fach !== null) && (GostFachbereich.SPORT.hat(ab3fach.kuerzel)))) 
+			this.addFehler(GostBelegungsfehler.ABI_15);
+	}
+
+	/**
+	 * Gesamtprüfung: Prüfe, ob eines der Abiturfächer mehrfach belegt wurde. Es ist nicht zulässig
+	 * Abiturfächer mehrfach belegt zu haben. 
+	 */
+	private pruefeMehrfacheAbiturfaecher() : void {
+		let abiFaecher : HashSet<GostAbiturFach> = new HashSet();
+		let alleFachbelegungen : List<AbiturFachbelegung> = this.manager.getFachbelegungen();
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			let abiturFach : GostAbiturFach | null = GostAbiturFach.fromID(fachbelegung.abiturFach);
+			if (abiturFach === null) 
+				continue;
+			if (!abiFaecher.contains(abiturFach)) {
+				abiFaecher.add(abiturFach);
+				continue;
+			}
+			switch (abiturFach) {
+				case GostAbiturFach.LK1: 
+					this.addFehler(GostBelegungsfehler.ABI_21);
+					break;
+				case GostAbiturFach.LK2: 
+					this.addFehler(GostBelegungsfehler.ABI_22);
+					break;
+				case GostAbiturFach.AB3: 
+					this.addFehler(GostBelegungsfehler.ABI_23);
+					break;
+				case GostAbiturFach.AB4: 
+					this.addFehler(GostBelegungsfehler.ABI_24);
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkte 76 und 77:
+	 * Prüfe ob das 3. Abiturfach von Q1.1 bis Q2.2 schriftlich belegt wurde 
+	 *   und on das 4. Abiturfach von Q1.1 bis Q2.1 schritlich und in Q2.2 mündlich belegt wurde
+	 * 
+	 */
+	private pruefeSchriftlichkeitAB3undAB4() : void {
+		let ab3 : AbiturFachbelegung | null = this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(GostAbiturFach.AB3);
+		if (ab3 !== null) {
+			if (!this.manager.pruefeBelegungMitSchriftlichkeit(ab3, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+				this.addFehler(GostBelegungsfehler.ABI_17);
+			if (!this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(ab3, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.Q22)) 
+				this.addFehler(GostBelegungsfehler.ABI_12);
+		}
+		let ab4 : AbiturFachbelegung | null = this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(GostAbiturFach.AB4);
+		if (ab4 !== null) {
+			if (!this.manager.pruefeBelegungMitSchriftlichkeit(ab4, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+				this.addFehler(GostBelegungsfehler.ABI_18);
+			if (!this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(ab4, GostSchriftlichkeit.MUENDLICH, GostHalbjahr.Q22)) 
+				this.addFehler(GostBelegungsfehler.ABI_13);
+		}
+	}
+
+	/**
+	 * Liefert die zugehörige Abitur-Fachbelegung zurück.
+	 * 
+	 * @param abifach  die Art des Abifachs (1., 2., 3. oder 4. Fach)
+	 * 
+	 * @return die Abitur-Fachbelegung oder null, falls es (noch) nicht festgelegt wurde
+	 */
+	public getAbiturfach(abifach : GostAbiturFach | null) : AbiturFachbelegung | null {
+		return this.mapAbiturFachbelegungen === null ? null : this.mapAbiturFachbelegungen.get(abifach);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.AbiFaecher', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_AbiFaecher(obj : unknown) : AbiFaecher {
+	return obj as AbiFaecher;
+}

+ 69 - 0
core/abschluss/gost/belegpruefung/Allgemeines.ts

@@ -0,0 +1,69 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { GostAbiturFach, cast_de_nrw_schule_svws_core_types_gost_GostAbiturFach } from '../../../../core/types/gost/GostAbiturFach';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Allgemeines extends GostBelegpruefung {
+
+
+	/**
+	 * Erstellt eine neue allgemeine Belegprüfung.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+	}
+
+	protected pruefeEF1() : void {
+		if (this.manager.zaehleBelegungInHalbjahren(this.manager.getFachbelegungen(GostFachbereich.RELIGION), GostHalbjahr.EF1) > 1) 
+			this.addFehler(GostBelegungsfehler.IGF_10);
+		if (this.manager.hatDoppelteFachbelegungInHalbjahr(GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.IGF_10);
+	}
+
+	protected pruefeGesamt() : void {
+		let alleFachbelegungen : List<AbiturFachbelegung> = this.manager.getFachbelegungen();
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			if (!this.manager.istBelegtSeitEF(fachbelegung)) 
+				this.addFehler(GostBelegungsfehler.E1BEL_10);
+		}
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			let abiturFach : GostAbiturFach | null = GostAbiturFach.fromID(fachbelegung.abiturFach);
+			if (abiturFach !== null) 
+				continue;
+			if (this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.Q22)) {
+				this.addFehler(GostBelegungsfehler.ABI_16);
+				break;
+			}
+		}
+		for (let halbjahr of GostHalbjahr.values()) {
+			if (this.manager.zaehleBelegungInHalbjahren(this.manager.getFachbelegungen(GostFachbereich.RELIGION), halbjahr) > 1) 
+				this.addFehler(GostBelegungsfehler.IGF_10);
+		}
+		if (this.manager.hatDoppelteFachbelegung(GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.IGF_10);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Allgemeines', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Allgemeines(obj : unknown) : Allgemeines {
+	return obj as Allgemeines;
+}

+ 58 - 0
core/abschluss/gost/belegpruefung/Deutsch.ts

@@ -0,0 +1,58 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Deutsch extends GostBelegpruefung {
+
+	private deutsch : AbiturFachbelegung | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für das Fach Deutsch.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.deutsch = this.manager.getFachbelegung(GostFachbereich.DEUTSCH);
+	}
+
+	protected pruefeEF1() : void {
+		if ((this.deutsch === null) || !this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(this.deutsch, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) {
+			this.addFehler(GostBelegungsfehler.D_10);
+			return;
+		}
+		if (!this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(this.deutsch, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.D_11);
+	}
+
+	protected pruefeGesamt() : void {
+		if (this.deutsch === null) {
+			this.addFehler(GostBelegungsfehler.D_10);
+			return;
+		}
+		if (!this.manager.pruefeBelegung(this.deutsch, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.D_10);
+		if (!this.manager.pruefeBelegungMitSchriftlichkeit(this.deutsch, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+			this.addFehler(GostBelegungsfehler.D_11);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Deutsch'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Deutsch(obj : unknown) : Deutsch {
+	return obj as Deutsch;
+}

+ 486 - 0
core/abschluss/gost/belegpruefung/Fremdsprachen.ts

@@ -0,0 +1,486 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { SprachendatenManager, cast_de_nrw_schule_svws_core_SprachendatenManager } from '../../../../core/SprachendatenManager';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../../core/data/gost/GostFach';
+import { GostAbiturFach, cast_de_nrw_schule_svws_core_types_gost_GostAbiturFach } from '../../../../core/types/gost/GostAbiturFach';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { JavaString, cast_java_lang_String } from '../../../../java/lang/JavaString';
+import { GostFachManager, cast_de_nrw_schule_svws_core_abschluss_gost_GostFachManager } from '../../../../core/abschluss/gost/GostFachManager';
+import { GostKursart, cast_de_nrw_schule_svws_core_types_gost_GostKursart } from '../../../../core/types/gost/GostKursart';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { Vector, cast_java_util_Vector } from '../../../../java/util/Vector';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Fremdsprachen extends GostBelegpruefung {
+
+	private fremdsprachen : List<AbiturFachbelegung> = new Vector();
+
+	private fremdsprachen_neu : List<AbiturFachbelegung> = new Vector();
+
+	private fremdsprachen_fortgefuehrt : List<AbiturFachbelegung> = new Vector();
+
+	private biliSachfaecher : List<AbiturFachbelegung> = new Vector();
+
+	private anzahl_schriftlich_durchgehend : number = 0;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für dir Fremdsprachen.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.fremdsprachen = this.manager.getFachbelegungen(GostFachbereich.FREMDSPRACHE);
+		this.fremdsprachen_neu = this.manager.filterFremdspracheNeuEinsetzend(this.fremdsprachen);
+		this.fremdsprachen_fortgefuehrt = this.manager.filterFremdspracheFortgefuehrt(this.fremdsprachen);
+		this.biliSachfaecher = this.manager.getFachbelegungenBilingual();
+		this.anzahl_schriftlich_durchgehend = 0;
+	}
+
+	protected pruefeEF1() : void {
+		this.pruefeEF1Sprachenfolge();
+		this.pruefeEF1Fremdsprache1();
+		this.pruefeEF1FremdsprachenfolgeZweiteFremdsprache();
+		this.pruefeEF1Schriftlichkeit();
+		this.pruefeEF1AnzahlDurchgehenedeSprachen();
+		this.pruefeEF1BilingualeSachfaecher();
+		this.pruefeEF1BilingualenBildungsgang();
+	}
+
+	/**
+	 * EF.1: Prüft bei der Sprachenfolge, ob eine gemäß Sprachenfolge fortgeführte
+	 * Fremdsprache fehlerhafterweise als neu einsetzende Fremdsprache belegt wurde.
+	 */
+	private pruefeEF1Sprachenfolge() : void {
+		if (this.manager.hatFortgefuehrteFremdspracheInSprachendaten(this.fremdsprachen_neu)) 
+			this.addFehler(GostBelegungsfehler.FS_20);
+		if (this.manager.hatNeuEinsetzendeFremdspracheInSprachendaten(this.fremdsprachen_fortgefuehrt)) 
+			this.addFehler(GostBelegungsfehler.FS_21);
+		if (!SprachendatenManager.hatSprachbelegung(this.manager.getSprachendaten(), "E")) 
+			this.addFehler(GostBelegungsfehler.FS_22_INFO);
+	}
+
+	/**
+	 * Prüft, ob eine gültige Fremdsprachenbelegung mit den EF.1-Wahlen möglich ist. 
+	 */
+	private pruefeEF1Fremdsprache1() : void {
+		let gefundenFremdsprachenbelegung : boolean = false;
+		let gefundenFortgefuehrteFremdsprachenbelegungOhneSprachenfolge : boolean = false;
+		let gefundenFortgefuehrteFremdspracheAlsNeueinsetzende : boolean = false;
+		let anzahlFortgefuehrteFremdsprachen : number = 0;
+		let anzahlFortgefuehrteFremdsprachenEFBelegbar : number = 0;
+		let anzahlFortgefuehrteFremdsprachenEFBelegbarFehlerMuendlich : number = 0;
+		let anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar : number = 0;
+		let anzahlFortgefuehrteFremdsprachenDurchgehendBelegbarFehlerMuendlich : number = 0;
+		let anzahlFortfuehrbareFremdsprachen : number = 0;
+		anzahlFortfuehrbareFremdsprachen = SprachendatenManager.getFortfuehrbareSprachenInGOSt(this.manager.getSprachendaten()).size();
+		for (let abiFachbelegung of this.fremdsprachen_fortgefuehrt) {
+			if (!this.manager.pruefeBelegung(abiFachbelegung, GostHalbjahr.EF1)) {
+				continue;
+			}
+			gefundenFremdsprachenbelegung = true;
+			let gostFach : GostFach | null = this.manager.getFach(abiFachbelegung);
+			if (gostFach !== null && !JavaObject.equalsTranspiler(gostFach.kuerzel, (""))) {
+				if (SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.manager.getSprachendaten(), gostFach.kuerzel.substring(0, 1))) {
+					anzahlFortgefuehrteFremdsprachen += 1;
+					if (this.manager.pruefeBelegungDurchgehendBelegbar(abiFachbelegung, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) {
+						anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar += 1;
+					} else 
+						if (this.manager.pruefeBelegungDurchgehendBelegbar(abiFachbelegung, GostSchriftlichkeit.MUENDLICH, GostHalbjahr.EF1)) {
+							anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar += 1;
+							anzahlFortgefuehrteFremdsprachenDurchgehendBelegbarFehlerMuendlich += 1;
+						} else 
+							if ((gostFach.istMoeglichEF1) && (gostFach.istMoeglichEF2)) {
+								anzahlFortgefuehrteFremdsprachenEFBelegbar += 1;
+								if (this.manager.pruefeBelegungMitSchriftlichkeit(abiFachbelegung, GostSchriftlichkeit.MUENDLICH, GostHalbjahr.EF1)) {
+									anzahlFortgefuehrteFremdsprachenEFBelegbarFehlerMuendlich += 1;
+								}
+							}
+				} else {
+					gefundenFortgefuehrteFremdsprachenbelegungOhneSprachenfolge = true;
+					this.addFehler(GostBelegungsfehler.FS_23);
+				}
+			}
+		}
+		if ((anzahlFortgefuehrteFremdsprachenDurchgehendBelegbarFehlerMuendlich + anzahlFortgefuehrteFremdsprachenEFBelegbarFehlerMuendlich) > 0) {
+			this.addFehler(GostBelegungsfehler.FS_12);
+		}
+		if ((anzahlFortgefuehrteFremdsprachen > 0) && (anzahlFortgefuehrteFremdsprachen === (anzahlFortgefuehrteFremdsprachenDurchgehendBelegbarFehlerMuendlich + anzahlFortgefuehrteFremdsprachenEFBelegbarFehlerMuendlich))) {
+			this.addFehler(GostBelegungsfehler.FS_18);
+		}
+		if (anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar > 0) {
+			return;
+		}
+		let anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar : number = 0;
+		let anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbarFehlerMuendlich : number = 0;
+		for (let abiFachbelegung of this.fremdsprachen_neu) {
+			if (!this.manager.pruefeBelegung(abiFachbelegung, GostHalbjahr.EF1)) {
+				continue;
+			}
+			gefundenFremdsprachenbelegung = true;
+			let gostFach : GostFach | null = this.manager.getFach(abiFachbelegung);
+			if (gostFach !== null && !JavaObject.equalsTranspiler(gostFach.kuerzel, (""))) {
+				if (!SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.manager.getSprachendaten(), gostFach.kuerzel.substring(0, 1))) {
+					if (this.manager.pruefeBelegungDurchgehendBelegbar(abiFachbelegung, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) {
+						anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar += 1;
+					} else 
+						if (this.manager.pruefeBelegungDurchgehendBelegbar(abiFachbelegung, GostSchriftlichkeit.MUENDLICH, GostHalbjahr.EF1)) {
+							anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar += 1;
+							anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbarFehlerMuendlich += 1;
+						}
+				} else {
+					this.addFehler(GostBelegungsfehler.FS_20);
+					gefundenFortgefuehrteFremdspracheAlsNeueinsetzende = true;
+				}
+			}
+		}
+		if (anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbarFehlerMuendlich > 0) {
+			this.addFehler(GostBelegungsfehler.FS_12);
+		}
+		if ((gefundenFremdsprachenbelegung && !(gefundenFortgefuehrteFremdsprachenbelegungOhneSprachenfolge || gefundenFortgefuehrteFremdspracheAlsNeueinsetzende)) && (anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar + anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar === 0)) {
+			this.addFehler(GostBelegungsfehler.FS_11);
+		}
+		if (anzahlFortgefuehrteFremdsprachenEFBelegbar > 0) {
+			if (anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar === 0) {
+				this.addFehler(GostBelegungsfehler.FS_10);
+			}
+			return;
+		}
+		if (anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar === 0) {
+			this.addFehler(GostBelegungsfehler.FS_18);
+			return;
+		}
+		if ((anzahlFortgefuehrteFremdsprachenDurchgehendBelegbar + anzahlFortgefuehrteFremdsprachenEFBelegbar) === 0 && anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbar > 0) {
+			if (anzahlNeueinsetzendeFremdsprachenDurchgehendBelegbarFehlerMuendlich > 0) {
+				this.addFehler(GostBelegungsfehler.FS_18);
+			}
+			if (this.manager.hatMuttersprachenPruefungEndeEF()) {
+				this.addFehler(GostBelegungsfehler.FS_19_INFO);
+			} else {
+				if (anzahlFortfuehrbareFremdsprachen === 0) {
+					this.addFehler(GostBelegungsfehler.FS_25);
+				} else {
+					this.addFehler(GostBelegungsfehler.FS_18);
+					if (!SprachendatenManager.hatZweiSprachenMitMin4JahrenDauerEndeSekI(this.manager.getSprachendaten())) 
+						this.addFehler(GostBelegungsfehler.FS_24);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Prüft, ob eine zweite Fremdsprache in der Sek I vorhanden ist und prüft sonst auf eine neu 
+	 * einsetzende Fremdsprache.
+	 */
+	private pruefeEF1FremdsprachenfolgeZweiteFremdsprache() : void {
+		if (SprachendatenManager.hatZweiSprachenMitMin4JahrenDauerEndeSekI(this.manager.getSprachendaten())) 
+			return;
+		if (SprachendatenManager.hatEineSpracheMitMin4JahrenDauerEndeSekI(this.manager.getSprachendaten())) {
+			if (this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.fremdsprachen_neu, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+				return;
+			if (SprachendatenManager.hatSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten())) {
+				let zweiteFremdsprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(SprachendatenManager.getSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten()));
+				if (!this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(zweiteFremdsprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+					this.addFehler(GostBelegungsfehler.FS_13);
+				return;
+			}
+		}
+		if (!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.fremdsprachen_neu, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) {
+			this.addFehler(GostBelegungsfehler.FS_14);
+		}
+	}
+
+	/**
+	 * Prüft, ob alle Fremdsprachen in der EF.1 schriftlich belegt wurden.
+	 */
+	private pruefeEF1Schriftlichkeit() : void {
+		if (this.fremdsprachen === null) 
+			return;
+		for (let fachbelegung of this.fremdsprachen) 
+			if (this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1) && !this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) {
+				this.addFehler(GostBelegungsfehler.FS_12);
+				break;
+			}
+	}
+
+	/**
+	 * Zähle alle Fremdsprachen, die durchgehend schriftlich belegt wurden.
+	 * Hierzu zählt auch die Unterrichtssprache eines bilingualen Sachfachs als zweite durchgehende 
+	 * Fremdsprache, sofern dieses durchgehende und schriftlich belegt werden kann. 
+	 */
+	private pruefeEF1AnzahlDurchgehenedeSprachen() : void {
+		let fremdsprachenDurchgehend : List<AbiturFachbelegung | null> | null = this.manager.filterBelegungenMitSchriftlichkeit(this.manager.filterDurchgehendBelegbar(this.fremdsprachen), GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1);
+		this.anzahl_schriftlich_durchgehend = fremdsprachenDurchgehend.size();
+		if (this.anzahl_schriftlich_durchgehend !== 1) 
+			return;
+		let fsDurchgehend : GostFach | null = this.manager.getFach(fremdsprachenDurchgehend.get(0));
+		if (fsDurchgehend === null) 
+			return;
+		let fremdspracheDurchgehend : String | null = GostFachManager.getFremdsprache(fsDurchgehend);
+		if (fremdspracheDurchgehend === null) 
+			return;
+		let biliSachfaecherDurchgehendSchriftlich : List<AbiturFachbelegung | null> | null = this.manager.filterBelegungenMitSchriftlichkeit(this.manager.filterDurchgehendBelegbar(this.biliSachfaecher), GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1);
+		for (let biliSachfach of biliSachfaecherDurchgehendSchriftlich) {
+			let fach : GostFach | null = this.manager.getFach(biliSachfach);
+			if ((fach === null) || (JavaObject.equalsTranspiler(fremdspracheDurchgehend, (fach.biliSprache)))) 
+				continue;
+			this.anzahl_schriftlich_durchgehend++;
+			return;
+		}
+	}
+
+	/**
+	 * Prüft, ob die Bedingungen für die Wahl eines bilingualen Sachfaches erfüllt sind, sofern eines 
+	 * in der EF.1 belegt wurde.
+	 */
+	private pruefeEF1BilingualeSachfaecher() : void {
+		if (this.biliSachfaecher === null) 
+			return;
+		for (let biliSachfach of this.biliSachfaecher) {
+			let fach : GostFach | null = this.manager.getFach(biliSachfach);
+			if (fach === null) 
+				continue;
+			let biliSprache : String | null = fach.biliSprache;
+			if (!SprachendatenManager.hatSprachbelegungInSekIMitDauer(this.manager.getSprachendaten(), biliSprache, 2)) {
+				this.addFehler(GostBelegungsfehler.BIL_14);
+				continue;
+			}
+			let fremdsprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(biliSprache);
+			if (this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(fremdsprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1) || this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(biliSachfach, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+				continue;
+			this.addFehler(GostBelegungsfehler.BIL_4_INFO);
+		}
+	}
+
+	/**
+	 * Prüfe, ob die Bedingungen für den bilingualen Bildungsgang erfüllt sind, sofern ein solcher vom Schüler gewählt wurde. 
+	 */
+	private pruefeEF1BilingualenBildungsgang() : void {
+		let biligualeSprache : String | null = this.manager.getBiligualenBildungsgang();
+		if (biligualeSprache === null) 
+			return;
+		let biliSprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(biligualeSprache);
+		if (!this.manager.pruefeBelegungDurchgehendBelegbar(biliSprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.BIL_10);
+		if ((this.biliSachfaecher === null) || (this.biliSachfaecher.size() < 1)) {
+			this.addFehler(GostBelegungsfehler.BIL_15);
+			return;
+		}
+		if (this.biliSachfaecher.size() < 2) 
+			this.addFehler(GostBelegungsfehler.BIL_11_INFO);
+	}
+
+	protected pruefeGesamt() : void {
+		this.pruefeGesamtSprachenfolge();
+		this.pruefeGesamtFremdsprache1();
+		this.pruefeGesamtFremdsprachenfolgeZweiteFremdsprache();
+		this.pruefeGesamtSchriftlichkeit();
+		this.pruefeGesamtAnzahlDurchgehenedeSprachen();
+		this.pruefeGesamtBilingualeSachfaecher();
+		this.pruefeGesamtBilingualenBildungsgang();
+	}
+
+	/**
+	 * Gesamt: Prüft bei der Sprachenfolge, ob eine laut Sprachenfolge fortgeführte
+	 * Fremdpsrache fehlerhafterweise als neu einsetzende Fremdsprache belegt wurde.  
+	 */
+	private pruefeGesamtSprachenfolge() : void {
+		if (this.manager.hatFortgefuehrteFremdspracheInSprachendaten(this.fremdsprachen_neu)) 
+			this.addFehler(GostBelegungsfehler.FS_20);
+		if (this.manager.hatNeuEinsetzendeFremdspracheInSprachendaten(this.fremdsprachen_fortgefuehrt)) 
+			this.addFehler(GostBelegungsfehler.FS_21);
+		if (!SprachendatenManager.hatSprachbelegung(this.manager.getSprachendaten(), "E")) 
+			this.addFehler(GostBelegungsfehler.FS_22_INFO);
+	}
+
+	/**
+	 * Prüft, ob eine gültige Fremdsprachenbelegung in Bezug auf eine durchgehende Belegung möglich ist. 
+	 */
+	private pruefeGesamtFremdsprache1() : void {
+		if (this.manager.pruefeBelegungExistiert(this.fremdsprachen_fortgefuehrt, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			return;
+		if (this.manager.hatMuttersprachenPruefungEndeEF()) {
+			if (this.manager.pruefeBelegungExistiert(this.fremdsprachen_neu, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+				this.addFehler(GostBelegungsfehler.FS_19_INFO); else 
+				this.addFehler(GostBelegungsfehler.FS_18);
+			return;
+		}
+		if (!this.manager.pruefeBelegungExistiert(this.fremdsprachen_fortgefuehrt, GostHalbjahr.EF1, GostHalbjahr.EF2)) {
+			this.addFehler(GostBelegungsfehler.FS_10);
+			return;
+		}
+		if (!this.manager.pruefeBelegungExistiert(this.fremdsprachen_neu, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.FS_10);
+	}
+
+	/**
+	 * Prüft, ob eine zweite Fremdsprache in der Sek I vorhanden ist und prüft sonst auf eine neu 
+	 * einsetzende Fremdsprache.
+	 */
+	private pruefeGesamtFremdsprachenfolgeZweiteFremdsprache() : void {
+		if (this.manager.istSekIZweiteFremdspracheManuellGeprueft()) 
+			return;
+		if (SprachendatenManager.hatZweiSprachenMitMin4JahrenDauerEndeSekI(this.manager.getSprachendaten())) 
+			return;
+		if (SprachendatenManager.hatEineSpracheMitMin4JahrenDauerEndeSekI(this.manager.getSprachendaten())) {
+			if (this.manager.pruefeBelegungExistiert(this.fremdsprachen_neu, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+				return;
+			if (SprachendatenManager.hatSprachfeststellungspruefungAufEFNiveau(this.manager.getSprachendaten()) || this.manager.hatMuttersprachenPruefungEndeEF()) {
+				return;
+			}
+			if (SprachendatenManager.hatSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten())) {
+				let zweiteFremdsprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(SprachendatenManager.getSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten()));
+				if (!this.manager.pruefeBelegungMitSchriftlichkeit(zweiteFremdsprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2)) 
+					this.addFehler(GostBelegungsfehler.FS_13);
+				return;
+			}
+		}
+		if (SprachendatenManager.hatSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten())) {
+			let zweiteFremdsprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(SprachendatenManager.getSpracheMit2JahrenDauerEndeSekI(this.manager.getSprachendaten()));
+			if (!this.manager.pruefeBelegungMitSchriftlichkeit(zweiteFremdsprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2)) 
+				this.addFehler(GostBelegungsfehler.FS_13);
+			if (this.manager.pruefeBelegungExistiert(this.fremdsprachen_neu, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+				return;
+			if (SprachendatenManager.hatSprachfeststellungspruefungAufEFNiveau(this.manager.getSprachendaten()) || this.manager.hatMuttersprachenPruefungEndeEF()) {
+				return;
+			}
+		}
+		if (this.manager.pruefeBelegungExistiert(this.fremdsprachen_neu, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) {
+			if (SprachendatenManager.hatSprachfeststellungspruefungAufEFNiveau(this.manager.getSprachendaten()) || this.manager.hatMuttersprachenPruefungEndeEF()) {
+				return;
+			}
+			return;
+		}
+		this.addFehler(GostBelegungsfehler.FS_14);
+	}
+
+	/**
+	 * Prüft, ob eine gültige Fremdsprachenbelegung in Bezug auf die Schriftlichkeit und LK-Wahl vohanden ist. 
+	 */
+	private pruefeGesamtSchriftlichkeit() : void {
+		if (this.manager.pruefeBelegungExistiertHatMindestensEinmalSchriftlichkeit(this.fremdsprachen_neu, GostSchriftlichkeit.MUENDLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+			this.addFehler(GostBelegungsfehler.FS_15);
+		if (this.manager.pruefeBelegungExistiertHatMindestensEinmalKursart(this.fremdsprachen_neu, GostKursart.LK, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.FS_17);
+		if (this.manager.pruefeBelegungExistiertErfuelltNichtFallsBelegt(this.fremdsprachen_fortgefuehrt, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2)) 
+			this.addFehler(GostBelegungsfehler.FS_12);
+		if (this.manager.pruefeBelegungDurchgehendBelegtExistiert(this.fremdsprachen_fortgefuehrt, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+			return;
+		if (!this.manager.pruefeBelegungDurchgehendBelegtExistiert(this.fremdsprachen_neu, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) {
+			this.addFehler(GostBelegungsfehler.FS_11);
+			return;
+		}
+		if (this.manager.hatMuttersprachenPruefungEndeEF() && this.manager.pruefeBelegungExistiertMitSchriftlichkeit(this.fremdsprachen_fortgefuehrt, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2)) 
+			return;
+		if (this.manager.hatMuttersprachenPruefungEndeEF() && this.manager.pruefeBelegungDurchgehendBelegtExistiert(this.fremdsprachen_neu, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+			return;
+		if (!this.manager.pruefeBelegungExistiertMitSchriftlichkeit(this.fremdsprachen_fortgefuehrt, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2)) 
+			this.addFehler(GostBelegungsfehler.FS_16);
+	}
+
+	/**
+	 * Zähle alle Fremdsprachen, die durchgehend schriftlich belegt wurden.
+	 * Hierzu zählt auch die Unterrichtssprache eines bilingualen Sachfachs als zweite durchgehende 
+	 * Fremdsprache, sofern dieses durchgehend und schriftlich belegt wurde. 
+	 */
+	private pruefeGesamtAnzahlDurchgehenedeSprachen() : void {
+		let fremdsprachenDurchgehend : List<AbiturFachbelegung> = this.manager.filterBelegungen(this.fremdsprachen, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22);
+		let fremdsprachenDurchgehendSchriftlich : List<AbiturFachbelegung> = this.manager.filterBelegungenMitSchriftlichkeit(fremdsprachenDurchgehend, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21);
+		this.anzahl_schriftlich_durchgehend = fremdsprachenDurchgehendSchriftlich.size();
+		if (this.anzahl_schriftlich_durchgehend !== 1) 
+			return;
+		let fsDurchgehend : GostFach | null = this.manager.getFach(fremdsprachenDurchgehendSchriftlich.get(0));
+		if (fsDurchgehend === null) 
+			return;
+		let fremdspracheDurchgehend : String | null = GostFachManager.getFremdsprache(fsDurchgehend);
+		if (fremdspracheDurchgehend === null) 
+			return;
+		let biliSachfaecherDurchgehend : List<AbiturFachbelegung> = this.manager.filterBelegungen(this.biliSachfaecher, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22);
+		let biliSachfaecherDurchgehendSchriftlich : List<AbiturFachbelegung> = this.manager.filterBelegungenMitSchriftlichkeit(biliSachfaecherDurchgehend, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21);
+		for (let biliSachfach of biliSachfaecherDurchgehendSchriftlich) {
+			let fach : GostFach | null = this.manager.getFach(biliSachfach);
+			if ((fach === null) || (JavaObject.equalsTranspiler(fremdspracheDurchgehend, (fach.biliSprache)))) 
+				continue;
+			this.anzahl_schriftlich_durchgehend++;
+			return;
+		}
+	}
+
+	/**
+	 * Prüft, ob die Bedingungen für die Wahl eines bilingualen Sachfaches erfüllt sind, sofern eines 
+	 * belegt wurde.
+	 */
+	private pruefeGesamtBilingualeSachfaecher() : void {
+		if (this.biliSachfaecher === null) 
+			return;
+		for (let biliSachfach of this.biliSachfaecher) {
+			let biliFach : GostFach | null = this.manager.getFach(biliSachfach);
+			if ((biliFach === null) || (!SprachendatenManager.hatSprachbelegungInSekIMitDauer(this.manager.getSprachendaten(), biliFach.biliSprache, 2))) 
+				this.addFehler(GostBelegungsfehler.BIL_14);
+		}
+	}
+
+	/**
+	 * Prüfe, ob die Bedingungen für ein bilinguales Abitur erfüllt sind, sofern ein solches vom 
+	 * Schüler gewählt wurde. 
+	 */
+	private pruefeGesamtBilingualenBildungsgang() : void {
+		let biligualeSprache : String | null = this.manager.getBiligualenBildungsgang();
+		if (biligualeSprache === null) 
+			return;
+		let biliSprache : AbiturFachbelegung | null = this.manager.getSprachbelegung(biligualeSprache);
+		if ((!this.manager.pruefeBelegungMitSchriftlichkeit(biliSprache, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2) || (!this.manager.pruefeBelegungMitKursart(biliSprache, GostKursart.LK, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)))) 
+			this.addFehler(GostBelegungsfehler.BIL_10);
+		let biliSachfaecherEF : List<AbiturFachbelegung | null> | null = this.manager.filterBelegungen(this.biliSachfaecher, GostHalbjahr.EF1, GostHalbjahr.EF2);
+		if (biliSachfaecherEF.size() < 1) {
+			this.addFehler(GostBelegungsfehler.BIL_15);
+			return;
+		}
+		if (biliSachfaecherEF.size() < 2) 
+			this.addFehler(GostBelegungsfehler.BIL_11_INFO);
+		let hatBiliSachfaecherDurchgehendSchriftlich : boolean = false;
+		if (this.biliSachfaecher !== null) {
+			for (let fach of this.biliSachfaecher) {
+				if (this.manager.pruefeDurchgaengigkeitSchriftlich(fach)) {
+					hatBiliSachfaecherDurchgehendSchriftlich = true;
+					break;
+				}
+			}
+		}
+		if (!hatBiliSachfaecherDurchgehendSchriftlich) 
+			this.addFehler(GostBelegungsfehler.BIL_12);
+		if (!this.manager.pruefeExistiertAbiFach(this.biliSachfaecher, GostAbiturFach.AB3, GostAbiturFach.AB4)) 
+			this.addFehler(GostBelegungsfehler.BIL_13);
+	}
+
+	/**
+	 * Gibt die Anzahl der durchgehend schriftlich belegten bzw. belegbaren Fremdsprachen zurück.
+	 * Durchgehend schriftlich bedeutet, dass das Fach mind. von EF.1 bis Q2.1 schriftlich belegt wurde.
+	 * Hierfür kommen Fremdsprachen und ggf. ein bilinguales Sachfach in Frage, dessen Unterrichtssprache
+	 * nicht durchgehend schriftlich belegt. 
+	 * 
+	 * @return die Anzahl der durchgehend schriftlich belegten bzw. belegbaren Fremdsprachen zurück.
+	 */
+	public getAnzahlDurchgehendSchritflichBelegt() : number {
+		return this.anzahl_schriftlich_durchgehend;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Fremdsprachen', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Fremdsprachen(obj : unknown) : Fremdsprachen {
+	return obj as Fremdsprachen;
+}

+ 287 - 0
core/abschluss/gost/belegpruefung/GesellschaftswissenschaftenUndReligion.ts

@@ -0,0 +1,287 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../../core/data/gost/GostFach';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { AbiturFachbelegungHalbjahr, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr } from '../../../../core/data/gost/AbiturFachbelegungHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostFachManager, cast_de_nrw_schule_svws_core_abschluss_gost_GostFachManager } from '../../../../core/abschluss/gost/GostFachManager';
+import { GostKursart, cast_de_nrw_schule_svws_core_types_gost_GostKursart } from '../../../../core/types/gost/GostKursart';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { Vector, cast_java_util_Vector } from '../../../../java/util/Vector';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class GesellschaftswissenschaftenUndReligion extends GostBelegpruefung {
+
+	private gesellschaftswissenschaften : List<AbiturFachbelegung> | null = null;
+
+	private geschichte : List<AbiturFachbelegung> | null = null;
+
+	private sozialwissenschaften : List<AbiturFachbelegung> | null = null;
+
+	private philosophie : AbiturFachbelegung | null = null;
+
+	private sonstige_gesellschaftswissenschaften : List<AbiturFachbelegung> | null = null;
+
+	private religion : List<AbiturFachbelegung> | null = null;
+
+	private zusatzkursFachbelegungen : Vector<AbiturFachbelegung> | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für den Bereich der Gesellschaftswissenschaften und Religion.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.gesellschaftswissenschaften = this.manager.getFachbelegungen(GostFachbereich.GESELLSCHAFTSWISSENSCHAFTLICH);
+		this.geschichte = this.manager.getFachbelegungen(GostFachbereich.GESCHICHTE);
+		this.sozialwissenschaften = this.manager.getFachbelegungen(GostFachbereich.SOZIALWISSENSCHAFTEN);
+		this.philosophie = this.manager.getFachbelegung(GostFachbereich.PHILOSOPHIE);
+		this.sonstige_gesellschaftswissenschaften = this.manager.getFachbelegungen(GostFachbereich.GESELLSCHAFTSWISSENSCHAFTLICH_SONSTIGE);
+		this.religion = this.manager.getFachbelegungen(GostFachbereich.RELIGION);
+		this.zusatzkursFachbelegungen = new Vector();
+	}
+
+	protected pruefeEF1() : void {
+		this.pruefeGesellschaftswissenschaftenEF1();
+		this.pruefeReligionEF1();
+	}
+
+	/**
+	 * EF1-Prüfung Punkte 8-10: 
+	 * Prüfe, ob eine Gesellschaftswissenschaft in EF.1 schriftlich belegt wurde und durchgängig belegbar ist
+	 *    und ob Geschichte belegt wurde
+	 *    und ob Sozialwissenschaften belegt wurde 
+	 */
+	private pruefeGesellschaftswissenschaftenEF1() : void {
+		if (!this.manager.pruefeBelegungDurchgehendBelegbarExistiert(this.gesellschaftswissenschaften, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.GW_10);
+		if (!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.gesellschaftswissenschaften, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.GW_11);
+		if (this.manager.zaehleBelegungInHalbjahren(this.geschichte, GostHalbjahr.EF1) <= 0) 
+			this.addFehler(GostBelegungsfehler.GE_1_INFO);
+		if (this.manager.zaehleBelegungInHalbjahren(this.sozialwissenschaften, GostHalbjahr.EF1) <= 0) 
+			this.addFehler(GostBelegungsfehler.SW_1_INFO);
+	}
+
+	/**
+	 * EF1-Prüfung Punkt 11:
+	 * Prüfe, ob Religion in EF.1 belegt wurde oder ob Philosophie und eine weitere durchgehend belegbare Gesellschaftswissenschaft belegt wurde.
+	 * Falls Philosophie als Ersatz für Religion gewählt wurde, zählt es nicht als durchgehend belegte Gesellschaftswissenschaft.   
+	 */
+	private pruefeReligionEF1() : void {
+		if (this.manager.pruefeBelegungExistiert(this.religion, GostHalbjahr.EF1)) 
+			return;
+		if (!this.manager.pruefeBelegung(this.philosophie, GostHalbjahr.EF1)) {
+			this.addFehler(GostBelegungsfehler.RE_10);
+		} else 
+			if ((!this.manager.pruefeBelegungDurchgehendBelegbarExistiert(this.geschichte, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) && (!this.manager.pruefeBelegungDurchgehendBelegbarExistiert(this.sozialwissenschaften, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) && (!this.manager.pruefeBelegungDurchgehendBelegbarExistiert(this.sonstige_gesellschaftswissenschaften, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1))) {
+				this.addFehler(GostBelegungsfehler.RE_10);
+			}
+	}
+
+	protected pruefeGesamt() : void {
+		this.pruefeSchriftlichkeitEF();
+		this.pruefeDurchgaengigeBelegung();
+		this.pruefeDurchgaengigeBelegungUndSchriftlich();
+		this.pruefeZusatzkurs(this.geschichte);
+		this.pruefeBelegungGeschichte();
+		this.pruefeZusatzkurs(this.sozialwissenschaften);
+		this.pruefeBelegungSozialwissenschaften();
+		this.pruefeReligionEF();
+		this.pruefeReligionQ1();
+		this.pruefeReligionKontinuitaet();
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 39:
+	 * Prüfe, on in EF.1 und EF.2 jeweils ein Fach der Gesellschaftswissenschaften schriftlich belegt wurde
+	 */
+	private pruefeSchriftlichkeitEF() : void {
+		if ((!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.gesellschaftswissenschaften, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) || (!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.gesellschaftswissenschaften, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF2))) 
+			this.addFehler(GostBelegungsfehler.GW_11);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 38:
+	 * Prüfe, ob ein Fach der Gesellschaftswissenschaften von EF.1 bis Q2.2 durchgängig belegt wurde 
+	 * - Zusatzkurse zählen hier nicht als Belegung
+	 */
+	private pruefeDurchgaengigeBelegung() : void {
+		if (!this.manager.pruefeBelegungExistiert(this.gesellschaftswissenschaften, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.GW_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 40:
+	 * Prüfe, ob ein Fach der Gesellschaftswissenschaften oder Religionslehre von EF.1 bis Q2.2 belegt 
+	 * und von Q1.1 bis Q2.1 schriftlich belegt wurde, damit es als potentielles Abiturfach zur Verfügung steht.
+	 * - Zusatzkurse zählen hier nicht als Belegung
+	 */
+	private pruefeDurchgaengigeBelegungUndSchriftlich() : void {
+		if (this.manager.pruefeBelegungExistiertDurchgehendSchriftlich(this.gesellschaftswissenschaften)) 
+			return;
+		if (this.manager.pruefeBelegungExistiertDurchgehendSchriftlich(this.religion)) 
+			return;
+		this.addFehler(GostBelegungsfehler.GW_12);
+	}
+
+	/**
+	 * Gesamtprüfung Punkte 27, 29 und 30:
+	 * Prüft, ob der Zusatzkurs genau zwei mal belegt wurde 
+	 *    und ob ein Zusatzkurs belegt wurde, obwohl im Halbjahr zuvor ein Geschichtskurs belegt wurde.
+	 * 
+	 * @param fachbelegungen   die Fachbelegung für Geschichte oder Sozialwissehschaften
+	 */
+	private pruefeZusatzkurs(fachbelegungen : List<AbiturFachbelegung> | null) : void {
+		if ((fachbelegungen === null) || (fachbelegungen.size() === 0)) 
+			return;
+		fachbelegungen = this.manager.filterBelegungKursartExistiert(fachbelegungen, GostKursart.ZK);
+		if (fachbelegungen.size() === 0) 
+			return;
+		if (fachbelegungen.size() > 1) 
+			this.addFehler(GostBelegungsfehler.ZK_13);
+		for (let fachbelegung of fachbelegungen) {
+			let fach : GostFach | null = this.manager.getFach(fachbelegung);
+			if ((fach === null) || (GostFachManager.istBilingual(fach))) 
+				this.addFehler(GostBelegungsfehler.ZK_13);
+			let halbjahre : List<GostHalbjahr> = this.manager.getHalbjahreKursart(fachbelegung, GostKursart.ZK);
+			if (halbjahre.size() === 2) {
+				if (((this.manager.pruefeBelegungMitKursart(fachbelegung, GostKursart.ZK, GostHalbjahr.Q11, GostHalbjahr.Q12)) || (this.manager.pruefeBelegungMitKursart(fachbelegung, GostKursart.ZK, GostHalbjahr.Q12, GostHalbjahr.Q21)) || (this.manager.pruefeBelegungMitKursart(fachbelegung, GostKursart.ZK, GostHalbjahr.Q21, GostHalbjahr.Q22)))) {
+					if (this.zusatzkursFachbelegungen !== null) 
+						this.zusatzkursFachbelegungen.add(fachbelegung);
+				}
+			} else 
+				if (halbjahre.size() > 1) {
+					this.addFehler(GostBelegungsfehler.ZK_12);
+				}
+			if (halbjahre.size() > 0) {
+				let prevHalbjahr : GostHalbjahr | null = halbjahre.get(0).previous();
+				if ((prevHalbjahr !== null) && (this.manager.pruefeBelegung(fachbelegung, prevHalbjahr))) 
+					this.addFehler(GostBelegungsfehler.ZK_10);
+			}
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 41:
+	 * Prüft, ob Geschichte korrekt belegt wurde (mind. von EF.1 bis Q1.2 oder als Zusatzkurs)
+	 */
+	private pruefeBelegungGeschichte() : void {
+		if ((this.geschichte === null) || (this.geschichte.size() <= 0)) {
+			this.addFehler(GostBelegungsfehler.GE_10);
+			return;
+		}
+		if (this.manager.pruefeBelegungExistiert(this.geschichte, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12)) 
+			return;
+		if (this.zusatzkursFachbelegungen !== null) 
+			for (let zkBelegung of this.zusatzkursFachbelegungen) 
+				if (this.geschichte.contains(zkBelegung)) 
+					return;
+		this.addFehler(GostBelegungsfehler.GE_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 42:
+	 * Prüft, ob Sozialwissenschaften korrekt belegt wurde (mind. von EF.1 bis Q1.2 oder als Zusatzkurs)
+	 */
+	private pruefeBelegungSozialwissenschaften() : void {
+		if ((this.sozialwissenschaften === null) || (this.sozialwissenschaften.size() <= 0)) {
+			this.addFehler(GostBelegungsfehler.SW_10);
+			return;
+		}
+		if (this.manager.pruefeBelegungExistiert(this.sozialwissenschaften, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12)) 
+			return;
+		if (this.zusatzkursFachbelegungen !== null) 
+			for (let zkBelegung of this.zusatzkursFachbelegungen) 
+				if (this.sozialwissenschaften.contains(zkBelegung)) 
+					return;
+		this.addFehler(GostBelegungsfehler.SW_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkte 43:
+	 * Prüft die Belegung von Religion und Philosophie in der EF. Wird Philosophie als Ersatz belegt, so wird auch geprüft, 
+	 * ob eine weitere Gesellschaftswissenschaft belegt wurde.
+	 */
+	private pruefeReligionEF() : void {
+		for (let halbjahr of GostHalbjahr.getEinfuehrungsphase()) {
+			if (this.manager.pruefeBelegungExistiertEinzeln(this.religion, halbjahr)) 
+				continue;
+			if ((!this.manager.pruefeBelegung(this.philosophie, halbjahr)) || (this.manager.pruefeDurchgaengigkeit(this.philosophie) && (this.manager.zaehleBelegungInHalbjahren(this.gesellschaftswissenschaften, halbjahr) <= 1))) {
+				this.addFehler(GostBelegungsfehler.RE_10);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 44:
+	 * Prüft die Belegung von Religion und Philosophie. Wird Philosophie als Ersatz belegt, so wird auch geprüft, ob eine weitere
+	 * Gesellschaftswissenschaft belegt wurde.
+	 */
+	private pruefeReligionQ1() : void {
+		for (let halbjahr of GostHalbjahr.getHalbjahreFromJahrgang("Q1")) {
+			if (this.manager.pruefeBelegungExistiertEinzeln(this.religion, halbjahr)) 
+				continue;
+			if (!this.manager.pruefeBelegung(this.philosophie, halbjahr)) {
+				this.addFehler(GostBelegungsfehler.RE_10);
+				return;
+			}
+			if (this.manager.pruefeDurchgaengigkeit(this.philosophie) && (this.manager.zaehleDurchgaengigeBelegungen(this.gesellschaftswissenschaften) > 1)) 
+				continue;
+			if (!this.manager.pruefeDurchgaengigkeit(this.philosophie) && (this.manager.zaehleDurchgaengigeBelegungen(this.gesellschaftswissenschaften) > 0)) 
+				continue;
+			if (this.manager.zaehleBelegungInHalbjahren(this.sonstige_gesellschaftswissenschaften, halbjahr) > 0) 
+				continue;
+			if ((halbjahr as unknown === GostHalbjahr.Q11 as unknown) && (this.manager.pruefeBelegungExistiertEinzeln(this.geschichte, GostHalbjahr.Q11) || this.manager.pruefeBelegungExistiertEinzeln(this.sozialwissenschaften, GostHalbjahr.Q11))) 
+				continue;
+			this.addFehler(GostBelegungsfehler.RE_10);
+			break;
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 55:
+	 * Prüft, ob Fehler bei der Kontinuität bei Philosophie und Religion nur durch die Ersatzfachregelung bei Religion
+	 * zustandekommen und damit zulässig sind.
+	 */
+	private pruefeReligionKontinuitaet() : void {
+		if (this.philosophie === null) 
+			return;
+		for (let belegung of this.philosophie.belegungen) {
+			if (belegung === null) 
+				continue;
+			let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegung.halbjahrKuerzel);
+			if (halbjahr === null) 
+				continue;
+			let prevHalbjahr : GostHalbjahr | null = halbjahr.previous();
+			if (prevHalbjahr === null) 
+				continue;
+			if (this.manager.pruefeBelegung(this.philosophie, prevHalbjahr)) 
+				continue;
+			if (this.manager.pruefeBelegungExistiertEinzeln(this.religion, halbjahr)) 
+				this.addFehler(GostBelegungsfehler.E1BEL_10);
+			if (!this.manager.pruefeBelegungExistiertEinzeln(this.religion, prevHalbjahr)) 
+				this.addFehler(GostBelegungsfehler.E1BEL_10);
+		}
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.GesellschaftswissenschaftenUndReligion', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_GesellschaftswissenschaftenUndReligion(obj : unknown) : GesellschaftswissenschaftenUndReligion {
+	return obj as GesellschaftswissenschaftenUndReligion;
+}

+ 490 - 0
core/abschluss/gost/belegpruefung/KurszahlenUndWochenstunden.ts

@@ -0,0 +1,490 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../../core/data/gost/GostFach';
+import { HashMap, cast_java_util_HashMap } from '../../../../java/util/HashMap';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { AbiturFachbelegungHalbjahr, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr } from '../../../../core/data/gost/AbiturFachbelegungHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostKursart, cast_de_nrw_schule_svws_core_types_gost_GostKursart } from '../../../../core/types/gost/GostKursart';
+import { Projektkurse, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Projektkurse } from '../../../../core/abschluss/gost/belegpruefung/Projektkurse';
+import { JavaInteger, cast_java_lang_Integer } from '../../../../java/lang/JavaInteger';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../../java/lang/NullPointerException';
+import { Note, cast_de_nrw_schule_svws_core_types_Note } from '../../../../core/types/Note';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { Collection, cast_java_util_Collection } from '../../../../java/util/Collection';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class KurszahlenUndWochenstunden extends GostBelegpruefung {
+
+	private kurszahlen : HashMap<GostHalbjahr, HashMap<GostKursart, Number>> | null = null;
+
+	private kurszahlenGrundkurse : HashMap<GostHalbjahr, Number> | null = null;
+
+	private kurszahlenLeistungskurse : HashMap<GostHalbjahr, Number> | null = null;
+
+	private kurszahlenAnrechenbar : HashMap<GostHalbjahr, Number> | null = null;
+
+	private kurszahlenEinfuehrungsphase : HashMap<GostKursart, Number> | null = null;
+
+	private kurszahlenQualifikationsphase : HashMap<GostKursart, Number> | null = null;
+
+	private blockIAnzahlGrundkurse : number = 0;
+
+	private anzahlLKFaecher : number = 0;
+
+	private blockIAnzahlLeistungskurse : number = 0;
+
+	private blockIAnzahlAnrechenbar : number = 0;
+
+	private wochenstunden : HashMap<GostHalbjahr, Number> | null = null;
+
+	private wochenstundenEinfuehrungsphase : number = 0;
+
+	private wochenstundenQualifikationsphase : number = 0;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für die Kurszahlen.
+	 * 
+	 * @param manager                 der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art           die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 * @param pruefungProjektkurse    das Ergebnis für die Belegprüfung der Projektkurse
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt, pruefungProjektkurse : GostBelegpruefung) {
+		super(manager, pruefungs_art, pruefungProjektkurse);
+	}
+
+	protected init() : void {
+		this.kurszahlen = new HashMap();
+		this.kurszahlenGrundkurse = new HashMap();
+		this.kurszahlenLeistungskurse = new HashMap();
+		this.kurszahlenAnrechenbar = new HashMap();
+		this.kurszahlenEinfuehrungsphase = new HashMap();
+		this.kurszahlenQualifikationsphase = new HashMap();
+		this.blockIAnzahlGrundkurse = 0;
+		this.anzahlLKFaecher = 0;
+		this.blockIAnzahlLeistungskurse = 0;
+		this.blockIAnzahlAnrechenbar = 0;
+		this.wochenstunden = new HashMap();
+		this.wochenstundenEinfuehrungsphase = 0;
+		this.wochenstundenQualifikationsphase = 0;
+		let projektkurse : Projektkurse = (cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Projektkurse(this.pruefungen_vorher[0]));
+		let kursarten : Collection<GostKursart> = GostKursart.values();
+		for (let halbjahr of GostHalbjahr.values()) {
+			let kurszahlenHalbjahr : HashMap<GostKursart, Number> = new HashMap();
+			this.kurszahlen.put(halbjahr, kurszahlenHalbjahr);
+			for (let kursart of kursarten) {
+				kurszahlenHalbjahr.put(kursart, 0);
+			}
+			this.kurszahlenGrundkurse.put(halbjahr, 0);
+			this.kurszahlenLeistungskurse.put(halbjahr, 0);
+			this.kurszahlenAnrechenbar.put(halbjahr, 0);
+			this.wochenstunden.put(halbjahr, 0);
+		}
+		for (let kursart of kursarten) {
+			this.kurszahlenEinfuehrungsphase.put(kursart, 0);
+			this.kurszahlenQualifikationsphase.put(kursart, 0);
+		}
+		let alleFachbelegungen : List<AbiturFachbelegung> = this.manager.getFachbelegungen();
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			let fach : GostFach | null = this.manager.getFach(fachbelegung);
+			let istLKFach : boolean = false;
+			for (let fachbelegungHalbjahr of fachbelegung.belegungen) {
+				if (fachbelegungHalbjahr === null) 
+					continue;
+				if (GostFachbereich.SPORT.hat(fach) && JavaObject.equalsTranspiler(Note.ATTEST, (Note.fromKuerzel(fachbelegungHalbjahr.notenkuerzel)))) 
+					continue;
+				let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(fachbelegungHalbjahr.halbjahrKuerzel);
+				if (halbjahr === null) 
+					continue;
+				let kursart : GostKursart | null = GostKursart.fromKuerzel(fachbelegungHalbjahr.kursartKuerzel);
+				if (kursart === null) 
+					continue;
+				let kurszahlenHalbjahr : HashMap<GostKursart, Number> | null = this.kurszahlen.get(halbjahr);
+				if (kurszahlenHalbjahr === null) 
+					kurszahlenHalbjahr = new HashMap();
+				let kurszahlAlt : Number | null = kurszahlenHalbjahr.get(kursart);
+				kurszahlenHalbjahr.put(kursart, kurszahlAlt === null ? 1 : kurszahlAlt.valueOf() + 1);
+				if ((kursart as unknown === GostKursart.GK as unknown) || (halbjahr.istQualifikationsphase() && ((kursart as unknown === GostKursart.ZK as unknown) || ((kursart as unknown === GostKursart.PJK as unknown) && (projektkurse.istAnrechenbar(fachbelegungHalbjahr)))))) {
+					let kurszahlGK : Number | null = this.kurszahlenGrundkurse.get(halbjahr);
+					this.kurszahlenGrundkurse.put(halbjahr, kurszahlGK === null ? 1 : kurszahlGK.valueOf() + 1);
+					let kurszahlAnrechenbar : Number | null = this.kurszahlenAnrechenbar.get(halbjahr);
+					this.kurszahlenAnrechenbar.put(halbjahr, kurszahlAnrechenbar === null ? 1 : kurszahlAnrechenbar.valueOf() + 1);
+					if (halbjahr.istQualifikationsphase()) {
+						this.blockIAnzahlGrundkurse++;
+						this.blockIAnzahlAnrechenbar++;
+					}
+				}
+				if (halbjahr.istQualifikationsphase() && (kursart as unknown === GostKursart.LK as unknown)) {
+					istLKFach = true;
+					let kurszahlLK : Number | null = this.kurszahlenLeistungskurse.get(halbjahr);
+					this.kurszahlenLeistungskurse.put(halbjahr, kurszahlLK === null ? 1 : kurszahlLK.valueOf() + 1);
+					let kurszahlAnrechenbar : Number | null = this.kurszahlenAnrechenbar.get(halbjahr);
+					this.kurszahlenAnrechenbar.put(halbjahr, kurszahlAnrechenbar === null ? 1 : kurszahlAnrechenbar.valueOf() + 1);
+					this.blockIAnzahlLeistungskurse++;
+					this.blockIAnzahlAnrechenbar++;
+				}
+				let stunden : number = 0;
+				switch (kursart.kuerzel) {
+					case "GK": 
+						stunden = ((fach !== null) && fach.istFremdSpracheNeuEinsetzend) ? 4 : 3;
+						break;
+					case "LK": 
+						stunden = 5;
+						break;
+					case "PJK": 
+						stunden = (fachbelegungHalbjahr.wochenstunden === 3) ? 3 : 2;
+						break;
+					case "VTF": 
+						stunden = 2;
+						break;
+					case "ZK": 
+						stunden = 3;
+						break;
+				}
+				let wochenstundenAlt : Number | null = this.wochenstunden.get(halbjahr);
+				this.wochenstunden.put(halbjahr, wochenstundenAlt === null ? stunden : wochenstundenAlt.valueOf() + stunden);
+				if (halbjahr.istEinfuehrungsphase()) {
+					let kurszahlEF : Number | null = this.kurszahlenEinfuehrungsphase.get(kursart);
+					this.kurszahlenEinfuehrungsphase.put(kursart, kurszahlEF === null ? 1 : kurszahlEF.valueOf() + 1);
+					this.wochenstundenEinfuehrungsphase += stunden;
+				} else {
+					let kurszahlQ : Number | null = this.kurszahlenQualifikationsphase.get(kursart);
+					this.kurszahlenQualifikationsphase.put(kursart, kurszahlQ === null ? 1 : kurszahlQ.valueOf() + 1);
+					this.wochenstundenQualifikationsphase += stunden;
+				}
+			}
+			if (istLKFach) 
+				this.anzahlLKFaecher++;
+		}
+	}
+
+	protected pruefeEF1() : void {
+		this.pruefeGrundkurseEF1();
+		this.pruefeWochenstundenEF1();
+	}
+
+	/**
+	 * EF1-Prüfung Punkt 21: 
+	 * Prüfe, ob zu wenige Grundkurse (ohne Vertiefungskurse) in der EF belegt wurden,
+	 * dh. weniger als 10 Kurse
+	 */
+	private pruefeGrundkurseEF1() : void {
+		if (this.kurszahlenGrundkurse === null) 
+			throw new NullPointerException()
+		let kurszahlGK : Number | null = this.kurszahlenGrundkurse.get(GostHalbjahr.EF1);
+		if ((kurszahlGK === null) || (kurszahlGK < 10)) 
+			this.addFehler(GostBelegungsfehler.ANZ_10);
+	}
+
+	/**
+	 * EF1-Prüfung Punkt 22:
+	 * Prüfe, ob die Summe der Kursstunden in der EF.1 größer oder gleich 32 und kleiner oder gleich 36 ist.
+	 */
+	private pruefeWochenstundenEF1() : void {
+		if (this.wochenstunden === null) 
+			throw new NullPointerException()
+		let stunden : Number | null = this.wochenstunden.get(GostHalbjahr.EF1);
+		if ((stunden === null) || (stunden < 32) || (stunden > 36)) 
+			this.addFehler(GostBelegungsfehler.ANZ_11_INFO);
+	}
+
+	protected pruefeGesamt() : void {
+		this.pruefeGrundkurseEF();
+		this.pruefeGrundkurseQ();
+		this.pruefeLeistungskurse();
+		this.pruefeVertiefungskurseEF();
+		this.pruefeWochenstunden();
+		this.pruefeVertiefungskurseQ();
+		this.pruefeAnrechenbareKurse();
+		this.pruefeKursstundenSummen();
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 58: 
+	 * Prüfe, ob zu wenige Grundkurse (ohne Vertiefungskurse) in der EF belegt wurden,
+	 * dh. weniger als 10 Kurse
+	 */
+	private pruefeGrundkurseEF() : void {
+		if (this.kurszahlenGrundkurse === null) 
+			throw new NullPointerException()
+		let kurszahlGK_EF1 : Number | null = this.kurszahlenGrundkurse.get(GostHalbjahr.EF1);
+		let kurszahlGK_EF2 : Number | null = this.kurszahlenGrundkurse.get(GostHalbjahr.EF2);
+		if ((kurszahlGK_EF1 === null) || (kurszahlGK_EF1 < 10) || (kurszahlGK_EF2 === null) || (kurszahlGK_EF2 < 10)) 
+			this.addFehler(GostBelegungsfehler.ANZ_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 59:
+	 * Prüfe, ob in jedem Halbjahr die Summe der Kursstunden größer oder gleich 32 und kleiner oder gleich 36 ist.
+	 */
+	private pruefeWochenstunden() : void {
+		if (this.wochenstunden === null) 
+			throw new NullPointerException()
+		for (let halbjahr of GostHalbjahr.values()) {
+			let stunden : Number | null = this.wochenstunden.get(halbjahr);
+			if ((stunden === null) || (stunden < 32) || (stunden > 36)) 
+				this.addFehler(GostBelegungsfehler.ANZ_11_INFO);
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 61:
+	 * Prüfe, ob in den Halbjahren der Qualifikationsphase mindestens 7 Grundkurse belegt wurden.
+	 * Dazu zählen auch Zusatzkurse sowie solche Projektkurse, die 2 Halbjahre belegt wurden 
+	 * und zu keiner besonderen Lernleistung zählen.
+	 */
+	private pruefeGrundkurseQ() : void {
+		if (this.kurszahlenGrundkurse === null) 
+			throw new NullPointerException()
+		for (let halbjahr of GostHalbjahr.getQualifikationsphase()) {
+			let kurszahlGK : Number | null = this.kurszahlenGrundkurse.get(halbjahr);
+			if ((kurszahlGK === null) || (kurszahlGK < 7)) 
+				this.addFehler(GostBelegungsfehler.GKS_10);
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 60 und 75:
+	 * Wurden in der Qualifikationsphase in jedem Halbjahr zwei LKs belegt in insgesamt genau 2 Fächern.
+	 */
+	private pruefeLeistungskurse() : void {
+		if (this.anzahlLKFaecher !== 2) 
+			this.addFehler(GostBelegungsfehler.LK_10);
+		if (this.kurszahlenLeistungskurse === null) 
+			throw new NullPointerException()
+		for (let halbjahr of GostHalbjahr.getQualifikationsphase()) {
+			let kurszahlLK : Number | null = this.kurszahlenLeistungskurse.get(halbjahr);
+			if ((kurszahlLK !== null) && (kurszahlLK > 2)) 
+				this.addFehler(GostBelegungsfehler.LK_11);
+		}
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 62:
+	 * Ist die Summe aller belegten Vertiefungskurse in der EF kleiner gleich 4?
+	 */
+	private pruefeVertiefungskurseEF() : void {
+		if (this.kurszahlenEinfuehrungsphase === null) 
+			throw new NullPointerException()
+		let kurszahlEF_VTF : Number | null = this.kurszahlenEinfuehrungsphase.get(GostKursart.VTF);
+		if ((kurszahlEF_VTF !== null) && (kurszahlEF_VTF > 4)) 
+			this.addFehler(GostBelegungsfehler.VF_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 63:
+	 * Ist die Summe aller belegten Vertiefungskurse in der Qualifikationsphase kleiner gleich 2?
+	 */
+	private pruefeVertiefungskurseQ() : void {
+		if (this.kurszahlenQualifikationsphase === null) 
+			throw new NullPointerException()
+		let kurszahlQ_VTF : Number | null = this.kurszahlenQualifikationsphase.get(GostKursart.VTF);
+		if ((kurszahlQ_VTF !== null) && (kurszahlQ_VTF > 2)) 
+			this.addFehler(GostBelegungsfehler.VF_11);
+	}
+
+	/**
+	 * Gesamtprüfung Punkt 69:
+	 * Ist die Anzahl anrechenbarer Kurse für Block I des Abiturs (Qualifikationsphase) größer gleich 38? 
+	 */
+	private pruefeAnrechenbareKurse() : void {
+		if (this.blockIAnzahlAnrechenbar < 38) 
+			this.addFehler(GostBelegungsfehler.ANZ_12);
+	}
+
+	/**
+	 * Gesamtprüfung Punkte 80-82:
+	 * Prüfe, ob die Summe der durschnittlichen Kursstunden der 3 Jahre größer oder gleich 100 bzw. 102 ist
+	 * und ob die durchschnittliche Summe der Kurstunden in der Einführungsphase under Qualifikationsphase 
+	 * größer oder gleich 34 ist. 
+	 */
+	private pruefeKursstundenSummen() : void {
+		if (this.wochenstundenEinfuehrungsphase / 2.0 < 34.0) 
+			this.addFehler(GostBelegungsfehler.WST_20);
+		if (this.wochenstundenQualifikationsphase / 4.0 < 34.0) 
+			this.addFehler(GostBelegungsfehler.WST_21);
+		let summeKursstundenDurchschnitte : number = (this.wochenstundenEinfuehrungsphase / 2.0) + (this.wochenstundenQualifikationsphase / 4.0) * 2.0;
+		if (summeKursstundenDurchschnitte < 102) {
+			if (summeKursstundenDurchschnitte < 100) {
+				this.addFehler(GostBelegungsfehler.STD_10);
+			} else {
+				this.addFehler(GostBelegungsfehler.STD_11_INFO);
+			}
+		}
+	}
+
+	/**
+	 * Gibt die Kurszahlen für das Halbjahr und die Kursart zurück.
+	 * 
+	 * @param halbjahr   das Halbjahr
+	 * @param kursart    die Kursart
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlen(halbjahr : GostHalbjahr, kursart : GostKursart) : number {
+		if (this.kurszahlen === null) 
+			return 0;
+		let kurszahlenHalbjahr : HashMap<GostKursart, Number> | null = this.kurszahlen.get(halbjahr);
+		if (kurszahlenHalbjahr === null) 
+			return 0;
+		let kurszahl : Number | null = kurszahlenHalbjahr.get(kursart);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Kurszahlen für die Grundkurse für das angegebene Halbjahr zurück.
+	 * 
+	 * @param halbjahr   das Halbjahr
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlenGrundkurse(halbjahr : GostHalbjahr) : number {
+		if (this.kurszahlenGrundkurse === null) 
+			return 0;
+		let kurszahl : Number | null = this.kurszahlenGrundkurse.get(halbjahr);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Kurszahlen für die Leistungskurse für das angegebene Halbjahr zurück.
+	 * 
+	 * @param halbjahr   das Halbjahr
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlenLeistungskurse(halbjahr : GostHalbjahr) : number {
+		if (this.kurszahlenLeistungskurse === null) 
+			return 0;
+		let kurszahl : Number | null = this.kurszahlenLeistungskurse.get(halbjahr);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Zahl der anrechenbaren Kurse für das angegebene Halbjahr zurück.
+	 * 
+	 * @param halbjahr   das Halbjahr
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlenAnrechenbar(halbjahr : GostHalbjahr) : number {
+		if (this.kurszahlenAnrechenbar === null) 
+			return 0;
+		let kurszahl : Number | null = this.kurszahlenAnrechenbar.get(halbjahr);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Zahl der Kurse mit der angegebenen Kursart in der Einführungsphase zurück.
+	 * 
+	 * @param kursart   die Kursart
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlenEinfuehrungsphase(kursart : GostKursart) : number {
+		if (this.kurszahlenEinfuehrungsphase === null) 
+			return 0;
+		let kurszahl : Number | null = this.kurszahlenEinfuehrungsphase.get(kursart);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Zahl der Kurse mit der angegebenen Kursart in der Qualifikationsphase zurück.
+	 * 
+	 * @param kursart   die Kursart
+	 * 
+	 * @return die Kurszahlen
+	 */
+	public getKurszahlenQualifikationsphase(kursart : GostKursart) : number {
+		if (this.kurszahlenQualifikationsphase === null) 
+			return 0;
+		let kurszahl : Number | null = this.kurszahlenQualifikationsphase.get(kursart);
+		if (kurszahl === null) 
+			return 0;
+		return kurszahl.valueOf();
+	}
+
+	/**
+	 * Gibt die Anzahl der Grundkurse für Block I zurück.
+	 * 
+	 * @return die Anzahl der Grundkurse
+	 */
+	public getBlockIAnzahlGrundkurse() : number {
+		return this.blockIAnzahlGrundkurse;
+	}
+
+	/**
+	 * Gibt die Anzahl der Leistungskurse für Block I zurück.
+	 * 
+	 * @return die Anzahl der Leistungskurse
+	 */
+	public getBlockIAnzahlLeistungskurse() : number {
+		return this.blockIAnzahlLeistungskurse;
+	}
+
+	/**
+	 * Gibt die Anzahl der anrechenbaren Kurse für Block I zurück.
+	 * 
+	 * @return die Anzahl der anrechenbaren Kurse
+	 */
+	public getBlockIAnzahlAnrechenbar() : number {
+		return this.blockIAnzahlAnrechenbar;
+	}
+
+	/**
+	 * Gibt die Anzahl der Wochenstunden für das angegebene Halbjahr zurück.
+	 *  
+	 * @param halbjahr  das Halbjahr
+	 * 
+	 * @return die Anzahl der Wochenstunden
+	 */
+	public getWochenstunden(halbjahr : GostHalbjahr) : number {
+		if (this.wochenstunden === null) 
+			return 0;
+		let stunden : Number | null = this.wochenstunden.get(halbjahr);
+		if (stunden === null) 
+			stunden = 0;
+		return stunden.valueOf();
+	}
+
+	/**
+	 * Gibt die Anzahl der Wochenstunden für die Einführungsphase zurück.
+	 *  
+	 * @return die Anzahl der Wochenstunden
+	 */
+	public getWochenstundenEinfuehrungsphase() : number {
+		return this.wochenstundenEinfuehrungsphase;
+	}
+
+	/**
+	 * Gibt die Anzahl der Wochenstunden für die Qualifikationsphase zurück.
+	 *  
+	 * @return die Anzahl der Wochenstunden
+	 */
+	public getWochenstundenQualifikationsphase() : number {
+		return this.wochenstundenQualifikationsphase;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.KurszahlenUndWochenstunden'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_KurszahlenUndWochenstunden(obj : unknown) : KurszahlenUndWochenstunden {
+	return obj as KurszahlenUndWochenstunden;
+}

+ 58 - 0
core/abschluss/gost/belegpruefung/Latinum.ts

@@ -0,0 +1,58 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { SprachendatenManager, cast_de_nrw_schule_svws_core_SprachendatenManager } from '../../../../core/SprachendatenManager';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Latinum extends GostBelegpruefung {
+
+	private latein : AbiturFachbelegung | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung in Bezug auf den Erwerb des Latinums.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.latein = this.manager.getSprachbelegung("L");
+	}
+
+	protected pruefeEF1() : void {
+		if (SprachendatenManager.hatSprachbelegungInSekI(this.manager.getSprachendaten(), "L") && (!this.manager.pruefeBelegung(this.latein, GostHalbjahr.EF1))) 
+			this.addFehler(GostBelegungsfehler.L_10_INFO);
+	}
+
+	protected pruefeGesamt() : void {
+		if (!SprachendatenManager.hatSprachbelegungInSekI(this.manager.getSprachendaten(), "L")) {
+			return;
+		}
+		if (SprachendatenManager.hatSprachbelegungInSekIMitDauer(this.manager.getSprachendaten(), "L", 4)) {
+			if (!this.manager.pruefeBelegung(this.latein, GostHalbjahr.EF1, GostHalbjahr.EF2)) {
+				this.addFehler(GostBelegungsfehler.L_10_INFO);
+			}
+			return;
+		}
+		if (SprachendatenManager.hatSprachbelegungInSekIMitDauer(this.manager.getSprachendaten(), "L", 2)) {
+			if (!this.manager.pruefeBelegung(this.latein, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+				this.addFehler(GostBelegungsfehler.L_11_INFO);
+		}
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Latinum', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Latinum(obj : unknown) : Latinum {
+	return obj as Latinum;
+}

+ 72 - 0
core/abschluss/gost/belegpruefung/LiterarischKuenstlerisch.ts

@@ -0,0 +1,72 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class LiterarischKuenstlerisch extends GostBelegpruefung {
+
+	private kunst_musik : List<AbiturFachbelegung> | null = null;
+
+	private kunst_musik_ersatz : List<AbiturFachbelegung> | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für den literarisch-künstlerischen Bereich.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.kunst_musik = this.manager.getFachbelegungen(GostFachbereich.KUNST_MUSIK);
+		this.kunst_musik_ersatz = this.manager.getFachbelegungen(GostFachbereich.LITERARISCH_KUENSTLERISCH_ERSATZ);
+	}
+
+	protected pruefeEF1() : void {
+		if (this.manager.zaehleBelegungInHalbjahren(this.kunst_musik, GostHalbjahr.EF1) === 0) 
+			this.addFehler(GostBelegungsfehler.KU_MU_10);
+	}
+
+	/**
+	 * Gesamtprüfung Punkte 26-28:
+	 * Prüfe, ob ein Kurs in Kunst oder Musik mindestens von EF.1 bis Q1.2 belegt wurde 
+	 *   oder ob ein Ersatzfach (Literatur, vokal- oder instrumentalpraktischer Grundkurs) in der 
+	 *           Qualifikationsphase gültig belegt wurde
+	 */
+	protected pruefeGesamt() : void {
+		let hatKuMuErsatz : boolean = false;
+		if (this.kunst_musik_ersatz !== null) {
+			for (let fach of this.kunst_musik_ersatz) {
+				if ((this.manager.zaehleBelegung(fach) === 2) && (this.manager.pruefeBelegung(fach, GostHalbjahr.Q11, GostHalbjahr.Q12) || this.manager.pruefeBelegung(fach, GostHalbjahr.Q12, GostHalbjahr.Q21) || this.manager.pruefeBelegung(fach, GostHalbjahr.Q21, GostHalbjahr.Q22))) {
+					hatKuMuErsatz = true;
+				} else 
+					if (this.manager.zaehleBelegung(fach) > 0) {
+						this.addFehler(GostBelegungsfehler.LI_IV_10);
+					}
+			}
+			if (this.kunst_musik_ersatz.size() > 1) 
+				this.addFehler(GostBelegungsfehler.LI_IV_11);
+		}
+		let hatKuMuBisQ12 : boolean = this.manager.pruefeBelegungExistiert(this.kunst_musik, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12);
+		let hatKuMuBisEF2 : boolean = this.manager.pruefeBelegungExistiert(this.kunst_musik, GostHalbjahr.EF1, GostHalbjahr.EF2);
+		if ((!hatKuMuBisEF2) || (hatKuMuBisEF2 && (!hatKuMuBisQ12) && (!hatKuMuErsatz))) 
+			this.addFehler(GostBelegungsfehler.KU_MU_10);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.LiterarischKuenstlerisch'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_LiterarischKuenstlerisch(obj : unknown) : LiterarischKuenstlerisch {
+	return obj as LiterarischKuenstlerisch;
+}

+ 58 - 0
core/abschluss/gost/belegpruefung/Mathematik.ts

@@ -0,0 +1,58 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Mathematik extends GostBelegpruefung {
+
+	private mathematik : AbiturFachbelegung | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für das Fach Mathematik.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.mathematik = this.manager.getFachbelegung(GostFachbereich.MATHEMATIK);
+	}
+
+	protected pruefeEF1() : void {
+		if ((this.mathematik === null) || !this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(this.mathematik, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) {
+			this.addFehler(GostBelegungsfehler.M_10);
+			return;
+		}
+		if (!this.manager.pruefeBelegungMitSchriftlichkeitEinzeln(this.mathematik, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.M_11);
+	}
+
+	protected pruefeGesamt() : void {
+		if (this.mathematik === null) {
+			this.addFehler(GostBelegungsfehler.M_10);
+			return;
+		}
+		if (!this.manager.pruefeBelegung(this.mathematik, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.M_10);
+		if (!this.manager.pruefeBelegungMitSchriftlichkeit(this.mathematik, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21)) 
+			this.addFehler(GostBelegungsfehler.M_11);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Mathematik', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Mathematik(obj : unknown) : Mathematik {
+	return obj as Mathematik;
+}

+ 88 - 0
core/abschluss/gost/belegpruefung/Naturwissenschaften.ts

@@ -0,0 +1,88 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostSchriftlichkeit, cast_de_nrw_schule_svws_core_types_gost_GostSchriftlichkeit } from '../../../../core/types/gost/GostSchriftlichkeit';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Naturwissenschaften extends GostBelegpruefung {
+
+	private naturwissenschaften : List<AbiturFachbelegung> | null = null;
+
+	private naturwissenschaften_klassisch : List<AbiturFachbelegung> | null = null;
+
+	private anzahl_durchgehend : number = 0;
+
+	private anzahl_schriftlich_durchgehend : number = 0;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für das Fach Mathematik.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.naturwissenschaften = this.manager.getFachbelegungen(GostFachbereich.NATURWISSENSCHAFTLICH);
+		this.naturwissenschaften_klassisch = this.manager.getFachbelegungen(GostFachbereich.NATURWISSENSCHAFTLICH_KLASSISCH);
+		this.anzahl_durchgehend = 0;
+		this.anzahl_schriftlich_durchgehend = 0;
+	}
+
+	protected pruefeEF1() : void {
+		if (!this.manager.pruefeBelegungDurchgehendBelegbarExistiert(this.naturwissenschaften_klassisch, GostSchriftlichkeit.BELIEBIG, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.NW_10);
+		if (!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.naturwissenschaften_klassisch, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) 
+			this.addFehler(GostBelegungsfehler.NW_11);
+		let fachbelegungen : List<AbiturFachbelegung> | null = this.manager.filterDurchgehendBelegbar(this.naturwissenschaften);
+		fachbelegungen = this.manager.filterBelegungen(fachbelegungen, GostHalbjahr.EF1);
+		this.anzahl_durchgehend = fachbelegungen === null ? 0 : fachbelegungen.size();
+		fachbelegungen = this.manager.filterBelegungenMitSchriftlichkeit(fachbelegungen, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1);
+		this.anzahl_schriftlich_durchgehend = fachbelegungen === null ? 0 : fachbelegungen.size();
+	}
+
+	protected pruefeGesamt() : void {
+		if (!this.manager.pruefeBelegungExistiert(this.naturwissenschaften_klassisch, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22)) 
+			this.addFehler(GostBelegungsfehler.NW_10);
+		if ((!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.naturwissenschaften_klassisch, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF1)) || (!this.manager.pruefeBelegungExistiertMitSchriftlichkeitEinzeln(this.naturwissenschaften_klassisch, GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr.EF2))) 
+			this.addFehler(GostBelegungsfehler.NW_11);
+		this.anzahl_durchgehend = this.manager.zaehleBelegungenDurchgaengig(this.naturwissenschaften);
+		this.anzahl_schriftlich_durchgehend = this.manager.zaehleBelegungenDurchgaengigSchriftlichInQPhase(this.naturwissenschaften);
+	}
+
+	/**
+	 * Gibt die Anzahl der durchgehend belegten bzw. belegbaren Naturwissenschaften zurück.
+	 * 
+	 * @return die Anzahl der durchgehend belegten bzw. belegbaren Naturwissenschaften zurück.
+	 */
+	public getAnzahlDurchgehendBelegt() : number {
+		return this.anzahl_durchgehend;
+	}
+
+	/**
+	 * Gibt die Anzahl der durchgehend schriftlich belegten bzw. belegbaren Naturwissenschaften zurück.
+	 * Durchgehend schriftlich bedeutet, dass das Fach mind. von Q1.1 bus Q2.1 schriftlich belegt wurde.
+	 * 
+	 * @return die Anzahl der durchgehend schriftlich belegten bzw. belegbaren Naturwissenschaften zurück.
+	 */
+	public getAnzahlDurchgehendSchritflichBelegt() : number {
+		return this.anzahl_schriftlich_durchgehend;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Naturwissenschaften'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Naturwissenschaften(obj : unknown) : Naturwissenschaften {
+	return obj as Naturwissenschaften;
+}

+ 261 - 0
core/abschluss/gost/belegpruefung/Projektkurse.ts

@@ -0,0 +1,261 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFach, cast_de_nrw_schule_svws_core_data_gost_GostFach } from '../../../../core/data/gost/GostFach';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { AbiturFachbelegungHalbjahr, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr } from '../../../../core/data/gost/AbiturFachbelegungHalbjahr';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostFachManager, cast_de_nrw_schule_svws_core_abschluss_gost_GostFachManager } from '../../../../core/abschluss/gost/GostFachManager';
+import { GostKursart, cast_de_nrw_schule_svws_core_types_gost_GostKursart } from '../../../../core/types/gost/GostKursart';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { Vector, cast_java_util_Vector } from '../../../../java/util/Vector';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+import { HashSet, cast_java_util_HashSet } from '../../../../java/util/HashSet';
+
+export class Projektkurse extends GostBelegpruefung {
+
+	private projektkursBelegung : Vector<AbiturFachbelegung> | null = null;
+
+	private projektkurs : AbiturFachbelegung | null = null;
+
+	private projektkursHalbjahre : Vector<GostHalbjahr> | null = null;
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für die Projektkurse.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.projektkurs = null;
+		this.projektkursBelegung = new Vector();
+		this.projektkursHalbjahre = new Vector();
+		let alleFachbelegungen : List<AbiturFachbelegung> = this.manager.getFachbelegungen();
+		for (let i : number = 0; i < alleFachbelegungen.size(); i++){
+			let fachbelegung : AbiturFachbelegung | null = alleFachbelegungen.get(i);
+			if (this.manager.zaehleBelegung(fachbelegung) <= 0) 
+				continue;
+			let fach : GostFach | null = this.manager.getFach(fachbelegung);
+			if ((fach !== null) && GostFachManager.istProjektkurs(fach)) {
+				this.projektkursBelegung.add(fachbelegung);
+			}
+		}
+	}
+
+	protected pruefeEF1() : void {
+		this.pruefeBelegungEF();
+	}
+
+	protected pruefeGesamt() : void {
+		this.pruefeBelegungEF();
+		this.pruefeAufAnrechenbarenProjektkurs();
+		this.pruefeBelegungHalbjahre();
+		this.pruefeBelegungLeitfaecher();
+		if (this.manager.istProjektKursBesondereLernleistung()) 
+			this.addFehler((this.projektkurs !== null) ? GostBelegungsfehler.PF_16_INFO : GostBelegungsfehler.PF_15);
+	}
+
+	/**
+	 * Prüft, ob ein Projektfach in der EF belegt wurde. Eine solche Belegung ist nicht zulässig.
+	 */
+	private pruefeBelegungEF() : void {
+		if (this.projektkursBelegung === null) 
+			return;
+		for (let fachbelegung of this.projektkursBelegung) {
+			for (let belegungHalbjahr of fachbelegung.belegungen) {
+				if (belegungHalbjahr === null) 
+					continue;
+				let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegungHalbjahr.halbjahrKuerzel);
+				if ((halbjahr as unknown === GostHalbjahr.EF1 as unknown) || (halbjahr as unknown === GostHalbjahr.EF2 as unknown)) 
+					this.addFehler(GostBelegungsfehler.PF_10);
+			}
+		}
+	}
+
+	/**
+	 * Prüft, ob ein anrechenbarer Projektkurs unter den belegten Projektfächern existiert. Es darf aber 
+	 * auch nur genau ein anrechenbarer Projektkurs existieren! 
+	 */
+	private pruefeAufAnrechenbarenProjektkurs() : void {
+		if (this.projektkursBelegung === null) 
+			return;
+		for (let fachbelegung of this.projektkursBelegung) {
+			for (let belegungHalbjahr of fachbelegung.belegungen) {
+				if (belegungHalbjahr === null) 
+					continue;
+				let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegungHalbjahr.halbjahrKuerzel);
+				if (halbjahr === null) 
+					continue;
+				if ((halbjahr as unknown === GostHalbjahr.EF1 as unknown) || (halbjahr as unknown === GostHalbjahr.EF2 as unknown)) 
+					continue;
+				let nextHalbjahr : GostHalbjahr | null = halbjahr.next();
+				if (nextHalbjahr === null) {
+					this.addFehler(GostBelegungsfehler.PF_18);
+					continue;
+				} else 
+					if (!this.manager.pruefeBelegung(fachbelegung, nextHalbjahr)) {
+						this.addFehler(GostBelegungsfehler.PF_17_INFO);
+						continue;
+					}
+				if (this.projektkurs !== null) {
+					this.addFehler(GostBelegungsfehler.PF_14);
+					break;
+				}
+				this.projektkurs = fachbelegung;
+				if (this.projektkursHalbjahre === null) 
+					this.projektkursHalbjahre = new Vector();
+				this.projektkursHalbjahre.add(halbjahr);
+				this.projektkursHalbjahre.add(nextHalbjahr);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Prüfe die Halbjahresbelegungen der belegten Projektfächer. Hierbei Darf 
+	 * es zu Einzelbelegungen neben dem anrechenbaren Projektkurs kommen. Diese dürfen
+	 * aber nur vor der Belegung des anrechenbaren Kurses liegen. Außerdem dürfen in 
+	 * einem Halbjahr nicht mehrere Projekfächer belegt sein.  
+	 */
+	private pruefeBelegungHalbjahre() : void {
+		if (this.projektkursBelegung === null) 
+			return;
+		let pjkHalbjahre : HashSet<GostHalbjahr> = new HashSet();
+		for (let fachbelegung of this.projektkursBelegung) {
+			for (let belegungHalbjahr of fachbelegung.belegungen) {
+				if (belegungHalbjahr === null) 
+					continue;
+				let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(belegungHalbjahr.halbjahrKuerzel);
+				if (halbjahr === null) 
+					continue;
+				if ((halbjahr as unknown === GostHalbjahr.EF1 as unknown) || (halbjahr as unknown === GostHalbjahr.EF2 as unknown)) 
+					continue;
+				if (!pjkHalbjahre.add(halbjahr)) {
+					this.addFehler(GostBelegungsfehler.PF_14);
+					continue;
+				}
+				if ((this.projektkurs !== null) && JavaObject.equalsTranspiler(this.projektkurs, (fachbelegung)) && (this.projektkursHalbjahre !== null) && this.projektkursHalbjahre.contains(halbjahr)) 
+					continue;
+				let nextHalbjahr : GostHalbjahr | null = halbjahr.next();
+				if ((nextHalbjahr !== null) && (GostFachManager.istWaehlbar(this.manager.getFach(fachbelegung), nextHalbjahr)) && ((this.projektkurs === null) || (this.projektkursHalbjahre === null) || (halbjahr.compareTo(this.projektkursHalbjahre.get(0)) < 0))) 
+					continue;
+				this.addFehler(GostBelegungsfehler.PF_14);
+			}
+		}
+	}
+
+	/**
+	 * Prüft die Belegung der Leitfächer 
+	 */
+	private pruefeBelegungLeitfaecher() : void {
+		if (this.projektkursBelegung === null) 
+			return;
+		for (let fachbelegung of this.projektkursBelegung) {
+			let fach : GostFach | null = this.manager.getFach(fachbelegung);
+			if (fach === null) 
+				continue;
+			let leitfach1 : AbiturFachbelegung | null = this.manager.getFachbelegungByKuerzel(fach.projektKursLeitfach1Kuerzel);
+			let leitfach2 : AbiturFachbelegung | null = this.manager.getFachbelegungByKuerzel(fach.projektKursLeitfach2Kuerzel);
+			if ((leitfach1 !== null) && this.pruefeBelegungLeitfachbelegung(fachbelegung, leitfach1)) 
+				continue;
+			if ((leitfach2 !== null) && this.pruefeBelegungLeitfachbelegung(fachbelegung, leitfach2)) 
+				continue;
+			this.addFehler(GostBelegungsfehler.PF_13);
+		}
+	}
+
+	/**
+	 * Prüft, ob das Leitfach in Bezug auf die Belegung des Projektfaches die korrekten Halbjahresbelegungen hat.
+	 * 
+	 * @param projektkurs   die Fachbelegungen des Projektfaches
+	 * @param leitfach      die Fachbelegungen des Leitfaches
+	 * 
+	 * @return true, falls das Leitfach eine geeigneten Belegung aufweist, sonst false
+	 */
+	private pruefeBelegungLeitfachbelegung(projektkurs : AbiturFachbelegung | null, leitfach : AbiturFachbelegung | null) : boolean {
+		if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q11, GostHalbjahr.Q12)) {
+			if ((leitfach !== null) && this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12)) 
+				return true;
+		} else 
+			if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q12, GostHalbjahr.Q21)) {
+				if ((leitfach !== null) && (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12) || this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q12, GostHalbjahr.Q21))) 
+					return true;
+			} else 
+				if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q21, GostHalbjahr.Q22)) {
+					if ((leitfach !== null) && ((this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q12, GostHalbjahr.Q21)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q21, GostHalbjahr.Q22)))) 
+						return true;
+				} else 
+					if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q11)) {
+						if ((leitfach !== null) && this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11)) 
+							return true;
+					} else 
+						if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q12)) {
+							if ((leitfach !== null) && (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12) || this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q12))) 
+								return true;
+						} else 
+							if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q21)) {
+								if ((leitfach !== null) && ((this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q12, GostHalbjahr.Q21)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q21)))) 
+									return true;
+							} else 
+								if (this.manager.pruefeBelegung(projektkurs, GostHalbjahr.Q22)) {
+									if ((leitfach !== null) && ((this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q11, GostHalbjahr.Q12)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q12, GostHalbjahr.Q21)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q21, GostHalbjahr.Q22)) || (this.manager.pruefeBelegung(leitfach, GostHalbjahr.Q22)))) 
+										return true;
+								}
+		return false;
+	}
+
+	/**
+	 * Gibt den belegten Projektkurs zurück, fall ein Kurs gültig belegt wurde.
+	 * 
+	 * @return die Fachbelegung des Projektkurses oder null
+	 */
+	public getProjektkurs() : AbiturFachbelegung | null {
+		return this.projektkurs;
+	}
+
+	/**
+	 * Gibt zurück, ob die angegebene Fachbelegung des Halbjahres eine Fachbelegung des
+	 * angewählten Projektkurses ist und anrechenbar ist. Sollte sie Teil des Projektkurses 
+	 * sein, aber auch zu einer besonderen Lernleistung gehören, so ist sie nicht anrechenbar.
+	 * 
+	 * @param fachbelegungHalbjahr   die Fachbelegung des Halbjahres
+	 * 
+	 * @return true, wenn die Fachbelegung anrechenbar ist.
+	 */
+	public istAnrechenbar(fachbelegungHalbjahr : AbiturFachbelegungHalbjahr | null) : boolean {
+		if (fachbelegungHalbjahr === null) 
+			return false;
+		if (GostKursart.fromKuerzel(fachbelegungHalbjahr.kursartKuerzel) as unknown !== GostKursart.PJK as unknown) 
+			return false;
+		let halbjahr : GostHalbjahr | null = GostHalbjahr.fromKuerzel(fachbelegungHalbjahr.halbjahrKuerzel);
+		if ((this.projektkurs === null) || (this.projektkursHalbjahre === null) || (this.manager.istProjektKursBesondereLernleistung())) 
+			return false;
+		return (halbjahr as unknown === this.projektkursHalbjahre.get(0) as unknown) || (halbjahr as unknown === this.projektkursHalbjahre.get(1) as unknown);
+	}
+
+	/**
+	 * Gibt die Anzahl der anrechenbaren Kurse für Block I des Abiturs zurück
+	 * 
+	 * @return die Anzahl der anrechenbaren Kurse
+	 */
+	public getAnrechenbareKurse() : number {
+		if ((this.projektkurs === null) || (this.manager.istProjektKursBesondereLernleistung())) 
+			return 0;
+		return 2;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Projektkurse', 'de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Projektkurse(obj : unknown) : Projektkurse {
+	return obj as Projektkurse;
+}

+ 67 - 0
core/abschluss/gost/belegpruefung/Schwerpunkt.ts

@@ -0,0 +1,67 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { Naturwissenschaften, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Naturwissenschaften } from '../../../../core/abschluss/gost/belegpruefung/Naturwissenschaften';
+import { Fremdsprachen, cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Fremdsprachen } from '../../../../core/abschluss/gost/belegpruefung/Fremdsprachen';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Schwerpunkt extends GostBelegpruefung {
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für den Schwerpunkt.
+	 * 
+	 * @param manager             der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art       die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 * @param pruefung_sprachen   das Ergebnis für die Belegprüfung der Sprachen
+	 * @param pruefung_nawi       das Ergebnis für die Belegprüfung der Naturwissenschaften
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt, pruefung_sprachen : Fremdsprachen, pruefung_nawi : Naturwissenschaften) {
+		super(manager, pruefungs_art, pruefung_sprachen, pruefung_nawi);
+	}
+
+	protected init() : void {
+	}
+
+	protected pruefeEF1() : void {
+		let pruefung_sprachen : Fremdsprachen = (cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Fremdsprachen(this.pruefungen_vorher[0]));
+		let pruefung_nawi : Naturwissenschaften = (cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Naturwissenschaften(this.pruefungen_vorher[1]));
+		if ((pruefung_sprachen.getAnzahlDurchgehendSchritflichBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendSchritflichBelegt() >= 1)) 
+			return;
+		if (pruefung_sprachen.getAnzahlDurchgehendSchritflichBelegt() >= 2) {
+			this.addFehler(GostBelegungsfehler.NW_FS_12_INFO);
+			return;
+		}
+		if ((pruefung_nawi.getAnzahlDurchgehendBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendSchritflichBelegt() >= 1)) {
+			this.addFehler(GostBelegungsfehler.NW_FS_13_INFO);
+			return;
+		}
+		this.addFehler(GostBelegungsfehler.NW_FS_10);
+	}
+
+	protected pruefeGesamt() : void {
+		let pruefung_sprachen : Fremdsprachen = (cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Fremdsprachen(this.pruefungen_vorher[0]));
+		let pruefung_nawi : Naturwissenschaften = (cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Naturwissenschaften(this.pruefungen_vorher[1]));
+		if ((pruefung_sprachen.getAnzahlDurchgehendSchritflichBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendSchritflichBelegt() >= 1)) 
+			return;
+		if (pruefung_sprachen.getAnzahlDurchgehendSchritflichBelegt() >= 2) {
+			this.addFehler(GostBelegungsfehler.NW_FS_12_INFO);
+			return;
+		}
+		if ((pruefung_nawi.getAnzahlDurchgehendBelegt() >= 2) && (pruefung_nawi.getAnzahlDurchgehendSchritflichBelegt() >= 1)) {
+			this.addFehler(GostBelegungsfehler.NW_FS_13_INFO);
+			return;
+		}
+		this.addFehler(GostBelegungsfehler.NW_FS_10);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Schwerpunkt'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Schwerpunkt(obj : unknown) : Schwerpunkt {
+	return obj as Schwerpunkt;
+}

+ 51 - 0
core/abschluss/gost/belegpruefung/Sport.ts

@@ -0,0 +1,51 @@
+import { JavaObject, cast_java_lang_Object } from '../../../../java/lang/JavaObject';
+import { GostFachbereich, cast_de_nrw_schule_svws_core_types_gost_GostFachbereich } from '../../../../core/types/gost/GostFachbereich';
+import { AbiturFachbelegung, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung } from '../../../../core/data/gost/AbiturFachbelegung';
+import { GostBelegpruefungsArt, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefungsArt } from '../../../../core/abschluss/gost/GostBelegpruefungsArt';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../../core/types/gost/GostHalbjahr';
+import { List, cast_java_util_List } from '../../../../java/util/List';
+import { GostBelegpruefung, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegpruefung } from '../../../../core/abschluss/gost/GostBelegpruefung';
+import { AbiturdatenManager, cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager } from '../../../../core/abschluss/gost/AbiturdatenManager';
+import { Vector, cast_java_util_Vector } from '../../../../java/util/Vector';
+import { GostBelegungsfehler, cast_de_nrw_schule_svws_core_abschluss_gost_GostBelegungsfehler } from '../../../../core/abschluss/gost/GostBelegungsfehler';
+
+export class Sport extends GostBelegpruefung {
+
+	private sport : List<AbiturFachbelegung> = new Vector();
+
+
+	/**
+	 * Erstellt eine neue Belegprüfung für das Fach Sport.
+	 * 
+	 * @param manager         der Daten-Manager für die Abiturdaten
+	 * @param pruefungs_art   die Art der durchzuführenden Prüfung (z.B. EF.1 oder GESAMT)
+	 */
+	public constructor(manager : AbiturdatenManager, pruefungs_art : GostBelegpruefungsArt) {
+		super(manager, pruefungs_art);
+	}
+
+	protected init() : void {
+		this.sport = this.manager.getFachbelegungen(GostFachbereich.SPORT);
+	}
+
+	protected pruefeEF1() : void {
+		if ((this.sport === null) || (!this.manager.pruefeBelegungExistiertEinzeln(this.sport, GostHalbjahr.EF1))) {
+			this.addFehler(GostBelegungsfehler.SP_10);
+			return;
+		}
+	}
+
+	protected pruefeGesamt() : void {
+		if ((this.sport === null) || (!this.manager.pruefeBelegungExistiert(this.sport, GostHalbjahr.EF1, GostHalbjahr.EF2, GostHalbjahr.Q11, GostHalbjahr.Q12, GostHalbjahr.Q21, GostHalbjahr.Q22))) 
+			this.addFehler(GostBelegungsfehler.SP_10);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.abschluss.gost.GostBelegpruefung', 'de.nrw.schule.svws.core.abschluss.gost.belegpruefung.Sport'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_abschluss_gost_belegpruefung_Sport(obj : unknown) : Sport {
+	return obj as Sport;
+}

+ 644 - 0
core/adt/collection/LinkedCollection.ts

@@ -0,0 +1,644 @@
+import { StringBuilder, cast_java_lang_StringBuilder } from '../../../java/lang/StringBuilder';
+import { IndexOutOfBoundsException, cast_java_lang_IndexOutOfBoundsException } from '../../../java/lang/IndexOutOfBoundsException';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Deque, cast_java_util_Deque } from '../../../java/util/Deque';
+import { LinkedCollectionElement, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionElement } from '../../../core/adt/collection/LinkedCollectionElement';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { Cloneable, cast_java_lang_Cloneable } from '../../../java/lang/Cloneable';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { LinkedCollectionDescendingIterator, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionDescendingIterator } from '../../../core/adt/collection/LinkedCollectionDescendingIterator';
+import { LinkedCollectionIterator, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionIterator } from '../../../core/adt/collection/LinkedCollectionIterator';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { CloneNotSupportedException, cast_java_lang_CloneNotSupportedException } from '../../../java/lang/CloneNotSupportedException';
+
+export class LinkedCollection<E> extends JavaObject implements Deque<E>, Cloneable {
+
+	_head : LinkedCollectionElement<E> | null = null;
+
+	_tail : LinkedCollectionElement<E> | null = null;
+
+	private _size : number = 0;
+
+	_modCount : number = 0;
+
+
+	/**
+	 * Erzeugt eine neue LinkedCollection.
+	 */
+	public constructor();
+
+	/**
+	 * Erzeugt eine neue LinkedCollection als Kopie der übergebenen 
+	 * LinkedCollection
+	 * 
+	 * @param c   die LinkedCollection, die kopiert wird
+	 */
+	public constructor(c : LinkedCollection<E> | null);
+
+	/**
+	 * Implementation for method overloads of 'constructor'
+	 */
+	public constructor(__param0? : LinkedCollection<E> | null) {
+		super();
+		if ((typeof __param0 === "undefined")) {
+			this._head = null;
+			this._tail = null;
+			this._size = 0;
+			this._modCount = 0;
+		} else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.collection.LinkedCollection'))) || (__param0 === null))) {
+			let c : LinkedCollection<E> | null = cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection(__param0);
+			this._size = 0;
+			this._modCount = 0;
+			let iter : JavaIterator<E> = c.iterator();
+			while (iter.hasNext()) 
+				this.add(iter.next());
+			this._modCount = c._modCount;
+		} else throw new Error('invalid method overload');
+	}
+
+	public size() : number {
+		return this._size;
+	}
+
+	public isEmpty() : boolean {
+		return (this._head === null) ? true : false;
+	}
+
+	public contains(obj : unknown | null) : boolean {
+		if (this.isEmpty()) 
+			return false;
+		let iter : JavaIterator<E> = this.iterator();
+		while (iter.hasNext()) 
+			if (JavaObject.equalsTranspiler(iter.next(), (obj))) 
+				return true;
+		return false;
+	}
+
+	public iterator() : JavaIterator<E> {
+		return new LinkedCollectionIterator(this);
+	}
+
+	public toArray() : Array<unknown>;
+
+	public toArray<T>(a : Array<T>) : Array<T>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<T>(__param0? : Array<T>) : Array<T> | Array<unknown> {
+		if ((typeof __param0 === "undefined")) {
+			if (this._size === 0) 
+				return Array(0).fill(null);
+			let array : Array<E> = Array(this._size).fill(null);
+			let iter : JavaIterator<E> = this.iterator();
+			for (let i : number = 0; i < this._size; i++){
+				array[i] = iter.next();
+			}
+			return array;
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<T> = __param0;
+			if (a.length < this._size) 
+				return this.toArray();
+			let iter : JavaIterator<E> = this.iterator();
+			for (let i : number = 0; i < this._size; i++){
+				let e : E = iter.next();
+				a[i] = e as unknown as T;
+			}
+			Arrays.fill(a, this._size, a.length, null);
+			return a;
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : E | null) : boolean {
+		if (e === null) 
+			return false;
+		let newElem : LinkedCollectionElement<E> = new LinkedCollectionElement(e, null, null);
+		if ((this._head === null) || (this._tail === null)) {
+			this._head = newElem;
+			this._tail = newElem;
+			this._size++;
+			this._modCount++;
+			return true;
+		}
+		newElem.setPrev(this._tail);
+		this._tail.setNext(newElem);
+		this._tail = newElem;
+		this._size++;
+		this._modCount++;
+		return true;
+	}
+
+	/**
+	 * Entfernt das übergebene Element.
+	 * 
+	 * @param elem   das zu entfernende Element
+	 *  
+	 * @return true, falls das Element erfolgreich entfernt wurde, und false, falls null übergeben wurde. 
+	 */
+	private removeElement(elem : LinkedCollectionElement<E> | null) : boolean {
+		if (elem === null) 
+			return false;
+		let prev : LinkedCollectionElement<E> | null = elem.getPrev();
+		let next : LinkedCollectionElement<E> | null = elem.getNext();
+		if (this._size === 1) {
+			this._head = null;
+			this._tail = null;
+		} else 
+			if (JavaObject.equalsTranspiler(elem, (this._head))) {
+				if (next === null) 
+					throw new NullPointerException()
+				this._head = next;
+				next.setPrev(null);
+			} else 
+				if (JavaObject.equalsTranspiler(elem, (this._tail))) {
+					if (prev === null) 
+						throw new NullPointerException()
+					this._tail = prev;
+					prev.setNext(null);
+				} else {
+					if ((next === null) || (prev === null)) 
+						throw new NullPointerException()
+					next.setPrev(prev);
+					prev.setNext(next);
+				}
+		this._size--;
+		this._modCount++;
+		return true;
+	}
+
+	public remove(obj : unknown | null) : boolean;
+
+	public remove() : E;
+
+	/**
+	 * Implementation for method overloads of 'remove'
+	 */
+	public remove(__param0? : null | unknown) : E | boolean {
+		if (((typeof __param0 !== "undefined") && ((__param0 instanceof Object) || ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.lang.Object')))) || (__param0 === null))) {
+			let obj : unknown | null = (__param0 instanceof JavaObject) ? cast_java_lang_Object(__param0) : __param0;
+			if (this.isEmpty()) 
+				return false;
+			return this.removeElement(this.findFirst(obj));
+		} else if ((typeof __param0 === "undefined")) {
+			let value : E | null = this.poll();
+			if (value === null) 
+				throw new NoSuchElementException()
+			return value;
+		} else throw new Error('invalid method overload');
+	}
+
+	public containsAll(c : Collection<unknown> | null) : boolean {
+		if ((c === null) || (this as unknown === c as unknown)) 
+			return true;
+		for (let o of c) 
+			if (!this.contains(o)) 
+				return false;
+		return true;
+	}
+
+	public addAll(c : Collection<E> | null) : boolean {
+		if ((c === null) || (c.size() === 0)) 
+			return false;
+		if (((c instanceof JavaObject) && (c.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.collection.LinkedCollection')))) {
+			let coll : LinkedCollection<E> = cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection(c);
+			if ((coll._tail === null) || (coll._head === null)) 
+				throw new NullPointerException()
+			let last : LinkedCollectionElement<E> = coll._tail;
+			let current : LinkedCollectionElement<E> | null = coll._head;
+			this.add(current.getValue());
+			while (current as unknown !== last as unknown) {
+				current = current.getNext();
+				if (current === null) 
+					throw new NullPointerException()
+				this.add(current.getValue());
+			}
+			return true;
+		}
+		let result : boolean = false;
+		for (let elem of c) {
+			if (this.add(elem)) 
+				result = true;
+		}
+		return result;
+	}
+
+	public removeAll(c : Collection<unknown> | null) : boolean {
+		if (c === null) 
+			return false;
+		if (this as unknown === c as unknown) {
+			if (this.size() === 0) 
+				return false;
+			this.clear();
+			return true;
+		}
+		let result : boolean = false;
+		for (let o of c) {
+			if (this.remove(o)) {
+				result = true;
+				while (this.remove(o)) ;
+			}
+		}
+		return result;
+	}
+
+	public retainAll(c : Collection<unknown> | null) : boolean {
+		if ((this as unknown === c as unknown) || (this._head === null)) 
+			return false;
+		if (c === null) {
+			this.clear();
+			return true;
+		}
+		let iter : JavaIterator<E> = this.iterator();
+		let tmp : LinkedCollection<E> = new LinkedCollection();
+		while (iter.hasNext()) {
+			let elem : E = iter.next();
+			if (!c.contains(elem)) 
+				tmp.add(elem);
+		}
+		if (tmp.isEmpty()) 
+			return false;
+		return this.removeAll(tmp);
+	}
+
+	public clear() : void {
+		this._head = null;
+		this._tail = null;
+		this._size = 0;
+		this._modCount++;
+	}
+
+	public hashCode() : number {
+		let hashCode : number = 1;
+		for (let e of this) 
+			hashCode = 31 * hashCode + (e === null ? 0 : JavaObject.getTranspilerHashCode(e));
+		return hashCode;
+	}
+
+	public equals(obj : unknown | null) : boolean {
+		if ((obj === null) || (!(((obj instanceof JavaObject) && (obj.isTranspiledInstanceOf('java.util.Collection')))))) 
+			return false;
+		let other : Collection<unknown> = cast_java_util_Collection(obj);
+		if (this._size !== other.size()) 
+			return false;
+		let iter : JavaIterator<E> = this.iterator();
+		let otherIter : JavaIterator<unknown> = other.iterator();
+		while (iter.hasNext()) {
+			if (!JavaObject.equalsTranspiler(iter.next(), (otherIter.next()))) 
+				return false;
+		}
+		return true;
+	}
+
+	public clone() : unknown {
+		return new LinkedCollection(this);
+	}
+
+	public toString() : String {
+		let sb : StringBuilder = new StringBuilder();
+		sb.append("[");
+		let iter : JavaIterator<E> = this.iterator();
+		while (iter.hasNext()) {
+			sb.append(iter.next());
+			if (iter.hasNext() === true) 
+				sb.append(", ");
+		}
+		sb.append("]");
+		return sb.toString();
+	}
+
+	/**
+	 * Diese Methode ist eine Hilfsmethode für die Methode sort(). Sie mischt die beiden über die prev-Zeiger
+	 * verketteten Listen left und right zu einer kombinierten, über die prev-Zeiger verketteten Liste. 
+	 * 
+	 * @param comparator   ein {@link Comparator} zum Vergleichen zweier Elemente
+	 * @param left         die erste sortierte Liste
+	 * @param right        die zweite sortierte Liste
+	 * 
+	 * @return die kombinierte sortierte Liste 
+	 */
+	private merge(comparator : Comparator<E>, left : LinkedCollectionElement<E>, right : LinkedCollectionElement<E>) : LinkedCollectionElement<E> {
+		let headTo : LinkedCollectionElement<E> | null;
+		let headFrom : LinkedCollectionElement<E> | null;
+		if (comparator.compare(left.getValue(), right.getValue()) > 0) {
+			headFrom = left;
+			headTo = right;
+		} else {
+			headFrom = right;
+			headTo = left;
+		}
+		let target : LinkedCollectionElement<E> = headTo;
+		while (headFrom !== null) {
+			let current : LinkedCollectionElement<E> = headFrom;
+			headFrom = headFrom.getPrev();
+			let targetPrev : LinkedCollectionElement<E> | null = target.getPrev();
+			while ((targetPrev !== null) && (comparator.compare(targetPrev.getValue(), current.getValue()) < 0)) {
+				target = targetPrev;
+				targetPrev = target.getPrev();
+			}
+			if (targetPrev === null) {
+				target.setPrev(current);
+				break;
+			}
+			current.setPrev(targetPrev);
+			target.setPrev(current);
+		}
+		return headTo;
+	}
+
+	/**
+	 * Sortiert den Inhalte dieser Liste mithilfe des übergebenen {@link Comparator}-Objekts. 
+	 * 
+	 * @param comparator   ein {@link Comparator} zum Vergleichen zweier Elemente
+	 * 
+	 * @return true, falls eine Sortierung erfolgreich war 
+	 */
+	public sort(comparator : Comparator<E> | null) : boolean {
+		if (comparator === null) 
+			return false;
+		if ((this._size <= 1) || (this._head === null) || (this._tail === null)) 
+			return true;
+		this._modCount++;
+		for (let current : LinkedCollectionElement<E> | null = this._head; current !== null; current = current.getNext())
+			current.setPrev(null);
+		while (this._head !== null) {
+			let left : LinkedCollectionElement<E> = this._head;
+			let right : LinkedCollectionElement<E> | null = left.getNext();
+			if (right === null) 
+				throw new NullPointerException()
+			this._head = right.getNext();
+			left.setNext(null);
+			right.setNext(null);
+			let sorted : LinkedCollectionElement<E> = this.merge(comparator, left, right);
+			this._tail.setNext(sorted);
+			this._tail = sorted;
+		}
+		this._head = this._tail;
+		this._tail.setNext(this._tail.getPrev());
+		while (this._tail.getPrev() !== null) {
+			this._tail = this._tail.getPrev();
+			if (this._tail === null) 
+				throw new NullPointerException()
+			this._tail.setNext(this._tail.getPrev());
+		}
+		this._head.setPrev(null);
+		let current : LinkedCollectionElement<E> = this._head;
+		let next : LinkedCollectionElement<E> | null = current.getNext();
+		while (next !== null) {
+			next.setPrev(current);
+			current = next;
+			next = current.getNext();
+		}
+		this._modCount++;
+		return true;
+	}
+
+	/**
+	 * Sucht das Element an der Stelle Index.
+	 *   
+	 * @param index   die Stelle des gesuchten Elements
+	 * 
+	 * @return das Element an der gesuchten Stelle 
+	 * 
+	 * @throws IndexOutOfBoundsException   wenn der Index nicht im gültigen Bereich liegt (index >= 0) && (index < size()))  
+	 */
+	private find(index : number) : LinkedCollectionElement<E> {
+		if ((index < 0) || (index >= this._size)) 
+			throw new IndexOutOfBoundsException()
+		let current : LinkedCollectionElement<E> | null = this._head;
+		for (let i : number = 0; (current !== null); i++, current = current.getNext())
+			if (i === index) 
+				return current;
+		throw new IndexOutOfBoundsException()
+	}
+
+	/**
+	 * Sucht ein LinkedCollectionElement in der Collection mit dem Wert obj
+	 * und gibt es zurück
+	 * 
+	 * @param obj   der Wert der in der LinkedCollection gesucht werden soll
+	 * 
+	 * @return  ein LinkedCollectionElement<E> falls der Wert in der Collection 
+	 * 			enthalten ist und das Element dessen , ansonsten null
+	 */
+	private findFirst(obj : unknown | null) : LinkedCollectionElement<E> | null {
+		if (obj === null) 
+			return null;
+		let current : LinkedCollectionElement<E> | null = this._head;
+		while (current !== null) {
+			if (JavaObject.equalsTranspiler(current.getValue(), (obj))) 
+				return current;
+			current = current.getNext();
+		}
+		return null;
+	}
+
+	/**
+	 * Sucht ein LinkedCollectionElement in der Collection mit dem Wert obj
+	 * und gibt es zurück
+	 * 
+	 * @param obj   der Wert der in der LinkedCollection gesucht werden soll
+	 * 
+	 * @return  ein LinkedCollectionElement<E> falls der Wert in der Collection 
+	 * 			enthalten ist und das Element dessen, ansonsten null
+	 */
+	private findLast(obj : unknown | null) : LinkedCollectionElement<E> | null {
+		if (obj === null) 
+			return null;
+		let current : LinkedCollectionElement<E> | null = this._tail;
+		while (current !== null) {
+			if (JavaObject.equalsTranspiler(current.getValue(), (obj))) 
+				return current;
+			current = current.getPrev();
+		}
+		return null;
+	}
+
+	public offer(e : E | null) : boolean {
+		return this.add(e);
+	}
+
+	public poll() : E | null {
+		if (this._head === null) 
+			return null;
+		let value : E = this._head.getValue();
+		this._head = this._head.getNext();
+		if (this._head === null) 
+			this._tail = null; else 
+			this._head.setPrev(null);
+		this._size--;
+		this._modCount++;
+		return value;
+	}
+
+	public element() : E {
+		if (this._head === null) 
+			throw new NoSuchElementException()
+		return this._head.getValue();
+	}
+
+	public peek() : E | null {
+		return (this._head === null) ? null : this._head.getValue();
+	}
+
+	public addFirst(e : E | null) : void {
+		if (e === null) 
+			throw new NullPointerException()
+		let newElem : LinkedCollectionElement<E> = new LinkedCollectionElement(e, null, null);
+		if ((this._head === null) || (this._tail === null)) {
+			this._head = newElem;
+			this._tail = newElem;
+		} else {
+			newElem.setNext(this._head);
+			this._head.setPrev(newElem);
+			this._head = newElem;
+		}
+		this._size++;
+		this._modCount++;
+	}
+
+	public addLast(e : E | null) : void {
+		if (e === null) 
+			throw new NullPointerException()
+		this.add(e);
+	}
+
+	public offerFirst(e : E | null) : boolean {
+		this.addFirst(e);
+		return true;
+	}
+
+	public offerLast(e : E | null) : boolean {
+		this.addLast(e);
+		return true;
+	}
+
+	public removeFirst() : E {
+		let value : E | null = this.poll();
+		if (value === null) 
+			throw new NoSuchElementException()
+		return value;
+	}
+
+	public removeLast() : E {
+		let value : E | null = this.pollLast();
+		if (value === null) 
+			throw new NoSuchElementException()
+		return value;
+	}
+
+	public pollFirst() : E | null {
+		return this.poll();
+	}
+
+	public pollLast() : E | null {
+		if (this._tail === null) 
+			return null;
+		let value : E = this._tail.getValue();
+		this._tail = this._tail.getPrev();
+		if (this._tail === null) 
+			this._head = null; else 
+			this._tail.setNext(null);
+		this._size--;
+		this._modCount++;
+		return value;
+	}
+
+	public getFirst() : E {
+		if (this._head === null) 
+			throw new NoSuchElementException()
+		return this._head.getValue();
+	}
+
+	public getLast() : E {
+		if (this._tail === null) 
+			throw new NoSuchElementException()
+		return this._tail.getValue();
+	}
+
+	public peekFirst() : E | null {
+		return (this._head === null) ? null : this._head.getValue();
+	}
+
+	public peekLast() : E | null {
+		return (this._tail === null) ? null : this._tail.getValue();
+	}
+
+	public removeFirstOccurrence(obj : unknown | null) : boolean {
+		if (this.isEmpty()) 
+			return false;
+		return this.removeElement(this.findFirst(obj));
+	}
+
+	public removeLastOccurrence(obj : unknown | null) : boolean {
+		if (this.isEmpty()) 
+			return false;
+		return this.removeElement(this.findLast(obj));
+	}
+
+	public push(e : E) : void {
+		this.addFirst(e);
+	}
+
+	public pop() : E {
+		let value : E | null = this.poll();
+		if (value === null) 
+			throw new NoSuchElementException()
+		return value;
+	}
+
+	public descendingIterator() : JavaIterator<E> {
+		return new LinkedCollectionDescendingIterator(this);
+	}
+
+	/**
+	 * Gibt den Wert an der Stelle index zurück.
+	 * 
+	 * @param index   der Index
+	 * 
+	 * @return der Wert
+	 * 
+	 * @throws IndexOutOfBoundsException   wenn der Index nicht im gültigen Bereich liegt {@code (index >= 0) && (index < size()))}  
+	 */
+	public get(index : number) : E {
+		return this.find(index).getValue();
+	}
+
+	/**
+	 * Ersetzt den Wert an der Stelle index mit dem neuen übergebenen Wert.
+	 *  
+	 * @param index     die Stelle, wo der Wert ersetzt werden soll
+	 * @param element   der neue Wert für die Stelle 
+	 * 
+	 * @return der alte Wert an der Stelle
+	 * 
+	 * @throws IndexOutOfBoundsException   wenn der Index nicht im gültigen Bereich liegt {@code (index >= 0) && (index < size()))}  
+	 */
+	public set(index : number, element : E) : E {
+		return this.find(index).setValue(element);
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.lang.Cloneable', 'java.util.Collection', 'java.util.Queue', 'java.util.Deque', 'java.lang.Iterable', 'de.nrw.schule.svws.core.adt.collection.LinkedCollection'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<E> {
+		let iter : JavaIterator<E> = this.iterator();
+		const result : Iterator<E> = {
+			next() : IteratorResult<E> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection<E>(obj : unknown) : LinkedCollection<E> {
+	return obj as LinkedCollection<E>;
+}

+ 59 - 0
core/adt/collection/LinkedCollectionDescendingIterator.ts

@@ -0,0 +1,59 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ConcurrentModificationException, cast_java_util_ConcurrentModificationException } from '../../../java/util/ConcurrentModificationException';
+import { LinkedCollection, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection } from '../../../core/adt/collection/LinkedCollection';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { LinkedCollectionElement, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionElement } from '../../../core/adt/collection/LinkedCollectionElement';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class LinkedCollectionDescendingIterator<E> extends JavaObject implements JavaIterator<E> {
+
+	private _collection : LinkedCollection<E>;
+
+	private _current : LinkedCollectionElement<E> | null = null;
+
+	private readonly _expModCount : number;
+
+
+	/**
+	 * Erzeugt einen neuen LinkedCollectionIterator. Dabei wird die Referenz auf 
+	 * die {@link LinkedCollection} übergeben.
+	 * 
+	 * @param collection   die zum Iterator zugehörige {@link LinkedCollection}
+	 */
+	constructor(collection : LinkedCollection<E>) {
+		super();
+		this._collection = collection;
+		this._expModCount = collection._modCount;
+		this._current = collection._tail;
+	}
+
+	public hasNext() : boolean {
+		if (this._collection._modCount !== this._expModCount) 
+			throw new ConcurrentModificationException()
+		return (this._current !== null);
+	}
+
+	public next() : E {
+		if (this._collection._modCount !== this._expModCount) 
+			throw new ConcurrentModificationException()
+		if (this._current === null) 
+			throw new NoSuchElementException()
+		let result : E = this._current.getValue();
+		this._current = this._current.getPrev();
+		return result;
+	}
+
+	public remove() : void {
+		throw new UnsupportedOperationException("remove")
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.adt.collection.LinkedCollectionDescendingIterator', 'java.util.Iterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionDescendingIterator<E>(obj : unknown) : LinkedCollectionDescendingIterator<E> {
+	return obj as LinkedCollectionDescendingIterator<E>;
+}

+ 93 - 0
core/adt/collection/LinkedCollectionElement.ts

@@ -0,0 +1,93 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+
+export class LinkedCollectionElement<E> extends JavaObject {
+
+	private _value : E;
+
+	private _prev : LinkedCollectionElement<E> | null = null;
+
+	private _next : LinkedCollectionElement<E> | null = null;
+
+
+	/**
+	 * Erstellt eine neues LinkedCollectionElement mit den Wert _value und den 
+	 * übergebenen Vorgänger bzw. Nachfolger
+	 * 
+	 * @param value   der Wert des SimpleCollectionElements
+	 * @param prev    der Vorgänger
+	 * @param next    der Nachfolger
+	 */
+	constructor(value : E, prev : LinkedCollectionElement<E> | null, next : LinkedCollectionElement<E> | null) {
+		super();
+		this._value = value;
+		this._prev = prev;
+		this._next = next;
+	}
+
+	/**
+	 * Gibt den Wert des Elements zurück.
+	 * 
+	 * @return der Wert des Elements
+	 */
+	getValue() : E {
+		return this._value;
+	}
+
+	/**
+	 * Ersetzt den Wert des Elements.
+	 * 
+	 * @param value   der neue Wert des Elements
+	 * 
+	 * @return der alte Wert des Elements
+	 */
+	setValue(value : E) : E {
+		let oldValue : E = this._value;
+		this._value = value;
+		return oldValue;
+	}
+
+	/**
+	 * Gibt den Vorgänger des Elementes zurück.
+	 * 
+	 * @return   das LinkedCollectionElement das der Vorgänger des Elementes ist
+	 */
+	getPrev() : LinkedCollectionElement<E> | null {
+		return this._prev;
+	}
+
+	/**
+	 * Setzt den Vorgänger des Elementes auf _prev
+	 * 
+	 * @param prev   der Vorgänger des Elements
+	 */
+	setPrev(prev : LinkedCollectionElement<E> | null) : void {
+		this._prev = prev;
+	}
+
+	/**
+	 * Gibt den Nachfolger des Elementes zurück.
+	 * 
+	 * @return   das LinkedCollectionElement das der Nachfolger des Elementes ist
+	 */
+	getNext() : LinkedCollectionElement<E> | null {
+		return this._next;
+	}
+
+	/**
+	 * Setzt den Nachfolger des Elementes auf _next
+	 * 
+	 * @param next   der Nachfolger des Elements
+	 */
+	setNext(next : LinkedCollectionElement<E> | null) : void {
+		this._next = next;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.adt.collection.LinkedCollectionElement'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionElement<E>(obj : unknown) : LinkedCollectionElement<E> {
+	return obj as LinkedCollectionElement<E>;
+}

+ 59 - 0
core/adt/collection/LinkedCollectionIterator.ts

@@ -0,0 +1,59 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ConcurrentModificationException, cast_java_util_ConcurrentModificationException } from '../../../java/util/ConcurrentModificationException';
+import { LinkedCollection, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection } from '../../../core/adt/collection/LinkedCollection';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { LinkedCollectionElement, cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionElement } from '../../../core/adt/collection/LinkedCollectionElement';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class LinkedCollectionIterator<E> extends JavaObject implements JavaIterator<E> {
+
+	private _collection : LinkedCollection<E>;
+
+	private _current : LinkedCollectionElement<E> | null = null;
+
+	private readonly _expModCount : number;
+
+
+	/**
+	 * Erzeugt einen neuen LinkedCollectionIterator. Dabei wird die Referenz auf 
+	 * die {@link LinkedCollection} übergeben.
+	 * 
+	 * @param collection   die zum Iterator zugehörige {@link LinkedCollection}
+	 */
+	constructor(collection : LinkedCollection<E>) {
+		super();
+		this._collection = collection;
+		this._expModCount = collection._modCount;
+		this._current = collection._head;
+	}
+
+	public hasNext() : boolean {
+		if (this._collection._modCount !== this._expModCount) 
+			throw new ConcurrentModificationException()
+		return (this._current !== null);
+	}
+
+	public next() : E {
+		if (this._collection._modCount !== this._expModCount) 
+			throw new ConcurrentModificationException()
+		if (this._current === null) 
+			throw new NoSuchElementException()
+		let result : E = this._current.getValue();
+		this._current = this._current.getNext();
+		return result;
+	}
+
+	public remove() : void {
+		throw new UnsupportedOperationException("remove")
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Iterator', 'de.nrw.schule.svws.core.adt.collection.LinkedCollectionIterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_collection_LinkedCollectionIterator<E>(obj : unknown) : LinkedCollectionIterator<E> {
+	return obj as LinkedCollectionIterator<E>;
+}

+ 857 - 0
core/adt/map/AVLMap.ts

@@ -0,0 +1,857 @@
+import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry';
+import { Comparable, cast_java_lang_Comparable } from '../../../java/lang/Comparable';
+import { NavigableSet, cast_java_util_NavigableSet } from '../../../java/util/NavigableSet';
+import { JavaSet, cast_java_util_Set } from '../../../java/util/JavaSet';
+import { NavigableMap, cast_java_util_NavigableMap } from '../../../java/util/NavigableMap';
+import { AVLMapIntervall, cast_de_nrw_schule_svws_core_adt_map_AVLMapIntervall } from '../../../core/adt/map/AVLMapIntervall';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
+import { AVLMapNode, cast_de_nrw_schule_svws_core_adt_map_AVLMapNode } from '../../../core/adt/map/AVLMapNode';
+import { ClassCastException, cast_java_lang_ClassCastException } from '../../../java/lang/ClassCastException';
+import { SortedMap, cast_java_util_SortedMap } from '../../../java/util/SortedMap';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaMap, cast_java_util_Map } from '../../../java/util/JavaMap';
+import { IllegalArgumentException, cast_java_lang_IllegalArgumentException } from '../../../java/lang/IllegalArgumentException';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class AVLMap<K, V> extends JavaObject implements NavigableMap<K, V> {
+
+	private readonly _infinityMinus : K = AVLMapIntervall._INFINITY_MINUS as unknown as K;
+
+	private readonly _infinityPlus : K = AVLMapIntervall._INFINITY_PLUS as unknown as K;
+
+	private readonly _dummyValue : V = new Object() as unknown as V;
+
+	private readonly _sub : AVLMapSubMap<K, V> = new AVLMapSubMap(this, new AVLMapIntervall(this._infinityMinus, false, this._infinityPlus, false), true);
+
+	private readonly _comparator : Comparator<K>;
+
+	private readonly _comparatorNatural : Comparator<K> = { compare : (key1: K, key2: K) => {
+		if ((key1 === null) || (key2 === null)) 
+			throw new NullPointerException()
+		if (!((((key1 instanceof JavaObject) && (key1.isTranspiledInstanceOf('java.lang.Comparable')))) && (((key2 instanceof JavaObject) && (key2.isTranspiledInstanceOf('java.lang.Comparable')))))) 
+			throw new ClassCastException()
+		let k1 : Comparable<K> = cast_java_lang_Comparable(key1);
+		return k1.compareTo(key2);
+	} };
+
+	private _root : AVLMapNode<K, V> | null = null;
+
+	private _allowKeyAlone : boolean = false;
+
+
+	/**
+	 * Erzeugt einen leere Map, welche bei den Schlüsselwerten die natürliche Ordnung des {@link Comparable} -
+	 * Interface nutzt.
+	 */
+	public constructor();
+
+	/**
+	 * Erstellt eine neue leere Map und nutzt dabei die angegeben Ordnung der Schlüssel.
+	 * 
+	 * @param comparator Die Ordnung für die Schlüssel.
+	 */
+	public constructor(comparator : Comparator<K>);
+
+	/**
+	 * Erstellt eine neue Map mit den Daten aus der angegebenen Map und nutzt dabei die Ordnung dieser Map.
+	 * 
+	 * @param map Die Map mit den Daten.
+	 */
+	public constructor(map : SortedMap<K, V>);
+
+	/**
+	 * Implementation for method overloads of 'constructor'
+	 */
+	public constructor(__param0? : Comparator<K> | SortedMap<K, V>) {
+		super();
+		if ((typeof __param0 === "undefined")) {
+			this._comparator = this._comparatorNatural;
+		} else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null))) {
+			let comparator : Comparator<K> = cast_java_util_Comparator(__param0);
+			this._comparator = comparator;
+		} else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.util.SortedMap'))) || (__param0 === null))) {
+			let map : SortedMap<K, V> = cast_java_util_SortedMap(__param0);
+			this._comparator = cast_java_util_Comparator(map.comparator());
+			this._sub.putAll(map);
+		} else throw new Error('invalid method overload');
+	}
+
+	public toString() : String {
+		return this._sub.toString();
+	}
+
+	/**
+	 * Bewirkt, dass das Hinzufügen von Keys ohne Value durch {@link AVLMapSubKeySet} erlaubt ist. Die Keys werden
+	 * auf einen Dummy-Wert gemapped.
+	 * 
+	 * @param b Falls TRUE, dürfen KEYs ohne VALUE hinzugefügt werden.
+	 */
+	public allowKeyAlone(b : boolean) : void {
+		this._allowKeyAlone = b;
+	}
+
+	public equals(o : unknown) : boolean {
+		return JavaObject.equalsTranspiler(this._sub, (o));
+	}
+
+	public hashCode() : number {
+		return JavaObject.getTranspilerHashCode(this._sub);
+	}
+
+	public comparator() : Comparator<K> {
+		return this._sub.comparator();
+	}
+
+	public firstKey() : K {
+		return this._sub.firstKey();
+	}
+
+	public lastKey() : K {
+		return this._sub.lastKey();
+	}
+
+	public keySet() : JavaSet<K> {
+		return this._sub.keySet();
+	}
+
+	public values() : Collection<V> {
+		return this._sub.values();
+	}
+
+	public entrySet() : JavaSet<JavaMapEntry<K, V>> {
+		return this._sub.entrySet();
+	}
+
+	public size() : number {
+		return this._sub.size();
+	}
+
+	public isEmpty() : boolean {
+		return this._sub.isEmpty();
+	}
+
+	public containsKey(key : unknown) : boolean {
+		return this._sub.containsKey(key);
+	}
+
+	public containsValue(value : unknown) : boolean {
+		return this._sub.containsValue(value);
+	}
+
+	public get(key : unknown) : V | null {
+		return this._sub.get(key);
+	}
+
+	public put(key : K, value : V) : V | null {
+		return this._sub.put(key, value);
+	}
+
+	public remove(key : unknown) : V | null {
+		return this._sub.remove(key);
+	}
+
+	public putAll(m : JavaMap<K, V>) : void {
+		this._sub.putAll(m);
+	}
+
+	public clear() : void {
+		this._sub.clear();
+	}
+
+	public lowerEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._sub.lowerEntry(key);
+	}
+
+	public lowerKey(key : K) : K | null {
+		return this._sub.lowerKey(key);
+	}
+
+	public floorEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._sub.floorEntry(key);
+	}
+
+	public floorKey(key : K) : K | null {
+		return this._sub.floorKey(key);
+	}
+
+	public ceilingEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._sub.ceilingEntry(key);
+	}
+
+	public ceilingKey(key : K) : K | null {
+		return this._sub.ceilingKey(key);
+	}
+
+	public higherEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._sub.higherEntry(key);
+	}
+
+	public higherKey(key : K) : K | null {
+		return this._sub.higherKey(key);
+	}
+
+	public firstEntry() : JavaMapEntry<K, V> | null {
+		return this._sub.firstEntry();
+	}
+
+	public lastEntry() : JavaMapEntry<K, V> | null {
+		return this._sub.lastEntry();
+	}
+
+	public pollFirstEntry() : JavaMapEntry<K, V> | null {
+		return this._sub.pollFirstEntry();
+	}
+
+	public pollLastEntry() : JavaMapEntry<K, V> | null {
+		return this._sub.pollLastEntry();
+	}
+
+	public descendingMap() : NavigableMap<K, V> {
+		return this._sub.descendingMap();
+	}
+
+	public navigableKeySet() : NavigableSet<K> {
+		return this._sub.navigableKeySet();
+	}
+
+	public descendingKeySet() : NavigableSet<K> {
+		return this._sub.descendingKeySet();
+	}
+
+	public subMap(fromKey : K, fromInclusive : boolean, toKey : K, toInclusive : boolean) : NavigableMap<K, V>;
+
+	public subMap(fromKey : K, toKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'subMap'
+	 */
+	public subMap(__param0 : K, __param1 : K | boolean, __param2? : K, __param3? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
+			let fromKey : K = __param0 as unknown as K;
+			let fromInclusive : boolean = __param1 as boolean;
+			let toKey : K = __param2 as unknown as K;
+			let toInclusive : boolean = __param3 as boolean;
+			return this._sub.subMap(fromKey, fromInclusive, toKey, toInclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
+			let fromKey : K = __param0 as unknown as K;
+			let toKey : K = __param1 as unknown as K;
+			return this._sub.subMap(fromKey, toKey);
+		} else throw new Error('invalid method overload');
+	}
+
+	public headMap(toKey : K, inclusive : boolean) : NavigableMap<K, V>;
+
+	public headMap(toKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'headMap'
+	 */
+	public headMap(__param0 : K, __param1? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let toKey : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._sub.headMap(toKey, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let toKey : K = __param0 as unknown as K;
+			return this._sub.headMap(toKey);
+		} else throw new Error('invalid method overload');
+	}
+
+	public tailMap(fromKey : K, inclusive : boolean) : NavigableMap<K, V>;
+
+	public tailMap(fromKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'tailMap'
+	 */
+	public tailMap(__param0 : K, __param1? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let fromKey : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._sub.tailMap(fromKey, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let fromKey : K = __param0 as unknown as K;
+			return this._sub.tailMap(fromKey);
+		} else throw new Error('invalid method overload');
+	}
+
+	bcAddEntryReturnBool(e : JavaMapEntry<K, V>, iv : AVLMapIntervall<K>) : boolean {
+		let old : V | null = this.bcAddEntryReturnOldValueOrNull(e.getKey(), e.getValue(), iv);
+		return !this._valEquals(old, e.getValue());
+	}
+
+	bcAddAllEntries(c : Collection<JavaMapEntry<K, V>>, iv : AVLMapIntervall<K>) : boolean {
+		let changed : boolean = false;
+		for (let entry of c) 
+			changed = changed || this.bcAddEntryReturnBool(entry, iv);
+		return changed;
+	}
+
+	bcAddEntryReturnOldValueOrNull(key : K, value : V, iv : AVLMapIntervall<K>) : V | null {
+		if (key === null) 
+			throw new NullPointerException("TreeMap erlaubt keine NULL keys.")
+		if (this._isOutOfRange(key, iv)) 
+			throw new IllegalArgumentException("Der Schlüsselwert liegt nicht im gültigen Bereich.")
+		if (this._root === null) {
+			this._root = new AVLMapNode(key, value);
+			return null;
+		}
+		let node : AVLMapNode<K, V> | null = this._nodeGetOrNull(key, iv);
+		let old : V | null = (node === null) ? null : node._val;
+		this._root = this._nodePutRecursive(this._root, key, value);
+		return old;
+	}
+
+	bcAddValue(e : V, iv : AVLMapIntervall<K>) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	bcAddKey(e : K, iv : AVLMapIntervall<K>) : boolean {
+		if (this._allowKeyAlone === false) 
+			throw new UnsupportedOperationException()
+		if (this.bcContainsKey(e, iv)) 
+			return false;
+		this.bcAddEntryReturnOldValueOrNull(e, this._dummyValue, iv);
+		return true;
+	}
+
+	bcAddAllKeys(c : Collection<K>, iv : AVLMapIntervall<K>) : boolean {
+		let changed : boolean = false;
+		for (let key of c) 
+			changed = changed || this.bcAddKey(key, iv);
+		return changed;
+	}
+
+	bcAddAllEntriesOfMap(map : JavaMap<K, V>, iv : AVLMapIntervall<K>) : void {
+		for (let entry of map.entrySet()) 
+			this.bcAddEntryReturnOldValueOrNull(entry.getKey(), entry.getValue(), iv);
+	}
+
+	bcContainsKey(objKey : unknown, iv : AVLMapIntervall<K>) : boolean {
+		return this._nodeGetOrNull(objKey as unknown as K, iv) !== null;
+	}
+
+	bcContainsAllKeys(c : Collection<unknown>, iv : AVLMapIntervall<K>) : boolean {
+		for (let key of c) 
+			if (!this.bcContainsKey(key, iv)) 
+				return false;
+		return true;
+	}
+
+	bcContainsValue(objValue : unknown, iv : AVLMapIntervall<K>) : boolean {
+		let value : V = objValue as unknown as V;
+		let n1 : AVLMapNode<K, V> | null = this._nodeFirstOrNull(iv);
+		if (n1 === null) 
+			return false;
+		let n2 : AVLMapNode<K, V> | null = this._nodeLastOrNull(iv);
+		if (n2 === null) 
+			return false;
+		while (n1 as unknown !== n2 as unknown) {
+			if (n1 === null) 
+				throw new NullPointerException()
+			if (this._valEquals(n1._val, value)) 
+				return true;
+			n1 = n1._next;
+		}
+		return this._valEquals(n2._val, value);
+	}
+
+	bcContainsAllValues(col : Collection<unknown>, iv : AVLMapIntervall<K>) : boolean {
+		for (let val of col) 
+			if (!this.bcContainsValue(val, iv)) 
+				return false;
+		return true;
+	}
+
+	bcContainsEntry(o : unknown, iv : AVLMapIntervall<K>) : boolean {
+		if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false) 
+			return false;
+		let e : JavaMapEntry<K, V> = cast_java_util_Map_Entry(o);
+		let node : AVLMapNode<K, V> | null = this._nodeGetOrNull(e.getKey(), iv);
+		return (node === null) ? false : this._valEquals(node._val, e.getValue());
+	}
+
+	bcContainsAllEntries(c : Collection<unknown>, iv : AVLMapIntervall<K>) : boolean {
+		for (let entry of c) 
+			if (!this.bcContainsEntry(entry, iv)) 
+				return false;
+		return true;
+	}
+
+	bcRemoveKeyReturnBool(o : unknown, iv : AVLMapIntervall<K>) : boolean {
+		if (!this.bcContainsKey(o, iv)) 
+			return false;
+		this.bcRemoveKeyReturnOldValueOrNull(o, iv);
+		return true;
+	}
+
+	bcRemoveAllKeys(c : Collection<unknown>, iv : AVLMapIntervall<K>) : boolean {
+		let changed : boolean = false;
+		for (let obj of c) 
+			changed = changed || this.bcRemoveKeyReturnBool(obj, iv);
+		return changed;
+	}
+
+	bcRemoveEntry(o : unknown, iv : AVLMapIntervall<K>) : boolean {
+		if (!this.bcContainsEntry(o, iv)) 
+			return false;
+		if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false) 
+			return false;
+		if (this._root === null) 
+			throw new NullPointerException()
+		let e : JavaMapEntry<K, V> = cast_java_util_Map_Entry(o);
+		this._root = this._nodeRemoveKeyRecursive(this._root, e.getKey());
+		return true;
+	}
+
+	bcRemoveAllEntries(c : Collection<unknown>, iv : AVLMapIntervall<K>) : boolean {
+		let removedAny : boolean = false;
+		for (let entry of c) 
+			removedAny = removedAny || this.bcRemoveEntry(entry, iv);
+		return removedAny;
+	}
+
+	bcRemoveKeyReturnOldValueOrNull(obj : unknown, iv : AVLMapIntervall<K>) : V | null {
+		if (obj === null) 
+			throw new NullPointerException("TreeMap unterstützt keine NULL-Schlüssel.")
+		let key : K = obj as unknown as K;
+		let old : AVLMapNode<K, V> | null = this._nodeGetOrNull(key, iv);
+		if (old === null) 
+			return null;
+		if (this._root === null) 
+			throw new NullPointerException()
+		this._root = this._nodeRemoveKeyRecursive(this._root, key);
+		return old._val;
+	}
+
+	bcPollFirstEntryOrNull(iv : AVLMapIntervall<K>) : JavaMapEntry<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeFirstOrNull(iv);
+		if (node === null) 
+			return node;
+		if (this._root === null) 
+			throw new NullPointerException()
+		this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
+		return node;
+	}
+
+	bcPollFirstKeyOrNull(iv : AVLMapIntervall<K>) : K | null {
+		let node : AVLMapNode<K, V> | null = this._nodeFirstOrNull(iv);
+		if (node === null) 
+			return null;
+		if (this._root === null) 
+			throw new NullPointerException()
+		this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
+		return node._key;
+	}
+
+	bcPollLastEntryOrNull(iv : AVLMapIntervall<K>) : JavaMapEntry<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeLastOrNull(iv);
+		if (node === null) 
+			return null;
+		if (this._root === null) 
+			throw new NullPointerException()
+		this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
+		return node;
+	}
+
+	bcPollLastKeyOrNull(iv : AVLMapIntervall<K>) : K | null {
+		let node : AVLMapNode<K, V> | null = this._nodeLastOrNull(iv);
+		if (node === null) 
+			return null;
+		if (this._root === null) 
+			throw new NullPointerException()
+		this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
+		return node._key;
+	}
+
+	bcIsEmpty(iv : AVLMapIntervall<K>) : boolean {
+		return this._nodeFirstOrNull(iv) === null;
+	}
+
+	bcGetComparator(iv : AVLMapIntervall<K>) : Comparator<K> {
+		return this._comparator;
+	}
+
+	bcGetFirstKeyOrException(iv : AVLMapIntervall<K>) : K {
+		return this._keyOrExeption(this._nodeFirstOrNull(iv));
+	}
+
+	bcGetFirstEntryOrNull(iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeFirstOrNull(iv);
+	}
+
+	bcGetLastKeyOrException(iv : AVLMapIntervall<K>) : K {
+		return this._keyOrExeption(this._nodeLastOrNull(iv));
+	}
+
+	bcGetLastEntryOrNull(iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeLastOrNull(iv);
+	}
+
+	bcGetNextEntryOrNull(current : AVLMapNode<K, V>, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeNextOrNull(current, iv);
+	}
+
+	bcGetPrevEntryOrNull(current : AVLMapNode<K, V>, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodePrevOrNull(current, iv);
+	}
+
+	bcGetSize(iv : AVLMapIntervall<K>) : number {
+		let n1 : AVLMapNode<K, V> | null = this._nodeFirstOrNull(iv);
+		if (n1 === null) 
+			return 0;
+		let n2 : AVLMapNode<K, V> | null = this._nodeLastOrNull(iv);
+		if (n2 === null) 
+			return 0;
+		return this._nodeIndexOf(n2._key) - this._nodeIndexOf(n1._key) + 1;
+	}
+
+	bcGetValueOfKeyOrNull(objKey : unknown, iv : AVLMapIntervall<K>) : V | null {
+		let key : K = objKey as unknown as K;
+		let node : AVLMapNode<K, V> | null = this._nodeGetOrNull(key, iv);
+		return (node === null) ? null : node._val;
+	}
+
+	bcGetLowerEntryOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeLowerOrNull(key, iv);
+	}
+
+	bcGetLowerKeyOrNull(key : K, iv : AVLMapIntervall<K>) : K | null {
+		return this._keyOrNull(this._nodeLowerOrNull(key, iv));
+	}
+
+	bcGetFloorEntryOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeFloorOrNull(key, iv);
+	}
+
+	bcGetFloorKeyOrNull(key : K, iv : AVLMapIntervall<K>) : K | null {
+		return this._keyOrNull(this._nodeFloorOrNull(key, iv));
+	}
+
+	bcGetCeilingEntryOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeCeilingOrNull(key, iv);
+	}
+
+	bcGetCeilingKeyOrNull(key : K, iv : AVLMapIntervall<K>) : K | null {
+		return this._keyOrNull(this._nodeCeilingOrNull(key, iv));
+	}
+
+	bcGetHigherEntryOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return this._nodeHigherOrNull(key, iv);
+	}
+
+	bcGetHigherKeyOrNull(key : K, iv : AVLMapIntervall<K>) : K | null {
+		return this._keyOrNull(this._nodeHigherOrNull(key, iv));
+	}
+
+	bcCheckOutOfIntervall(key : K, inc : boolean, iv : AVLMapIntervall<K>) : boolean {
+		if ((key === this._infinityMinus) || (key === this._infinityPlus)) 
+			return false;
+		let cmpF : number = this._compare(key, iv.from);
+		if (cmpF < 0) 
+			return true;
+		if ((cmpF === 0) && (!iv.fromInc) && (inc)) 
+			return true;
+		let cmpT : number = this._compare(key, iv.to);
+		if (cmpT > 0) 
+			return true;
+		if ((cmpT === 0) && (!iv.toInc) && (inc)) 
+			return true;
+		return false;
+	}
+
+	private _keyOrNull(node : AVLMapNode<K, V> | null) : K | null {
+		return (node === null) ? null : node._key;
+	}
+
+	private _valEquals(v1 : V | null, v2 : V | null) : boolean {
+		return (v1 === null) ? v2 === null : JavaObject.equalsTranspiler(v1, (v2));
+	}
+
+	private _keyOrExeption(node : AVLMapNode<K, V> | null) : K {
+		if (node === null) 
+			throw new NoSuchElementException()
+		return node._key;
+	}
+
+	private _compare(key1 : K, key2 : K) : number {
+		if ((key1 === this._infinityMinus) || (key2 === this._infinityPlus)) 
+			return -1;
+		if ((key1 === this._infinityPlus) || (key2 === this._infinityMinus)) 
+			return +1;
+		return this._comparator.compare(key1, key2);
+	}
+
+	private _isOutOfRange(key : K, iv : AVLMapIntervall<K>) : boolean {
+		let cmpKeyFrom : number = this._compare(key, iv.from);
+		if ((cmpKeyFrom < 0) || (cmpKeyFrom === 0) && (!iv.fromInc)) 
+			return true;
+		let cmpKeyTo : number = this._compare(key, iv.to);
+		if ((cmpKeyTo > 0) || (cmpKeyTo === 0) && (!iv.toInc)) 
+			return true;
+		return false;
+	}
+
+	private _nodeFirstOrNull(iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return iv.fromInc ? this._nodeCeilingOrNull(iv.from, iv) : this._nodeHigherOrNull(iv.from, iv);
+	}
+
+	private _nodeLastOrNull(iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		return iv.toInc ? this._nodeFloorOrNull(iv.to, iv) : this._nodeLowerOrNull(iv.to, iv);
+	}
+
+	private _nodeCeilingOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeDeepestOrNull(key, iv);
+		if (node === null) 
+			return null;
+		let cmpNodeKey : number = this._compare(node._key, key);
+		return cmpNodeKey >= 0 ? node : this._nodeNextOrNull(node, iv);
+	}
+
+	private _nodeHigherOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeDeepestOrNull(key, iv);
+		if (node === null) 
+			return null;
+		let cmpNodeKey : number = this._compare(node._key, key);
+		return cmpNodeKey > 0 ? node : this._nodeNextOrNull(node, iv);
+	}
+
+	private _nodeFloorOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeDeepestOrNull(key, iv);
+		if (node === null) 
+			return null;
+		let cmpNodeKey : number = this._compare(node._key, key);
+		return cmpNodeKey <= 0 ? node : this._nodePrevOrNull(node, iv);
+	}
+
+	private _nodeLowerOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeDeepestOrNull(key, iv);
+		if (node === null) 
+			return null;
+		let cmpNodeKey : number = this._compare(node._key, key);
+		return cmpNodeKey < 0 ? node : this._nodePrevOrNull(node, iv);
+	}
+
+	private _nodeNextOrNull(node : AVLMapNode<K, V>, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let next : AVLMapNode<K, V> | null = node._next;
+		return (next === null) ? null : this._isOutOfRange(next._key, iv) ? null : next;
+	}
+
+	private _nodePrevOrNull(node : AVLMapNode<K, V>, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let prev : AVLMapNode<K, V> | null = node._prev;
+		return (prev === null) ? null : this._isOutOfRange(prev._key, iv) ? null : prev;
+	}
+
+	private _nodeGetOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let node : AVLMapNode<K, V> | null = this._nodeDeepestOrNull(key, iv);
+		if (node === null) 
+			return null;
+		return this._compare(key, node._key) === 0 ? node : null;
+	}
+
+	private _nodeIndexOf(key : K) : number {
+		let current : AVLMapNode<K, V> | null = this._root;
+		let index : number = 0;
+		while (true) {
+			if (current === null) 
+				throw new NullPointerException()
+			let cmp : number = this._compare(key, current._key);
+			if (cmp < 0) {
+				current = current._childL;
+				continue;
+			}
+			let left : AVLMapNode<K, V> | null = current._childL;
+			let sizeL : number = (left === null) ? 0 : left._size;
+			if (cmp > 0) {
+				index += sizeL + 1;
+				current = current._childR;
+				continue;
+			}
+			return index + sizeL;
+		}
+	}
+
+	private _nodeDeepestOrNull(key : K, iv : AVLMapIntervall<K>) : AVLMapNode<K, V> | null {
+		let current : AVLMapNode<K, V> | null = this._root;
+		let last : AVLMapNode<K, V> | null = null;
+		while (current !== null) {
+			let cmpToKey : number = this._compare(iv.to, current._key);
+			if ((cmpToKey < 0) || (cmpToKey === 0) && (!iv.toInc)) {
+				current = current._childL;
+				continue;
+			}
+			let cmpFromKey : number = this._compare(iv.from, current._key);
+			if ((cmpFromKey > 0) || (cmpFromKey === 0) && (!iv.fromInc)) {
+				current = current._childR;
+				continue;
+			}
+			last = current;
+			let cmp : number = this._compare(key, current._key);
+			if (cmp < 0) {
+				current = current._childL;
+				continue;
+			}
+			if (cmp > 0) {
+				current = current._childR;
+				continue;
+			}
+			return current;
+		}
+		return last;
+	}
+
+	private _nodePutRecursive(current : AVLMapNode<K, V>, key : K, value : V) : AVLMapNode<K, V> {
+		let cmp : number = this._compare(key, current._key);
+		if (cmp === 0) {
+			current._val = value;
+			return current;
+		}
+		if (cmp < 0) 
+			current._childL = (current._childL === null) ? this._nodeCreateLeaf(current._prev, current, key, value) : this._nodePutRecursive(current._childL, key, value); else 
+			current._childR = (current._childR === null) ? this._nodeCreateLeaf(current, current._next, key, value) : this._nodePutRecursive(current._childR, key, value);
+		return this._nodeRevalidate(current);
+	}
+
+	private _nodeCreateLeaf(prev : AVLMapNode<K, V> | null, next : AVLMapNode<K, V> | null, key : K, value : V) : AVLMapNode<K, V> {
+		let child : AVLMapNode<K, V> | null = new AVLMapNode(key, value);
+		if (prev !== null) {
+			prev._next = child;
+			child._prev = prev;
+		}
+		if (next !== null) {
+			next._prev = child;
+			child._next = next;
+		}
+		return child;
+	}
+
+	private _nodeRemoveKeyRecursive(current : AVLMapNode<K, V>, key : K) : AVLMapNode<K, V> | null {
+		let cmp : number = this._compare(key, current._key);
+		if (cmp < 0) {
+			if (current._childL === null) 
+				throw new NullPointerException()
+			current._childL = this._nodeRemoveKeyRecursive(current._childL, key);
+			return this._nodeRevalidate(current);
+		}
+		if (cmp > 0) {
+			if (current._childR === null) 
+				throw new NullPointerException()
+			current._childR = this._nodeRemoveKeyRecursive(current._childR, key);
+			return this._nodeRevalidate(current);
+		}
+		if (current._childL === null) {
+			this._nodeRemovePrevNext(current);
+			return current._childR;
+		}
+		if (current._childR === null) {
+			this._nodeRemovePrevNext(current);
+			return current._childL;
+		}
+		let next : AVLMapNode<K, V> | null = current._next;
+		if (next === null) 
+			throw new NullPointerException()
+		current._childR = this._nodeRemoveKeyRecursive(current._childR, next._key);
+		return this._nodeRevalidate(this._nodeReplaceReferencesFromAwithB(next, current));
+	}
+
+	private _nodeReplaceReferencesFromAwithB(a : AVLMapNode<K, V>, b : AVLMapNode<K, V>) : AVLMapNode<K, V> {
+		a._childL = b._childL;
+		a._childR = b._childR;
+		let p : AVLMapNode<K, V> | null = b._prev;
+		let n : AVLMapNode<K, V> | null = b._next;
+		a._prev = p;
+		a._next = n;
+		if (p !== null) 
+			p._next = a;
+		if (n !== null) 
+			n._prev = a;
+		return a;
+	}
+
+	private _nodeRemovePrevNext(current : AVLMapNode<K, V>) : void {
+		let nodeP : AVLMapNode<K, V> | null = current._prev;
+		let nodeN : AVLMapNode<K, V> | null = current._next;
+		if (nodeP !== null) 
+			nodeP._next = nodeN;
+		if (nodeN !== null) 
+			nodeN._prev = nodeP;
+	}
+
+	/**
+	 * Aktualisiert {@code node} und liefert, wenn es zur Rotation kommt, eine neue Sub-Wurzel.
+	 * 
+	 * @param node Der Knoten, der revalidiert werden soll.
+	 * 
+	 * @return node, oder die neue Sub-Wurzel, wenn es zur Rotation kam.
+	 */
+	private _nodeRevalidate(node : AVLMapNode<K, V>) : AVLMapNode<K, V> {
+		let heightBalance : number = this._nodeGetHeightBalance(node);
+		if (heightBalance > +1) {
+			if (node._childR === null) 
+				throw new NullPointerException()
+			if (this._nodeGetHeightBalance(node._childR) < 0) 
+				node._childR = this._nodeRotateRight(node._childR);
+			return this._nodeRotateLeft(node);
+		}
+		if (heightBalance < -1) {
+			if (node._childL === null) 
+				throw new NullPointerException()
+			if (this._nodeGetHeightBalance(node._childL) > 0) 
+				node._childL = this._nodeRotateLeft(node._childL);
+			return this._nodeRotateRight(node);
+		}
+		this._nodeRevalidateHeightAndSize(node);
+		return node;
+	}
+
+	private _nodeRotateLeft(nodeM : AVLMapNode<K, V>) : AVLMapNode<K, V> {
+		if (nodeM._childR === null) 
+			throw new NullPointerException()
+		let nodeR : AVLMapNode<K, V> = nodeM._childR;
+		nodeM._childR = nodeR._childL;
+		nodeR._childL = nodeM;
+		this._nodeRevalidateHeightAndSize(nodeM);
+		this._nodeRevalidateHeightAndSize(nodeR);
+		return nodeR;
+	}
+
+	private _nodeRotateRight(nodeM : AVLMapNode<K, V>) : AVLMapNode<K, V> {
+		if (nodeM._childL === null) 
+			throw new NullPointerException()
+		let nodeL : AVLMapNode<K, V> = nodeM._childL;
+		nodeM._childL = nodeL._childR;
+		nodeL._childR = nodeM;
+		this._nodeRevalidateHeightAndSize(nodeM);
+		this._nodeRevalidateHeightAndSize(nodeL);
+		return nodeL;
+	}
+
+	private _nodeRevalidateHeightAndSize(node : AVLMapNode<K, V>) : void {
+		let sizeL : number = (node._childL === null) ? 0 : node._childL._size;
+		let sizeR : number = (node._childR === null) ? 0 : node._childR._size;
+		node._size = sizeL + sizeR + 1;
+		let heightL : number = (node._childL === null) ? 0 : node._childL._height;
+		let heightR : number = (node._childR === null) ? 0 : node._childR._height;
+		node._height = Math.max(heightL, heightR) + 1;
+	}
+
+	private _nodeGetHeightBalance(node : AVLMapNode<K, V>) : number {
+		let heightL : number = (node._childL === null) ? 0 : node._childL._height;
+		let heightR : number = (node._childR === null) ? 0 : node._childR._height;
+		return heightR - heightL;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Map', 'de.nrw.schule.svws.core.adt.map.AVLMap', 'java.util.NavigableMap', 'java.util.SortedMap'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMap<K, V>(obj : unknown) : AVLMap<K, V> {
+	return obj as AVLMap<K, V>;
+}

+ 47 - 0
core/adt/map/AVLMapIntervall.ts

@@ -0,0 +1,47 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class AVLMapIntervall<K> extends JavaObject {
+
+	static readonly _INFINITY_MINUS : unknown | null = new Object();
+
+	static readonly _INFINITY_PLUS : unknown | null = new Object();
+
+	readonly from : K;
+
+	readonly fromInc : boolean;
+
+	readonly to : K;
+
+	readonly toInc : boolean;
+
+
+	/**
+	 * @param pFrom    Der Anfang des Intervalls.
+	 * @param pFromInc Gibt an, ob der Intervall-Anfang inklusive ist.
+	 * @param pTo      Das Ende des Intervalls.
+	 * @param pToInc   Gibt an, ob das Intervall-Ende inklusive ist.
+	 */
+	constructor(pFrom : K, pFromInc : boolean, pTo : K, pToInc : boolean) {
+		super();
+		this.from = pFrom;
+		this.fromInc = pFromInc;
+		this.to = pTo;
+		this.toInc = pToInc;
+	}
+
+	public toString() : String {
+		let sFrom : String = (this.from === AVLMapIntervall._INFINITY_MINUS) ? "-INF" : "" + this.from;
+		let sTo : String = (this.to === AVLMapIntervall._INFINITY_PLUS) ? "+INF" : "" + this.to;
+		return "[" + sFrom.valueOf() + ", " + this.fromInc + ", " + sTo.valueOf() + ", " + this.toInc + "]";
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.adt.map.AVLMapIntervall'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapIntervall<K>(obj : unknown) : AVLMapIntervall<K> {
+	return obj as AVLMapIntervall<K>;
+}

+ 69 - 0
core/adt/map/AVLMapNode.ts

@@ -0,0 +1,69 @@
+import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class AVLMapNode<K, V> extends JavaObject implements JavaMapEntry<K, V> {
+
+	readonly _key : K;
+
+	_val : V;
+
+	_prev : AVLMapNode<K, V> | null = null;
+
+	_next : AVLMapNode<K, V> | null = null;
+
+	_childL : AVLMapNode<K, V> | null = null;
+
+	_childR : AVLMapNode<K, V> | null = null;
+
+	_height : number = 1;
+
+	_size : number = 1;
+
+
+	/**
+	 * Erstellt ein neues Blatt des Baumes.
+	 */
+	constructor(key : K, val : V) {
+		super();
+		this._key = key;
+		this._val = val;
+	}
+
+	public toString() : String {
+		return "[" + this._key + ", " + this._val + "]";
+	}
+
+	public equals(o : unknown) : boolean {
+		if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false) 
+			return false;
+		let e : JavaMapEntry<unknown, unknown> | null = cast_java_util_Map_Entry(o);
+		return JavaObject.equalsTranspiler(this._key, (e.getKey())) && (JavaObject.equalsTranspiler(this._val, (e.getValue())));
+	}
+
+	public hashCode() : number {
+		return JavaObject.getTranspilerHashCode(this._key) ^ JavaObject.getTranspilerHashCode(this._val);
+	}
+
+	public getKey() : K {
+		return this._key;
+	}
+
+	public getValue() : V {
+		return this._val;
+	}
+
+	public setValue(value : V) : V {
+		throw new UnsupportedOperationException()
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.adt.map.AVLMapNode', 'java.util.Map.Entry'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapNode<K, V>(obj : unknown) : AVLMapNode<K, V> {
+	return obj as AVLMapNode<K, V>;
+}

+ 110 - 0
core/adt/map/AVLMapSubCollection.ts

@@ -0,0 +1,110 @@
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class AVLMapSubCollection<K, V> extends JavaObject implements Collection<V> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+
+	/**
+	 * Erstellt eine neue Sub-Collection zur übergebenen {@link AVLMapSubMap}.
+	 * 
+	 * @param sub Die {@link AVLMapSubMap} auf der diese Sub-Collection operiert.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+	}
+
+	public toString() : String {
+		let s : String | null = "";
+		for (let value of this) 
+			s += (s.length === 0 ? "" : ", ") + value;
+		return "values = [" + s.valueOf() + "], size = " + this.size() + " --> " + this._sub.toString().valueOf();
+	}
+
+	public size() : number {
+		return this._sub.size();
+	}
+
+	public isEmpty() : boolean {
+		return this._sub.isEmpty();
+	}
+
+	public contains(o : unknown) : boolean {
+		return this._sub.containsValue(o);
+	}
+
+	public iterator() : JavaIterator<V> {
+		return this._sub.bcGetSubCollectionIterator();
+	}
+
+	public toArray() : Array<unknown | null>;
+
+	public toArray<T>(a : Array<T | null>) : Array<T | null>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<T>(__param0? : Array<T | null>) : Array<T | null> | Array<unknown | null> {
+		if ((typeof __param0 === "undefined")) {
+			return this._sub.bcGetArrayListOfValues().toArray();
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<T | null> = __param0;
+			return this._sub.bcGetArrayListOfValues().toArray(a);
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : V) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	public remove(o : unknown) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	public containsAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcContainsAllValues(c);
+	}
+
+	public addAll(c : Collection<V>) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	public removeAll(c : Collection<unknown>) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	public retainAll(c : Collection<unknown>) : boolean {
+		throw new UnsupportedOperationException()
+	}
+
+	public clear() : void {
+		this._sub.clear();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.adt.map.AVLMapSubCollection', 'java.util.Collection', 'java.lang.Iterable'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<V> {
+		let iter : JavaIterator<V> = this.iterator();
+		const result : Iterator<V> = {
+			next() : IteratorResult<V> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubCollection<K, V>(obj : unknown) : AVLMapSubCollection<K, V> {
+	return obj as AVLMapSubCollection<K, V>;
+}

+ 56 - 0
core/adt/map/AVLMapSubCollectionIterator.ts

@@ -0,0 +1,56 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { IllegalStateException, cast_java_lang_IllegalStateException } from '../../../java/lang/IllegalStateException';
+import { AVLMapNode, cast_de_nrw_schule_svws_core_adt_map_AVLMapNode } from '../../../core/adt/map/AVLMapNode';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+
+export class AVLMapSubCollectionIterator<K, V> extends JavaObject implements JavaIterator<V> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+	private _current : AVLMapNode<K, V> | null = null;
+
+	private _next : AVLMapNode<K, V> | null = null;
+
+
+	/**
+	 * Erstellt einen neuen VALUES-Iterator, welcher auf der {@link AVLMapSubMap} operiert.
+	 * 
+	 * @param sub Die {@link AVLMapSubMap} auf der dieser Iterator operiert.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+		this._current = null;
+		this._next = this._sub.firstEntryAsNode();
+	}
+
+	public next() : V {
+		if (this._next === null) 
+			throw new NoSuchElementException()
+		this._current = this._next;
+		this._next = this._sub.nextEntryOrNull(this._current);
+		return this._current._val;
+	}
+
+	public hasNext() : boolean {
+		return this._next !== null;
+	}
+
+	public remove() : void {
+		if (this._current === null) 
+			throw new IllegalStateException()
+		this._sub.remove(this._current.getKey());
+		this._current = null;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Iterator', 'de.nrw.schule.svws.core.adt.map.AVLMapSubCollectionIterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubCollectionIterator<K, V>(obj : unknown) : AVLMapSubCollectionIterator<K, V> {
+	return obj as AVLMapSubCollectionIterator<K, V>;
+}

+ 109 - 0
core/adt/map/AVLMapSubEntrySet.ts

@@ -0,0 +1,109 @@
+import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry';
+import { JavaSet, cast_java_util_Set } from '../../../java/util/JavaSet';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaMap, cast_java_util_Map } from '../../../java/util/JavaMap';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+
+export class AVLMapSubEntrySet<K, V> extends JavaObject implements JavaSet<JavaMapEntry<K, V>> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+
+	/**
+	 * Erstellt ein neues SubEntrySet auf die übergebene {@link AVLMap}.
+	 * 
+	 * @param sub Die {@link AVLMapSubMap} auf der operiert wird.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+	}
+
+	public toString() : String {
+		return this._sub.toString();
+	}
+
+	public size() : number {
+		return this._sub.size();
+	}
+
+	public isEmpty() : boolean {
+		return this._sub.isEmpty();
+	}
+
+	public contains(o : unknown) : boolean {
+		return this._sub.bcContainsEntry(o);
+	}
+
+	public iterator() : JavaIterator<JavaMapEntry<K, V>> {
+		return this._sub.bcGetSubEntrySetIterator();
+	}
+
+	public toArray() : Array<unknown | null>;
+
+	public toArray<T>(a : Array<T | null>) : Array<T | null>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<T>(__param0? : Array<T | null>) : Array<T | null> | Array<unknown | null> {
+		if ((typeof __param0 === "undefined")) {
+			return this._sub.bcGetArrayListOfEntries().toArray();
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<T | null> = __param0;
+			return this._sub.bcGetArrayListOfEntries().toArray(a);
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : JavaMapEntry<K, V>) : boolean {
+		return this._sub.bcAddEntryReturnBool(e);
+	}
+
+	public remove(o : unknown) : boolean {
+		return this._sub.bcRemoveEntry(o);
+	}
+
+	public containsAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcContainsAllEntries(c);
+	}
+
+	public addAll(c : Collection<JavaMapEntry<K, V>>) : boolean {
+		return this._sub.bcAddAllEntries(c);
+	}
+
+	public retainAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcRetainAllEntries(c);
+	}
+
+	public removeAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcRemoveAllEntries(c);
+	}
+
+	public clear() : void {
+		this._sub.clear();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Collection', 'java.util.Set', 'java.lang.Iterable', 'de.nrw.schule.svws.core.adt.map.AVLMapSubEntrySet'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<JavaMapEntry<any, any>> {
+		let iter : JavaIterator<JavaMapEntry<any, any>> = this.iterator();
+		const result : Iterator<JavaMapEntry<any, any>> = {
+			next() : IteratorResult<JavaMapEntry<any, any>> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubEntrySet<K, V>(obj : unknown) : AVLMapSubEntrySet<K, V> {
+	return obj as AVLMapSubEntrySet<K, V>;
+}

+ 57 - 0
core/adt/map/AVLMapSubEntrySetIterator.ts

@@ -0,0 +1,57 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { IllegalStateException, cast_java_lang_IllegalStateException } from '../../../java/lang/IllegalStateException';
+import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+
+export class AVLMapSubEntrySetIterator<K, V> extends JavaObject implements JavaIterator<JavaMapEntry<K, V>> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+	private _current : JavaMapEntry<K, V> | null = null;
+
+	private _next : JavaMapEntry<K, V> | null = null;
+
+
+	/**
+	 * Erstellt einen neuen ENTRY-Iterator für die angegebene {@link AVLMapSubMap} im gültigen
+	 * {@link AVLMapIntervall}.
+	 * 
+	 * @param sub Die {@link AVLMapSubMap} auf der operiert wird.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+		this._current = null;
+		this._next = this._sub.firstEntry();
+	}
+
+	public next() : JavaMapEntry<K, V> {
+		if (this._next === null) 
+			throw new NoSuchElementException()
+		this._current = this._next;
+		this._next = this._sub.higherEntry(this._next.getKey());
+		return this._current;
+	}
+
+	public hasNext() : boolean {
+		return this._next !== null;
+	}
+
+	public remove() : void {
+		if (this._current === null) 
+			throw new IllegalStateException()
+		this._sub.remove(this._current.getKey());
+		this._current = null;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Iterator', 'de.nrw.schule.svws.core.adt.map.AVLMapSubEntrySetIterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubEntrySetIterator<K, V>(obj : unknown) : AVLMapSubEntrySetIterator<K, V> {
+	return obj as AVLMapSubEntrySetIterator<K, V>;
+}

+ 210 - 0
core/adt/map/AVLMapSubKeySet.ts

@@ -0,0 +1,210 @@
+import { NavigableSet, cast_java_util_NavigableSet } from '../../../java/util/NavigableSet';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { SortedSet, cast_java_util_SortedSet } from '../../../java/util/SortedSet';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+
+export class AVLMapSubKeySet<K, V> extends JavaObject implements NavigableSet<K> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+
+	/**
+	 * Erstellt eine neues Sub-Set auf die übergebene {@link AVLMap}.
+	 * 
+	 * @param sub Die {@link AVLMap} auf der operiert wird.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+	}
+
+	public toString() : String {
+		return this._sub.toString();
+	}
+
+	public comparator() : Comparator<Partial<K>> {
+		return this._sub.comparator();
+	}
+
+	public first() : K {
+		return this._sub.firstKey();
+	}
+
+	public last() : K {
+		return this._sub.lastKey();
+	}
+
+	public size() : number {
+		return this._sub.size();
+	}
+
+	public isEmpty() : boolean {
+		return this._sub.isEmpty();
+	}
+
+	public contains(o : unknown) : boolean {
+		return this._sub.containsKey(o);
+	}
+
+	public toArray() : Array<unknown>;
+
+	public toArray<T>(a : Array<T>) : Array<T>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<T>(__param0? : Array<T>) : Array<T> | Array<unknown> {
+		if ((typeof __param0 === "undefined")) {
+			return this._sub.bcGetArrayListOfKeys().toArray();
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<T> = __param0;
+			return this._sub.bcGetArrayListOfKeys().toArray(a);
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : K) : boolean {
+		return this._sub.bcAddKey(e);
+	}
+
+	public remove(o : unknown) : boolean {
+		return this._sub.bcRemoveKeyReturnBool(o);
+	}
+
+	public containsAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcContainsAllKeys(c);
+	}
+
+	public addAll(c : Collection<K>) : boolean {
+		return this._sub.bcAddAllKeys(c);
+	}
+
+	public retainAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcRetainAllKeys(c);
+	}
+
+	public removeAll(c : Collection<unknown>) : boolean {
+		return this._sub.bcRemoveAllKeys(c);
+	}
+
+	public clear() : void {
+		this._sub.clear();
+	}
+
+	public lower(e : K) : K | null {
+		return this._sub.bcGetLowerKeyOrNull(e);
+	}
+
+	public floor(e : K) : K | null {
+		return this._sub.bcGetFloorKeyOrNull(e);
+	}
+
+	public ceiling(e : K) : K | null {
+		return this._sub.bcGetCeilingKeyOrNull(e);
+	}
+
+	public higher(e : K) : K | null {
+		return this._sub.bcGetHigherKeyOrNull(e);
+	}
+
+	public pollFirst() : K | null {
+		return this._sub.bcPollFirstKeyOrNull();
+	}
+
+	public pollLast() : K | null {
+		return this._sub.bcPollLastKeyOrNull();
+	}
+
+	public iterator() : JavaIterator<K> {
+		return this._sub.bcGetSubKeySetIterator();
+	}
+
+	public descendingSet() : NavigableSet<K> {
+		return this._sub.bcGetSubKeySetDescending();
+	}
+
+	public descendingIterator() : JavaIterator<K> {
+		return this._sub.bcGetSubKeySetDescendingIterator();
+	}
+
+	public subSet(fromElement : K, fromInclusive : boolean, toElement : K, toInclusive : boolean) : NavigableSet<K>;
+
+	public subSet(fromElement : K, toElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'subSet'
+	 */
+	public subSet(__param0 : K, __param1 : K | boolean, __param2? : K, __param3? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
+			let fromElement : K = __param0 as unknown as K;
+			let fromInclusive : boolean = __param1 as boolean;
+			let toElement : K = __param2 as unknown as K;
+			let toInclusive : boolean = __param3 as boolean;
+			return this._sub.bcGetSubKeySet(fromElement, fromInclusive, toElement, toInclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
+			let fromElement : K = __param0 as unknown as K;
+			let toElement : K = __param1 as unknown as K;
+			return this._sub.bcGetSubKeySet(fromElement, toElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	public headSet(toElement : K, inclusive : boolean) : NavigableSet<K>;
+
+	public headSet(toElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'headSet'
+	 */
+	public headSet(__param0 : K, __param1? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let toElement : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._sub.bcGetSubKeyHeadSet(toElement, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let toElement : K = __param0 as unknown as K;
+			return this._sub.bcGetSubKeyHeadSet(toElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	public tailSet(fromElement : K, inclusive : boolean) : NavigableSet<K>;
+
+	public tailSet(fromElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'tailSet'
+	 */
+	public tailSet(__param0 : K, __param1? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let fromElement : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._sub.bcGetSubKeyTailSet(fromElement, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let fromElement : K = __param0 as unknown as K;
+			return this._sub.bcGetSubKeyTailSet(fromElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.SortedSet', 'java.util.Collection', 'de.nrw.schule.svws.core.adt.map.AVLMapSubKeySet', 'java.util.Set', 'java.util.NavigableSet', 'java.lang.Iterable'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<K> {
+		let iter : JavaIterator<K> = this.iterator();
+		const result : Iterator<K> = {
+			next() : IteratorResult<K> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubKeySet<K, V>(obj : unknown) : AVLMapSubKeySet<K, V> {
+	return obj as AVLMapSubKeySet<K, V>;
+}

+ 57 - 0
core/adt/map/AVLMapSubKeySetIterator.ts

@@ -0,0 +1,57 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { IllegalStateException, cast_java_lang_IllegalStateException } from '../../../java/lang/IllegalStateException';
+import { AVLMapNode, cast_de_nrw_schule_svws_core_adt_map_AVLMapNode } from '../../../core/adt/map/AVLMapNode';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap';
+
+export class AVLMapSubKeySetIterator<K, V> extends JavaObject implements JavaIterator<K> {
+
+	private readonly _sub : AVLMapSubMap<K, V>;
+
+	private _current : AVLMapNode<K, V> | null = null;
+
+	private _next : AVLMapNode<K, V> | null = null;
+
+
+	/**
+	 * Erstellt einen neuen KEY-Iterator für die angegebene {@link AVLMapSubMap} im gültigen Bereich
+	 * {@link AVLMapIntervall}.
+	 * 
+	 * @param sub Die {@link AVLMapSubMap} auf der operiert wird.
+	 */
+	constructor(sub : AVLMapSubMap<K, V>) {
+		super();
+		this._sub = sub;
+		this._current = null;
+		this._next = this._sub.firstEntryAsNode();
+	}
+
+	public next() : K {
+		if (this._next === null) 
+			throw new NoSuchElementException()
+		this._current = this._next;
+		this._next = this._sub.nextEntryOrNull(this._next);
+		return this._current._key;
+	}
+
+	public hasNext() : boolean {
+		return this._next !== null;
+	}
+
+	public remove() : void {
+		if (this._current === null) 
+			throw new IllegalStateException()
+		this._sub.remove(this._current._key);
+		this._current = null;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Iterator', 'de.nrw.schule.svws.core.adt.map.AVLMapSubKeySetIterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubKeySetIterator<K, V>(obj : unknown) : AVLMapSubKeySetIterator<K, V> {
+	return obj as AVLMapSubKeySetIterator<K, V>;
+}

+ 491 - 0
core/adt/map/AVLMapSubMap.ts

@@ -0,0 +1,491 @@
+import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry';
+import { NavigableSet, cast_java_util_NavigableSet } from '../../../java/util/NavigableSet';
+import { JavaSet, cast_java_util_Set } from '../../../java/util/JavaSet';
+import { NavigableMap, cast_java_util_NavigableMap } from '../../../java/util/NavigableMap';
+import { AVLMapSubCollection, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubCollection } from '../../../core/adt/map/AVLMapSubCollection';
+import { AVLMapIntervall, cast_de_nrw_schule_svws_core_adt_map_AVLMapIntervall } from '../../../core/adt/map/AVLMapIntervall';
+import { AVLMapSubEntrySetIterator, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubEntrySetIterator } from '../../../core/adt/map/AVLMapSubEntrySetIterator';
+import { AVLMapSubKeySet, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubKeySet } from '../../../core/adt/map/AVLMapSubKeySet';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { SortedSet, cast_java_util_SortedSet } from '../../../java/util/SortedSet';
+import { AVLMap, cast_de_nrw_schule_svws_core_adt_map_AVLMap } from '../../../core/adt/map/AVLMap';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+import { AVLMapNode, cast_de_nrw_schule_svws_core_adt_map_AVLMapNode } from '../../../core/adt/map/AVLMapNode';
+import { SortedMap, cast_java_util_SortedMap } from '../../../java/util/SortedMap';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { AVLMapSubKeySetIterator, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubKeySetIterator } from '../../../core/adt/map/AVLMapSubKeySetIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { AVLMapSubEntrySet, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubEntrySet } from '../../../core/adt/map/AVLMapSubEntrySet';
+import { JavaMap, cast_java_util_Map } from '../../../java/util/JavaMap';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { AVLMapSubCollectionIterator, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubCollectionIterator } from '../../../core/adt/map/AVLMapSubCollectionIterator';
+import { IllegalArgumentException, cast_java_lang_IllegalArgumentException } from '../../../java/lang/IllegalArgumentException';
+
+export class AVLMapSubMap<K, V> extends JavaObject implements NavigableMap<K, V> {
+
+	private readonly _par : AVLMap<K, V>;
+
+	private readonly _iv : AVLMapIntervall<K>;
+
+	private _asc : boolean = false;
+
+
+	/**
+	 * Erstellt eine neue Sub-Map relativ zur übergebenen {@link AVLMap}.
+	 * 
+	 * @param parent    Die {@link AVLMap} auf der diese Sup-Map operiert.
+	 * @param intervall Das {@link AVLMapIntervall} auf das sich diese Sub-Map bezieht.
+	 */
+	constructor(parent : AVLMap<K, V>, intervall : AVLMapIntervall<K>, asc : boolean) {
+		super();
+		this._par = parent;
+		this._iv = intervall;
+		this._asc = asc;
+	}
+
+	public toString() : String {
+		let s : String | null = "";
+		for (let e of this.entrySet()) 
+			s += (s.length === 0 ? "" : ", ") + e;
+		return "Entries = [" + s.valueOf() + "], iv = " + this._iv + ", asc = " + this._asc;
+	}
+
+	public equals(o : unknown) : boolean {
+		if (o as unknown === this as unknown) 
+			return true;
+		if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map'))) === false) 
+			return false;
+		let mapO : JavaMap<unknown, unknown> | null = cast_java_util_Map(o);
+		if (mapO.size() !== this.size()) 
+			return false;
+		for (let e of this.entrySet()) 
+			if (JavaObject.equalsTranspiler(e.getValue(), (mapO.get(e.getKey()))) === false) 
+				return false;
+		return true;
+	}
+
+	public hashCode() : number {
+		let h : number = 0;
+		for (let entry of this.entrySet()) 
+			h += JavaObject.getTranspilerHashCode(entry);
+		return h;
+	}
+
+	public comparator() : Comparator<K> {
+		return this._par.bcGetComparator(this._iv);
+	}
+
+	public firstKey() : K {
+		return this._asc ? this._par.bcGetFirstKeyOrException(this._iv) : this._par.bcGetLastKeyOrException(this._iv);
+	}
+
+	public lastKey() : K {
+		return this._asc ? this._par.bcGetLastKeyOrException(this._iv) : this._par.bcGetFirstKeyOrException(this._iv);
+	}
+
+	public keySet() : JavaSet<K> {
+		return new AVLMapSubKeySet<K, V>(this);
+	}
+
+	public values() : Collection<V> {
+		return new AVLMapSubCollection(this);
+	}
+
+	public entrySet() : JavaSet<JavaMapEntry<K, V>> {
+		return new AVLMapSubEntrySet(this);
+	}
+
+	public size() : number {
+		return this._par.bcGetSize(this._iv);
+	}
+
+	public isEmpty() : boolean {
+		return this._par.bcIsEmpty(this._iv);
+	}
+
+	public containsKey(key : unknown) : boolean {
+		return this._par.bcContainsKey(key, this._iv);
+	}
+
+	public containsValue(value : unknown) : boolean {
+		return this._par.bcContainsValue(value, this._iv);
+	}
+
+	public get(key : unknown) : V | null {
+		return this._par.bcGetValueOfKeyOrNull(key, this._iv);
+	}
+
+	public put(key : K, value : V) : V | null {
+		return this._par.bcAddEntryReturnOldValueOrNull(key, value, this._iv);
+	}
+
+	public remove(key : unknown) : V | null {
+		return this._par.bcRemoveKeyReturnOldValueOrNull(key, this._iv);
+	}
+
+	public putAll(map : JavaMap<K, V>) : void {
+		this._par.bcAddAllEntriesOfMap(map, this._iv);
+	}
+
+	public clear() : void {
+		let iter : JavaIterator<JavaMapEntry<K | null, V | null> | null> | null = this.bcGetSubEntrySetIterator();
+		while (iter.hasNext()) {
+			iter.next();
+			iter.remove();
+		}
+	}
+
+	public lowerEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetLowerEntryOrNull(key, this._iv) : this._par.bcGetHigherEntryOrNull(key, this._iv);
+	}
+
+	public lowerKey(key : K) : K | null {
+		return this._asc ? this._par.bcGetLowerKeyOrNull(key, this._iv) : this._par.bcGetHigherKeyOrNull(key, this._iv);
+	}
+
+	public floorEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetFloorEntryOrNull(key, this._iv) : this._par.bcGetCeilingEntryOrNull(key, this._iv);
+	}
+
+	public floorKey(key : K) : K | null {
+		return this._asc ? this._par.bcGetFloorKeyOrNull(key, this._iv) : this._par.bcGetCeilingKeyOrNull(key, this._iv);
+	}
+
+	public ceilingEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetCeilingEntryOrNull(key, this._iv) : this._par.bcGetFloorEntryOrNull(key, this._iv);
+	}
+
+	public ceilingKey(key : K) : K | null {
+		return this._asc ? this._par.bcGetCeilingKeyOrNull(key, this._iv) : this._par.bcGetFloorKeyOrNull(key, this._iv);
+	}
+
+	public higherEntry(key : K) : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetHigherEntryOrNull(key, this._iv) : this._par.bcGetLowerEntryOrNull(key, this._iv);
+	}
+
+	public higherKey(key : K) : K | null {
+		return this._asc ? this._par.bcGetHigherKeyOrNull(key, this._iv) : this._par.bcGetLowerKeyOrNull(key, this._iv);
+	}
+
+	public firstEntry() : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetFirstEntryOrNull(this._iv) : this._par.bcGetLastEntryOrNull(this._iv);
+	}
+
+	public lastEntry() : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcGetLastEntryOrNull(this._iv) : this._par.bcGetFirstEntryOrNull(this._iv);
+	}
+
+	public pollFirstEntry() : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcPollFirstEntryOrNull(this._iv) : this._par.bcPollLastEntryOrNull(this._iv);
+	}
+
+	public pollLastEntry() : JavaMapEntry<K, V> | null {
+		return this._asc ? this._par.bcPollLastEntryOrNull(this._iv) : this._par.bcPollFirstEntryOrNull(this._iv);
+	}
+
+	public descendingMap() : NavigableMap<K, V> {
+		return new AVLMapSubMap<K, V>(this._par, this._iv, !this._asc);
+	}
+
+	public navigableKeySet() : NavigableSet<K> {
+		return new AVLMapSubKeySet(this);
+	}
+
+	public descendingKeySet() : NavigableSet<K> {
+		return new AVLMapSubKeySet(new AVLMapSubMap<K, V>(this._par, this._iv, !this._asc));
+	}
+
+	public subMap(fromKey : K, fromInclusive : boolean, toKey : K, toInclusive : boolean) : NavigableMap<K, V>;
+
+	public subMap(fromKey : K, toKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'subMap'
+	 */
+	public subMap(__param0 : K, __param1 : K | boolean, __param2? : K, __param3? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
+			let fromKey : K = __param0 as unknown as K;
+			let fromInclusive : boolean = __param1 as boolean;
+			let toKey : K = __param2 as unknown as K;
+			let toInclusive : boolean = __param3 as boolean;
+			return this._createMap(fromKey, fromInclusive, toKey, toInclusive, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
+			let fromKey : K = __param0 as unknown as K;
+			let toKey : K = __param1 as unknown as K;
+			return this._createMap(fromKey, true, toKey, false, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	public headMap(toKey : K, inclusive : boolean) : NavigableMap<K, V>;
+
+	public headMap(toKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'headMap'
+	 */
+	public headMap(__param0 : K, __param1? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let toKey : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._createMap(this._iv.from, this._iv.fromInc, toKey, inclusive, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let toKey : K = __param0 as unknown as K;
+			return this._createMap(this._iv.from, this._iv.fromInc, toKey, false, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	public tailMap(fromKey : K, inclusive : boolean) : NavigableMap<K, V>;
+
+	public tailMap(fromKey : K) : SortedMap<K, V>;
+
+	/**
+	 * Implementation for method overloads of 'tailMap'
+	 */
+	public tailMap(__param0 : K, __param1? : boolean) : NavigableMap<K, V> | SortedMap<K, V> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let fromKey : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._createMap(fromKey, inclusive, this._iv.to, this._iv.toInc, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let fromKey : K = __param0 as unknown as K;
+			return this._createMap(fromKey, true, this._iv.to, this._iv.toInc, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	bcAddKey(e : K) : boolean {
+		return this._par.bcAddKey(e, this._iv);
+	}
+
+	bcAddAllEntries(c : Collection<JavaMapEntry<K, V>>) : boolean {
+		return this._par.bcAddAllEntries(c, this._iv);
+	}
+
+	bcAddEntryReturnBool(e : JavaMapEntry<K, V>) : boolean {
+		return this._par.bcAddEntryReturnBool(e, this._iv);
+	}
+
+	bcContainsAllKeys(c : Collection<unknown>) : boolean {
+		return this._par.bcContainsAllKeys(c, this._iv);
+	}
+
+	bcContainsAllEntries(c : Collection<unknown>) : boolean {
+		return this._par.bcContainsAllEntries(c, this._iv);
+	}
+
+	bcContainsEntry(o : unknown) : boolean {
+		return this._par.bcContainsEntry(o, this._iv);
+	}
+
+	bcRemoveKeyReturnBool(o : unknown) : boolean {
+		return this._par.bcRemoveKeyReturnBool(o, this._iv);
+	}
+
+	bcRemoveEntry(o : unknown) : boolean {
+		return this._par.bcRemoveEntry(o, this._iv);
+	}
+
+	bcRemoveAllKeys(c : Collection<unknown>) : boolean {
+		return this._par.bcRemoveAllKeys(c, this._iv);
+	}
+
+	bcRemoveAllEntries(c : Collection<unknown>) : boolean {
+		return this._par.bcRemoveAllEntries(c, this._iv);
+	}
+
+	bcRetainAllKeys(c : Collection<unknown>) : boolean {
+		let mapRetain : AVLMap<K, K> = new AVLMap();
+		for (let obj of c) {
+			let key : K = obj as unknown as K;
+			mapRetain.put(key, key);
+		}
+		let changed : boolean = false;
+		let iterOfKeys : JavaIterator<K | null> | null = this.bcGetSubKeySetIterator();
+		while (iterOfKeys.hasNext()) {
+			let key : K | null = iterOfKeys.next();
+			if (mapRetain.containsKey(key) === false) {
+				iterOfKeys.remove();
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
+	bcRetainAllEntries(c : Collection<unknown>) : boolean {
+		let mapSave : AVLMap<K, V> = new AVLMap();
+		let setSave : JavaSet<JavaMapEntry<K, V>> = mapSave.entrySet();
+		for (let o of c) 
+			if (this.bcContainsEntry(o)) 
+				setSave.add(cast_java_util_Map_Entry(o));
+		let changed : boolean = false;
+		let iterOfEntries : JavaIterator<JavaMapEntry<K | null, V | null> | null> | null = this.bcGetSubEntrySetIterator();
+		while (iterOfEntries.hasNext()) 
+			if (setSave.contains(iterOfEntries.next()) === false) {
+				iterOfEntries.remove();
+				changed = true;
+			}
+		return changed;
+	}
+
+	firstEntryAsNode() : AVLMapNode<K, V> | null {
+		return this._asc ? this._par.bcGetFirstEntryOrNull(this._iv) : this._par.bcGetLastEntryOrNull(this._iv);
+	}
+
+	nextEntryOrNull(node : AVLMapNode<K, V>) : AVLMapNode<K, V> | null {
+		return this._asc ? this._par.bcGetNextEntryOrNull(node, this._iv) : this._par.bcGetPrevEntryOrNull(node, this._iv);
+	}
+
+	bcAddAllKeys(c : Collection<K>) : boolean {
+		return this._par.bcAddAllKeys(c, this._iv);
+	}
+
+	bcGetLowerKeyOrNull(e : K) : K | null {
+		return this._asc ? this._par.bcGetLowerKeyOrNull(e, this._iv) : this._par.bcGetHigherKeyOrNull(e, this._iv);
+	}
+
+	bcGetFloorKeyOrNull(e : K) : K | null {
+		return this._asc ? this._par.bcGetFloorKeyOrNull(e, this._iv) : this._par.bcGetCeilingKeyOrNull(e, this._iv);
+	}
+
+	bcGetCeilingKeyOrNull(e : K) : K | null {
+		return this._asc ? this._par.bcGetCeilingKeyOrNull(e, this._iv) : this._par.bcGetFloorKeyOrNull(e, this._iv);
+	}
+
+	bcGetHigherKeyOrNull(e : K) : K | null {
+		return this._asc ? this._par.bcGetHigherKeyOrNull(e, this._iv) : this._par.bcGetLowerKeyOrNull(e, this._iv);
+	}
+
+	bcPollFirstKeyOrNull() : K | null {
+		return this._asc ? this._par.bcPollFirstKeyOrNull(this._iv) : this._par.bcPollLastKeyOrNull(this._iv);
+	}
+
+	bcPollLastKeyOrNull() : K | null {
+		return this._asc ? this._par.bcPollLastKeyOrNull(this._iv) : this._par.bcPollFirstKeyOrNull(this._iv);
+	}
+
+	bcGetArrayListOfKeys() : Vector<K | null> {
+		let v : Vector<K | null> | null = new Vector();
+		let iter : JavaIterator<K | null> | null = this.navigableKeySet().iterator();
+		while (iter.hasNext()) 
+			v.add(iter.next());
+		return v;
+	}
+
+	bcGetArrayListOfValues() : Vector<V | null> {
+		let v : Vector<V | null> | null = new Vector();
+		let iter : JavaIterator<V | null> | null = this.values().iterator();
+		while (iter.hasNext()) 
+			v.add(iter.next());
+		return v;
+	}
+
+	bcGetArrayListOfEntries() : Vector<JavaMapEntry<K | null, V | null> | null> {
+		let v : Vector<JavaMapEntry<K | null, V | null> | null> | null = new Vector();
+		let iter : JavaIterator<JavaMapEntry<K | null, V | null> | null> | null = this.entrySet().iterator();
+		while (iter.hasNext()) 
+			v.add(iter.next());
+		return v;
+	}
+
+	bcGetSubKeySetIterator() : JavaIterator<K> {
+		return new AVLMapSubKeySetIterator(this);
+	}
+
+	bcGetSubKeySetDescending() : NavigableSet<K> {
+		return new AVLMapSubKeySet(new AVLMapSubMap(this._par, this._iv, !this._asc));
+	}
+
+	bcGetSubKeySetDescendingIterator() : JavaIterator<K> {
+		return new AVLMapSubKeySetIterator(new AVLMapSubMap(this._par, this._iv, !this._asc));
+	}
+
+	public bcGetSubKeySet(fromElement : K, fromInclusive : boolean, toElement : K, toInclusive : boolean) : NavigableSet<K>;
+
+	public bcGetSubKeySet(fromElement : K, toElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'bcGetSubKeySet'
+	 */
+	public bcGetSubKeySet(__param0 : K, __param1 : K | boolean, __param2? : K, __param3? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
+			let fromElement : K = __param0 as unknown as K;
+			let fromInclusive : boolean = __param1 as boolean;
+			let toElement : K = __param2 as unknown as K;
+			let toInclusive : boolean = __param3 as boolean;
+			return this._createSet(fromElement, fromInclusive, toElement, toInclusive, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
+			let fromElement : K = __param0 as unknown as K;
+			let toElement : K = __param1 as unknown as K;
+			return this._createSet(fromElement, true, toElement, false, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	public bcGetSubKeyHeadSet(toElement : K, inclusive : boolean) : NavigableSet<K>;
+
+	public bcGetSubKeyHeadSet(toElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'bcGetSubKeyHeadSet'
+	 */
+	public bcGetSubKeyHeadSet(__param0 : K, __param1? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let toElement : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._createSet(this._iv.from, this._iv.fromInc, toElement, inclusive, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let toElement : K = __param0 as unknown as K;
+			return this._createSet(this._iv.from, this._iv.fromInc, toElement, false, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	public bcGetSubKeyTailSet(fromElement : K, inclusive : boolean) : NavigableSet<K>;
+
+	public bcGetSubKeyTailSet(fromElement : K) : SortedSet<K>;
+
+	/**
+	 * Implementation for method overloads of 'bcGetSubKeyTailSet'
+	 */
+	public bcGetSubKeyTailSet(__param0 : K, __param1? : boolean) : NavigableSet<K> | SortedSet<K> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let fromElement : K = __param0 as unknown as K;
+			let inclusive : boolean = __param1 as boolean;
+			return this._createSet(fromElement, inclusive, this._iv.to, this._iv.toInc, this._asc);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let fromElement : K = __param0 as unknown as K;
+			return this._createSet(fromElement, true, this._iv.to, this._iv.toInc, this._asc);
+		} else throw new Error('invalid method overload');
+	}
+
+	bcGetSubCollectionIterator() : JavaIterator<V> {
+		return new AVLMapSubCollectionIterator(this);
+	}
+
+	bcContainsAllValues(c : Collection<unknown>) : boolean {
+		return this._par.bcContainsAllValues(c, this._iv);
+	}
+
+	bcGetSubEntrySetIterator() : JavaIterator<JavaMapEntry<K, V>> {
+		return new AVLMapSubEntrySetIterator(this);
+	}
+
+	private _createMap(from : K, fromInc : boolean, to : K, toInc : boolean, asc : boolean) : AVLMapSubMap<K, V> {
+		if (this._par.bcCheckOutOfIntervall(from, fromInc, this._iv)) 
+			throw new IllegalArgumentException("FROM-KEY " + from + "/" + fromInc + " nicht in " + this._iv)
+		if (this._par.bcCheckOutOfIntervall(to, toInc, this._iv)) 
+			throw new IllegalArgumentException("TO-KEY " + to + "/" + toInc + " nicht in " + this._iv)
+		return new AVLMapSubMap<K, V>(this._par, new AVLMapIntervall<K>(from, fromInc, to, toInc), asc);
+	}
+
+	private _createSet(from : K, fromInc : boolean, to : K, toInc : boolean, asc : boolean) : AVLMapSubKeySet<K, V> {
+		return new AVLMapSubKeySet<K, V>(this._createMap(from, fromInc, to, toInc, asc));
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Map', 'java.util.NavigableMap', 'de.nrw.schule.svws.core.adt.map.AVLMapSubMap', 'java.util.SortedMap'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap<K, V>(obj : unknown) : AVLMapSubMap<K, V> {
+	return obj as AVLMapSubMap<K, V>;
+}

+ 238 - 0
core/adt/set/AVLSet.ts

@@ -0,0 +1,238 @@
+import { NavigableSet, cast_java_util_NavigableSet } from '../../../java/util/NavigableSet';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { SortedSet, cast_java_util_SortedSet } from '../../../java/util/SortedSet';
+import { AVLMap, cast_de_nrw_schule_svws_core_adt_map_AVLMap } from '../../../core/adt/map/AVLMap';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+
+export class AVLSet<E> extends JavaObject implements NavigableSet<E> {
+
+	private readonly _set : NavigableSet<E>;
+
+
+	/**
+	 * Erzeugt ein leeres Set, welche bei den Schlüsselwerten die natürliche Ordnung des {@link Comparable} -
+	 * Interface nutzt.
+	 */
+	public constructor();
+
+	/**
+	 * Erstellt eine neues Setp und nutzt dabei die angegeben Ordnung der Schlüssel.
+	 * 
+	 * @param comparator Die Ordnung für die Schlüssel.
+	 */
+	public constructor(comparator : Comparator<E>);
+
+	/**
+	 * Erstellt ein neues Set mit den Daten des angegebenen Sets und nutzt dabei die Ordnung dieses Sets.
+	 * 
+	 * @param set Die Map mit den Daten.
+	 */
+	public constructor(set : SortedSet<E>);
+
+	/**
+	 * Implementation for method overloads of 'constructor'
+	 */
+	public constructor(__param0? : Comparator<E> | SortedSet<E>) {
+		super();
+		if ((typeof __param0 === "undefined")) {
+			let map : AVLMap<E, E> = new AVLMap();
+			map.allowKeyAlone(true);
+			this._set = map.navigableKeySet();
+		} else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null))) {
+			let comparator : Comparator<E> = cast_java_util_Comparator(__param0);
+			let map : AVLMap<E, E> = new AVLMap(comparator);
+			map.allowKeyAlone(true);
+			this._set = map.navigableKeySet();
+		} else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.util.SortedSet'))) || (__param0 === null))) {
+			let set : SortedSet<E> = cast_java_util_SortedSet(__param0);
+			let map : AVLMap<E, E> = new AVLMap();
+			map.allowKeyAlone(true);
+			this._set = map.navigableKeySet();
+			this._set.addAll(set);
+		} else throw new Error('invalid method overload');
+	}
+
+	public comparator() : Comparator<Partial<E>> {
+		return this._set.comparator();
+	}
+
+	public first() : E {
+		return this._set.first();
+	}
+
+	public last() : E {
+		return this._set.last();
+	}
+
+	public size() : number {
+		return this._set.size();
+	}
+
+	public isEmpty() : boolean {
+		return this._set.isEmpty();
+	}
+
+	public contains(o : unknown) : boolean {
+		return this._set.contains(o);
+	}
+
+	public toArray() : Array<unknown>;
+
+	public toArray<T>(a : Array<T>) : Array<T>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<T>(__param0? : Array<T>) : Array<T> | Array<unknown> {
+		if ((typeof __param0 === "undefined")) {
+			return this._set.toArray();
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<T> = __param0;
+			return this._set.toArray(a);
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : E) : boolean {
+		return this._set.add(e);
+	}
+
+	public remove(o : unknown) : boolean {
+		return this._set.remove(o);
+	}
+
+	public containsAll(c : Collection<unknown>) : boolean {
+		return this._set.containsAll(c);
+	}
+
+	public addAll(c : Collection<E>) : boolean {
+		return this._set.addAll(c);
+	}
+
+	public retainAll(c : Collection<unknown>) : boolean {
+		return this._set.retainAll(c);
+	}
+
+	public removeAll(c : Collection<unknown>) : boolean {
+		return this._set.removeAll(c);
+	}
+
+	public clear() : void {
+		this._set.clear();
+	}
+
+	public lower(e : E) : E | null {
+		return this._set.lower(e);
+	}
+
+	public floor(e : E) : E | null {
+		return this._set.floor(e);
+	}
+
+	public ceiling(e : E) : E | null {
+		return this._set.ceiling(e);
+	}
+
+	public higher(e : E) : E | null {
+		return this._set.higher(e);
+	}
+
+	public pollFirst() : E | null {
+		return this._set.pollFirst();
+	}
+
+	public pollLast() : E | null {
+		return this._set.pollLast();
+	}
+
+	public iterator() : JavaIterator<E> {
+		return this._set.iterator();
+	}
+
+	public descendingSet() : NavigableSet<E> {
+		return this._set.descendingSet();
+	}
+
+	public descendingIterator() : JavaIterator<E> {
+		return this._set.descendingIterator();
+	}
+
+	public subSet(fromElement : E, fromInclusive : boolean, toElement : E, toInclusive : boolean) : NavigableSet<E>;
+
+	public subSet(fromElement : E, toElement : E) : SortedSet<E>;
+
+	/**
+	 * Implementation for method overloads of 'subSet'
+	 */
+	public subSet(__param0 : E, __param1 : E | boolean, __param2? : E, __param3? : boolean) : NavigableSet<E> | SortedSet<E> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
+			let fromElement : E = __param0 as unknown as E;
+			let fromInclusive : boolean = __param1 as boolean;
+			let toElement : E = __param2 as unknown as E;
+			let toInclusive : boolean = __param3 as boolean;
+			return this._set.subSet(fromElement, fromInclusive, toElement, toInclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
+			let fromElement : E = __param0 as unknown as E;
+			let toElement : E = __param1 as unknown as E;
+			return this._set.subSet(fromElement, toElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	public headSet(toElement : E, inclusive : boolean) : NavigableSet<E>;
+
+	public headSet(toElement : E) : SortedSet<E>;
+
+	/**
+	 * Implementation for method overloads of 'headSet'
+	 */
+	public headSet(__param0 : E, __param1? : boolean) : NavigableSet<E> | SortedSet<E> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let toElement : E = __param0 as unknown as E;
+			let inclusive : boolean = __param1 as boolean;
+			return this._set.headSet(toElement, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let toElement : E = __param0 as unknown as E;
+			return this._set.headSet(toElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	public tailSet(fromElement : E, inclusive : boolean) : NavigableSet<E>;
+
+	public tailSet(fromElement : E) : SortedSet<E>;
+
+	/**
+	 * Implementation for method overloads of 'tailSet'
+	 */
+	public tailSet(__param0 : E, __param1? : boolean) : NavigableSet<E> | SortedSet<E> {
+		if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
+			let fromElement : E = __param0 as unknown as E;
+			let inclusive : boolean = __param1 as boolean;
+			return this._set.tailSet(fromElement, inclusive);
+		} else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
+			let fromElement : E = __param0 as unknown as E;
+			return this._set.tailSet(fromElement);
+		} else throw new Error('invalid method overload');
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.SortedSet', 'java.util.Collection', 'de.nrw.schule.svws.core.adt.set.AVLSet', 'java.util.Set', 'java.util.NavigableSet', 'java.lang.Iterable'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<E> {
+		let iter : JavaIterator<E> = this.iterator();
+		const result : Iterator<E> = {
+			next() : IteratorResult<E> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_set_AVLSet<E>(obj : unknown) : AVLSet<E> {
+	return obj as AVLSet<E>;
+}

+ 546 - 0
core/adt/tree/MinHeap.ts

@@ -0,0 +1,546 @@
+import { IllegalStateException, cast_java_lang_IllegalStateException } from '../../../java/lang/IllegalStateException';
+import { MinHeapIterator, cast_de_nrw_schule_svws_core_adt_tree_MinHeapIterator } from '../../../core/adt/tree/MinHeapIterator';
+import { StringBuilder, cast_java_lang_StringBuilder } from '../../../java/lang/StringBuilder';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { System, cast_java_lang_System } from '../../../java/lang/System';
+import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
+import { Cloneable, cast_java_lang_Cloneable } from '../../../java/lang/Cloneable';
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
+import { Queue, cast_java_util_Queue } from '../../../java/util/Queue';
+import { IllegalArgumentException, cast_java_lang_IllegalArgumentException } from '../../../java/lang/IllegalArgumentException';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { CloneNotSupportedException, cast_java_lang_CloneNotSupportedException } from '../../../java/lang/CloneNotSupportedException';
+
+export class MinHeap<T> extends JavaObject implements Queue<T>, Cloneable {
+
+	private _size : number = 0;
+
+	private _nodes : Array<T | null> = Array(0).fill(null);
+
+	private readonly _comparator : Comparator<T>;
+
+	private readonly _initialCapacity : number;
+
+	protected _modCount : number = 0;
+
+
+	/**
+	 * Erzeugt einen neuen Minimum-Heap mit dem übergebenen {@link Comparator} und
+	 * der übergebenen initialen Kapazität.
+	 * 
+	 * @param comparator      das Objekt zum Vergleich von zwei Objekten des Typ T
+	 * @param initialCapacity die initiale Kapazität des Baums
+	 */
+	public constructor(comparator : Comparator<T>, initialCapacity : number);
+
+	/**
+	 * Erzeugt einen neuen Minimum-Heap mit dem übergebenen {@link Comparator} und
+	 * einer initialen Kapazität von 63.
+	 * 
+	 * @param comparator das Objekt zum Vergleich von zwei Objekten des Typ T
+	 */
+	public constructor(comparator : Comparator<T>);
+
+	/**
+	 * Erstellt eine Kopie des als Parameter übergebenen Heaps. 
+	 * 
+	 * @param original    Das zu kopierende Original
+	 */
+	public constructor(original : MinHeap<T>);
+
+	/**
+	 * Implementation for method overloads of 'constructor'
+	 */
+	public constructor(__param0 : Comparator<T> | MinHeap<T>, __param1? : number) {
+		super();
+		if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null)) && ((typeof __param1 !== "undefined") && typeof __param1 === "number")) {
+			let comparator : Comparator<T> = cast_java_util_Comparator(__param0);
+			let initialCapacity : number = __param1 as number;
+			if (initialCapacity <= 0) 
+				throw new IllegalArgumentException("Die initiale Kapazität muss größer als 0 sein.")
+			this._comparator = comparator;
+			this._initialCapacity = initialCapacity;
+			this._modCount = 0;
+		} else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null)) && (typeof __param1 === "undefined")) {
+			let comparator : Comparator<T> = cast_java_util_Comparator(__param0);
+			this._comparator = comparator;
+			this._initialCapacity = 63;
+			this._modCount = 0;
+		} else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap'))) || (__param0 === null)) && (typeof __param1 === "undefined")) {
+			let original : MinHeap<T> = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(__param0);
+			this._comparator = original._comparator;
+			this._initialCapacity = original._initialCapacity;
+			this._nodes = Arrays.copyOf(original._nodes, original._nodes.length);
+			this._size = original._size;
+			this._modCount = original._modCount;
+		} else throw new Error('invalid method overload');
+	}
+
+	public add(e : T) : boolean {
+		if (e === null) 
+			return false;
+		if (this._nodes.length === 0) 
+			this._nodes = this.newArray(e, this._initialCapacity);
+		if (this._size === this._nodes.length) 
+			this.grow();
+		this._nodes[this._size] = e;
+		this.heapifyUp(this._size++);
+		this._modCount++;
+		return true;
+	}
+
+	public element() : T {
+		if ((this._size === 0) || (this._nodes[0] === null)) 
+			throw new NoSuchElementException()
+		return this._nodes[0];
+	}
+
+	public offer(e : T) : boolean {
+		return this.add(e);
+	}
+
+	public peek() : T | null {
+		return this._nodes.length === 0 ? null : this._nodes[0];
+	}
+
+	public poll() : T | null {
+		if (this._size === 0) 
+			return null;
+		let elem : T | null = this._nodes[0];
+		this._nodes[0] = this._nodes[--this._size];
+		this._nodes[this._size] = null;
+		this.heapifyDown(0);
+		this._modCount++;
+		return elem;
+	}
+
+	public remove() : T;
+
+	public remove(o : unknown | null) : boolean;
+
+	/**
+	 * Implementation for method overloads of 'remove'
+	 */
+	public remove(__param0? : null | unknown) : T | boolean {
+		if ((typeof __param0 === "undefined")) {
+			let result : T | null = this.poll();
+			if (result === null) 
+				throw new NoSuchElementException()
+			return result;
+		} else if (((typeof __param0 !== "undefined") && ((__param0 instanceof Object) || ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.lang.Object')))) || (__param0 === null))) {
+			let o : unknown | null = (__param0 instanceof JavaObject) ? cast_java_lang_Object(__param0) : __param0;
+			if (o === null) 
+				return false;
+			let index : number = this.findIndex(o);
+			if (index === -1) 
+				return false;
+			this._size--;
+			this._modCount++;
+			if (index === this._size) 
+				return true;
+			this._nodes[index] = this._nodes[this._size];
+			this._nodes[this._size] = null;
+			this.heapifyUp(index);
+			this.heapifyDown(index);
+			return true;
+		} else throw new Error('invalid method overload');
+	}
+
+	public size() : number {
+		return this._size;
+	}
+
+	public isEmpty() : boolean {
+		return this._size === 0;
+	}
+
+	public contains(o : unknown | null) : boolean {
+		if (o === null) 
+			return false;
+		for (let i : number = 0; i < this._size; i++){
+			if (JavaObject.equalsTranspiler(this._nodes[i], (o))) 
+				return true;
+		}
+		return false;
+	}
+
+	public containsAll(c : Collection<unknown> | null) : boolean {
+		if (c === null) 
+			return true;
+		if (this as unknown === c as unknown) 
+			return true;
+		for (let o of c) 
+			if (!this.contains(o)) 
+				return false;
+		return true;
+	}
+
+	public addAll(c : Collection<T> | null) : boolean {
+		if (c === null) 
+			return false;
+		if (this as unknown === c as unknown) {
+			if (this._size === 0) 
+				return false;
+			let tmp : Array<T | null> = Arrays.copyOf(this._nodes, this._size);
+			for (let t of tmp) 
+				if (t !== null) 
+					this.add(t);
+			return true;
+		}
+		let result : boolean = false;
+		for (let t of c) {
+			if (this.add(t)) 
+				result = true;
+		}
+		return result;
+	}
+
+	public removeAll(c : Collection<unknown> | null) : boolean {
+		if (c === null) 
+			return false;
+		if (this as unknown === c as unknown) {
+			if (this.size() === 0) 
+				return false;
+			this.clear();
+			return true;
+		}
+		let result : boolean = false;
+		for (let o of c) {
+			if (this.remove(o)) {
+				result = true;
+				while (this.remove(o)) ;
+			}
+		}
+		return result;
+	}
+
+	public retainAll(c : Collection<unknown> | null) : boolean {
+		if (this._size === 0) 
+			return false;
+		if (c === null) {
+			this.clear();
+			return true;
+		}
+		if (this as unknown === c as unknown) 
+			return false;
+		let tmp : Array<T | null> = this.newArray(this._nodes[0], this._nodes.length);
+		if (tmp === null) 
+			return false;
+		let i : number = 0;
+		let elem : T | null;
+		let changed : boolean = false;
+		while ((elem = this.poll()) !== null) {
+			if (c.contains(elem)) 
+				tmp[i++] = elem; else 
+				changed = true;
+		}
+		this._nodes = tmp;
+		this._size = i;
+		this._modCount++;
+		return changed;
+	}
+
+	public clear() : void {
+		this._nodes = Array(0).fill(null);
+		this._size = 0;
+		this._modCount++;
+	}
+
+	public toArray() : Array<unknown>;
+
+	public toArray<U>(a : Array<U>) : Array<U>;
+
+	/**
+	 * Implementation for method overloads of 'toArray'
+	 */
+	public toArray<U>(__param0? : Array<U>) : Array<U> | Array<unknown> {
+		if ((typeof __param0 === "undefined")) {
+			return this.copyNodes();
+		} else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
+			let a : Array<U> = __param0;
+			if (a.length < this._size) 
+				return this.copyNodes();
+			System.arraycopy(this._nodes, 0, a, 0, this._size);
+			Arrays.fill(a, this._size, a.length, null);
+			return a;
+		} else throw new Error('invalid method overload');
+	}
+
+	public iterator() : JavaIterator<T> {
+		return new MinHeapIterator(this._nodes, this);
+	}
+
+	public clone() : unknown {
+		return new MinHeap(this);
+	}
+
+	/**
+	 * Gibt den {@link Comparator} des Minimum Heaps zurück.
+	 * 
+	 * @return der Comparator
+	 */
+	public comparator() : Comparator<T> {
+		return this._comparator;
+	}
+
+	/**
+	 * Gibt die aktuelle Kapazität des Arrays zurück.
+	 * 
+	 * @return die aktuelle Kapazität des Arrays zurück
+	 */
+	public capacity() : number {
+		return (this._nodes.length === 0) ? this._initialCapacity : this._nodes.length;
+	}
+
+	/**
+	 * Gibt den Inhalt des Minimum Heaps in einem sortierten Array zurück.
+	 * 
+	 * @return ein sortiertes Array mit den Elementen des Minimum Heaps.
+	 */
+	public toSortedArray() : Array<T> {
+		if (this._size === 0) 
+			return Array(0).fill(null);
+		let copy : MinHeap<T> = new MinHeap(this);
+		let tmp : Array<T> = this.newArray(this._nodes[0], this._size);
+		let current : T | null;
+		let i : number = 0;
+		while ((current = copy.poll()) !== null) 
+			tmp[i++] = current;
+		return tmp;
+	}
+
+	/**
+	 * Gibt den Inhalt des Heaps als Array-Repräsentation aus.
+	 * 
+	 * @return der Inhalt des Heaps
+	 */
+	public toString() : String {
+		let sb : StringBuilder = new StringBuilder();
+		for (let i : number = 0; i < this._size; i++){
+			sb.append(this._nodes[i]);
+			if (i !== this._size - 1) 
+				sb.append(", ");
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Ermittelt eine Hash-Code für dieses Objekt basierend auf den gespeicherten 
+	 * Daten im Heap (die konkrete Ordnung des Baumes wird nicht unterschieden).
+	 * 
+	 * @return der Hashcode des Minimum Heaps
+	 */
+	public hashCode() : number {
+		return Arrays.deepHashCode(this.toSortedArray());
+	}
+
+	/**
+	 * Prüft, ob das übergebene Objekt ein Minimum-Heap ist, der
+	 * die gleichen Elemente mit der gleichen Ordnung beinhaltet.
+	 * 
+	 * @param obj   das zu vergleichende Objekt
+	 */
+	public equals(obj : unknown | null) : boolean {
+		if (this as unknown === obj as unknown) 
+			return true;
+		if (obj === null) 
+			return false;
+		if (((obj instanceof JavaObject) && (obj.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap')))) {
+			let other : MinHeap<unknown> | null = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(obj);
+			return Arrays.deepEquals(this.toSortedArray(), other.toSortedArray());
+		}
+		return false;
+	}
+
+	/**
+	 * Liefert zum Index i den Index des Elter zurück.
+	 * 
+	 * @param i
+	 * 
+	 * @return den Index des Elter
+	 */
+	private static getParentIndex(i : number) : number {
+		return (i <= 0) ? -1 : Math.trunc((i - 1) / 2);
+	}
+
+	/**
+	 * Liefert zum Index i den Index des linken Kindes zurück.
+	 * 
+	 * @param i
+	 * 
+	 * @return den Index des linken Kindes
+	 */
+	private static getLeftChildIndex(i : number) : number {
+		return 2 * i + 1;
+	}
+
+	/**
+	 * Liefert zum Index i den Index des rechten Kindes zurück.
+	 * 
+	 * @param i
+	 * 
+	 * @return den Index des rechten Kindes
+	 */
+	private static getRightChildIndex(i : number) : number {
+		return 2 * i + 2;
+	}
+
+	/**
+	 * Tauscht die Elemente an den Stellen i und j im Array
+	 * 
+	 * @param i
+	 * @param j
+	 */
+	private swap(i : number, j : number) : void {
+		let elem : T | null = this._nodes[i];
+		this._nodes[i] = this._nodes[j];
+		this._nodes[j] = elem;
+	}
+
+	/**
+	 * Stellt die Minimum Heap Eigenschaft vom Index i aus im Baum abwärts her.
+	 * 
+	 * @param i   ab diesem Index wird im Baum abwärts geprüft.
+	 */
+	private heapifyDown(i : number) : void {
+		let left : number = MinHeap.getLeftChildIndex(i);
+		let right : number = MinHeap.getRightChildIndex(i);
+		if (left >= this._size) 
+			return;
+		let child : number = right;
+		if (right === this._size) {
+			child = left;
+		} else {
+			let nodeLeft : T | null = this._nodes[left];
+			let nodeRight : T | null = this._nodes[right];
+			if ((nodeLeft === null) || (nodeRight === null)) 
+				return;
+			if (this._comparator.compare(nodeLeft, nodeRight) < 0) 
+				child = left;
+		}
+		let nodeCurrent : T | null = this._nodes[i];
+		let nodeChild : T | null = this._nodes[child];
+		if ((nodeCurrent === null) || (nodeChild === null)) 
+			throw new NullPointerException()
+		if (this._comparator.compare(nodeCurrent, nodeChild) <= 0) 
+			return;
+		this.swap(i, child);
+		this.heapifyDown(child);
+	}
+
+	/**
+	 * Stellt die Minimum-Heap-Eigenschaft des Arrays ab Position i aufwärts wieder her.
+	 * 
+	 * @param i   ab diesem Index wird überprüft
+	 */
+	private heapifyUp(i : number) : void {
+		let parentIndex : number = MinHeap.getParentIndex(i);
+		if (parentIndex < 0) 
+			return;
+		let nodeCurrent : T | null = this._nodes[i];
+		let nodeParent : T | null = this._nodes[parentIndex];
+		if ((nodeCurrent === null) || (nodeParent === null) || (this._comparator.compare(nodeCurrent, nodeParent) >= 0)) 
+			return;
+		this.swap(i, parentIndex);
+		this.heapifyUp(parentIndex);
+	}
+
+	/**
+	 * Erstellt ein neues Array vom Typ T mit der angegebenen Länge.
+	 *   
+	 * @param elem     Ein Element vom Typ T, welches als Vorlage für die Elemente des Arrays dient 
+	 * @param length   die Länge des neuen Arrays
+	 * 
+	 * @return das neue Array
+	 */
+	private newArray(elem : T | null, length : number) : Array<T> {
+		if (elem === null) 
+			return Array(length).fill(null);
+		return Array(length).fill(null);
+	}
+
+	/**
+	 * Erzeugt eine Kopie des internen Arrays _nodes.
+	 * 
+	 * @return die Kopie des _nodes-Array.
+	 */
+	private copyNodes() : Array<T> {
+		let result : Array<T> = this.newArray(this._size <= 0 ? null : this._nodes[0], this._size);
+		System.arraycopy(this._nodes, 0, result, 0, this._size);
+		return result;
+	}
+
+	/**
+	 * Lässt den dem Baum zu Grunde liegenden Baum wachsen. Verdoppelt die Menge der Elemente, die im Heap 
+	 * gespeichert werden können. 
+	 * 
+	 * Falls der Heap durch das Wachsen auf mehr als {@link Integer.MAX_VALUE} Elemente ansteigen würde, 
+	 * wird eine IllegalStateException geworfen.
+	 * 
+	 * @throws IllegalStateException
+	 */
+	private grow() : void {
+		if (this._nodes.length === Number.MAX_VALUE) 
+			throw new IllegalStateException("Der Minimum-Heap kann nicht mehr als " + Number.MAX_VALUE + " Elemente beinhalten.")
+		let newLength : number = this._nodes.length * 2 + 1;
+		if (newLength < 0) 
+			newLength = Number.MAX_VALUE;
+		let tmp : Array<T> = this.newArray(this._nodes[0], newLength);
+		System.arraycopy(this._nodes, 0, tmp, 0, this._size);
+		this._nodes = tmp;
+	}
+
+	/**
+	 * Findet den Index an dem das Element t im dem dem Heap zu Grunde liegendem Array gespeichert ist. 
+	 * Gibt -1 zurück, falls das Element nicht vorhanden ist.
+	 * 
+	 * @param t   zu diesem Element soll der Index gefunden werden
+	 * 
+	 * @return  der Index, falls das Element enthalten ist, ansonsten -1
+	 */
+	private findIndex(obj : unknown | null) : number {
+		if (obj === null) 
+			return -1;
+		for (let i : number = 0; i < this._size; i++){
+			if (JavaObject.equalsTranspiler(this._nodes[i], (obj))) 
+				return i;
+		}
+		return -1;
+	}
+
+	/**
+	 * Gibt die Anzahl der Operationen zurück, die diese Datenstruktur
+	 * verändert haben.
+	 * 
+	 * @return die Anzahl der Operationen
+	 */
+	getModCount() : number {
+		return this._modCount;
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.lang.Cloneable', 'de.nrw.schule.svws.core.adt.tree.MinHeap', 'java.util.Collection', 'java.util.Queue', 'java.lang.Iterable'].includes(name);
+	}
+
+	public [Symbol.iterator](): Iterator<T> {
+		let iter : JavaIterator<T> = this.iterator();
+		const result : Iterator<T> = {
+			next() : IteratorResult<T> {
+				if (iter.hasNext())
+					return { value : iter.next(), done : false };
+				return { value : null, done : true };
+			}
+		};
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_tree_MinHeap<T>(obj : unknown) : MinHeap<T> {
+	return obj as MinHeap<T>;
+}

+ 60 - 0
core/adt/tree/MinHeapIterator.ts

@@ -0,0 +1,60 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ConcurrentModificationException, cast_java_util_ConcurrentModificationException } from '../../../java/util/ConcurrentModificationException';
+import { MinHeap, cast_de_nrw_schule_svws_core_adt_tree_MinHeap } from '../../../core/adt/tree/MinHeap';
+import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
+import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
+import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException';
+
+export class MinHeapIterator<T> extends JavaObject implements JavaIterator<T> {
+
+	private readonly _elements : Array<T | null>;
+
+	private _current : number = 0;
+
+	private readonly _heap : MinHeap<T>;
+
+	private readonly _expModCount : number;
+
+
+	/**
+	 * Erstellt einen neuen Iterator für die Klasse MinHeap
+	 * 
+	 * @param elem   die Elemente des Minimum Heaps 
+	 * @param heap   eine Referenz zum Minimum Heap, um auf parallel erfolgende modifizierende Zugriffe reagierenzu können.
+	 */
+	constructor(elem : Array<T | null>, heap : MinHeap<T>) {
+		super();
+		this._current = -1;
+		this._elements = elem;
+		this._heap = heap;
+		this._expModCount = heap.getModCount();
+	}
+
+	public hasNext() : boolean {
+		if (this._heap.getModCount() !== this._expModCount) 
+			throw new ConcurrentModificationException()
+		return ((this._current + 1) < this._heap.size());
+	}
+
+	public next() : T {
+		if (!this.hasNext()) 
+			throw new NoSuchElementException("Keine weiteren Elemente vorhanden. Eine Prüfung mit hasNext() vorab ist empfehlenswert.")
+		let elem : T | null = this._elements[++this._current];
+		if (elem === null) 
+			throw new NoSuchElementException("Interner Fehler in der Datenstruktur.")
+		return elem;
+	}
+
+	public remove() : void {
+		throw new UnsupportedOperationException("remove")
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['java.util.Iterator', 'de.nrw.schule.svws.core.adt.tree.MinHeapIterator'].includes(name);
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_adt_tree_MinHeapIterator<T>(obj : unknown) : MinHeapIterator<T> {
+	return obj as MinHeapIterator<T>;
+}

+ 53 - 0
core/data/BenutzerKennwort.ts

@@ -0,0 +1,53 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../java/lang/JavaString';
+
+export class BenutzerKennwort extends JavaObject {
+
+	public user : String | null = null;
+
+	public password : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.BenutzerKennwort'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): BenutzerKennwort {
+		const obj = JSON.parse(json);
+		const result = new BenutzerKennwort();
+		result.user = typeof obj.user === "undefined" ? null : obj.user;
+		result.password = typeof obj.password === "undefined" ? null : obj.password;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : BenutzerKennwort) : string {
+		let result = '{';
+		result += '"user" : ' + ((!obj.user) ? 'null' : '"' + obj.user.valueOf() + '"') + ',';
+		result += '"password" : ' + ((!obj.password) ? 'null' : '"' + obj.password.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<BenutzerKennwort>) : string {
+		let result = '{';
+		if (typeof obj.user !== "undefined") {
+			result += '"user" : ' + ((!obj.user) ? 'null' : '"' + obj.user.valueOf() + '"') + ',';
+		}
+		if (typeof obj.password !== "undefined") {
+			result += '"password" : ' + ((!obj.password) ? 'null' : '"' + obj.password.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_BenutzerKennwort(obj : unknown) : BenutzerKennwort {
+	return obj as BenutzerKennwort;
+}

+ 91 - 0
core/data/Sprachbelegung.ts

@@ -0,0 +1,91 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../java/lang/JavaInteger';
+import { JavaString, cast_java_lang_String } from '../../java/lang/JavaString';
+
+export class Sprachbelegung extends JavaObject {
+
+	public sprache : String = "";
+
+	public reihenfolge : Number | null = null;
+
+	public belegungVonJahrgang : String | null = null;
+
+	public belegungVonAbschnitt : Number | null = null;
+
+	public belegungBisJahrgang : String | null = null;
+
+	public belegungBisAbschnitt : Number | null = null;
+
+	public referenzniveau : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.Sprachbelegung'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): Sprachbelegung {
+		const obj = JSON.parse(json);
+		const result = new Sprachbelegung();
+		if (typeof obj.sprache === "undefined")
+			 throw new Error('invalid json format, missing attribute sprache');
+		result.sprache = obj.sprache;
+		result.reihenfolge = typeof obj.reihenfolge === "undefined" ? null : obj.reihenfolge;
+		result.belegungVonJahrgang = typeof obj.belegungVonJahrgang === "undefined" ? null : obj.belegungVonJahrgang;
+		result.belegungVonAbschnitt = typeof obj.belegungVonAbschnitt === "undefined" ? null : obj.belegungVonAbschnitt;
+		result.belegungBisJahrgang = typeof obj.belegungBisJahrgang === "undefined" ? null : obj.belegungBisJahrgang;
+		result.belegungBisAbschnitt = typeof obj.belegungBisAbschnitt === "undefined" ? null : obj.belegungBisAbschnitt;
+		result.referenzniveau = typeof obj.referenzniveau === "undefined" ? null : obj.referenzniveau;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : Sprachbelegung) : string {
+		let result = '{';
+		result += '"sprache" : ' + '"' + obj.sprache.valueOf() + '"' + ',';
+		result += '"reihenfolge" : ' + ((!obj.reihenfolge) ? 'null' : obj.reihenfolge.valueOf()) + ',';
+		result += '"belegungVonJahrgang" : ' + ((!obj.belegungVonJahrgang) ? 'null' : '"' + obj.belegungVonJahrgang.valueOf() + '"') + ',';
+		result += '"belegungVonAbschnitt" : ' + ((!obj.belegungVonAbschnitt) ? 'null' : obj.belegungVonAbschnitt.valueOf()) + ',';
+		result += '"belegungBisJahrgang" : ' + ((!obj.belegungBisJahrgang) ? 'null' : '"' + obj.belegungBisJahrgang.valueOf() + '"') + ',';
+		result += '"belegungBisAbschnitt" : ' + ((!obj.belegungBisAbschnitt) ? 'null' : obj.belegungBisAbschnitt.valueOf()) + ',';
+		result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<Sprachbelegung>) : string {
+		let result = '{';
+		if (typeof obj.sprache !== "undefined") {
+			result += '"sprache" : ' + '"' + obj.sprache.valueOf() + '"' + ',';
+		}
+		if (typeof obj.reihenfolge !== "undefined") {
+			result += '"reihenfolge" : ' + ((!obj.reihenfolge) ? 'null' : obj.reihenfolge.valueOf()) + ',';
+		}
+		if (typeof obj.belegungVonJahrgang !== "undefined") {
+			result += '"belegungVonJahrgang" : ' + ((!obj.belegungVonJahrgang) ? 'null' : '"' + obj.belegungVonJahrgang.valueOf() + '"') + ',';
+		}
+		if (typeof obj.belegungVonAbschnitt !== "undefined") {
+			result += '"belegungVonAbschnitt" : ' + ((!obj.belegungVonAbschnitt) ? 'null' : obj.belegungVonAbschnitt.valueOf()) + ',';
+		}
+		if (typeof obj.belegungBisJahrgang !== "undefined") {
+			result += '"belegungBisJahrgang" : ' + ((!obj.belegungBisJahrgang) ? 'null' : '"' + obj.belegungBisJahrgang.valueOf() + '"') + ',';
+		}
+		if (typeof obj.belegungBisAbschnitt !== "undefined") {
+			result += '"belegungBisAbschnitt" : ' + ((!obj.belegungBisAbschnitt) ? 'null' : obj.belegungBisAbschnitt.valueOf()) + ',';
+		}
+		if (typeof obj.referenzniveau !== "undefined") {
+			result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_Sprachbelegung(obj : unknown) : Sprachbelegung {
+	return obj as Sprachbelegung;
+}

+ 116 - 0
core/data/Sprachendaten.ts

@@ -0,0 +1,116 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { Sprachbelegung, cast_de_nrw_schule_svws_core_data_Sprachbelegung } from '../../core/data/Sprachbelegung';
+import { Sprachpruefung, cast_de_nrw_schule_svws_core_data_Sprachpruefung } from '../../core/data/Sprachpruefung';
+import { Vector, cast_java_util_Vector } from '../../java/util/Vector';
+
+export class Sprachendaten extends JavaObject {
+
+	public schuelerID : number = 0;
+
+	public belegungen : Vector<Sprachbelegung> = new Vector();
+
+	public pruefungen : Vector<Sprachpruefung> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.Sprachendaten'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): Sprachendaten {
+		const obj = JSON.parse(json);
+		const result = new Sprachendaten();
+		if (typeof obj.schuelerID === "undefined")
+			 throw new Error('invalid json format, missing attribute schuelerID');
+		result.schuelerID = obj.schuelerID;
+		if (!!obj.belegungen) {
+			for (let elem of obj.belegungen) {
+				result.belegungen?.add(Sprachbelegung.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.pruefungen) {
+			for (let elem of obj.pruefungen) {
+				result.pruefungen?.add(Sprachpruefung.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : Sprachendaten) : string {
+		let result = '{';
+		result += '"schuelerID" : ' + obj.schuelerID + ',';
+		if (!obj.belegungen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.belegungen.size(); i++) {
+				let elem = obj.belegungen.get(i);
+				result += Sprachbelegung.transpilerToJSON(elem);
+				if (i < obj.belegungen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.pruefungen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.pruefungen.size(); i++) {
+				let elem = obj.pruefungen.get(i);
+				result += Sprachpruefung.transpilerToJSON(elem);
+				if (i < obj.pruefungen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<Sprachendaten>) : string {
+		let result = '{';
+		if (typeof obj.schuelerID !== "undefined") {
+			result += '"schuelerID" : ' + obj.schuelerID + ',';
+		}
+		if (typeof obj.belegungen !== "undefined") {
+			if (!obj.belegungen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.belegungen.size(); i++) {
+					let elem = obj.belegungen.get(i);
+					result += Sprachbelegung.transpilerToJSON(elem);
+					if (i < obj.belegungen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.pruefungen !== "undefined") {
+			if (!obj.pruefungen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.pruefungen.size(); i++) {
+					let elem = obj.pruefungen.get(i);
+					result += Sprachpruefung.transpilerToJSON(elem);
+					if (i < obj.pruefungen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_Sprachendaten(obj : unknown) : Sprachendaten {
+	return obj as Sprachendaten;
+}

+ 136 - 0
core/data/Sprachpruefung.ts

@@ -0,0 +1,136 @@
+import { JavaObject, cast_java_lang_Object } from '../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../java/lang/JavaInteger';
+import { JavaString, cast_java_lang_String } from '../../java/lang/JavaString';
+
+export class Sprachpruefung extends JavaObject {
+
+	public sprache : String | null = null;
+
+	public jahrgang : String | null = null;
+
+	public anspruchsniveauId : Number | null = null;
+
+	public ersetzteSprache : String | null = null;
+
+	public istHKUPruefung : boolean = false;
+
+	public istFeststellungspruefung : boolean = false;
+
+	public kannErstePflichtfremdspracheErsetzen : boolean = false;
+
+	public kannZweitePflichtfremdspracheErsetzen : boolean = false;
+
+	public kannWahlpflichtfremdspracheErsetzen : boolean = false;
+
+	public kannBelegungAlsFortgefuehrteSpracheErlauben : boolean = false;
+
+	public referenzniveau : String | null = null;
+
+	public note : Number | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.Sprachpruefung'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): Sprachpruefung {
+		const obj = JSON.parse(json);
+		const result = new Sprachpruefung();
+		result.sprache = typeof obj.sprache === "undefined" ? null : obj.sprache;
+		result.jahrgang = typeof obj.jahrgang === "undefined" ? null : obj.jahrgang;
+		result.anspruchsniveauId = typeof obj.anspruchsniveauId === "undefined" ? null : obj.anspruchsniveauId;
+		result.ersetzteSprache = typeof obj.ersetzteSprache === "undefined" ? null : obj.ersetzteSprache;
+		if (typeof obj.istHKUPruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute istHKUPruefung');
+		result.istHKUPruefung = obj.istHKUPruefung;
+		if (typeof obj.istFeststellungspruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute istFeststellungspruefung');
+		result.istFeststellungspruefung = obj.istFeststellungspruefung;
+		if (typeof obj.kannErstePflichtfremdspracheErsetzen === "undefined")
+			 throw new Error('invalid json format, missing attribute kannErstePflichtfremdspracheErsetzen');
+		result.kannErstePflichtfremdspracheErsetzen = obj.kannErstePflichtfremdspracheErsetzen;
+		if (typeof obj.kannZweitePflichtfremdspracheErsetzen === "undefined")
+			 throw new Error('invalid json format, missing attribute kannZweitePflichtfremdspracheErsetzen');
+		result.kannZweitePflichtfremdspracheErsetzen = obj.kannZweitePflichtfremdspracheErsetzen;
+		if (typeof obj.kannWahlpflichtfremdspracheErsetzen === "undefined")
+			 throw new Error('invalid json format, missing attribute kannWahlpflichtfremdspracheErsetzen');
+		result.kannWahlpflichtfremdspracheErsetzen = obj.kannWahlpflichtfremdspracheErsetzen;
+		if (typeof obj.kannBelegungAlsFortgefuehrteSpracheErlauben === "undefined")
+			 throw new Error('invalid json format, missing attribute kannBelegungAlsFortgefuehrteSpracheErlauben');
+		result.kannBelegungAlsFortgefuehrteSpracheErlauben = obj.kannBelegungAlsFortgefuehrteSpracheErlauben;
+		result.referenzniveau = typeof obj.referenzniveau === "undefined" ? null : obj.referenzniveau;
+		result.note = typeof obj.note === "undefined" ? null : obj.note;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : Sprachpruefung) : string {
+		let result = '{';
+		result += '"sprache" : ' + ((!obj.sprache) ? 'null' : '"' + obj.sprache.valueOf() + '"') + ',';
+		result += '"jahrgang" : ' + ((!obj.jahrgang) ? 'null' : '"' + obj.jahrgang.valueOf() + '"') + ',';
+		result += '"anspruchsniveauId" : ' + ((!obj.anspruchsniveauId) ? 'null' : obj.anspruchsniveauId.valueOf()) + ',';
+		result += '"ersetzteSprache" : ' + ((!obj.ersetzteSprache) ? 'null' : '"' + obj.ersetzteSprache.valueOf() + '"') + ',';
+		result += '"istHKUPruefung" : ' + obj.istHKUPruefung + ',';
+		result += '"istFeststellungspruefung" : ' + obj.istFeststellungspruefung + ',';
+		result += '"kannErstePflichtfremdspracheErsetzen" : ' + obj.kannErstePflichtfremdspracheErsetzen + ',';
+		result += '"kannZweitePflichtfremdspracheErsetzen" : ' + obj.kannZweitePflichtfremdspracheErsetzen + ',';
+		result += '"kannWahlpflichtfremdspracheErsetzen" : ' + obj.kannWahlpflichtfremdspracheErsetzen + ',';
+		result += '"kannBelegungAlsFortgefuehrteSpracheErlauben" : ' + obj.kannBelegungAlsFortgefuehrteSpracheErlauben + ',';
+		result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		result += '"note" : ' + ((!obj.note) ? 'null' : obj.note.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<Sprachpruefung>) : string {
+		let result = '{';
+		if (typeof obj.sprache !== "undefined") {
+			result += '"sprache" : ' + ((!obj.sprache) ? 'null' : '"' + obj.sprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.jahrgang !== "undefined") {
+			result += '"jahrgang" : ' + ((!obj.jahrgang) ? 'null' : '"' + obj.jahrgang.valueOf() + '"') + ',';
+		}
+		if (typeof obj.anspruchsniveauId !== "undefined") {
+			result += '"anspruchsniveauId" : ' + ((!obj.anspruchsniveauId) ? 'null' : obj.anspruchsniveauId.valueOf()) + ',';
+		}
+		if (typeof obj.ersetzteSprache !== "undefined") {
+			result += '"ersetzteSprache" : ' + ((!obj.ersetzteSprache) ? 'null' : '"' + obj.ersetzteSprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istHKUPruefung !== "undefined") {
+			result += '"istHKUPruefung" : ' + obj.istHKUPruefung + ',';
+		}
+		if (typeof obj.istFeststellungspruefung !== "undefined") {
+			result += '"istFeststellungspruefung" : ' + obj.istFeststellungspruefung + ',';
+		}
+		if (typeof obj.kannErstePflichtfremdspracheErsetzen !== "undefined") {
+			result += '"kannErstePflichtfremdspracheErsetzen" : ' + obj.kannErstePflichtfremdspracheErsetzen + ',';
+		}
+		if (typeof obj.kannZweitePflichtfremdspracheErsetzen !== "undefined") {
+			result += '"kannZweitePflichtfremdspracheErsetzen" : ' + obj.kannZweitePflichtfremdspracheErsetzen + ',';
+		}
+		if (typeof obj.kannWahlpflichtfremdspracheErsetzen !== "undefined") {
+			result += '"kannWahlpflichtfremdspracheErsetzen" : ' + obj.kannWahlpflichtfremdspracheErsetzen + ',';
+		}
+		if (typeof obj.kannBelegungAlsFortgefuehrteSpracheErlauben !== "undefined") {
+			result += '"kannBelegungAlsFortgefuehrteSpracheErlauben" : ' + obj.kannBelegungAlsFortgefuehrteSpracheErlauben + ',';
+		}
+		if (typeof obj.referenzniveau !== "undefined") {
+			result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		}
+		if (typeof obj.note !== "undefined") {
+			result += '"note" : ' + ((!obj.note) ? 'null' : obj.note.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_Sprachpruefung(obj : unknown) : Sprachpruefung {
+	return obj as Sprachpruefung;
+}

+ 122 - 0
core/data/abschluss/AbschlussErgebnis.ts

@@ -0,0 +1,122 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class AbschlussErgebnis extends JavaObject {
+
+	public erworben : boolean = false;
+
+	public abschluss : String | null = null;
+
+	public npFaecher : List<String> | null = null;
+
+	public log : List<String> | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.abschluss.AbschlussErgebnis'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): AbschlussErgebnis {
+		const obj = JSON.parse(json);
+		const result = new AbschlussErgebnis();
+		if (typeof obj.erworben === "undefined")
+			 throw new Error('invalid json format, missing attribute erworben');
+		result.erworben = obj.erworben;
+		result.abschluss = typeof obj.abschluss === "undefined" ? null : obj.abschluss;
+		if (!!obj.npFaecher) {
+			for (let elem of obj.npFaecher) {
+				result.npFaecher?.add(elem);
+			}
+		}
+		if (!!obj.log) {
+			for (let elem of obj.log) {
+				result.log?.add(elem);
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : AbschlussErgebnis) : string {
+		let result = '{';
+		result += '"erworben" : ' + obj.erworben + ',';
+		result += '"abschluss" : ' + ((!obj.abschluss) ? 'null' : '"' + obj.abschluss.valueOf() + '"') + ',';
+		if (!obj.npFaecher) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.npFaecher.size(); i++) {
+				let elem = obj.npFaecher.get(i);
+				result += '"' + elem + '"';
+				if (i < obj.npFaecher.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.log) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.log.size(); i++) {
+				let elem = obj.log.get(i);
+				result += '"' + elem + '"';
+				if (i < obj.log.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<AbschlussErgebnis>) : string {
+		let result = '{';
+		if (typeof obj.erworben !== "undefined") {
+			result += '"erworben" : ' + obj.erworben + ',';
+		}
+		if (typeof obj.abschluss !== "undefined") {
+			result += '"abschluss" : ' + ((!obj.abschluss) ? 'null' : '"' + obj.abschluss.valueOf() + '"') + ',';
+		}
+		if (typeof obj.npFaecher !== "undefined") {
+			if (!obj.npFaecher) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.npFaecher.size(); i++) {
+					let elem = obj.npFaecher.get(i);
+					result += '"' + elem + '"';
+					if (i < obj.npFaecher.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.log !== "undefined") {
+			if (!obj.log) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.log.size(); i++) {
+					let elem = obj.log.get(i);
+					result += '"' + elem + '"';
+					if (i < obj.log.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnis(obj : unknown) : AbschlussErgebnis {
+	return obj as AbschlussErgebnis;
+}

+ 106 - 0
core/data/abschluss/AbschlussErgebnisBerufsbildend.ts

@@ -0,0 +1,106 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+
+export class AbschlussErgebnisBerufsbildend extends JavaObject {
+
+	public hatBSA : boolean = false;
+
+	public note : number = 0;
+
+	public hatBA : Boolean | null = null;
+
+	public abschlussAllgemeinbildend : String | null = null;
+
+	public log : List<String> | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.abschluss.AbschlussErgebnisBerufsbildend'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): AbschlussErgebnisBerufsbildend {
+		const obj = JSON.parse(json);
+		const result = new AbschlussErgebnisBerufsbildend();
+		if (typeof obj.hatBSA === "undefined")
+			 throw new Error('invalid json format, missing attribute hatBSA');
+		result.hatBSA = obj.hatBSA;
+		if (typeof obj.note === "undefined")
+			 throw new Error('invalid json format, missing attribute note');
+		result.note = obj.note;
+		result.hatBA = typeof obj.hatBA === "undefined" ? null : obj.hatBA;
+		result.abschlussAllgemeinbildend = typeof obj.abschlussAllgemeinbildend === "undefined" ? null : obj.abschlussAllgemeinbildend;
+		if (!!obj.log) {
+			for (let elem of obj.log) {
+				result.log?.add(elem);
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : AbschlussErgebnisBerufsbildend) : string {
+		let result = '{';
+		result += '"hatBSA" : ' + obj.hatBSA + ',';
+		result += '"note" : ' + obj.note + ',';
+		result += '"hatBA" : ' + ((!obj.hatBA) ? 'null' : obj.hatBA.valueOf()) + ',';
+		result += '"abschlussAllgemeinbildend" : ' + ((!obj.abschlussAllgemeinbildend) ? 'null' : '"' + obj.abschlussAllgemeinbildend.valueOf() + '"') + ',';
+		if (!obj.log) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.log.size(); i++) {
+				let elem = obj.log.get(i);
+				result += '"' + elem + '"';
+				if (i < obj.log.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<AbschlussErgebnisBerufsbildend>) : string {
+		let result = '{';
+		if (typeof obj.hatBSA !== "undefined") {
+			result += '"hatBSA" : ' + obj.hatBSA + ',';
+		}
+		if (typeof obj.note !== "undefined") {
+			result += '"note" : ' + obj.note + ',';
+		}
+		if (typeof obj.hatBA !== "undefined") {
+			result += '"hatBA" : ' + ((!obj.hatBA) ? 'null' : obj.hatBA.valueOf()) + ',';
+		}
+		if (typeof obj.abschlussAllgemeinbildend !== "undefined") {
+			result += '"abschlussAllgemeinbildend" : ' + ((!obj.abschlussAllgemeinbildend) ? 'null' : '"' + obj.abschlussAllgemeinbildend.valueOf() + '"') + ',';
+		}
+		if (typeof obj.log !== "undefined") {
+			if (!obj.log) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.log.size(); i++) {
+					let elem = obj.log.get(i);
+					result += '"' + elem + '"';
+					if (i < obj.log.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_abschluss_AbschlussErgebnisBerufsbildend(obj : unknown) : AbschlussErgebnisBerufsbildend {
+	return obj as AbschlussErgebnisBerufsbildend;
+}

+ 91 - 0
core/data/abschluss/GEAbschlussFach.ts

@@ -0,0 +1,91 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+
+export class GEAbschlussFach extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public bezeichnung : String | null = null;
+
+	public note : number = -1;
+
+	public istFremdsprache : Boolean | null = false;
+
+	public kursart : String | null = "";
+
+	public ausgleich : Boolean | null = false;
+
+	public ausgeglichen : Boolean | null = false;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.abschluss.GEAbschlussFach'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): GEAbschlussFach {
+		const obj = JSON.parse(json);
+		const result = new GEAbschlussFach();
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		if (typeof obj.note === "undefined")
+			 throw new Error('invalid json format, missing attribute note');
+		result.note = obj.note;
+		result.istFremdsprache = typeof obj.istFremdsprache === "undefined" ? null : obj.istFremdsprache;
+		result.kursart = typeof obj.kursart === "undefined" ? null : obj.kursart;
+		result.ausgleich = typeof obj.ausgleich === "undefined" ? null : obj.ausgleich;
+		result.ausgeglichen = typeof obj.ausgeglichen === "undefined" ? null : obj.ausgeglichen;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : GEAbschlussFach) : string {
+		let result = '{';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"note" : ' + obj.note + ',';
+		result += '"istFremdsprache" : ' + ((!obj.istFremdsprache) ? 'null' : obj.istFremdsprache.valueOf()) + ',';
+		result += '"kursart" : ' + ((!obj.kursart) ? 'null' : '"' + obj.kursart.valueOf() + '"') + ',';
+		result += '"ausgleich" : ' + ((!obj.ausgleich) ? 'null' : obj.ausgleich.valueOf()) + ',';
+		result += '"ausgeglichen" : ' + ((!obj.ausgeglichen) ? 'null' : obj.ausgeglichen.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<GEAbschlussFach>) : string {
+		let result = '{';
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.note !== "undefined") {
+			result += '"note" : ' + obj.note + ',';
+		}
+		if (typeof obj.istFremdsprache !== "undefined") {
+			result += '"istFremdsprache" : ' + ((!obj.istFremdsprache) ? 'null' : obj.istFremdsprache.valueOf()) + ',';
+		}
+		if (typeof obj.kursart !== "undefined") {
+			result += '"kursart" : ' + ((!obj.kursart) ? 'null' : '"' + obj.kursart.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ausgleich !== "undefined") {
+			result += '"ausgleich" : ' + ((!obj.ausgleich) ? 'null' : obj.ausgleich.valueOf()) + ',';
+		}
+		if (typeof obj.ausgeglichen !== "undefined") {
+			result += '"ausgeglichen" : ' + ((!obj.ausgeglichen) ? 'null' : obj.ausgeglichen.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach(obj : unknown) : GEAbschlussFach {
+	return obj as GEAbschlussFach;
+}

+ 100 - 0
core/data/abschluss/GEAbschlussFaecher.ts

@@ -0,0 +1,100 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { GEAbschlussFach, cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFach } from '../../../core/data/abschluss/GEAbschlussFach';
+import { List, cast_java_util_List } from '../../../java/util/List';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class GEAbschlussFaecher extends JavaObject {
+
+	public schuljahr : number = 0;
+
+	public abschnitt : number = 0;
+
+	public jahrgang : String | null = null;
+
+	public faecher : List<GEAbschlussFach> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.abschluss.GEAbschlussFaecher'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): GEAbschlussFaecher {
+		const obj = JSON.parse(json);
+		const result = new GEAbschlussFaecher();
+		if (typeof obj.schuljahr === "undefined")
+			 throw new Error('invalid json format, missing attribute schuljahr');
+		result.schuljahr = obj.schuljahr;
+		if (typeof obj.abschnitt === "undefined")
+			 throw new Error('invalid json format, missing attribute abschnitt');
+		result.abschnitt = obj.abschnitt;
+		result.jahrgang = typeof obj.jahrgang === "undefined" ? null : obj.jahrgang;
+		if (!!obj.faecher) {
+			for (let elem of obj.faecher) {
+				result.faecher?.add(GEAbschlussFach.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : GEAbschlussFaecher) : string {
+		let result = '{';
+		result += '"schuljahr" : ' + obj.schuljahr + ',';
+		result += '"abschnitt" : ' + obj.abschnitt + ',';
+		result += '"jahrgang" : ' + ((!obj.jahrgang) ? 'null' : '"' + obj.jahrgang.valueOf() + '"') + ',';
+		if (!obj.faecher) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.faecher.size(); i++) {
+				let elem = obj.faecher.get(i);
+				result += GEAbschlussFach.transpilerToJSON(elem);
+				if (i < obj.faecher.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<GEAbschlussFaecher>) : string {
+		let result = '{';
+		if (typeof obj.schuljahr !== "undefined") {
+			result += '"schuljahr" : ' + obj.schuljahr + ',';
+		}
+		if (typeof obj.abschnitt !== "undefined") {
+			result += '"abschnitt" : ' + obj.abschnitt + ',';
+		}
+		if (typeof obj.jahrgang !== "undefined") {
+			result += '"jahrgang" : ' + ((!obj.jahrgang) ? 'null' : '"' + obj.jahrgang.valueOf() + '"') + ',';
+		}
+		if (typeof obj.faecher !== "undefined") {
+			if (!obj.faecher) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.faecher.size(); i++) {
+					let elem = obj.faecher.get(i);
+					result += GEAbschlussFach.transpilerToJSON(elem);
+					if (i < obj.faecher.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_abschluss_GEAbschlussFaecher(obj : unknown) : GEAbschlussFaecher {
+	return obj as GEAbschlussFaecher;
+}

+ 102 - 0
core/data/benutzer/BenutzerListeEintrag.ts

@@ -0,0 +1,102 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class BenutzerListeEintrag extends JavaObject {
+
+	public id : number = -1;
+
+	public typ : number = 0;
+
+	public typID : number = -1;
+
+	public anzeigename : String = "";
+
+	public name : String = "";
+
+	public istAdmin : boolean = false;
+
+	public idCredentials : number = -1;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.benutzer.BenutzerListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): BenutzerListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new BenutzerListeEintrag();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.typ === "undefined")
+			 throw new Error('invalid json format, missing attribute typ');
+		result.typ = obj.typ;
+		if (typeof obj.typID === "undefined")
+			 throw new Error('invalid json format, missing attribute typID');
+		result.typID = obj.typID;
+		if (typeof obj.anzeigename === "undefined")
+			 throw new Error('invalid json format, missing attribute anzeigename');
+		result.anzeigename = obj.anzeigename;
+		if (typeof obj.name === "undefined")
+			 throw new Error('invalid json format, missing attribute name');
+		result.name = obj.name;
+		if (typeof obj.istAdmin === "undefined")
+			 throw new Error('invalid json format, missing attribute istAdmin');
+		result.istAdmin = obj.istAdmin;
+		if (typeof obj.idCredentials === "undefined")
+			 throw new Error('invalid json format, missing attribute idCredentials');
+		result.idCredentials = obj.idCredentials;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : BenutzerListeEintrag) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"typ" : ' + obj.typ + ',';
+		result += '"typID" : ' + obj.typID + ',';
+		result += '"anzeigename" : ' + '"' + obj.anzeigename.valueOf() + '"' + ',';
+		result += '"name" : ' + '"' + obj.name.valueOf() + '"' + ',';
+		result += '"istAdmin" : ' + obj.istAdmin + ',';
+		result += '"idCredentials" : ' + obj.idCredentials + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<BenutzerListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.typ !== "undefined") {
+			result += '"typ" : ' + obj.typ + ',';
+		}
+		if (typeof obj.typID !== "undefined") {
+			result += '"typID" : ' + obj.typID + ',';
+		}
+		if (typeof obj.anzeigename !== "undefined") {
+			result += '"anzeigename" : ' + '"' + obj.anzeigename.valueOf() + '"' + ',';
+		}
+		if (typeof obj.name !== "undefined") {
+			result += '"name" : ' + '"' + obj.name.valueOf() + '"' + ',';
+		}
+		if (typeof obj.istAdmin !== "undefined") {
+			result += '"istAdmin" : ' + obj.istAdmin + ',';
+		}
+		if (typeof obj.idCredentials !== "undefined") {
+			result += '"idCredentials" : ' + obj.idCredentials + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_benutzer_BenutzerListeEintrag(obj : unknown) : BenutzerListeEintrag {
+	return obj as BenutzerListeEintrag;
+}

+ 110 - 0
core/data/betrieb/BetriebAnsprechpartner.ts

@@ -0,0 +1,110 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class BetriebAnsprechpartner extends JavaObject {
+
+	public id : Number | null = null;
+
+	public betrieb_id : Number | null = null;
+
+	public name : String | null = null;
+
+	public vorname : String | null = null;
+
+	public anrede : String | null = null;
+
+	public telefon : String | null = null;
+
+	public email : String | null = null;
+
+	public abteilung : String | null = null;
+
+	public titel : String | null = null;
+
+	public GU_ID : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.betrieb.BetriebAnsprechpartner'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): BetriebAnsprechpartner {
+		const obj = JSON.parse(json);
+		const result = new BetriebAnsprechpartner();
+		result.id = typeof obj.id === "undefined" ? null : obj.id;
+		result.betrieb_id = typeof obj.betrieb_id === "undefined" ? null : obj.betrieb_id;
+		result.name = typeof obj.name === "undefined" ? null : obj.name;
+		result.vorname = typeof obj.vorname === "undefined" ? null : obj.vorname;
+		result.anrede = typeof obj.anrede === "undefined" ? null : obj.anrede;
+		result.telefon = typeof obj.telefon === "undefined" ? null : obj.telefon;
+		result.email = typeof obj.email === "undefined" ? null : obj.email;
+		result.abteilung = typeof obj.abteilung === "undefined" ? null : obj.abteilung;
+		result.titel = typeof obj.titel === "undefined" ? null : obj.titel;
+		result.GU_ID = typeof obj.GU_ID === "undefined" ? null : obj.GU_ID;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : BetriebAnsprechpartner) : string {
+		let result = '{';
+		result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		result += '"betrieb_id" : ' + ((!obj.betrieb_id) ? 'null' : obj.betrieb_id.valueOf()) + ',';
+		result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		result += '"telefon" : ' + ((!obj.telefon) ? 'null' : '"' + obj.telefon.valueOf() + '"') + ',';
+		result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		result += '"abteilung" : ' + ((!obj.abteilung) ? 'null' : '"' + obj.abteilung.valueOf() + '"') + ',';
+		result += '"titel" : ' + ((!obj.titel) ? 'null' : '"' + obj.titel.valueOf() + '"') + ',';
+		result += '"GU_ID" : ' + ((!obj.GU_ID) ? 'null' : '"' + obj.GU_ID.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<BetriebAnsprechpartner>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		}
+		if (typeof obj.betrieb_id !== "undefined") {
+			result += '"betrieb_id" : ' + ((!obj.betrieb_id) ? 'null' : obj.betrieb_id.valueOf()) + ',';
+		}
+		if (typeof obj.name !== "undefined") {
+			result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		}
+		if (typeof obj.vorname !== "undefined") {
+			result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.anrede !== "undefined") {
+			result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		}
+		if (typeof obj.telefon !== "undefined") {
+			result += '"telefon" : ' + ((!obj.telefon) ? 'null' : '"' + obj.telefon.valueOf() + '"') + ',';
+		}
+		if (typeof obj.email !== "undefined") {
+			result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		}
+		if (typeof obj.abteilung !== "undefined") {
+			result += '"abteilung" : ' + ((!obj.abteilung) ? 'null' : '"' + obj.abteilung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.titel !== "undefined") {
+			result += '"titel" : ' + ((!obj.titel) ? 'null' : '"' + obj.titel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.GU_ID !== "undefined") {
+			result += '"GU_ID" : ' + ((!obj.GU_ID) ? 'null' : '"' + obj.GU_ID.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_betrieb_BetriebAnsprechpartner(obj : unknown) : BetriebAnsprechpartner {
+	return obj as BetriebAnsprechpartner;
+}

+ 96 - 0
core/data/betrieb/BetriebListeEintrag.ts

@@ -0,0 +1,96 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class BetriebListeEintrag extends JavaObject {
+
+	public id : Number | null = null;
+
+	public adressArt : Number | null = null;
+
+	public name1 : String | null = null;
+
+	public strassenname : String | null = null;
+
+	public hausnr : String | null = null;
+
+	public hausnrzusatz : String | null = null;
+
+	public ort_id : Number | null = null;
+
+	public branche : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.betrieb.BetriebListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): BetriebListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new BetriebListeEintrag();
+		result.id = typeof obj.id === "undefined" ? null : obj.id;
+		result.adressArt = typeof obj.adressArt === "undefined" ? null : obj.adressArt;
+		result.name1 = typeof obj.name1 === "undefined" ? null : obj.name1;
+		result.strassenname = typeof obj.strassenname === "undefined" ? null : obj.strassenname;
+		result.hausnr = typeof obj.hausnr === "undefined" ? null : obj.hausnr;
+		result.hausnrzusatz = typeof obj.hausnrzusatz === "undefined" ? null : obj.hausnrzusatz;
+		result.ort_id = typeof obj.ort_id === "undefined" ? null : obj.ort_id;
+		result.branche = typeof obj.branche === "undefined" ? null : obj.branche;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : BetriebListeEintrag) : string {
+		let result = '{';
+		result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		result += '"adressArt" : ' + ((!obj.adressArt) ? 'null' : obj.adressArt.valueOf()) + ',';
+		result += '"name1" : ' + ((!obj.name1) ? 'null' : '"' + obj.name1.valueOf() + '"') + ',';
+		result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		result += '"hausnr" : ' + ((!obj.hausnr) ? 'null' : '"' + obj.hausnr.valueOf() + '"') + ',';
+		result += '"hausnrzusatz" : ' + ((!obj.hausnrzusatz) ? 'null' : '"' + obj.hausnrzusatz.valueOf() + '"') + ',';
+		result += '"ort_id" : ' + ((!obj.ort_id) ? 'null' : obj.ort_id.valueOf()) + ',';
+		result += '"branche" : ' + ((!obj.branche) ? 'null' : '"' + obj.branche.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<BetriebListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		}
+		if (typeof obj.adressArt !== "undefined") {
+			result += '"adressArt" : ' + ((!obj.adressArt) ? 'null' : obj.adressArt.valueOf()) + ',';
+		}
+		if (typeof obj.name1 !== "undefined") {
+			result += '"name1" : ' + ((!obj.name1) ? 'null' : '"' + obj.name1.valueOf() + '"') + ',';
+		}
+		if (typeof obj.strassenname !== "undefined") {
+			result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnr !== "undefined") {
+			result += '"hausnr" : ' + ((!obj.hausnr) ? 'null' : '"' + obj.hausnr.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnrzusatz !== "undefined") {
+			result += '"hausnrzusatz" : ' + ((!obj.hausnrzusatz) ? 'null' : '"' + obj.hausnrzusatz.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ort_id !== "undefined") {
+			result += '"ort_id" : ' + ((!obj.ort_id) ? 'null' : obj.ort_id.valueOf()) + ',';
+		}
+		if (typeof obj.branche !== "undefined") {
+			result += '"branche" : ' + ((!obj.branche) ? 'null' : '"' + obj.branche.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_betrieb_BetriebListeEintrag(obj : unknown) : BetriebListeEintrag {
+	return obj as BetriebListeEintrag;
+}

+ 266 - 0
core/data/betrieb/BetriebStammdaten.ts

@@ -0,0 +1,266 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { BetriebAnsprechpartner, cast_de_nrw_schule_svws_core_data_betrieb_BetriebAnsprechpartner } from '../../../core/data/betrieb/BetriebAnsprechpartner';
+
+export class BetriebStammdaten extends JavaObject {
+
+	public id : Number | null = null;
+
+	public adressArt : Number | null = null;
+
+	public name1 : String | null = null;
+
+	public name2 : String | null = null;
+
+	public strassenname : String | null = null;
+
+	public hausnr : String | null = null;
+
+	public hausnrzusatz : String | null = null;
+
+	public ort_id : Number | null = null;
+
+	public plz : String | null = null;
+
+	public telefon1 : String | null = null;
+
+	public telefon2 : String | null = null;
+
+	public fax : String | null = null;
+
+	public email : String | null = null;
+
+	public bemerkungen : String | null = null;
+
+	public sortierung : Number | null = null;
+
+	public ausbildungsbetrieb : Boolean | null = null;
+
+	public bietetPraktika : Boolean | null = null;
+
+	public branche : String | null = null;
+
+	public zusatz1 : String | null = null;
+
+	public zusatz2 : String | null = null;
+
+	public Sichtbar : Boolean | null = null;
+
+	public Aenderbar : Boolean | null = null;
+
+	public Massnahmentraeger : Boolean | null = null;
+
+	public BelehrungISG : Boolean | null = null;
+
+	public GU_ID : String | null = null;
+
+	public ErwFuehrungszeugnis : Boolean | null = null;
+
+	public ExtID : String | null = null;
+
+	public ansprechpartner : Vector<BetriebAnsprechpartner> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.betrieb.BetriebStammdaten'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): BetriebStammdaten {
+		const obj = JSON.parse(json);
+		const result = new BetriebStammdaten();
+		result.id = typeof obj.id === "undefined" ? null : obj.id;
+		result.adressArt = typeof obj.adressArt === "undefined" ? null : obj.adressArt;
+		result.name1 = typeof obj.name1 === "undefined" ? null : obj.name1;
+		result.name2 = typeof obj.name2 === "undefined" ? null : obj.name2;
+		result.strassenname = typeof obj.strassenname === "undefined" ? null : obj.strassenname;
+		result.hausnr = typeof obj.hausnr === "undefined" ? null : obj.hausnr;
+		result.hausnrzusatz = typeof obj.hausnrzusatz === "undefined" ? null : obj.hausnrzusatz;
+		result.ort_id = typeof obj.ort_id === "undefined" ? null : obj.ort_id;
+		result.plz = typeof obj.plz === "undefined" ? null : obj.plz;
+		result.telefon1 = typeof obj.telefon1 === "undefined" ? null : obj.telefon1;
+		result.telefon2 = typeof obj.telefon2 === "undefined" ? null : obj.telefon2;
+		result.fax = typeof obj.fax === "undefined" ? null : obj.fax;
+		result.email = typeof obj.email === "undefined" ? null : obj.email;
+		result.bemerkungen = typeof obj.bemerkungen === "undefined" ? null : obj.bemerkungen;
+		result.sortierung = typeof obj.sortierung === "undefined" ? null : obj.sortierung;
+		result.ausbildungsbetrieb = typeof obj.ausbildungsbetrieb === "undefined" ? null : obj.ausbildungsbetrieb;
+		result.bietetPraktika = typeof obj.bietetPraktika === "undefined" ? null : obj.bietetPraktika;
+		result.branche = typeof obj.branche === "undefined" ? null : obj.branche;
+		result.zusatz1 = typeof obj.zusatz1 === "undefined" ? null : obj.zusatz1;
+		result.zusatz2 = typeof obj.zusatz2 === "undefined" ? null : obj.zusatz2;
+		result.Sichtbar = typeof obj.Sichtbar === "undefined" ? null : obj.Sichtbar;
+		result.Aenderbar = typeof obj.Aenderbar === "undefined" ? null : obj.Aenderbar;
+		result.Massnahmentraeger = typeof obj.Massnahmentraeger === "undefined" ? null : obj.Massnahmentraeger;
+		result.BelehrungISG = typeof obj.BelehrungISG === "undefined" ? null : obj.BelehrungISG;
+		result.GU_ID = typeof obj.GU_ID === "undefined" ? null : obj.GU_ID;
+		result.ErwFuehrungszeugnis = typeof obj.ErwFuehrungszeugnis === "undefined" ? null : obj.ErwFuehrungszeugnis;
+		result.ExtID = typeof obj.ExtID === "undefined" ? null : obj.ExtID;
+		if (!!obj.ansprechpartner) {
+			for (let elem of obj.ansprechpartner) {
+				result.ansprechpartner?.add(BetriebAnsprechpartner.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : BetriebStammdaten) : string {
+		let result = '{';
+		result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		result += '"adressArt" : ' + ((!obj.adressArt) ? 'null' : obj.adressArt.valueOf()) + ',';
+		result += '"name1" : ' + ((!obj.name1) ? 'null' : '"' + obj.name1.valueOf() + '"') + ',';
+		result += '"name2" : ' + ((!obj.name2) ? 'null' : '"' + obj.name2.valueOf() + '"') + ',';
+		result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		result += '"hausnr" : ' + ((!obj.hausnr) ? 'null' : '"' + obj.hausnr.valueOf() + '"') + ',';
+		result += '"hausnrzusatz" : ' + ((!obj.hausnrzusatz) ? 'null' : '"' + obj.hausnrzusatz.valueOf() + '"') + ',';
+		result += '"ort_id" : ' + ((!obj.ort_id) ? 'null' : obj.ort_id.valueOf()) + ',';
+		result += '"plz" : ' + ((!obj.plz) ? 'null' : '"' + obj.plz.valueOf() + '"') + ',';
+		result += '"telefon1" : ' + ((!obj.telefon1) ? 'null' : '"' + obj.telefon1.valueOf() + '"') + ',';
+		result += '"telefon2" : ' + ((!obj.telefon2) ? 'null' : '"' + obj.telefon2.valueOf() + '"') + ',';
+		result += '"fax" : ' + ((!obj.fax) ? 'null' : '"' + obj.fax.valueOf() + '"') + ',';
+		result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : '"' + obj.bemerkungen.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + ((!obj.sortierung) ? 'null' : obj.sortierung.valueOf()) + ',';
+		result += '"ausbildungsbetrieb" : ' + ((!obj.ausbildungsbetrieb) ? 'null' : obj.ausbildungsbetrieb.valueOf()) + ',';
+		result += '"bietetPraktika" : ' + ((!obj.bietetPraktika) ? 'null' : obj.bietetPraktika.valueOf()) + ',';
+		result += '"branche" : ' + ((!obj.branche) ? 'null' : '"' + obj.branche.valueOf() + '"') + ',';
+		result += '"zusatz1" : ' + ((!obj.zusatz1) ? 'null' : '"' + obj.zusatz1.valueOf() + '"') + ',';
+		result += '"zusatz2" : ' + ((!obj.zusatz2) ? 'null' : '"' + obj.zusatz2.valueOf() + '"') + ',';
+		result += '"Sichtbar" : ' + ((!obj.Sichtbar) ? 'null' : obj.Sichtbar.valueOf()) + ',';
+		result += '"Aenderbar" : ' + ((!obj.Aenderbar) ? 'null' : obj.Aenderbar.valueOf()) + ',';
+		result += '"Massnahmentraeger" : ' + ((!obj.Massnahmentraeger) ? 'null' : obj.Massnahmentraeger.valueOf()) + ',';
+		result += '"BelehrungISG" : ' + ((!obj.BelehrungISG) ? 'null' : obj.BelehrungISG.valueOf()) + ',';
+		result += '"GU_ID" : ' + ((!obj.GU_ID) ? 'null' : '"' + obj.GU_ID.valueOf() + '"') + ',';
+		result += '"ErwFuehrungszeugnis" : ' + ((!obj.ErwFuehrungszeugnis) ? 'null' : obj.ErwFuehrungszeugnis.valueOf()) + ',';
+		result += '"ExtID" : ' + ((!obj.ExtID) ? 'null' : '"' + obj.ExtID.valueOf() + '"') + ',';
+		if (!obj.ansprechpartner) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.ansprechpartner.size(); i++) {
+				let elem = obj.ansprechpartner.get(i);
+				result += BetriebAnsprechpartner.transpilerToJSON(elem);
+				if (i < obj.ansprechpartner.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<BetriebStammdaten>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		}
+		if (typeof obj.adressArt !== "undefined") {
+			result += '"adressArt" : ' + ((!obj.adressArt) ? 'null' : obj.adressArt.valueOf()) + ',';
+		}
+		if (typeof obj.name1 !== "undefined") {
+			result += '"name1" : ' + ((!obj.name1) ? 'null' : '"' + obj.name1.valueOf() + '"') + ',';
+		}
+		if (typeof obj.name2 !== "undefined") {
+			result += '"name2" : ' + ((!obj.name2) ? 'null' : '"' + obj.name2.valueOf() + '"') + ',';
+		}
+		if (typeof obj.strassenname !== "undefined") {
+			result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnr !== "undefined") {
+			result += '"hausnr" : ' + ((!obj.hausnr) ? 'null' : '"' + obj.hausnr.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnrzusatz !== "undefined") {
+			result += '"hausnrzusatz" : ' + ((!obj.hausnrzusatz) ? 'null' : '"' + obj.hausnrzusatz.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ort_id !== "undefined") {
+			result += '"ort_id" : ' + ((!obj.ort_id) ? 'null' : obj.ort_id.valueOf()) + ',';
+		}
+		if (typeof obj.plz !== "undefined") {
+			result += '"plz" : ' + ((!obj.plz) ? 'null' : '"' + obj.plz.valueOf() + '"') + ',';
+		}
+		if (typeof obj.telefon1 !== "undefined") {
+			result += '"telefon1" : ' + ((!obj.telefon1) ? 'null' : '"' + obj.telefon1.valueOf() + '"') + ',';
+		}
+		if (typeof obj.telefon2 !== "undefined") {
+			result += '"telefon2" : ' + ((!obj.telefon2) ? 'null' : '"' + obj.telefon2.valueOf() + '"') + ',';
+		}
+		if (typeof obj.fax !== "undefined") {
+			result += '"fax" : ' + ((!obj.fax) ? 'null' : '"' + obj.fax.valueOf() + '"') + ',';
+		}
+		if (typeof obj.email !== "undefined") {
+			result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bemerkungen !== "undefined") {
+			result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : '"' + obj.bemerkungen.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + ((!obj.sortierung) ? 'null' : obj.sortierung.valueOf()) + ',';
+		}
+		if (typeof obj.ausbildungsbetrieb !== "undefined") {
+			result += '"ausbildungsbetrieb" : ' + ((!obj.ausbildungsbetrieb) ? 'null' : obj.ausbildungsbetrieb.valueOf()) + ',';
+		}
+		if (typeof obj.bietetPraktika !== "undefined") {
+			result += '"bietetPraktika" : ' + ((!obj.bietetPraktika) ? 'null' : obj.bietetPraktika.valueOf()) + ',';
+		}
+		if (typeof obj.branche !== "undefined") {
+			result += '"branche" : ' + ((!obj.branche) ? 'null' : '"' + obj.branche.valueOf() + '"') + ',';
+		}
+		if (typeof obj.zusatz1 !== "undefined") {
+			result += '"zusatz1" : ' + ((!obj.zusatz1) ? 'null' : '"' + obj.zusatz1.valueOf() + '"') + ',';
+		}
+		if (typeof obj.zusatz2 !== "undefined") {
+			result += '"zusatz2" : ' + ((!obj.zusatz2) ? 'null' : '"' + obj.zusatz2.valueOf() + '"') + ',';
+		}
+		if (typeof obj.Sichtbar !== "undefined") {
+			result += '"Sichtbar" : ' + ((!obj.Sichtbar) ? 'null' : obj.Sichtbar.valueOf()) + ',';
+		}
+		if (typeof obj.Aenderbar !== "undefined") {
+			result += '"Aenderbar" : ' + ((!obj.Aenderbar) ? 'null' : obj.Aenderbar.valueOf()) + ',';
+		}
+		if (typeof obj.Massnahmentraeger !== "undefined") {
+			result += '"Massnahmentraeger" : ' + ((!obj.Massnahmentraeger) ? 'null' : obj.Massnahmentraeger.valueOf()) + ',';
+		}
+		if (typeof obj.BelehrungISG !== "undefined") {
+			result += '"BelehrungISG" : ' + ((!obj.BelehrungISG) ? 'null' : obj.BelehrungISG.valueOf()) + ',';
+		}
+		if (typeof obj.GU_ID !== "undefined") {
+			result += '"GU_ID" : ' + ((!obj.GU_ID) ? 'null' : '"' + obj.GU_ID.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ErwFuehrungszeugnis !== "undefined") {
+			result += '"ErwFuehrungszeugnis" : ' + ((!obj.ErwFuehrungszeugnis) ? 'null' : obj.ErwFuehrungszeugnis.valueOf()) + ',';
+		}
+		if (typeof obj.ExtID !== "undefined") {
+			result += '"ExtID" : ' + ((!obj.ExtID) ? 'null' : '"' + obj.ExtID.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ansprechpartner !== "undefined") {
+			if (!obj.ansprechpartner) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.ansprechpartner.size(); i++) {
+					let elem = obj.ansprechpartner.get(i);
+					result += BetriebAnsprechpartner.transpilerToJSON(elem);
+					if (i < obj.ansprechpartner.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_betrieb_BetriebStammdaten(obj : unknown) : BetriebStammdaten {
+	return obj as BetriebStammdaten;
+}

+ 55 - 0
core/data/db/DBSchemaListeEintrag.ts

@@ -0,0 +1,55 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class DBSchemaListeEintrag extends JavaObject {
+
+	public name : String | null = null;
+
+	public isDefault : boolean = false;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.db.DBSchemaListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): DBSchemaListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new DBSchemaListeEintrag();
+		result.name = typeof obj.name === "undefined" ? null : obj.name;
+		if (typeof obj.isDefault === "undefined")
+			 throw new Error('invalid json format, missing attribute isDefault');
+		result.isDefault = obj.isDefault;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : DBSchemaListeEintrag) : string {
+		let result = '{';
+		result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		result += '"isDefault" : ' + obj.isDefault + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<DBSchemaListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.name !== "undefined") {
+			result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		}
+		if (typeof obj.isDefault !== "undefined") {
+			result += '"isDefault" : ' + obj.isDefault + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_db_DBSchemaListeEintrag(obj : unknown) : DBSchemaListeEintrag {
+	return obj as DBSchemaListeEintrag;
+}

+ 64 - 0
core/data/db/SchemaListeEintrag.ts

@@ -0,0 +1,64 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class SchemaListeEintrag extends JavaObject {
+
+	public name : String | null = null;
+
+	public revision : number = 0;
+
+	public isTainted : boolean = false;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.db.SchemaListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): SchemaListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new SchemaListeEintrag();
+		result.name = typeof obj.name === "undefined" ? null : obj.name;
+		if (typeof obj.revision === "undefined")
+			 throw new Error('invalid json format, missing attribute revision');
+		result.revision = obj.revision;
+		if (typeof obj.isTainted === "undefined")
+			 throw new Error('invalid json format, missing attribute isTainted');
+		result.isTainted = obj.isTainted;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : SchemaListeEintrag) : string {
+		let result = '{';
+		result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		result += '"revision" : ' + obj.revision + ',';
+		result += '"isTainted" : ' + obj.isTainted + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<SchemaListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.name !== "undefined") {
+			result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		}
+		if (typeof obj.revision !== "undefined") {
+			result += '"revision" : ' + obj.revision + ',';
+		}
+		if (typeof obj.isTainted !== "undefined") {
+			result += '"isTainted" : ' + obj.isTainted + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_db_SchemaListeEintrag(obj : unknown) : SchemaListeEintrag {
+	return obj as SchemaListeEintrag;
+}

+ 174 - 0
core/data/enm/ENMBKAbschluss.ts

@@ -0,0 +1,174 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ENMBKFach, cast_de_nrw_schule_svws_core_data_enm_ENMBKFach } from '../../../core/data/enm/ENMBKFach';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class ENMBKAbschluss extends JavaObject {
+
+	public hatZulassung : boolean = false;
+
+	public hatBestanden : boolean = false;
+
+	public hatZulassungErweiterteBeruflicheKenntnisse : boolean = false;
+
+	public hatErworbenErweiterteBeruflicheKenntnisse : boolean = false;
+
+	public notePraktischePruefung : String | null = null;
+
+	public noteKolloqium : String | null = null;
+
+	public hatZulassungBerufsabschlusspruefung : boolean = false;
+
+	public hatBestandenBerufsabschlusspruefung : boolean = false;
+
+	public themaAbschlussarbeit : String | null = null;
+
+	public istVorhandenBerufsabschlusspruefung : boolean = false;
+
+	public noteFachpraxis : String | null = null;
+
+	public istFachpraktischerTeilAusreichend : boolean = false;
+
+	public faecher : Vector<ENMBKFach> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMBKAbschluss'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMBKAbschluss {
+		const obj = JSON.parse(json);
+		const result = new ENMBKAbschluss();
+		if (typeof obj.hatZulassung === "undefined")
+			 throw new Error('invalid json format, missing attribute hatZulassung');
+		result.hatZulassung = obj.hatZulassung;
+		if (typeof obj.hatBestanden === "undefined")
+			 throw new Error('invalid json format, missing attribute hatBestanden');
+		result.hatBestanden = obj.hatBestanden;
+		if (typeof obj.hatZulassungErweiterteBeruflicheKenntnisse === "undefined")
+			 throw new Error('invalid json format, missing attribute hatZulassungErweiterteBeruflicheKenntnisse');
+		result.hatZulassungErweiterteBeruflicheKenntnisse = obj.hatZulassungErweiterteBeruflicheKenntnisse;
+		if (typeof obj.hatErworbenErweiterteBeruflicheKenntnisse === "undefined")
+			 throw new Error('invalid json format, missing attribute hatErworbenErweiterteBeruflicheKenntnisse');
+		result.hatErworbenErweiterteBeruflicheKenntnisse = obj.hatErworbenErweiterteBeruflicheKenntnisse;
+		result.notePraktischePruefung = typeof obj.notePraktischePruefung === "undefined" ? null : obj.notePraktischePruefung;
+		result.noteKolloqium = typeof obj.noteKolloqium === "undefined" ? null : obj.noteKolloqium;
+		if (typeof obj.hatZulassungBerufsabschlusspruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute hatZulassungBerufsabschlusspruefung');
+		result.hatZulassungBerufsabschlusspruefung = obj.hatZulassungBerufsabschlusspruefung;
+		if (typeof obj.hatBestandenBerufsabschlusspruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute hatBestandenBerufsabschlusspruefung');
+		result.hatBestandenBerufsabschlusspruefung = obj.hatBestandenBerufsabschlusspruefung;
+		result.themaAbschlussarbeit = typeof obj.themaAbschlussarbeit === "undefined" ? null : obj.themaAbschlussarbeit;
+		if (typeof obj.istVorhandenBerufsabschlusspruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute istVorhandenBerufsabschlusspruefung');
+		result.istVorhandenBerufsabschlusspruefung = obj.istVorhandenBerufsabschlusspruefung;
+		result.noteFachpraxis = typeof obj.noteFachpraxis === "undefined" ? null : obj.noteFachpraxis;
+		if (typeof obj.istFachpraktischerTeilAusreichend === "undefined")
+			 throw new Error('invalid json format, missing attribute istFachpraktischerTeilAusreichend');
+		result.istFachpraktischerTeilAusreichend = obj.istFachpraktischerTeilAusreichend;
+		if (!!obj.faecher) {
+			for (let elem of obj.faecher) {
+				result.faecher?.add(ENMBKFach.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMBKAbschluss) : string {
+		let result = '{';
+		result += '"hatZulassung" : ' + obj.hatZulassung + ',';
+		result += '"hatBestanden" : ' + obj.hatBestanden + ',';
+		result += '"hatZulassungErweiterteBeruflicheKenntnisse" : ' + obj.hatZulassungErweiterteBeruflicheKenntnisse + ',';
+		result += '"hatErworbenErweiterteBeruflicheKenntnisse" : ' + obj.hatErworbenErweiterteBeruflicheKenntnisse + ',';
+		result += '"notePraktischePruefung" : ' + ((!obj.notePraktischePruefung) ? 'null' : '"' + obj.notePraktischePruefung.valueOf() + '"') + ',';
+		result += '"noteKolloqium" : ' + ((!obj.noteKolloqium) ? 'null' : '"' + obj.noteKolloqium.valueOf() + '"') + ',';
+		result += '"hatZulassungBerufsabschlusspruefung" : ' + obj.hatZulassungBerufsabschlusspruefung + ',';
+		result += '"hatBestandenBerufsabschlusspruefung" : ' + obj.hatBestandenBerufsabschlusspruefung + ',';
+		result += '"themaAbschlussarbeit" : ' + ((!obj.themaAbschlussarbeit) ? 'null' : '"' + obj.themaAbschlussarbeit.valueOf() + '"') + ',';
+		result += '"istVorhandenBerufsabschlusspruefung" : ' + obj.istVorhandenBerufsabschlusspruefung + ',';
+		result += '"noteFachpraxis" : ' + ((!obj.noteFachpraxis) ? 'null' : '"' + obj.noteFachpraxis.valueOf() + '"') + ',';
+		result += '"istFachpraktischerTeilAusreichend" : ' + obj.istFachpraktischerTeilAusreichend + ',';
+		if (!obj.faecher) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.faecher.size(); i++) {
+				let elem = obj.faecher.get(i);
+				result += ENMBKFach.transpilerToJSON(elem);
+				if (i < obj.faecher.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMBKAbschluss>) : string {
+		let result = '{';
+		if (typeof obj.hatZulassung !== "undefined") {
+			result += '"hatZulassung" : ' + obj.hatZulassung + ',';
+		}
+		if (typeof obj.hatBestanden !== "undefined") {
+			result += '"hatBestanden" : ' + obj.hatBestanden + ',';
+		}
+		if (typeof obj.hatZulassungErweiterteBeruflicheKenntnisse !== "undefined") {
+			result += '"hatZulassungErweiterteBeruflicheKenntnisse" : ' + obj.hatZulassungErweiterteBeruflicheKenntnisse + ',';
+		}
+		if (typeof obj.hatErworbenErweiterteBeruflicheKenntnisse !== "undefined") {
+			result += '"hatErworbenErweiterteBeruflicheKenntnisse" : ' + obj.hatErworbenErweiterteBeruflicheKenntnisse + ',';
+		}
+		if (typeof obj.notePraktischePruefung !== "undefined") {
+			result += '"notePraktischePruefung" : ' + ((!obj.notePraktischePruefung) ? 'null' : '"' + obj.notePraktischePruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.noteKolloqium !== "undefined") {
+			result += '"noteKolloqium" : ' + ((!obj.noteKolloqium) ? 'null' : '"' + obj.noteKolloqium.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hatZulassungBerufsabschlusspruefung !== "undefined") {
+			result += '"hatZulassungBerufsabschlusspruefung" : ' + obj.hatZulassungBerufsabschlusspruefung + ',';
+		}
+		if (typeof obj.hatBestandenBerufsabschlusspruefung !== "undefined") {
+			result += '"hatBestandenBerufsabschlusspruefung" : ' + obj.hatBestandenBerufsabschlusspruefung + ',';
+		}
+		if (typeof obj.themaAbschlussarbeit !== "undefined") {
+			result += '"themaAbschlussarbeit" : ' + ((!obj.themaAbschlussarbeit) ? 'null' : '"' + obj.themaAbschlussarbeit.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istVorhandenBerufsabschlusspruefung !== "undefined") {
+			result += '"istVorhandenBerufsabschlusspruefung" : ' + obj.istVorhandenBerufsabschlusspruefung + ',';
+		}
+		if (typeof obj.noteFachpraxis !== "undefined") {
+			result += '"noteFachpraxis" : ' + ((!obj.noteFachpraxis) ? 'null' : '"' + obj.noteFachpraxis.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istFachpraktischerTeilAusreichend !== "undefined") {
+			result += '"istFachpraktischerTeilAusreichend" : ' + obj.istFachpraktischerTeilAusreichend + ',';
+		}
+		if (typeof obj.faecher !== "undefined") {
+			if (!obj.faecher) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.faecher.size(); i++) {
+					let elem = obj.faecher.get(i);
+					result += ENMBKFach.transpilerToJSON(elem);
+					if (i < obj.faecher.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMBKAbschluss(obj : unknown) : ENMBKAbschluss {
+	return obj as ENMBKAbschluss;
+}

+ 128 - 0
core/data/enm/ENMBKFach.ts

@@ -0,0 +1,128 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMBKFach extends JavaObject {
+
+	public fachID : number = 0;
+
+	public lehrerID : number = 0;
+
+	public istSchriftlich : boolean = false;
+
+	public vornote : String | null = null;
+
+	public noteSchriftlichePruefung : String | null = null;
+
+	public muendlichePruefung : boolean = false;
+
+	public muendlichePruefungFreiwillig : boolean = false;
+
+	public noteMuendlichePruefung : String | null = null;
+
+	public istSchriftlichBerufsabschluss : boolean = false;
+
+	public noteBerufsabschluss : String | null = null;
+
+	public abschlussnote : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMBKFach'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMBKFach {
+		const obj = JSON.parse(json);
+		const result = new ENMBKFach();
+		if (typeof obj.fachID === "undefined")
+			 throw new Error('invalid json format, missing attribute fachID');
+		result.fachID = obj.fachID;
+		if (typeof obj.lehrerID === "undefined")
+			 throw new Error('invalid json format, missing attribute lehrerID');
+		result.lehrerID = obj.lehrerID;
+		if (typeof obj.istSchriftlich === "undefined")
+			 throw new Error('invalid json format, missing attribute istSchriftlich');
+		result.istSchriftlich = obj.istSchriftlich;
+		result.vornote = typeof obj.vornote === "undefined" ? null : obj.vornote;
+		result.noteSchriftlichePruefung = typeof obj.noteSchriftlichePruefung === "undefined" ? null : obj.noteSchriftlichePruefung;
+		if (typeof obj.muendlichePruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute muendlichePruefung');
+		result.muendlichePruefung = obj.muendlichePruefung;
+		if (typeof obj.muendlichePruefungFreiwillig === "undefined")
+			 throw new Error('invalid json format, missing attribute muendlichePruefungFreiwillig');
+		result.muendlichePruefungFreiwillig = obj.muendlichePruefungFreiwillig;
+		result.noteMuendlichePruefung = typeof obj.noteMuendlichePruefung === "undefined" ? null : obj.noteMuendlichePruefung;
+		if (typeof obj.istSchriftlichBerufsabschluss === "undefined")
+			 throw new Error('invalid json format, missing attribute istSchriftlichBerufsabschluss');
+		result.istSchriftlichBerufsabschluss = obj.istSchriftlichBerufsabschluss;
+		result.noteBerufsabschluss = typeof obj.noteBerufsabschluss === "undefined" ? null : obj.noteBerufsabschluss;
+		result.abschlussnote = typeof obj.abschlussnote === "undefined" ? null : obj.abschlussnote;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMBKFach) : string {
+		let result = '{';
+		result += '"fachID" : ' + obj.fachID + ',';
+		result += '"lehrerID" : ' + obj.lehrerID + ',';
+		result += '"istSchriftlich" : ' + obj.istSchriftlich + ',';
+		result += '"vornote" : ' + ((!obj.vornote) ? 'null' : '"' + obj.vornote.valueOf() + '"') + ',';
+		result += '"noteSchriftlichePruefung" : ' + ((!obj.noteSchriftlichePruefung) ? 'null' : '"' + obj.noteSchriftlichePruefung.valueOf() + '"') + ',';
+		result += '"muendlichePruefung" : ' + obj.muendlichePruefung + ',';
+		result += '"muendlichePruefungFreiwillig" : ' + obj.muendlichePruefungFreiwillig + ',';
+		result += '"noteMuendlichePruefung" : ' + ((!obj.noteMuendlichePruefung) ? 'null' : '"' + obj.noteMuendlichePruefung.valueOf() + '"') + ',';
+		result += '"istSchriftlichBerufsabschluss" : ' + obj.istSchriftlichBerufsabschluss + ',';
+		result += '"noteBerufsabschluss" : ' + ((!obj.noteBerufsabschluss) ? 'null' : '"' + obj.noteBerufsabschluss.valueOf() + '"') + ',';
+		result += '"abschlussnote" : ' + ((!obj.abschlussnote) ? 'null' : '"' + obj.abschlussnote.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMBKFach>) : string {
+		let result = '{';
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + obj.fachID + ',';
+		}
+		if (typeof obj.lehrerID !== "undefined") {
+			result += '"lehrerID" : ' + obj.lehrerID + ',';
+		}
+		if (typeof obj.istSchriftlich !== "undefined") {
+			result += '"istSchriftlich" : ' + obj.istSchriftlich + ',';
+		}
+		if (typeof obj.vornote !== "undefined") {
+			result += '"vornote" : ' + ((!obj.vornote) ? 'null' : '"' + obj.vornote.valueOf() + '"') + ',';
+		}
+		if (typeof obj.noteSchriftlichePruefung !== "undefined") {
+			result += '"noteSchriftlichePruefung" : ' + ((!obj.noteSchriftlichePruefung) ? 'null' : '"' + obj.noteSchriftlichePruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.muendlichePruefung !== "undefined") {
+			result += '"muendlichePruefung" : ' + obj.muendlichePruefung + ',';
+		}
+		if (typeof obj.muendlichePruefungFreiwillig !== "undefined") {
+			result += '"muendlichePruefungFreiwillig" : ' + obj.muendlichePruefungFreiwillig + ',';
+		}
+		if (typeof obj.noteMuendlichePruefung !== "undefined") {
+			result += '"noteMuendlichePruefung" : ' + ((!obj.noteMuendlichePruefung) ? 'null' : '"' + obj.noteMuendlichePruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istSchriftlichBerufsabschluss !== "undefined") {
+			result += '"istSchriftlichBerufsabschluss" : ' + obj.istSchriftlichBerufsabschluss + ',';
+		}
+		if (typeof obj.noteBerufsabschluss !== "undefined") {
+			result += '"noteBerufsabschluss" : ' + ((!obj.noteBerufsabschluss) ? 'null' : '"' + obj.noteBerufsabschluss.valueOf() + '"') + ',';
+		}
+		if (typeof obj.abschlussnote !== "undefined") {
+			result += '"abschlussnote" : ' + ((!obj.abschlussnote) ? 'null' : '"' + obj.abschlussnote.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMBKFach(obj : unknown) : ENMBKFach {
+	return obj as ENMBKFach;
+}

+ 473 - 0
core/data/enm/ENMDaten.ts

@@ -0,0 +1,473 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ENMKlasse, cast_de_nrw_schule_svws_core_data_enm_ENMKlasse } from '../../../core/data/enm/ENMKlasse';
+import { ENMTeilleistungsart, cast_de_nrw_schule_svws_core_data_enm_ENMTeilleistungsart } from '../../../core/data/enm/ENMTeilleistungsart';
+import { ENMFach, cast_de_nrw_schule_svws_core_data_enm_ENMFach } from '../../../core/data/enm/ENMFach';
+import { ENMJahrgang, cast_de_nrw_schule_svws_core_data_enm_ENMJahrgang } from '../../../core/data/enm/ENMJahrgang';
+import { ENMLerngruppe, cast_de_nrw_schule_svws_core_data_enm_ENMLerngruppe } from '../../../core/data/enm/ENMLerngruppe';
+import { ENMLehrer, cast_de_nrw_schule_svws_core_data_enm_ENMLehrer } from '../../../core/data/enm/ENMLehrer';
+import { ENMSchueler, cast_de_nrw_schule_svws_core_data_enm_ENMSchueler } from '../../../core/data/enm/ENMSchueler';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { ENMNote, cast_de_nrw_schule_svws_core_data_enm_ENMNote } from '../../../core/data/enm/ENMNote';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { ENMFoerderschwerpunkt, cast_de_nrw_schule_svws_core_data_enm_ENMFoerderschwerpunkt } from '../../../core/data/enm/ENMFoerderschwerpunkt';
+import { ENMFloskelgruppe, cast_de_nrw_schule_svws_core_data_enm_ENMFloskelgruppe } from '../../../core/data/enm/ENMFloskelgruppe';
+
+export class ENMDaten extends JavaObject {
+
+	public enmRevision : number = -1;
+
+	public schuljahr : number = 0;
+
+	public anzahlAbschnitte : number = 0;
+
+	public aktuellerAbschnitt : number = 0;
+
+	public publicKey : String | null = null;
+
+	public lehrerID : number = 0;
+
+	public fehlstundenEingabe : boolean = false;
+
+	public fehlstundenSIFachbezogen : boolean = false;
+
+	public fehlstundenSIIFachbezogen : boolean = false;
+
+	public schulform : String | null = null;
+
+	public mailadresse : String | null = null;
+
+	public noten : Vector<ENMNote> = new Vector();
+
+	public foerderschwerpunkte : Vector<ENMFoerderschwerpunkt> = new Vector();
+
+	public jahrgaenge : Vector<ENMJahrgang> = new Vector();
+
+	public klassen : Vector<ENMKlasse> = new Vector();
+
+	public floskelgruppen : Vector<ENMFloskelgruppe> = new Vector();
+
+	public lehrer : Vector<ENMLehrer> = new Vector();
+
+	public faecher : Vector<ENMFach> = new Vector();
+
+	public teilleistungsarten : Vector<ENMTeilleistungsart> = new Vector();
+
+	public lerngruppen : Vector<ENMLerngruppe> = new Vector();
+
+	public schueler : Vector<ENMSchueler> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMDaten'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMDaten {
+		const obj = JSON.parse(json);
+		const result = new ENMDaten();
+		if (typeof obj.enmRevision === "undefined")
+			 throw new Error('invalid json format, missing attribute enmRevision');
+		result.enmRevision = obj.enmRevision;
+		if (typeof obj.schuljahr === "undefined")
+			 throw new Error('invalid json format, missing attribute schuljahr');
+		result.schuljahr = obj.schuljahr;
+		if (typeof obj.anzahlAbschnitte === "undefined")
+			 throw new Error('invalid json format, missing attribute anzahlAbschnitte');
+		result.anzahlAbschnitte = obj.anzahlAbschnitte;
+		if (typeof obj.aktuellerAbschnitt === "undefined")
+			 throw new Error('invalid json format, missing attribute aktuellerAbschnitt');
+		result.aktuellerAbschnitt = obj.aktuellerAbschnitt;
+		result.publicKey = typeof obj.publicKey === "undefined" ? null : obj.publicKey;
+		if (typeof obj.lehrerID === "undefined")
+			 throw new Error('invalid json format, missing attribute lehrerID');
+		result.lehrerID = obj.lehrerID;
+		if (typeof obj.fehlstundenEingabe === "undefined")
+			 throw new Error('invalid json format, missing attribute fehlstundenEingabe');
+		result.fehlstundenEingabe = obj.fehlstundenEingabe;
+		if (typeof obj.fehlstundenSIFachbezogen === "undefined")
+			 throw new Error('invalid json format, missing attribute fehlstundenSIFachbezogen');
+		result.fehlstundenSIFachbezogen = obj.fehlstundenSIFachbezogen;
+		if (typeof obj.fehlstundenSIIFachbezogen === "undefined")
+			 throw new Error('invalid json format, missing attribute fehlstundenSIIFachbezogen');
+		result.fehlstundenSIIFachbezogen = obj.fehlstundenSIIFachbezogen;
+		result.schulform = typeof obj.schulform === "undefined" ? null : obj.schulform;
+		result.mailadresse = typeof obj.mailadresse === "undefined" ? null : obj.mailadresse;
+		if (!!obj.noten) {
+			for (let elem of obj.noten) {
+				result.noten?.add(ENMNote.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.foerderschwerpunkte) {
+			for (let elem of obj.foerderschwerpunkte) {
+				result.foerderschwerpunkte?.add(ENMFoerderschwerpunkt.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.jahrgaenge) {
+			for (let elem of obj.jahrgaenge) {
+				result.jahrgaenge?.add(ENMJahrgang.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.klassen) {
+			for (let elem of obj.klassen) {
+				result.klassen?.add(ENMKlasse.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.floskelgruppen) {
+			for (let elem of obj.floskelgruppen) {
+				result.floskelgruppen?.add(ENMFloskelgruppe.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.lehrer) {
+			for (let elem of obj.lehrer) {
+				result.lehrer?.add(ENMLehrer.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.faecher) {
+			for (let elem of obj.faecher) {
+				result.faecher?.add(ENMFach.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.teilleistungsarten) {
+			for (let elem of obj.teilleistungsarten) {
+				result.teilleistungsarten?.add(ENMTeilleistungsart.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.lerngruppen) {
+			for (let elem of obj.lerngruppen) {
+				result.lerngruppen?.add(ENMLerngruppe.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (!!obj.schueler) {
+			for (let elem of obj.schueler) {
+				result.schueler?.add(ENMSchueler.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMDaten) : string {
+		let result = '{';
+		result += '"enmRevision" : ' + obj.enmRevision + ',';
+		result += '"schuljahr" : ' + obj.schuljahr + ',';
+		result += '"anzahlAbschnitte" : ' + obj.anzahlAbschnitte + ',';
+		result += '"aktuellerAbschnitt" : ' + obj.aktuellerAbschnitt + ',';
+		result += '"publicKey" : ' + ((!obj.publicKey) ? 'null' : '"' + obj.publicKey.valueOf() + '"') + ',';
+		result += '"lehrerID" : ' + obj.lehrerID + ',';
+		result += '"fehlstundenEingabe" : ' + obj.fehlstundenEingabe + ',';
+		result += '"fehlstundenSIFachbezogen" : ' + obj.fehlstundenSIFachbezogen + ',';
+		result += '"fehlstundenSIIFachbezogen" : ' + obj.fehlstundenSIIFachbezogen + ',';
+		result += '"schulform" : ' + ((!obj.schulform) ? 'null' : '"' + obj.schulform.valueOf() + '"') + ',';
+		result += '"mailadresse" : ' + ((!obj.mailadresse) ? 'null' : '"' + obj.mailadresse.valueOf() + '"') + ',';
+		if (!obj.noten) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.noten.size(); i++) {
+				let elem = obj.noten.get(i);
+				result += ENMNote.transpilerToJSON(elem);
+				if (i < obj.noten.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.foerderschwerpunkte) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.foerderschwerpunkte.size(); i++) {
+				let elem = obj.foerderschwerpunkte.get(i);
+				result += ENMFoerderschwerpunkt.transpilerToJSON(elem);
+				if (i < obj.foerderschwerpunkte.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.jahrgaenge) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.jahrgaenge.size(); i++) {
+				let elem = obj.jahrgaenge.get(i);
+				result += ENMJahrgang.transpilerToJSON(elem);
+				if (i < obj.jahrgaenge.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.klassen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.klassen.size(); i++) {
+				let elem = obj.klassen.get(i);
+				result += ENMKlasse.transpilerToJSON(elem);
+				if (i < obj.klassen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.floskelgruppen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.floskelgruppen.size(); i++) {
+				let elem = obj.floskelgruppen.get(i);
+				result += ENMFloskelgruppe.transpilerToJSON(elem);
+				if (i < obj.floskelgruppen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.lehrer) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.lehrer.size(); i++) {
+				let elem = obj.lehrer.get(i);
+				result += ENMLehrer.transpilerToJSON(elem);
+				if (i < obj.lehrer.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.faecher) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.faecher.size(); i++) {
+				let elem = obj.faecher.get(i);
+				result += ENMFach.transpilerToJSON(elem);
+				if (i < obj.faecher.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.teilleistungsarten) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.teilleistungsarten.size(); i++) {
+				let elem = obj.teilleistungsarten.get(i);
+				result += ENMTeilleistungsart.transpilerToJSON(elem);
+				if (i < obj.teilleistungsarten.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.lerngruppen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.lerngruppen.size(); i++) {
+				let elem = obj.lerngruppen.get(i);
+				result += ENMLerngruppe.transpilerToJSON(elem);
+				if (i < obj.lerngruppen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		if (!obj.schueler) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.schueler.size(); i++) {
+				let elem = obj.schueler.get(i);
+				result += ENMSchueler.transpilerToJSON(elem);
+				if (i < obj.schueler.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMDaten>) : string {
+		let result = '{';
+		if (typeof obj.enmRevision !== "undefined") {
+			result += '"enmRevision" : ' + obj.enmRevision + ',';
+		}
+		if (typeof obj.schuljahr !== "undefined") {
+			result += '"schuljahr" : ' + obj.schuljahr + ',';
+		}
+		if (typeof obj.anzahlAbschnitte !== "undefined") {
+			result += '"anzahlAbschnitte" : ' + obj.anzahlAbschnitte + ',';
+		}
+		if (typeof obj.aktuellerAbschnitt !== "undefined") {
+			result += '"aktuellerAbschnitt" : ' + obj.aktuellerAbschnitt + ',';
+		}
+		if (typeof obj.publicKey !== "undefined") {
+			result += '"publicKey" : ' + ((!obj.publicKey) ? 'null' : '"' + obj.publicKey.valueOf() + '"') + ',';
+		}
+		if (typeof obj.lehrerID !== "undefined") {
+			result += '"lehrerID" : ' + obj.lehrerID + ',';
+		}
+		if (typeof obj.fehlstundenEingabe !== "undefined") {
+			result += '"fehlstundenEingabe" : ' + obj.fehlstundenEingabe + ',';
+		}
+		if (typeof obj.fehlstundenSIFachbezogen !== "undefined") {
+			result += '"fehlstundenSIFachbezogen" : ' + obj.fehlstundenSIFachbezogen + ',';
+		}
+		if (typeof obj.fehlstundenSIIFachbezogen !== "undefined") {
+			result += '"fehlstundenSIIFachbezogen" : ' + obj.fehlstundenSIIFachbezogen + ',';
+		}
+		if (typeof obj.schulform !== "undefined") {
+			result += '"schulform" : ' + ((!obj.schulform) ? 'null' : '"' + obj.schulform.valueOf() + '"') + ',';
+		}
+		if (typeof obj.mailadresse !== "undefined") {
+			result += '"mailadresse" : ' + ((!obj.mailadresse) ? 'null' : '"' + obj.mailadresse.valueOf() + '"') + ',';
+		}
+		if (typeof obj.noten !== "undefined") {
+			if (!obj.noten) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.noten.size(); i++) {
+					let elem = obj.noten.get(i);
+					result += ENMNote.transpilerToJSON(elem);
+					if (i < obj.noten.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.foerderschwerpunkte !== "undefined") {
+			if (!obj.foerderschwerpunkte) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.foerderschwerpunkte.size(); i++) {
+					let elem = obj.foerderschwerpunkte.get(i);
+					result += ENMFoerderschwerpunkt.transpilerToJSON(elem);
+					if (i < obj.foerderschwerpunkte.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.jahrgaenge !== "undefined") {
+			if (!obj.jahrgaenge) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.jahrgaenge.size(); i++) {
+					let elem = obj.jahrgaenge.get(i);
+					result += ENMJahrgang.transpilerToJSON(elem);
+					if (i < obj.jahrgaenge.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.klassen !== "undefined") {
+			if (!obj.klassen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.klassen.size(); i++) {
+					let elem = obj.klassen.get(i);
+					result += ENMKlasse.transpilerToJSON(elem);
+					if (i < obj.klassen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.floskelgruppen !== "undefined") {
+			if (!obj.floskelgruppen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.floskelgruppen.size(); i++) {
+					let elem = obj.floskelgruppen.get(i);
+					result += ENMFloskelgruppe.transpilerToJSON(elem);
+					if (i < obj.floskelgruppen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.lehrer !== "undefined") {
+			if (!obj.lehrer) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.lehrer.size(); i++) {
+					let elem = obj.lehrer.get(i);
+					result += ENMLehrer.transpilerToJSON(elem);
+					if (i < obj.lehrer.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.faecher !== "undefined") {
+			if (!obj.faecher) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.faecher.size(); i++) {
+					let elem = obj.faecher.get(i);
+					result += ENMFach.transpilerToJSON(elem);
+					if (i < obj.faecher.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.teilleistungsarten !== "undefined") {
+			if (!obj.teilleistungsarten) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.teilleistungsarten.size(); i++) {
+					let elem = obj.teilleistungsarten.get(i);
+					result += ENMTeilleistungsart.transpilerToJSON(elem);
+					if (i < obj.teilleistungsarten.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.lerngruppen !== "undefined") {
+			if (!obj.lerngruppen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.lerngruppen.size(); i++) {
+					let elem = obj.lerngruppen.get(i);
+					result += ENMLerngruppe.transpilerToJSON(elem);
+					if (i < obj.lerngruppen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.schueler !== "undefined") {
+			if (!obj.schueler) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.schueler.size(); i++) {
+					let elem = obj.schueler.get(i);
+					result += ENMSchueler.transpilerToJSON(elem);
+					if (i < obj.schueler.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMDaten(obj : unknown) : ENMDaten {
+	return obj as ENMDaten;
+}

+ 80 - 0
core/data/enm/ENMFach.ts

@@ -0,0 +1,80 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMFach extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public kuerzelAnzeige : String | null = null;
+
+	public sortierung : number = 0;
+
+	public istFremdsprache : boolean = false;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMFach'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMFach {
+		const obj = JSON.parse(json);
+		const result = new ENMFach();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.kuerzelAnzeige = typeof obj.kuerzelAnzeige === "undefined" ? null : obj.kuerzelAnzeige;
+		if (typeof obj.sortierung === "undefined")
+			 throw new Error('invalid json format, missing attribute sortierung');
+		result.sortierung = obj.sortierung;
+		if (typeof obj.istFremdsprache === "undefined")
+			 throw new Error('invalid json format, missing attribute istFremdsprache');
+		result.istFremdsprache = obj.istFremdsprache;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMFach) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + obj.sortierung + ',';
+		result += '"istFremdsprache" : ' + obj.istFremdsprache + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMFach>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kuerzelAnzeige !== "undefined") {
+			result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + obj.sortierung + ',';
+		}
+		if (typeof obj.istFremdsprache !== "undefined") {
+			result += '"istFremdsprache" : ' + obj.istFremdsprache + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMFach(obj : unknown) : ENMFach {
+	return obj as ENMFach;
+}

+ 75 - 0
core/data/enm/ENMFloskel.ts

@@ -0,0 +1,75 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMFloskel extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public text : String | null = null;
+
+	public fachID : Number | null = null;
+
+	public niveau : Number | null = null;
+
+	public jahrgangID : Number | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMFloskel'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMFloskel {
+		const obj = JSON.parse(json);
+		const result = new ENMFloskel();
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.text = typeof obj.text === "undefined" ? null : obj.text;
+		result.fachID = typeof obj.fachID === "undefined" ? null : obj.fachID;
+		result.niveau = typeof obj.niveau === "undefined" ? null : obj.niveau;
+		result.jahrgangID = typeof obj.jahrgangID === "undefined" ? null : obj.jahrgangID;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMFloskel) : string {
+		let result = '{';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"text" : ' + ((!obj.text) ? 'null' : '"' + obj.text.valueOf() + '"') + ',';
+		result += '"fachID" : ' + ((!obj.fachID) ? 'null' : obj.fachID.valueOf()) + ',';
+		result += '"niveau" : ' + ((!obj.niveau) ? 'null' : obj.niveau.valueOf()) + ',';
+		result += '"jahrgangID" : ' + ((!obj.jahrgangID) ? 'null' : obj.jahrgangID.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMFloskel>) : string {
+		let result = '{';
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.text !== "undefined") {
+			result += '"text" : ' + ((!obj.text) ? 'null' : '"' + obj.text.valueOf() + '"') + ',';
+		}
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + ((!obj.fachID) ? 'null' : obj.fachID.valueOf()) + ',';
+		}
+		if (typeof obj.niveau !== "undefined") {
+			result += '"niveau" : ' + ((!obj.niveau) ? 'null' : obj.niveau.valueOf()) + ',';
+		}
+		if (typeof obj.jahrgangID !== "undefined") {
+			result += '"jahrgangID" : ' + ((!obj.jahrgangID) ? 'null' : obj.jahrgangID.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMFloskel(obj : unknown) : ENMFloskel {
+	return obj as ENMFloskel;
+}

+ 95 - 0
core/data/enm/ENMFloskelgruppe.ts

@@ -0,0 +1,95 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ENMFloskel, cast_de_nrw_schule_svws_core_data_enm_ENMFloskel } from '../../../core/data/enm/ENMFloskel';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class ENMFloskelgruppe extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public bezeichnung : String | null = null;
+
+	public hauptgruppe : String | null = null;
+
+	public readonly floskeln : Vector<ENMFloskel> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMFloskelgruppe'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMFloskelgruppe {
+		const obj = JSON.parse(json);
+		const result = new ENMFloskelgruppe();
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		result.hauptgruppe = typeof obj.hauptgruppe === "undefined" ? null : obj.hauptgruppe;
+		if (!!obj.floskeln) {
+			for (let elem of obj.floskeln) {
+				result.floskeln?.add(ENMFloskel.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMFloskelgruppe) : string {
+		let result = '{';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"hauptgruppe" : ' + ((!obj.hauptgruppe) ? 'null' : '"' + obj.hauptgruppe.valueOf() + '"') + ',';
+		if (!obj.floskeln) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.floskeln.size(); i++) {
+				let elem = obj.floskeln.get(i);
+				result += ENMFloskel.transpilerToJSON(elem);
+				if (i < obj.floskeln.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMFloskelgruppe>) : string {
+		let result = '{';
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hauptgruppe !== "undefined") {
+			result += '"hauptgruppe" : ' + ((!obj.hauptgruppe) ? 'null' : '"' + obj.hauptgruppe.valueOf() + '"') + ',';
+		}
+		if (typeof obj.floskeln !== "undefined") {
+			if (!obj.floskeln) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.floskeln.size(); i++) {
+					let elem = obj.floskeln.get(i);
+					result += ENMFloskel.transpilerToJSON(elem);
+					if (i < obj.floskeln.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMFloskelgruppe(obj : unknown) : ENMFloskelgruppe {
+	return obj as ENMFloskelgruppe;
+}

+ 53 - 0
core/data/enm/ENMFoerderschwerpunkt.ts

@@ -0,0 +1,53 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMFoerderschwerpunkt extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public beschreibung : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMFoerderschwerpunkt'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMFoerderschwerpunkt {
+		const obj = JSON.parse(json);
+		const result = new ENMFoerderschwerpunkt();
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.beschreibung = typeof obj.beschreibung === "undefined" ? null : obj.beschreibung;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMFoerderschwerpunkt) : string {
+		let result = '{';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"beschreibung" : ' + ((!obj.beschreibung) ? 'null' : '"' + obj.beschreibung.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMFoerderschwerpunkt>) : string {
+		let result = '{';
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.beschreibung !== "undefined") {
+			result += '"beschreibung" : ' + ((!obj.beschreibung) ? 'null' : '"' + obj.beschreibung.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMFoerderschwerpunkt(obj : unknown) : ENMFoerderschwerpunkt {
+	return obj as ENMFoerderschwerpunkt;
+}

+ 85 - 0
core/data/enm/ENMJahrgang.ts

@@ -0,0 +1,85 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMJahrgang extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public kuerzelAnzeige : String | null = null;
+
+	public beschreibung : String | null = null;
+
+	public stufe : String | null = null;
+
+	public sortierung : number = 0;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMJahrgang'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMJahrgang {
+		const obj = JSON.parse(json);
+		const result = new ENMJahrgang();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.kuerzelAnzeige = typeof obj.kuerzelAnzeige === "undefined" ? null : obj.kuerzelAnzeige;
+		result.beschreibung = typeof obj.beschreibung === "undefined" ? null : obj.beschreibung;
+		result.stufe = typeof obj.stufe === "undefined" ? null : obj.stufe;
+		if (typeof obj.sortierung === "undefined")
+			 throw new Error('invalid json format, missing attribute sortierung');
+		result.sortierung = obj.sortierung;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMJahrgang) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		result += '"beschreibung" : ' + ((!obj.beschreibung) ? 'null' : '"' + obj.beschreibung.valueOf() + '"') + ',';
+		result += '"stufe" : ' + ((!obj.stufe) ? 'null' : '"' + obj.stufe.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + obj.sortierung + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMJahrgang>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kuerzelAnzeige !== "undefined") {
+			result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		}
+		if (typeof obj.beschreibung !== "undefined") {
+			result += '"beschreibung" : ' + ((!obj.beschreibung) ? 'null' : '"' + obj.beschreibung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.stufe !== "undefined") {
+			result += '"stufe" : ' + ((!obj.stufe) ? 'null' : '"' + obj.stufe.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + obj.sortierung + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMJahrgang(obj : unknown) : ENMJahrgang {
+	return obj as ENMJahrgang;
+}

+ 106 - 0
core/data/enm/ENMKlasse.ts

@@ -0,0 +1,106 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class ENMKlasse extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public kuerzelAnzeige : String | null = null;
+
+	public sortierung : number = 0;
+
+	public klassenlehrer : Vector<Number> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMKlasse'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMKlasse {
+		const obj = JSON.parse(json);
+		const result = new ENMKlasse();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.kuerzelAnzeige = typeof obj.kuerzelAnzeige === "undefined" ? null : obj.kuerzelAnzeige;
+		if (typeof obj.sortierung === "undefined")
+			 throw new Error('invalid json format, missing attribute sortierung');
+		result.sortierung = obj.sortierung;
+		if (!!obj.klassenlehrer) {
+			for (let elem of obj.klassenlehrer) {
+				result.klassenlehrer?.add(elem);
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMKlasse) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + obj.sortierung + ',';
+		if (!obj.klassenlehrer) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.klassenlehrer.size(); i++) {
+				let elem = obj.klassenlehrer.get(i);
+				result += elem;
+				if (i < obj.klassenlehrer.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMKlasse>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kuerzelAnzeige !== "undefined") {
+			result += '"kuerzelAnzeige" : ' + ((!obj.kuerzelAnzeige) ? 'null' : '"' + obj.kuerzelAnzeige.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + obj.sortierung + ',';
+		}
+		if (typeof obj.klassenlehrer !== "undefined") {
+			if (!obj.klassenlehrer) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.klassenlehrer.size(); i++) {
+					let elem = obj.klassenlehrer.get(i);
+					result += elem;
+					if (i < obj.klassenlehrer.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMKlasse(obj : unknown) : ENMKlasse {
+	return obj as ENMKlasse;
+}

+ 76 - 0
core/data/enm/ENMLehrer.ts

@@ -0,0 +1,76 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMLehrer extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public nachname : String | null = null;
+
+	public vorname : String | null = null;
+
+	public eMailDienstlich : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMLehrer'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMLehrer {
+		const obj = JSON.parse(json);
+		const result = new ENMLehrer();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.nachname = typeof obj.nachname === "undefined" ? null : obj.nachname;
+		result.vorname = typeof obj.vorname === "undefined" ? null : obj.vorname;
+		result.eMailDienstlich = typeof obj.eMailDienstlich === "undefined" ? null : obj.eMailDienstlich;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMLehrer) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		result += '"eMailDienstlich" : ' + ((!obj.eMailDienstlich) ? 'null' : '"' + obj.eMailDienstlich.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMLehrer>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.nachname !== "undefined") {
+			result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.vorname !== "undefined") {
+			result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.eMailDienstlich !== "undefined") {
+			result += '"eMailDienstlich" : ' + ((!obj.eMailDienstlich) ? 'null' : '"' + obj.eMailDienstlich.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMLehrer(obj : unknown) : ENMLehrer {
+	return obj as ENMLehrer;
+}

+ 143 - 0
core/data/enm/ENMLeistung.ts

@@ -0,0 +1,143 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { ENMTeilleistung, cast_de_nrw_schule_svws_core_data_enm_ENMTeilleistung } from '../../../core/data/enm/ENMTeilleistung';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class ENMLeistung extends JavaObject {
+
+	public id : number = 0;
+
+	public lerngruppenID : number = 0;
+
+	public note : String | null = null;
+
+	public istSchriftlich : Boolean | null = null;
+
+	public abiturfach : Number | null = null;
+
+	public fehlstundenGesamt : Number | null = null;
+
+	public fehlstundenUnentschuldigt : Number | null = null;
+
+	public fachbezogeneBemerkungen : String | null = null;
+
+	public neueZuweisungKursart : String | null = null;
+
+	public teilleistungen : Vector<ENMTeilleistung> = new Vector();
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMLeistung'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMLeistung {
+		const obj = JSON.parse(json);
+		const result = new ENMLeistung();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.lerngruppenID === "undefined")
+			 throw new Error('invalid json format, missing attribute lerngruppenID');
+		result.lerngruppenID = obj.lerngruppenID;
+		result.note = typeof obj.note === "undefined" ? null : obj.note;
+		result.istSchriftlich = typeof obj.istSchriftlich === "undefined" ? null : obj.istSchriftlich;
+		result.abiturfach = typeof obj.abiturfach === "undefined" ? null : obj.abiturfach;
+		result.fehlstundenGesamt = typeof obj.fehlstundenGesamt === "undefined" ? null : obj.fehlstundenGesamt;
+		result.fehlstundenUnentschuldigt = typeof obj.fehlstundenUnentschuldigt === "undefined" ? null : obj.fehlstundenUnentschuldigt;
+		result.fachbezogeneBemerkungen = typeof obj.fachbezogeneBemerkungen === "undefined" ? null : obj.fachbezogeneBemerkungen;
+		result.neueZuweisungKursart = typeof obj.neueZuweisungKursart === "undefined" ? null : obj.neueZuweisungKursart;
+		if (!!obj.teilleistungen) {
+			for (let elem of obj.teilleistungen) {
+				result.teilleistungen?.add(ENMTeilleistung.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMLeistung) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"lerngruppenID" : ' + obj.lerngruppenID + ',';
+		result += '"note" : ' + ((!obj.note) ? 'null' : '"' + obj.note.valueOf() + '"') + ',';
+		result += '"istSchriftlich" : ' + ((!obj.istSchriftlich) ? 'null' : obj.istSchriftlich.valueOf()) + ',';
+		result += '"abiturfach" : ' + ((!obj.abiturfach) ? 'null' : obj.abiturfach.valueOf()) + ',';
+		result += '"fehlstundenGesamt" : ' + ((!obj.fehlstundenGesamt) ? 'null' : obj.fehlstundenGesamt.valueOf()) + ',';
+		result += '"fehlstundenUnentschuldigt" : ' + ((!obj.fehlstundenUnentschuldigt) ? 'null' : obj.fehlstundenUnentschuldigt.valueOf()) + ',';
+		result += '"fachbezogeneBemerkungen" : ' + ((!obj.fachbezogeneBemerkungen) ? 'null' : '"' + obj.fachbezogeneBemerkungen.valueOf() + '"') + ',';
+		result += '"neueZuweisungKursart" : ' + ((!obj.neueZuweisungKursart) ? 'null' : '"' + obj.neueZuweisungKursart.valueOf() + '"') + ',';
+		if (!obj.teilleistungen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.teilleistungen.size(); i++) {
+				let elem = obj.teilleistungen.get(i);
+				result += ENMTeilleistung.transpilerToJSON(elem);
+				if (i < obj.teilleistungen.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMLeistung>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.lerngruppenID !== "undefined") {
+			result += '"lerngruppenID" : ' + obj.lerngruppenID + ',';
+		}
+		if (typeof obj.note !== "undefined") {
+			result += '"note" : ' + ((!obj.note) ? 'null' : '"' + obj.note.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istSchriftlich !== "undefined") {
+			result += '"istSchriftlich" : ' + ((!obj.istSchriftlich) ? 'null' : obj.istSchriftlich.valueOf()) + ',';
+		}
+		if (typeof obj.abiturfach !== "undefined") {
+			result += '"abiturfach" : ' + ((!obj.abiturfach) ? 'null' : obj.abiturfach.valueOf()) + ',';
+		}
+		if (typeof obj.fehlstundenGesamt !== "undefined") {
+			result += '"fehlstundenGesamt" : ' + ((!obj.fehlstundenGesamt) ? 'null' : obj.fehlstundenGesamt.valueOf()) + ',';
+		}
+		if (typeof obj.fehlstundenUnentschuldigt !== "undefined") {
+			result += '"fehlstundenUnentschuldigt" : ' + ((!obj.fehlstundenUnentschuldigt) ? 'null' : obj.fehlstundenUnentschuldigt.valueOf()) + ',';
+		}
+		if (typeof obj.fachbezogeneBemerkungen !== "undefined") {
+			result += '"fachbezogeneBemerkungen" : ' + ((!obj.fachbezogeneBemerkungen) ? 'null' : '"' + obj.fachbezogeneBemerkungen.valueOf() + '"') + ',';
+		}
+		if (typeof obj.neueZuweisungKursart !== "undefined") {
+			result += '"neueZuweisungKursart" : ' + ((!obj.neueZuweisungKursart) ? 'null' : '"' + obj.neueZuweisungKursart.valueOf() + '"') + ',';
+		}
+		if (typeof obj.teilleistungen !== "undefined") {
+			if (!obj.teilleistungen) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.teilleistungen.size(); i++) {
+					let elem = obj.teilleistungen.get(i);
+					result += ENMTeilleistung.transpilerToJSON(elem);
+					if (i < obj.teilleistungen.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMLeistung(obj : unknown) : ENMLeistung {
+	return obj as ENMLeistung;
+}

+ 88 - 0
core/data/enm/ENMLeistungBemerkungen.ts

@@ -0,0 +1,88 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMLeistungBemerkungen extends JavaObject {
+
+	public ASV : String | null = null;
+
+	public AUE : String | null = null;
+
+	public ZB : String | null = null;
+
+	public LELS : String | null = null;
+
+	public schulformEmpf : String | null = null;
+
+	public individuelleVersetzungsbemerkungen : String | null = null;
+
+	public foerderbemerkungen : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMLeistungBemerkungen'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMLeistungBemerkungen {
+		const obj = JSON.parse(json);
+		const result = new ENMLeistungBemerkungen();
+		result.ASV = typeof obj.ASV === "undefined" ? null : obj.ASV;
+		result.AUE = typeof obj.AUE === "undefined" ? null : obj.AUE;
+		result.ZB = typeof obj.ZB === "undefined" ? null : obj.ZB;
+		result.LELS = typeof obj.LELS === "undefined" ? null : obj.LELS;
+		result.schulformEmpf = typeof obj.schulformEmpf === "undefined" ? null : obj.schulformEmpf;
+		result.individuelleVersetzungsbemerkungen = typeof obj.individuelleVersetzungsbemerkungen === "undefined" ? null : obj.individuelleVersetzungsbemerkungen;
+		result.foerderbemerkungen = typeof obj.foerderbemerkungen === "undefined" ? null : obj.foerderbemerkungen;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMLeistungBemerkungen) : string {
+		let result = '{';
+		result += '"ASV" : ' + ((!obj.ASV) ? 'null' : '"' + obj.ASV.valueOf() + '"') + ',';
+		result += '"AUE" : ' + ((!obj.AUE) ? 'null' : '"' + obj.AUE.valueOf() + '"') + ',';
+		result += '"ZB" : ' + ((!obj.ZB) ? 'null' : '"' + obj.ZB.valueOf() + '"') + ',';
+		result += '"LELS" : ' + ((!obj.LELS) ? 'null' : '"' + obj.LELS.valueOf() + '"') + ',';
+		result += '"schulformEmpf" : ' + ((!obj.schulformEmpf) ? 'null' : '"' + obj.schulformEmpf.valueOf() + '"') + ',';
+		result += '"individuelleVersetzungsbemerkungen" : ' + ((!obj.individuelleVersetzungsbemerkungen) ? 'null' : '"' + obj.individuelleVersetzungsbemerkungen.valueOf() + '"') + ',';
+		result += '"foerderbemerkungen" : ' + ((!obj.foerderbemerkungen) ? 'null' : '"' + obj.foerderbemerkungen.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMLeistungBemerkungen>) : string {
+		let result = '{';
+		if (typeof obj.ASV !== "undefined") {
+			result += '"ASV" : ' + ((!obj.ASV) ? 'null' : '"' + obj.ASV.valueOf() + '"') + ',';
+		}
+		if (typeof obj.AUE !== "undefined") {
+			result += '"AUE" : ' + ((!obj.AUE) ? 'null' : '"' + obj.AUE.valueOf() + '"') + ',';
+		}
+		if (typeof obj.ZB !== "undefined") {
+			result += '"ZB" : ' + ((!obj.ZB) ? 'null' : '"' + obj.ZB.valueOf() + '"') + ',';
+		}
+		if (typeof obj.LELS !== "undefined") {
+			result += '"LELS" : ' + ((!obj.LELS) ? 'null' : '"' + obj.LELS.valueOf() + '"') + ',';
+		}
+		if (typeof obj.schulformEmpf !== "undefined") {
+			result += '"schulformEmpf" : ' + ((!obj.schulformEmpf) ? 'null' : '"' + obj.schulformEmpf.valueOf() + '"') + ',';
+		}
+		if (typeof obj.individuelleVersetzungsbemerkungen !== "undefined") {
+			result += '"individuelleVersetzungsbemerkungen" : ' + ((!obj.individuelleVersetzungsbemerkungen) ? 'null' : '"' + obj.individuelleVersetzungsbemerkungen.valueOf() + '"') + ',';
+		}
+		if (typeof obj.foerderbemerkungen !== "undefined") {
+			result += '"foerderbemerkungen" : ' + ((!obj.foerderbemerkungen) ? 'null' : '"' + obj.foerderbemerkungen.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMLeistungBemerkungen(obj : unknown) : ENMLeistungBemerkungen {
+	return obj as ENMLeistungBemerkungen;
+}

+ 83 - 0
core/data/enm/ENMLernabschnitt.ts

@@ -0,0 +1,83 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMLernabschnitt extends JavaObject {
+
+	public id : number = 0;
+
+	public pruefungsordnung : String | null = null;
+
+	public lernbereich1note : String | null = null;
+
+	public lernbereich2note : String | null = null;
+
+	public foerderschwerpunkt1 : String | null = null;
+
+	public foerderschwerpunkt2 : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMLernabschnitt'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMLernabschnitt {
+		const obj = JSON.parse(json);
+		const result = new ENMLernabschnitt();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.pruefungsordnung = typeof obj.pruefungsordnung === "undefined" ? null : obj.pruefungsordnung;
+		result.lernbereich1note = typeof obj.lernbereich1note === "undefined" ? null : obj.lernbereich1note;
+		result.lernbereich2note = typeof obj.lernbereich2note === "undefined" ? null : obj.lernbereich2note;
+		result.foerderschwerpunkt1 = typeof obj.foerderschwerpunkt1 === "undefined" ? null : obj.foerderschwerpunkt1;
+		result.foerderschwerpunkt2 = typeof obj.foerderschwerpunkt2 === "undefined" ? null : obj.foerderschwerpunkt2;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMLernabschnitt) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"pruefungsordnung" : ' + ((!obj.pruefungsordnung) ? 'null' : '"' + obj.pruefungsordnung.valueOf() + '"') + ',';
+		result += '"lernbereich1note" : ' + ((!obj.lernbereich1note) ? 'null' : '"' + obj.lernbereich1note.valueOf() + '"') + ',';
+		result += '"lernbereich2note" : ' + ((!obj.lernbereich2note) ? 'null' : '"' + obj.lernbereich2note.valueOf() + '"') + ',';
+		result += '"foerderschwerpunkt1" : ' + ((!obj.foerderschwerpunkt1) ? 'null' : '"' + obj.foerderschwerpunkt1.valueOf() + '"') + ',';
+		result += '"foerderschwerpunkt2" : ' + ((!obj.foerderschwerpunkt2) ? 'null' : '"' + obj.foerderschwerpunkt2.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMLernabschnitt>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.pruefungsordnung !== "undefined") {
+			result += '"pruefungsordnung" : ' + ((!obj.pruefungsordnung) ? 'null' : '"' + obj.pruefungsordnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.lernbereich1note !== "undefined") {
+			result += '"lernbereich1note" : ' + ((!obj.lernbereich1note) ? 'null' : '"' + obj.lernbereich1note.valueOf() + '"') + ',';
+		}
+		if (typeof obj.lernbereich2note !== "undefined") {
+			result += '"lernbereich2note" : ' + ((!obj.lernbereich2note) ? 'null' : '"' + obj.lernbereich2note.valueOf() + '"') + ',';
+		}
+		if (typeof obj.foerderschwerpunkt1 !== "undefined") {
+			result += '"foerderschwerpunkt1" : ' + ((!obj.foerderschwerpunkt1) ? 'null' : '"' + obj.foerderschwerpunkt1.valueOf() + '"') + ',';
+		}
+		if (typeof obj.foerderschwerpunkt2 !== "undefined") {
+			result += '"foerderschwerpunkt2" : ' + ((!obj.foerderschwerpunkt2) ? 'null' : '"' + obj.foerderschwerpunkt2.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMLernabschnitt(obj : unknown) : ENMLernabschnitt {
+	return obj as ENMLernabschnitt;
+}

+ 139 - 0
core/data/enm/ENMLerngruppe.ts

@@ -0,0 +1,139 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+
+export class ENMLerngruppe extends JavaObject {
+
+	public id : number = 0;
+
+	public kID : number = 0;
+
+	public fachID : number = 0;
+
+	public kursartID : Number | null = null;
+
+	public bezeichnung : String | null = null;
+
+	public kursartKuerzel : String | null = null;
+
+	public bilingualeSprache : String | null = null;
+
+	public lehrerID : Vector<Number> = new Vector();
+
+	public wochenstunden : number = 0;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMLerngruppe'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMLerngruppe {
+		const obj = JSON.parse(json);
+		const result = new ENMLerngruppe();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.kID === "undefined")
+			 throw new Error('invalid json format, missing attribute kID');
+		result.kID = obj.kID;
+		if (typeof obj.fachID === "undefined")
+			 throw new Error('invalid json format, missing attribute fachID');
+		result.fachID = obj.fachID;
+		result.kursartID = typeof obj.kursartID === "undefined" ? null : obj.kursartID;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		result.kursartKuerzel = typeof obj.kursartKuerzel === "undefined" ? null : obj.kursartKuerzel;
+		result.bilingualeSprache = typeof obj.bilingualeSprache === "undefined" ? null : obj.bilingualeSprache;
+		if (!!obj.lehrerID) {
+			for (let elem of obj.lehrerID) {
+				result.lehrerID?.add(elem);
+			}
+		}
+		if (typeof obj.wochenstunden === "undefined")
+			 throw new Error('invalid json format, missing attribute wochenstunden');
+		result.wochenstunden = obj.wochenstunden;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMLerngruppe) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kID" : ' + obj.kID + ',';
+		result += '"fachID" : ' + obj.fachID + ',';
+		result += '"kursartID" : ' + ((!obj.kursartID) ? 'null' : obj.kursartID.valueOf()) + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"kursartKuerzel" : ' + ((!obj.kursartKuerzel) ? 'null' : '"' + obj.kursartKuerzel.valueOf() + '"') + ',';
+		result += '"bilingualeSprache" : ' + ((!obj.bilingualeSprache) ? 'null' : '"' + obj.bilingualeSprache.valueOf() + '"') + ',';
+		if (!obj.lehrerID) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.lehrerID.size(); i++) {
+				let elem = obj.lehrerID.get(i);
+				result += elem;
+				if (i < obj.lehrerID.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result += '"wochenstunden" : ' + obj.wochenstunden + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMLerngruppe>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kID !== "undefined") {
+			result += '"kID" : ' + obj.kID + ',';
+		}
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + obj.fachID + ',';
+		}
+		if (typeof obj.kursartID !== "undefined") {
+			result += '"kursartID" : ' + ((!obj.kursartID) ? 'null' : obj.kursartID.valueOf()) + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kursartKuerzel !== "undefined") {
+			result += '"kursartKuerzel" : ' + ((!obj.kursartKuerzel) ? 'null' : '"' + obj.kursartKuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bilingualeSprache !== "undefined") {
+			result += '"bilingualeSprache" : ' + ((!obj.bilingualeSprache) ? 'null' : '"' + obj.bilingualeSprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.lehrerID !== "undefined") {
+			if (!obj.lehrerID) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.lehrerID.size(); i++) {
+					let elem = obj.lehrerID.get(i);
+					result += elem;
+					if (i < obj.lehrerID.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.wochenstunden !== "undefined") {
+			result += '"wochenstunden" : ' + obj.wochenstunden + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMLerngruppe(obj : unknown) : ENMLerngruppe {
+	return obj as ENMLerngruppe;
+}

+ 61 - 0
core/data/enm/ENMNote.ts

@@ -0,0 +1,61 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMNote extends JavaObject {
+
+	public kuerzel : String | null = null;
+
+	public notenpunkte : Number | null = null;
+
+	public text : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMNote'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMNote {
+		const obj = JSON.parse(json);
+		const result = new ENMNote();
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.notenpunkte = typeof obj.notenpunkte === "undefined" ? null : obj.notenpunkte;
+		result.text = typeof obj.text === "undefined" ? null : obj.text;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMNote) : string {
+		let result = '{';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"notenpunkte" : ' + ((!obj.notenpunkte) ? 'null' : obj.notenpunkte.valueOf()) + ',';
+		result += '"text" : ' + ((!obj.text) ? 'null' : '"' + obj.text.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMNote>) : string {
+		let result = '{';
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.notenpunkte !== "undefined") {
+			result += '"notenpunkte" : ' + ((!obj.notenpunkte) ? 'null' : obj.notenpunkte.valueOf()) + ',';
+		}
+		if (typeof obj.text !== "undefined") {
+			result += '"text" : ' + ((!obj.text) ? 'null' : '"' + obj.text.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMNote(obj : unknown) : ENMNote {
+	return obj as ENMNote;
+}

+ 215 - 0
core/data/enm/ENMSchueler.ts

@@ -0,0 +1,215 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { ENMLeistung, cast_de_nrw_schule_svws_core_data_enm_ENMLeistung } from '../../../core/data/enm/ENMLeistung';
+import { ENMLernabschnitt, cast_de_nrw_schule_svws_core_data_enm_ENMLernabschnitt } from '../../../core/data/enm/ENMLernabschnitt';
+import { ENMLeistungBemerkungen, cast_de_nrw_schule_svws_core_data_enm_ENMLeistungBemerkungen } from '../../../core/data/enm/ENMLeistungBemerkungen';
+import { ENMZP10, cast_de_nrw_schule_svws_core_data_enm_ENMZP10 } from '../../../core/data/enm/ENMZP10';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { ENMBKAbschluss, cast_de_nrw_schule_svws_core_data_enm_ENMBKAbschluss } from '../../../core/data/enm/ENMBKAbschluss';
+import { Vector, cast_java_util_Vector } from '../../../java/util/Vector';
+import { ENMSprachenfolge, cast_de_nrw_schule_svws_core_data_enm_ENMSprachenfolge } from '../../../core/data/enm/ENMSprachenfolge';
+
+export class ENMSchueler extends JavaObject {
+
+	public id : number = 0;
+
+	public jahrgangID : number = 0;
+
+	public klasseID : number = 0;
+
+	public nachname : String | null = null;
+
+	public vorname : String | null = null;
+
+	public geschlecht : String | null = null;
+
+	public bilingualeSprache : String | null = null;
+
+	public istZieldifferent : boolean = false;
+
+	public istDaZFoerderung : boolean = false;
+
+	public sprachenfolge : Vector<ENMSprachenfolge> = new Vector();
+
+	public lernabschnitt : ENMLernabschnitt = new ENMLernabschnitt();
+
+	public readonly leistungsdaten : Vector<ENMLeistung> = new Vector();
+
+	public bemerkungen : ENMLeistungBemerkungen | null = null;
+
+	public zp10 : ENMZP10 | null = null;
+
+	public bkabschluss : ENMBKAbschluss | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMSchueler'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMSchueler {
+		const obj = JSON.parse(json);
+		const result = new ENMSchueler();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.jahrgangID === "undefined")
+			 throw new Error('invalid json format, missing attribute jahrgangID');
+		result.jahrgangID = obj.jahrgangID;
+		if (typeof obj.klasseID === "undefined")
+			 throw new Error('invalid json format, missing attribute klasseID');
+		result.klasseID = obj.klasseID;
+		result.nachname = typeof obj.nachname === "undefined" ? null : obj.nachname;
+		result.vorname = typeof obj.vorname === "undefined" ? null : obj.vorname;
+		result.geschlecht = typeof obj.geschlecht === "undefined" ? null : obj.geschlecht;
+		result.bilingualeSprache = typeof obj.bilingualeSprache === "undefined" ? null : obj.bilingualeSprache;
+		if (typeof obj.istZieldifferent === "undefined")
+			 throw new Error('invalid json format, missing attribute istZieldifferent');
+		result.istZieldifferent = obj.istZieldifferent;
+		if (typeof obj.istDaZFoerderung === "undefined")
+			 throw new Error('invalid json format, missing attribute istDaZFoerderung');
+		result.istDaZFoerderung = obj.istDaZFoerderung;
+		if (!!obj.sprachenfolge) {
+			for (let elem of obj.sprachenfolge) {
+				result.sprachenfolge?.add(ENMSprachenfolge.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		if (typeof obj.lernabschnitt === "undefined")
+			 throw new Error('invalid json format, missing attribute lernabschnitt');
+		result.lernabschnitt = ENMLernabschnitt.transpilerFromJSON(JSON.stringify(obj.lernabschnitt));
+		if (!!obj.leistungsdaten) {
+			for (let elem of obj.leistungsdaten) {
+				result.leistungsdaten?.add(ENMLeistung.transpilerFromJSON(JSON.stringify(elem)));
+			}
+		}
+		result.bemerkungen = typeof obj.bemerkungen === "undefined" ? null : ENMLeistungBemerkungen.transpilerFromJSON(JSON.stringify(obj.bemerkungen));
+		result.zp10 = typeof obj.zp10 === "undefined" ? null : ENMZP10.transpilerFromJSON(JSON.stringify(obj.zp10));
+		result.bkabschluss = typeof obj.bkabschluss === "undefined" ? null : ENMBKAbschluss.transpilerFromJSON(JSON.stringify(obj.bkabschluss));
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMSchueler) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"jahrgangID" : ' + obj.jahrgangID + ',';
+		result += '"klasseID" : ' + obj.klasseID + ',';
+		result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		result += '"geschlecht" : ' + ((!obj.geschlecht) ? 'null' : '"' + obj.geschlecht.valueOf() + '"') + ',';
+		result += '"bilingualeSprache" : ' + ((!obj.bilingualeSprache) ? 'null' : '"' + obj.bilingualeSprache.valueOf() + '"') + ',';
+		result += '"istZieldifferent" : ' + obj.istZieldifferent + ',';
+		result += '"istDaZFoerderung" : ' + obj.istDaZFoerderung + ',';
+		if (!obj.sprachenfolge) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.sprachenfolge.size(); i++) {
+				let elem = obj.sprachenfolge.get(i);
+				result += ENMSprachenfolge.transpilerToJSON(elem);
+				if (i < obj.sprachenfolge.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result += '"lernabschnitt" : ' + ENMLernabschnitt.transpilerToJSON(obj.lernabschnitt) + ',';
+		if (!obj.leistungsdaten) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.leistungsdaten.size(); i++) {
+				let elem = obj.leistungsdaten.get(i);
+				result += ENMLeistung.transpilerToJSON(elem);
+				if (i < obj.leistungsdaten.size() - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : ENMLeistungBemerkungen.transpilerToJSON(obj.bemerkungen)) + ',';
+		result += '"zp10" : ' + ((!obj.zp10) ? 'null' : ENMZP10.transpilerToJSON(obj.zp10)) + ',';
+		result += '"bkabschluss" : ' + ((!obj.bkabschluss) ? 'null' : ENMBKAbschluss.transpilerToJSON(obj.bkabschluss)) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMSchueler>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.jahrgangID !== "undefined") {
+			result += '"jahrgangID" : ' + obj.jahrgangID + ',';
+		}
+		if (typeof obj.klasseID !== "undefined") {
+			result += '"klasseID" : ' + obj.klasseID + ',';
+		}
+		if (typeof obj.nachname !== "undefined") {
+			result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.vorname !== "undefined") {
+			result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.geschlecht !== "undefined") {
+			result += '"geschlecht" : ' + ((!obj.geschlecht) ? 'null' : '"' + obj.geschlecht.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bilingualeSprache !== "undefined") {
+			result += '"bilingualeSprache" : ' + ((!obj.bilingualeSprache) ? 'null' : '"' + obj.bilingualeSprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.istZieldifferent !== "undefined") {
+			result += '"istZieldifferent" : ' + obj.istZieldifferent + ',';
+		}
+		if (typeof obj.istDaZFoerderung !== "undefined") {
+			result += '"istDaZFoerderung" : ' + obj.istDaZFoerderung + ',';
+		}
+		if (typeof obj.sprachenfolge !== "undefined") {
+			if (!obj.sprachenfolge) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.sprachenfolge.size(); i++) {
+					let elem = obj.sprachenfolge.get(i);
+					result += ENMSprachenfolge.transpilerToJSON(elem);
+					if (i < obj.sprachenfolge.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.lernabschnitt !== "undefined") {
+			result += '"lernabschnitt" : ' + ENMLernabschnitt.transpilerToJSON(obj.lernabschnitt) + ',';
+		}
+		if (typeof obj.leistungsdaten !== "undefined") {
+			if (!obj.leistungsdaten) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < obj.leistungsdaten.size(); i++) {
+					let elem = obj.leistungsdaten.get(i);
+					result += ENMLeistung.transpilerToJSON(elem);
+					if (i < obj.leistungsdaten.size() - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		if (typeof obj.bemerkungen !== "undefined") {
+			result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : ENMLeistungBemerkungen.transpilerToJSON(obj.bemerkungen)) + ',';
+		}
+		if (typeof obj.zp10 !== "undefined") {
+			result += '"zp10" : ' + ((!obj.zp10) ? 'null' : ENMZP10.transpilerToJSON(obj.zp10)) + ',';
+		}
+		if (typeof obj.bkabschluss !== "undefined") {
+			result += '"bkabschluss" : ' + ((!obj.bkabschluss) ? 'null' : ENMBKAbschluss.transpilerToJSON(obj.bkabschluss)) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMSchueler(obj : unknown) : ENMSchueler {
+	return obj as ENMSchueler;
+}

+ 118 - 0
core/data/enm/ENMSprachenfolge.ts

@@ -0,0 +1,118 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMSprachenfolge extends JavaObject {
+
+	public sprache : String | null = null;
+
+	public fachID : number = 0;
+
+	public fachKuerzel : String | null = null;
+
+	public reihenfolge : number = 0;
+
+	public belegungVonJahrgang : number = 0;
+
+	public belegungVonAbschnitt : number = 0;
+
+	public belegungBisJahrgang : Number | null = null;
+
+	public belegungBisAbschnitt : Number | null = null;
+
+	public referenzniveau : String | null = null;
+
+	public belegungSekI : Number | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMSprachenfolge'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMSprachenfolge {
+		const obj = JSON.parse(json);
+		const result = new ENMSprachenfolge();
+		result.sprache = typeof obj.sprache === "undefined" ? null : obj.sprache;
+		if (typeof obj.fachID === "undefined")
+			 throw new Error('invalid json format, missing attribute fachID');
+		result.fachID = obj.fachID;
+		result.fachKuerzel = typeof obj.fachKuerzel === "undefined" ? null : obj.fachKuerzel;
+		if (typeof obj.reihenfolge === "undefined")
+			 throw new Error('invalid json format, missing attribute reihenfolge');
+		result.reihenfolge = obj.reihenfolge;
+		if (typeof obj.belegungVonJahrgang === "undefined")
+			 throw new Error('invalid json format, missing attribute belegungVonJahrgang');
+		result.belegungVonJahrgang = obj.belegungVonJahrgang;
+		if (typeof obj.belegungVonAbschnitt === "undefined")
+			 throw new Error('invalid json format, missing attribute belegungVonAbschnitt');
+		result.belegungVonAbschnitt = obj.belegungVonAbschnitt;
+		result.belegungBisJahrgang = typeof obj.belegungBisJahrgang === "undefined" ? null : obj.belegungBisJahrgang;
+		result.belegungBisAbschnitt = typeof obj.belegungBisAbschnitt === "undefined" ? null : obj.belegungBisAbschnitt;
+		result.referenzniveau = typeof obj.referenzniveau === "undefined" ? null : obj.referenzniveau;
+		result.belegungSekI = typeof obj.belegungSekI === "undefined" ? null : obj.belegungSekI;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMSprachenfolge) : string {
+		let result = '{';
+		result += '"sprache" : ' + ((!obj.sprache) ? 'null' : '"' + obj.sprache.valueOf() + '"') + ',';
+		result += '"fachID" : ' + obj.fachID + ',';
+		result += '"fachKuerzel" : ' + ((!obj.fachKuerzel) ? 'null' : '"' + obj.fachKuerzel.valueOf() + '"') + ',';
+		result += '"reihenfolge" : ' + obj.reihenfolge + ',';
+		result += '"belegungVonJahrgang" : ' + obj.belegungVonJahrgang + ',';
+		result += '"belegungVonAbschnitt" : ' + obj.belegungVonAbschnitt + ',';
+		result += '"belegungBisJahrgang" : ' + ((!obj.belegungBisJahrgang) ? 'null' : obj.belegungBisJahrgang.valueOf()) + ',';
+		result += '"belegungBisAbschnitt" : ' + ((!obj.belegungBisAbschnitt) ? 'null' : obj.belegungBisAbschnitt.valueOf()) + ',';
+		result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		result += '"belegungSekI" : ' + ((!obj.belegungSekI) ? 'null' : obj.belegungSekI.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMSprachenfolge>) : string {
+		let result = '{';
+		if (typeof obj.sprache !== "undefined") {
+			result += '"sprache" : ' + ((!obj.sprache) ? 'null' : '"' + obj.sprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + obj.fachID + ',';
+		}
+		if (typeof obj.fachKuerzel !== "undefined") {
+			result += '"fachKuerzel" : ' + ((!obj.fachKuerzel) ? 'null' : '"' + obj.fachKuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.reihenfolge !== "undefined") {
+			result += '"reihenfolge" : ' + obj.reihenfolge + ',';
+		}
+		if (typeof obj.belegungVonJahrgang !== "undefined") {
+			result += '"belegungVonJahrgang" : ' + obj.belegungVonJahrgang + ',';
+		}
+		if (typeof obj.belegungVonAbschnitt !== "undefined") {
+			result += '"belegungVonAbschnitt" : ' + obj.belegungVonAbschnitt + ',';
+		}
+		if (typeof obj.belegungBisJahrgang !== "undefined") {
+			result += '"belegungBisJahrgang" : ' + ((!obj.belegungBisJahrgang) ? 'null' : obj.belegungBisJahrgang.valueOf()) + ',';
+		}
+		if (typeof obj.belegungBisAbschnitt !== "undefined") {
+			result += '"belegungBisAbschnitt" : ' + ((!obj.belegungBisAbschnitt) ? 'null' : obj.belegungBisAbschnitt.valueOf()) + ',';
+		}
+		if (typeof obj.referenzniveau !== "undefined") {
+			result += '"referenzniveau" : ' + ((!obj.referenzniveau) ? 'null' : '"' + obj.referenzniveau.valueOf() + '"') + ',';
+		}
+		if (typeof obj.belegungSekI !== "undefined") {
+			result += '"belegungSekI" : ' + ((!obj.belegungSekI) ? 'null' : obj.belegungSekI.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMSprachenfolge(obj : unknown) : ENMSprachenfolge {
+	return obj as ENMSprachenfolge;
+}

+ 78 - 0
core/data/enm/ENMTeilleistung.ts

@@ -0,0 +1,78 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMTeilleistung extends JavaObject {
+
+	public id : number = 0;
+
+	public artID : number = 0;
+
+	public datum : String | null = null;
+
+	public bemerkung : String | null = null;
+
+	public notenKuerzel : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMTeilleistung'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMTeilleistung {
+		const obj = JSON.parse(json);
+		const result = new ENMTeilleistung();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.artID === "undefined")
+			 throw new Error('invalid json format, missing attribute artID');
+		result.artID = obj.artID;
+		result.datum = typeof obj.datum === "undefined" ? null : obj.datum;
+		result.bemerkung = typeof obj.bemerkung === "undefined" ? null : obj.bemerkung;
+		result.notenKuerzel = typeof obj.notenKuerzel === "undefined" ? null : obj.notenKuerzel;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMTeilleistung) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"artID" : ' + obj.artID + ',';
+		result += '"datum" : ' + ((!obj.datum) ? 'null' : '"' + obj.datum.valueOf() + '"') + ',';
+		result += '"bemerkung" : ' + ((!obj.bemerkung) ? 'null' : '"' + obj.bemerkung.valueOf() + '"') + ',';
+		result += '"notenKuerzel" : ' + ((!obj.notenKuerzel) ? 'null' : '"' + obj.notenKuerzel.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMTeilleistung>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.artID !== "undefined") {
+			result += '"artID" : ' + obj.artID + ',';
+		}
+		if (typeof obj.datum !== "undefined") {
+			result += '"datum" : ' + ((!obj.datum) ? 'null' : '"' + obj.datum.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bemerkung !== "undefined") {
+			result += '"bemerkung" : ' + ((!obj.bemerkung) ? 'null' : '"' + obj.bemerkung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.notenKuerzel !== "undefined") {
+			result += '"notenKuerzel" : ' + ((!obj.notenKuerzel) ? 'null' : '"' + obj.notenKuerzel.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMTeilleistung(obj : unknown) : ENMTeilleistung {
+	return obj as ENMTeilleistung;
+}

+ 71 - 0
core/data/enm/ENMTeilleistungsart.ts

@@ -0,0 +1,71 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaDouble, cast_java_lang_Double } from '../../../java/lang/JavaDouble';
+
+export class ENMTeilleistungsart extends JavaObject {
+
+	public id : number = 0;
+
+	public bezeichnung : String | null = null;
+
+	public sortierung : Number | null = null;
+
+	public gewichtung : Number | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMTeilleistungsart'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMTeilleistungsart {
+		const obj = JSON.parse(json);
+		const result = new ENMTeilleistungsart();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		result.sortierung = typeof obj.sortierung === "undefined" ? null : obj.sortierung;
+		result.gewichtung = typeof obj.gewichtung === "undefined" ? null : obj.gewichtung;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMTeilleistungsart) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + ((!obj.sortierung) ? 'null' : obj.sortierung.valueOf()) + ',';
+		result += '"gewichtung" : ' + ((!obj.gewichtung) ? 'null' : obj.gewichtung.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMTeilleistungsart>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + ((!obj.sortierung) ? 'null' : obj.sortierung.valueOf()) + ',';
+		}
+		if (typeof obj.gewichtung !== "undefined") {
+			result += '"gewichtung" : ' + ((!obj.gewichtung) ? 'null' : obj.gewichtung.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMTeilleistungsart(obj : unknown) : ENMTeilleistungsart {
+	return obj as ENMTeilleistungsart;
+}

+ 94 - 0
core/data/enm/ENMZP10.ts

@@ -0,0 +1,94 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ENMZP10 extends JavaObject {
+
+	public fachID : number = 0;
+
+	public vornote : String | null = null;
+
+	public noteSchriftlichePruefung : String | null = null;
+
+	public muendlichePruefung : boolean = false;
+
+	public muendlichePruefungFreiwillig : boolean = false;
+
+	public noteMuendlichePruefung : String | null = null;
+
+	public abschlussnote : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.enm.ENMZP10'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ENMZP10 {
+		const obj = JSON.parse(json);
+		const result = new ENMZP10();
+		if (typeof obj.fachID === "undefined")
+			 throw new Error('invalid json format, missing attribute fachID');
+		result.fachID = obj.fachID;
+		result.vornote = typeof obj.vornote === "undefined" ? null : obj.vornote;
+		result.noteSchriftlichePruefung = typeof obj.noteSchriftlichePruefung === "undefined" ? null : obj.noteSchriftlichePruefung;
+		if (typeof obj.muendlichePruefung === "undefined")
+			 throw new Error('invalid json format, missing attribute muendlichePruefung');
+		result.muendlichePruefung = obj.muendlichePruefung;
+		if (typeof obj.muendlichePruefungFreiwillig === "undefined")
+			 throw new Error('invalid json format, missing attribute muendlichePruefungFreiwillig');
+		result.muendlichePruefungFreiwillig = obj.muendlichePruefungFreiwillig;
+		result.noteMuendlichePruefung = typeof obj.noteMuendlichePruefung === "undefined" ? null : obj.noteMuendlichePruefung;
+		result.abschlussnote = typeof obj.abschlussnote === "undefined" ? null : obj.abschlussnote;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ENMZP10) : string {
+		let result = '{';
+		result += '"fachID" : ' + obj.fachID + ',';
+		result += '"vornote" : ' + ((!obj.vornote) ? 'null' : '"' + obj.vornote.valueOf() + '"') + ',';
+		result += '"noteSchriftlichePruefung" : ' + ((!obj.noteSchriftlichePruefung) ? 'null' : '"' + obj.noteSchriftlichePruefung.valueOf() + '"') + ',';
+		result += '"muendlichePruefung" : ' + obj.muendlichePruefung + ',';
+		result += '"muendlichePruefungFreiwillig" : ' + obj.muendlichePruefungFreiwillig + ',';
+		result += '"noteMuendlichePruefung" : ' + ((!obj.noteMuendlichePruefung) ? 'null' : '"' + obj.noteMuendlichePruefung.valueOf() + '"') + ',';
+		result += '"abschlussnote" : ' + ((!obj.abschlussnote) ? 'null' : '"' + obj.abschlussnote.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ENMZP10>) : string {
+		let result = '{';
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + obj.fachID + ',';
+		}
+		if (typeof obj.vornote !== "undefined") {
+			result += '"vornote" : ' + ((!obj.vornote) ? 'null' : '"' + obj.vornote.valueOf() + '"') + ',';
+		}
+		if (typeof obj.noteSchriftlichePruefung !== "undefined") {
+			result += '"noteSchriftlichePruefung" : ' + ((!obj.noteSchriftlichePruefung) ? 'null' : '"' + obj.noteSchriftlichePruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.muendlichePruefung !== "undefined") {
+			result += '"muendlichePruefung" : ' + obj.muendlichePruefung + ',';
+		}
+		if (typeof obj.muendlichePruefungFreiwillig !== "undefined") {
+			result += '"muendlichePruefungFreiwillig" : ' + obj.muendlichePruefungFreiwillig + ',';
+		}
+		if (typeof obj.noteMuendlichePruefung !== "undefined") {
+			result += '"noteMuendlichePruefung" : ' + ((!obj.noteMuendlichePruefung) ? 'null' : '"' + obj.noteMuendlichePruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.abschlussnote !== "undefined") {
+			result += '"abschlussnote" : ' + ((!obj.abschlussnote) ? 'null' : '"' + obj.abschlussnote.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_enm_ENMZP10(obj : unknown) : ENMZP10 {
+	return obj as ENMZP10;
+}

+ 93 - 0
core/data/erzieher/ErzieherListeEintrag.ts

@@ -0,0 +1,93 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class ErzieherListeEintrag extends JavaObject {
+
+	public id : number = 0;
+
+	public idSchueler : number = 0;
+
+	public idErzieherArt : Number | null = null;
+
+	public anrede : String | null = null;
+
+	public name : String | null = null;
+
+	public vorname : String | null = null;
+
+	public email : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.erzieher.ErzieherListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ErzieherListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new ErzieherListeEintrag();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.idSchueler === "undefined")
+			 throw new Error('invalid json format, missing attribute idSchueler');
+		result.idSchueler = obj.idSchueler;
+		result.idErzieherArt = typeof obj.idErzieherArt === "undefined" ? null : obj.idErzieherArt;
+		result.anrede = typeof obj.anrede === "undefined" ? null : obj.anrede;
+		result.name = typeof obj.name === "undefined" ? null : obj.name;
+		result.vorname = typeof obj.vorname === "undefined" ? null : obj.vorname;
+		result.email = typeof obj.email === "undefined" ? null : obj.email;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ErzieherListeEintrag) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"idSchueler" : ' + obj.idSchueler + ',';
+		result += '"idErzieherArt" : ' + ((!obj.idErzieherArt) ? 'null' : obj.idErzieherArt.valueOf()) + ',';
+		result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ErzieherListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.idSchueler !== "undefined") {
+			result += '"idSchueler" : ' + obj.idSchueler + ',';
+		}
+		if (typeof obj.idErzieherArt !== "undefined") {
+			result += '"idErzieherArt" : ' + ((!obj.idErzieherArt) ? 'null' : obj.idErzieherArt.valueOf()) + ',';
+		}
+		if (typeof obj.anrede !== "undefined") {
+			result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		}
+		if (typeof obj.name !== "undefined") {
+			result += '"name" : ' + ((!obj.name) ? 'null' : '"' + obj.name.valueOf() + '"') + ',';
+		}
+		if (typeof obj.vorname !== "undefined") {
+			result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.email !== "undefined") {
+			result += '"email" : ' + ((!obj.email) ? 'null' : '"' + obj.email.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_erzieher_ErzieherListeEintrag(obj : unknown) : ErzieherListeEintrag {
+	return obj as ErzieherListeEintrag;
+}

+ 164 - 0
core/data/erzieher/ErzieherStammdaten.ts

@@ -0,0 +1,164 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+
+export class ErzieherStammdaten extends JavaObject {
+
+	public id : number = 0;
+
+	public idSchueler : number = 0;
+
+	public idErzieherArt : Number | null = null;
+
+	public titel : String | null = null;
+
+	public anrede : String | null = null;
+
+	public nachname : String | null = null;
+
+	public zusatzNachname : String | null = null;
+
+	public vorname : String | null = null;
+
+	public strassenname : String | null = null;
+
+	public hausnummer : String | null = null;
+
+	public hausnummerZusatz : String | null = null;
+
+	public wohnortID : Number | null = null;
+
+	public ortsteilID : Number | null = null;
+
+	public erhaeltAnschreiben : Boolean | null = null;
+
+	public eMail : String | null = null;
+
+	public staatsangehoerigkeitID : String | null = null;
+
+	public bemerkungen : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.erzieher.ErzieherStammdaten'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): ErzieherStammdaten {
+		const obj = JSON.parse(json);
+		const result = new ErzieherStammdaten();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		if (typeof obj.idSchueler === "undefined")
+			 throw new Error('invalid json format, missing attribute idSchueler');
+		result.idSchueler = obj.idSchueler;
+		result.idErzieherArt = typeof obj.idErzieherArt === "undefined" ? null : obj.idErzieherArt;
+		result.titel = typeof obj.titel === "undefined" ? null : obj.titel;
+		result.anrede = typeof obj.anrede === "undefined" ? null : obj.anrede;
+		result.nachname = typeof obj.nachname === "undefined" ? null : obj.nachname;
+		result.zusatzNachname = typeof obj.zusatzNachname === "undefined" ? null : obj.zusatzNachname;
+		result.vorname = typeof obj.vorname === "undefined" ? null : obj.vorname;
+		result.strassenname = typeof obj.strassenname === "undefined" ? null : obj.strassenname;
+		result.hausnummer = typeof obj.hausnummer === "undefined" ? null : obj.hausnummer;
+		result.hausnummerZusatz = typeof obj.hausnummerZusatz === "undefined" ? null : obj.hausnummerZusatz;
+		result.wohnortID = typeof obj.wohnortID === "undefined" ? null : obj.wohnortID;
+		result.ortsteilID = typeof obj.ortsteilID === "undefined" ? null : obj.ortsteilID;
+		result.erhaeltAnschreiben = typeof obj.erhaeltAnschreiben === "undefined" ? null : obj.erhaeltAnschreiben;
+		result.eMail = typeof obj.eMail === "undefined" ? null : obj.eMail;
+		result.staatsangehoerigkeitID = typeof obj.staatsangehoerigkeitID === "undefined" ? null : obj.staatsangehoerigkeitID;
+		result.bemerkungen = typeof obj.bemerkungen === "undefined" ? null : obj.bemerkungen;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : ErzieherStammdaten) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"idSchueler" : ' + obj.idSchueler + ',';
+		result += '"idErzieherArt" : ' + ((!obj.idErzieherArt) ? 'null' : obj.idErzieherArt.valueOf()) + ',';
+		result += '"titel" : ' + ((!obj.titel) ? 'null' : '"' + obj.titel.valueOf() + '"') + ',';
+		result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		result += '"zusatzNachname" : ' + ((!obj.zusatzNachname) ? 'null' : '"' + obj.zusatzNachname.valueOf() + '"') + ',';
+		result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		result += '"hausnummer" : ' + ((!obj.hausnummer) ? 'null' : '"' + obj.hausnummer.valueOf() + '"') + ',';
+		result += '"hausnummerZusatz" : ' + ((!obj.hausnummerZusatz) ? 'null' : '"' + obj.hausnummerZusatz.valueOf() + '"') + ',';
+		result += '"wohnortID" : ' + ((!obj.wohnortID) ? 'null' : obj.wohnortID.valueOf()) + ',';
+		result += '"ortsteilID" : ' + ((!obj.ortsteilID) ? 'null' : obj.ortsteilID.valueOf()) + ',';
+		result += '"erhaeltAnschreiben" : ' + ((!obj.erhaeltAnschreiben) ? 'null' : obj.erhaeltAnschreiben.valueOf()) + ',';
+		result += '"eMail" : ' + ((!obj.eMail) ? 'null' : '"' + obj.eMail.valueOf() + '"') + ',';
+		result += '"staatsangehoerigkeitID" : ' + ((!obj.staatsangehoerigkeitID) ? 'null' : '"' + obj.staatsangehoerigkeitID.valueOf() + '"') + ',';
+		result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : '"' + obj.bemerkungen.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<ErzieherStammdaten>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.idSchueler !== "undefined") {
+			result += '"idSchueler" : ' + obj.idSchueler + ',';
+		}
+		if (typeof obj.idErzieherArt !== "undefined") {
+			result += '"idErzieherArt" : ' + ((!obj.idErzieherArt) ? 'null' : obj.idErzieherArt.valueOf()) + ',';
+		}
+		if (typeof obj.titel !== "undefined") {
+			result += '"titel" : ' + ((!obj.titel) ? 'null' : '"' + obj.titel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.anrede !== "undefined") {
+			result += '"anrede" : ' + ((!obj.anrede) ? 'null' : '"' + obj.anrede.valueOf() + '"') + ',';
+		}
+		if (typeof obj.nachname !== "undefined") {
+			result += '"nachname" : ' + ((!obj.nachname) ? 'null' : '"' + obj.nachname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.zusatzNachname !== "undefined") {
+			result += '"zusatzNachname" : ' + ((!obj.zusatzNachname) ? 'null' : '"' + obj.zusatzNachname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.vorname !== "undefined") {
+			result += '"vorname" : ' + ((!obj.vorname) ? 'null' : '"' + obj.vorname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.strassenname !== "undefined") {
+			result += '"strassenname" : ' + ((!obj.strassenname) ? 'null' : '"' + obj.strassenname.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnummer !== "undefined") {
+			result += '"hausnummer" : ' + ((!obj.hausnummer) ? 'null' : '"' + obj.hausnummer.valueOf() + '"') + ',';
+		}
+		if (typeof obj.hausnummerZusatz !== "undefined") {
+			result += '"hausnummerZusatz" : ' + ((!obj.hausnummerZusatz) ? 'null' : '"' + obj.hausnummerZusatz.valueOf() + '"') + ',';
+		}
+		if (typeof obj.wohnortID !== "undefined") {
+			result += '"wohnortID" : ' + ((!obj.wohnortID) ? 'null' : obj.wohnortID.valueOf()) + ',';
+		}
+		if (typeof obj.ortsteilID !== "undefined") {
+			result += '"ortsteilID" : ' + ((!obj.ortsteilID) ? 'null' : obj.ortsteilID.valueOf()) + ',';
+		}
+		if (typeof obj.erhaeltAnschreiben !== "undefined") {
+			result += '"erhaeltAnschreiben" : ' + ((!obj.erhaeltAnschreiben) ? 'null' : obj.erhaeltAnschreiben.valueOf()) + ',';
+		}
+		if (typeof obj.eMail !== "undefined") {
+			result += '"eMail" : ' + ((!obj.eMail) ? 'null' : '"' + obj.eMail.valueOf() + '"') + ',';
+		}
+		if (typeof obj.staatsangehoerigkeitID !== "undefined") {
+			result += '"staatsangehoerigkeitID" : ' + ((!obj.staatsangehoerigkeitID) ? 'null' : '"' + obj.staatsangehoerigkeitID.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bemerkungen !== "undefined") {
+			result += '"bemerkungen" : ' + ((!obj.bemerkungen) ? 'null' : '"' + obj.bemerkungen.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_erzieher_ErzieherStammdaten(obj : unknown) : ErzieherStammdaten {
+	return obj as ErzieherStammdaten;
+}

+ 54 - 0
core/data/erzieher/Erzieherart.ts

@@ -0,0 +1,54 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class Erzieherart extends JavaObject {
+
+	public id : Number | null = null;
+
+	public bezeichnung : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.erzieher.Erzieherart'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): Erzieherart {
+		const obj = JSON.parse(json);
+		const result = new Erzieherart();
+		result.id = typeof obj.id === "undefined" ? null : obj.id;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : Erzieherart) : string {
+		let result = '{';
+		result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<Erzieherart>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + ((!obj.id) ? 'null' : obj.id.valueOf()) + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_erzieher_Erzieherart(obj : unknown) : Erzieherart {
+	return obj as Erzieherart;
+}

+ 69 - 0
core/data/fach/FachDaten.ts

@@ -0,0 +1,69 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class FachDaten extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public bezeichnung : String | null = null;
+
+	public kuerzelStatistik : String | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.fach.FachDaten'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): FachDaten {
+		const obj = JSON.parse(json);
+		const result = new FachDaten();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		result.kuerzelStatistik = typeof obj.kuerzelStatistik === "undefined" ? null : obj.kuerzelStatistik;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : FachDaten) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"kuerzelStatistik" : ' + ((!obj.kuerzelStatistik) ? 'null' : '"' + obj.kuerzelStatistik.valueOf() + '"') + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<FachDaten>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kuerzelStatistik !== "undefined") {
+			result += '"kuerzelStatistik" : ' + ((!obj.kuerzelStatistik) ? 'null' : '"' + obj.kuerzelStatistik.valueOf() + '"') + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_fach_FachDaten(obj : unknown) : FachDaten {
+	return obj as FachDaten;
+}

+ 105 - 0
core/data/fach/FaecherListeEintrag.ts

@@ -0,0 +1,105 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+
+export class FaecherListeEintrag extends JavaObject {
+
+	public id : number = 0;
+
+	public kuerzel : String | null = null;
+
+	public kuerzelStatistik : String | null = null;
+
+	public bezeichnung : String | null = null;
+
+	public sortierung : number = 0;
+
+	public istOberstufenFach : boolean = false;
+
+	public istSichtbar : boolean = false;
+
+	public istAenderbar : boolean = false;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.fach.FaecherListeEintrag'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): FaecherListeEintrag {
+		const obj = JSON.parse(json);
+		const result = new FaecherListeEintrag();
+		if (typeof obj.id === "undefined")
+			 throw new Error('invalid json format, missing attribute id');
+		result.id = obj.id;
+		result.kuerzel = typeof obj.kuerzel === "undefined" ? null : obj.kuerzel;
+		result.kuerzelStatistik = typeof obj.kuerzelStatistik === "undefined" ? null : obj.kuerzelStatistik;
+		result.bezeichnung = typeof obj.bezeichnung === "undefined" ? null : obj.bezeichnung;
+		if (typeof obj.sortierung === "undefined")
+			 throw new Error('invalid json format, missing attribute sortierung');
+		result.sortierung = obj.sortierung;
+		if (typeof obj.istOberstufenFach === "undefined")
+			 throw new Error('invalid json format, missing attribute istOberstufenFach');
+		result.istOberstufenFach = obj.istOberstufenFach;
+		if (typeof obj.istSichtbar === "undefined")
+			 throw new Error('invalid json format, missing attribute istSichtbar');
+		result.istSichtbar = obj.istSichtbar;
+		if (typeof obj.istAenderbar === "undefined")
+			 throw new Error('invalid json format, missing attribute istAenderbar');
+		result.istAenderbar = obj.istAenderbar;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : FaecherListeEintrag) : string {
+		let result = '{';
+		result += '"id" : ' + obj.id + ',';
+		result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		result += '"kuerzelStatistik" : ' + ((!obj.kuerzelStatistik) ? 'null' : '"' + obj.kuerzelStatistik.valueOf() + '"') + ',';
+		result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		result += '"sortierung" : ' + obj.sortierung + ',';
+		result += '"istOberstufenFach" : ' + obj.istOberstufenFach + ',';
+		result += '"istSichtbar" : ' + obj.istSichtbar + ',';
+		result += '"istAenderbar" : ' + obj.istAenderbar + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<FaecherListeEintrag>) : string {
+		let result = '{';
+		if (typeof obj.id !== "undefined") {
+			result += '"id" : ' + obj.id + ',';
+		}
+		if (typeof obj.kuerzel !== "undefined") {
+			result += '"kuerzel" : ' + ((!obj.kuerzel) ? 'null' : '"' + obj.kuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.kuerzelStatistik !== "undefined") {
+			result += '"kuerzelStatistik" : ' + ((!obj.kuerzelStatistik) ? 'null' : '"' + obj.kuerzelStatistik.valueOf() + '"') + ',';
+		}
+		if (typeof obj.bezeichnung !== "undefined") {
+			result += '"bezeichnung" : ' + ((!obj.bezeichnung) ? 'null' : '"' + obj.bezeichnung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.sortierung !== "undefined") {
+			result += '"sortierung" : ' + obj.sortierung + ',';
+		}
+		if (typeof obj.istOberstufenFach !== "undefined") {
+			result += '"istOberstufenFach" : ' + obj.istOberstufenFach + ',';
+		}
+		if (typeof obj.istSichtbar !== "undefined") {
+			result += '"istSichtbar" : ' + obj.istSichtbar + ',';
+		}
+		if (typeof obj.istAenderbar !== "undefined") {
+			result += '"istAenderbar" : ' + obj.istAenderbar + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_fach_FaecherListeEintrag(obj : unknown) : FaecherListeEintrag {
+	return obj as FaecherListeEintrag;
+}

+ 186 - 0
core/data/gost/AbiturFachbelegung.ts

@@ -0,0 +1,186 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { AbiturFachbelegungHalbjahr, cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr } from '../../../core/data/gost/AbiturFachbelegungHalbjahr';
+import { GostHalbjahr, cast_de_nrw_schule_svws_core_types_gost_GostHalbjahr } from '../../../core/types/gost/GostHalbjahr';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+import { JavaDouble, cast_java_lang_Double } from '../../../java/lang/JavaDouble';
+
+export class AbiturFachbelegung extends JavaObject {
+
+	public fachID : number = -1;
+
+	public letzteKursart : String | null = null;
+
+	public abiturFach : Number | null = null;
+
+	public istFSNeu : boolean = false;
+
+	public block1PunktSumme : Number | null = null;
+
+	public block1NotenpunkteDurchschnitt : Number | null = null;
+
+	public block2NotenKuerzelPruefung : String | null = null;
+
+	public block2PunkteZwischenstand : Number | null = null;
+
+	public block2MuendlichePruefungAbweichung : Boolean | null = null;
+
+	public block2MuendlichePruefungBestehen : Boolean | null = null;
+
+	public block2MuendlichePruefungFreiwillig : Boolean | null = null;
+
+	public block2MuendlichePruefungReihenfolge : Number | null = null;
+
+	public block2MuendlichePruefungNotenKuerzel : String | null = null;
+
+	public block2Punkte : Number | null = null;
+
+	public block2Pruefer : Number | null = null;
+
+	public readonly belegungen : Array<AbiturFachbelegungHalbjahr | null> = Array(GostHalbjahr.maxHalbjahre).fill(null);
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.gost.AbiturFachbelegung'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): AbiturFachbelegung {
+		const obj = JSON.parse(json);
+		const result = new AbiturFachbelegung();
+		if (typeof obj.fachID === "undefined")
+			 throw new Error('invalid json format, missing attribute fachID');
+		result.fachID = obj.fachID;
+		result.letzteKursart = typeof obj.letzteKursart === "undefined" ? null : obj.letzteKursart;
+		result.abiturFach = typeof obj.abiturFach === "undefined" ? null : obj.abiturFach;
+		if (typeof obj.istFSNeu === "undefined")
+			 throw new Error('invalid json format, missing attribute istFSNeu');
+		result.istFSNeu = obj.istFSNeu;
+		result.block1PunktSumme = typeof obj.block1PunktSumme === "undefined" ? null : obj.block1PunktSumme;
+		result.block1NotenpunkteDurchschnitt = typeof obj.block1NotenpunkteDurchschnitt === "undefined" ? null : obj.block1NotenpunkteDurchschnitt;
+		result.block2NotenKuerzelPruefung = typeof obj.block2NotenKuerzelPruefung === "undefined" ? null : obj.block2NotenKuerzelPruefung;
+		result.block2PunkteZwischenstand = typeof obj.block2PunkteZwischenstand === "undefined" ? null : obj.block2PunkteZwischenstand;
+		result.block2MuendlichePruefungAbweichung = typeof obj.block2MuendlichePruefungAbweichung === "undefined" ? null : obj.block2MuendlichePruefungAbweichung;
+		result.block2MuendlichePruefungBestehen = typeof obj.block2MuendlichePruefungBestehen === "undefined" ? null : obj.block2MuendlichePruefungBestehen;
+		result.block2MuendlichePruefungFreiwillig = typeof obj.block2MuendlichePruefungFreiwillig === "undefined" ? null : obj.block2MuendlichePruefungFreiwillig;
+		result.block2MuendlichePruefungReihenfolge = typeof obj.block2MuendlichePruefungReihenfolge === "undefined" ? null : obj.block2MuendlichePruefungReihenfolge;
+		result.block2MuendlichePruefungNotenKuerzel = typeof obj.block2MuendlichePruefungNotenKuerzel === "undefined" ? null : obj.block2MuendlichePruefungNotenKuerzel;
+		result.block2Punkte = typeof obj.block2Punkte === "undefined" ? null : obj.block2Punkte;
+		result.block2Pruefer = typeof obj.block2Pruefer === "undefined" ? null : obj.block2Pruefer;
+		for (let i : number = 0; i < obj.belegungen.length; i++) {
+			result.belegungen[i] = obj.belegungen[i] == null ? null : (AbiturFachbelegungHalbjahr.transpilerFromJSON(JSON.stringify(obj.belegungen[i])));
+		}
+		return result;
+	}
+
+	public static transpilerToJSON(obj : AbiturFachbelegung) : string {
+		let result = '{';
+		result += '"fachID" : ' + obj.fachID + ',';
+		result += '"letzteKursart" : ' + ((!obj.letzteKursart) ? 'null' : '"' + obj.letzteKursart.valueOf() + '"') + ',';
+		result += '"abiturFach" : ' + ((!obj.abiturFach) ? 'null' : obj.abiturFach.valueOf()) + ',';
+		result += '"istFSNeu" : ' + obj.istFSNeu + ',';
+		result += '"block1PunktSumme" : ' + ((!obj.block1PunktSumme) ? 'null' : obj.block1PunktSumme.valueOf()) + ',';
+		result += '"block1NotenpunkteDurchschnitt" : ' + ((!obj.block1NotenpunkteDurchschnitt) ? 'null' : obj.block1NotenpunkteDurchschnitt.valueOf()) + ',';
+		result += '"block2NotenKuerzelPruefung" : ' + ((!obj.block2NotenKuerzelPruefung) ? 'null' : '"' + obj.block2NotenKuerzelPruefung.valueOf() + '"') + ',';
+		result += '"block2PunkteZwischenstand" : ' + ((!obj.block2PunkteZwischenstand) ? 'null' : obj.block2PunkteZwischenstand.valueOf()) + ',';
+		result += '"block2MuendlichePruefungAbweichung" : ' + ((!obj.block2MuendlichePruefungAbweichung) ? 'null' : obj.block2MuendlichePruefungAbweichung.valueOf()) + ',';
+		result += '"block2MuendlichePruefungBestehen" : ' + ((!obj.block2MuendlichePruefungBestehen) ? 'null' : obj.block2MuendlichePruefungBestehen.valueOf()) + ',';
+		result += '"block2MuendlichePruefungFreiwillig" : ' + ((!obj.block2MuendlichePruefungFreiwillig) ? 'null' : obj.block2MuendlichePruefungFreiwillig.valueOf()) + ',';
+		result += '"block2MuendlichePruefungReihenfolge" : ' + ((!obj.block2MuendlichePruefungReihenfolge) ? 'null' : obj.block2MuendlichePruefungReihenfolge.valueOf()) + ',';
+		result += '"block2MuendlichePruefungNotenKuerzel" : ' + ((!obj.block2MuendlichePruefungNotenKuerzel) ? 'null' : '"' + obj.block2MuendlichePruefungNotenKuerzel.valueOf() + '"') + ',';
+		result += '"block2Punkte" : ' + ((!obj.block2Punkte) ? 'null' : obj.block2Punkte.valueOf()) + ',';
+		result += '"block2Pruefer" : ' + ((!obj.block2Pruefer) ? 'null' : obj.block2Pruefer.valueOf()) + ',';
+		if (!obj.belegungen) {
+			result += '[]';
+		} else {
+			result += '[ ';
+			for (let i : number = 0; i < obj.belegungen.length; i++) {
+				let elem = obj.belegungen[i];
+				result += (elem == null) ? null : AbiturFachbelegungHalbjahr.transpilerToJSON(elem);
+				if (i < obj.belegungen.length - 1)
+					result += ',';
+			}
+			result += ' ]' + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<AbiturFachbelegung>) : string {
+		let result = '{';
+		if (typeof obj.fachID !== "undefined") {
+			result += '"fachID" : ' + obj.fachID + ',';
+		}
+		if (typeof obj.letzteKursart !== "undefined") {
+			result += '"letzteKursart" : ' + ((!obj.letzteKursart) ? 'null' : '"' + obj.letzteKursart.valueOf() + '"') + ',';
+		}
+		if (typeof obj.abiturFach !== "undefined") {
+			result += '"abiturFach" : ' + ((!obj.abiturFach) ? 'null' : obj.abiturFach.valueOf()) + ',';
+		}
+		if (typeof obj.istFSNeu !== "undefined") {
+			result += '"istFSNeu" : ' + obj.istFSNeu + ',';
+		}
+		if (typeof obj.block1PunktSumme !== "undefined") {
+			result += '"block1PunktSumme" : ' + ((!obj.block1PunktSumme) ? 'null' : obj.block1PunktSumme.valueOf()) + ',';
+		}
+		if (typeof obj.block1NotenpunkteDurchschnitt !== "undefined") {
+			result += '"block1NotenpunkteDurchschnitt" : ' + ((!obj.block1NotenpunkteDurchschnitt) ? 'null' : obj.block1NotenpunkteDurchschnitt.valueOf()) + ',';
+		}
+		if (typeof obj.block2NotenKuerzelPruefung !== "undefined") {
+			result += '"block2NotenKuerzelPruefung" : ' + ((!obj.block2NotenKuerzelPruefung) ? 'null' : '"' + obj.block2NotenKuerzelPruefung.valueOf() + '"') + ',';
+		}
+		if (typeof obj.block2PunkteZwischenstand !== "undefined") {
+			result += '"block2PunkteZwischenstand" : ' + ((!obj.block2PunkteZwischenstand) ? 'null' : obj.block2PunkteZwischenstand.valueOf()) + ',';
+		}
+		if (typeof obj.block2MuendlichePruefungAbweichung !== "undefined") {
+			result += '"block2MuendlichePruefungAbweichung" : ' + ((!obj.block2MuendlichePruefungAbweichung) ? 'null' : obj.block2MuendlichePruefungAbweichung.valueOf()) + ',';
+		}
+		if (typeof obj.block2MuendlichePruefungBestehen !== "undefined") {
+			result += '"block2MuendlichePruefungBestehen" : ' + ((!obj.block2MuendlichePruefungBestehen) ? 'null' : obj.block2MuendlichePruefungBestehen.valueOf()) + ',';
+		}
+		if (typeof obj.block2MuendlichePruefungFreiwillig !== "undefined") {
+			result += '"block2MuendlichePruefungFreiwillig" : ' + ((!obj.block2MuendlichePruefungFreiwillig) ? 'null' : obj.block2MuendlichePruefungFreiwillig.valueOf()) + ',';
+		}
+		if (typeof obj.block2MuendlichePruefungReihenfolge !== "undefined") {
+			result += '"block2MuendlichePruefungReihenfolge" : ' + ((!obj.block2MuendlichePruefungReihenfolge) ? 'null' : obj.block2MuendlichePruefungReihenfolge.valueOf()) + ',';
+		}
+		if (typeof obj.block2MuendlichePruefungNotenKuerzel !== "undefined") {
+			result += '"block2MuendlichePruefungNotenKuerzel" : ' + ((!obj.block2MuendlichePruefungNotenKuerzel) ? 'null' : '"' + obj.block2MuendlichePruefungNotenKuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.block2Punkte !== "undefined") {
+			result += '"block2Punkte" : ' + ((!obj.block2Punkte) ? 'null' : obj.block2Punkte.valueOf()) + ',';
+		}
+		if (typeof obj.block2Pruefer !== "undefined") {
+			result += '"block2Pruefer" : ' + ((!obj.block2Pruefer) ? 'null' : obj.block2Pruefer.valueOf()) + ',';
+		}
+		if (typeof obj.belegungen !== "undefined") {
+			let a = obj.belegungen;
+			if (!a) {
+				result += '[]';
+			} else {
+				result += '[ ';
+				for (let i : number = 0; i < a.length; i++) {
+					let elem = a[i];
+					result += (elem == null) ? null : AbiturFachbelegungHalbjahr.transpilerToJSON(elem);
+					if (i < a.length - 1)
+						result += ',';
+				}
+				result += ' ]' + ',';
+			}
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegung(obj : unknown) : AbiturFachbelegung {
+	return obj as AbiturFachbelegung;
+}

+ 128 - 0
core/data/gost/AbiturFachbelegungHalbjahr.ts

@@ -0,0 +1,128 @@
+import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
+import { JavaLong, cast_java_lang_Long } from '../../../java/lang/JavaLong';
+import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
+import { JavaBoolean, cast_java_lang_Boolean } from '../../../java/lang/JavaBoolean';
+
+export class AbiturFachbelegungHalbjahr extends JavaObject {
+
+	public halbjahrKuerzel : String = "";
+
+	public kursartKuerzel : String = "";
+
+	public schriftlich : Boolean | null = null;
+
+	public biliSprache : String | null = null;
+
+	public lehrer : Number | null = null;
+
+	public wochenstunden : number = 0;
+
+	public fehlstundenGesamt : number = 0;
+
+	public fehlstundenUnentschuldigt : number = 0;
+
+	public notenkuerzel : String | null = null;
+
+	public block1gewertet : Boolean | null = null;
+
+	public block1kursAufZeugnis : Boolean | null = null;
+
+
+	public constructor() {
+		super();
+	}
+
+	isTranspiledInstanceOf(name : string): boolean {
+		return ['de.nrw.schule.svws.core.data.gost.AbiturFachbelegungHalbjahr'].includes(name);
+	}
+
+	public static transpilerFromJSON(json : string): AbiturFachbelegungHalbjahr {
+		const obj = JSON.parse(json);
+		const result = new AbiturFachbelegungHalbjahr();
+		if (typeof obj.halbjahrKuerzel === "undefined")
+			 throw new Error('invalid json format, missing attribute halbjahrKuerzel');
+		result.halbjahrKuerzel = obj.halbjahrKuerzel;
+		if (typeof obj.kursartKuerzel === "undefined")
+			 throw new Error('invalid json format, missing attribute kursartKuerzel');
+		result.kursartKuerzel = obj.kursartKuerzel;
+		result.schriftlich = typeof obj.schriftlich === "undefined" ? null : obj.schriftlich;
+		result.biliSprache = typeof obj.biliSprache === "undefined" ? null : obj.biliSprache;
+		result.lehrer = typeof obj.lehrer === "undefined" ? null : obj.lehrer;
+		if (typeof obj.wochenstunden === "undefined")
+			 throw new Error('invalid json format, missing attribute wochenstunden');
+		result.wochenstunden = obj.wochenstunden;
+		if (typeof obj.fehlstundenGesamt === "undefined")
+			 throw new Error('invalid json format, missing attribute fehlstundenGesamt');
+		result.fehlstundenGesamt = obj.fehlstundenGesamt;
+		if (typeof obj.fehlstundenUnentschuldigt === "undefined")
+			 throw new Error('invalid json format, missing attribute fehlstundenUnentschuldigt');
+		result.fehlstundenUnentschuldigt = obj.fehlstundenUnentschuldigt;
+		result.notenkuerzel = typeof obj.notenkuerzel === "undefined" ? null : obj.notenkuerzel;
+		result.block1gewertet = typeof obj.block1gewertet === "undefined" ? null : obj.block1gewertet;
+		result.block1kursAufZeugnis = typeof obj.block1kursAufZeugnis === "undefined" ? null : obj.block1kursAufZeugnis;
+		return result;
+	}
+
+	public static transpilerToJSON(obj : AbiturFachbelegungHalbjahr) : string {
+		let result = '{';
+		result += '"halbjahrKuerzel" : ' + '"' + obj.halbjahrKuerzel.valueOf() + '"' + ',';
+		result += '"kursartKuerzel" : ' + '"' + obj.kursartKuerzel.valueOf() + '"' + ',';
+		result += '"schriftlich" : ' + ((!obj.schriftlich) ? 'null' : obj.schriftlich.valueOf()) + ',';
+		result += '"biliSprache" : ' + ((!obj.biliSprache) ? 'null' : '"' + obj.biliSprache.valueOf() + '"') + ',';
+		result += '"lehrer" : ' + ((!obj.lehrer) ? 'null' : obj.lehrer.valueOf()) + ',';
+		result += '"wochenstunden" : ' + obj.wochenstunden + ',';
+		result += '"fehlstundenGesamt" : ' + obj.fehlstundenGesamt + ',';
+		result += '"fehlstundenUnentschuldigt" : ' + obj.fehlstundenUnentschuldigt + ',';
+		result += '"notenkuerzel" : ' + ((!obj.notenkuerzel) ? 'null' : '"' + obj.notenkuerzel.valueOf() + '"') + ',';
+		result += '"block1gewertet" : ' + ((!obj.block1gewertet) ? 'null' : obj.block1gewertet.valueOf()) + ',';
+		result += '"block1kursAufZeugnis" : ' + ((!obj.block1kursAufZeugnis) ? 'null' : obj.block1kursAufZeugnis.valueOf()) + ',';
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+	public static transpilerToJSONPatch(obj : Partial<AbiturFachbelegungHalbjahr>) : string {
+		let result = '{';
+		if (typeof obj.halbjahrKuerzel !== "undefined") {
+			result += '"halbjahrKuerzel" : ' + '"' + obj.halbjahrKuerzel.valueOf() + '"' + ',';
+		}
+		if (typeof obj.kursartKuerzel !== "undefined") {
+			result += '"kursartKuerzel" : ' + '"' + obj.kursartKuerzel.valueOf() + '"' + ',';
+		}
+		if (typeof obj.schriftlich !== "undefined") {
+			result += '"schriftlich" : ' + ((!obj.schriftlich) ? 'null' : obj.schriftlich.valueOf()) + ',';
+		}
+		if (typeof obj.biliSprache !== "undefined") {
+			result += '"biliSprache" : ' + ((!obj.biliSprache) ? 'null' : '"' + obj.biliSprache.valueOf() + '"') + ',';
+		}
+		if (typeof obj.lehrer !== "undefined") {
+			result += '"lehrer" : ' + ((!obj.lehrer) ? 'null' : obj.lehrer.valueOf()) + ',';
+		}
+		if (typeof obj.wochenstunden !== "undefined") {
+			result += '"wochenstunden" : ' + obj.wochenstunden + ',';
+		}
+		if (typeof obj.fehlstundenGesamt !== "undefined") {
+			result += '"fehlstundenGesamt" : ' + obj.fehlstundenGesamt + ',';
+		}
+		if (typeof obj.fehlstundenUnentschuldigt !== "undefined") {
+			result += '"fehlstundenUnentschuldigt" : ' + obj.fehlstundenUnentschuldigt + ',';
+		}
+		if (typeof obj.notenkuerzel !== "undefined") {
+			result += '"notenkuerzel" : ' + ((!obj.notenkuerzel) ? 'null' : '"' + obj.notenkuerzel.valueOf() + '"') + ',';
+		}
+		if (typeof obj.block1gewertet !== "undefined") {
+			result += '"block1gewertet" : ' + ((!obj.block1gewertet) ? 'null' : obj.block1gewertet.valueOf()) + ',';
+		}
+		if (typeof obj.block1kursAufZeugnis !== "undefined") {
+			result += '"block1kursAufZeugnis" : ' + ((!obj.block1kursAufZeugnis) ? 'null' : obj.block1kursAufZeugnis.valueOf()) + ',';
+		}
+		result = result.slice(0, -1);
+		result += '}';
+		return result;
+	}
+
+}
+
+export function cast_de_nrw_schule_svws_core_data_gost_AbiturFachbelegungHalbjahr(obj : unknown) : AbiturFachbelegungHalbjahr {
+	return obj as AbiturFachbelegungHalbjahr;
+}

Some files were not shown because too many files changed in this diff