diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..443b5d2bbffe591f3521ae7716cac354109a0e36
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <bytecodeTargetLevel target="1.6" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ce1c62c7c60561be6b5a9bc9f115e8966e9e5a4a
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c9b4bee44e04c45c5b9b6b14a14beb919daa5497
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" project-jdk-name="IDE SDK" project-jdk-type="JavaSDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/06/.gradle/6.8.3/executionHistory/executionHistory.bin b/06/.gradle/6.8.3/executionHistory/executionHistory.bin
new file mode 100644
index 0000000000000000000000000000000000000000..d3b9b822b5f44c0c024487213c4ca380d33ef27b
Binary files /dev/null and b/06/.gradle/6.8.3/executionHistory/executionHistory.bin differ
diff --git a/06/.gradle/6.8.3/executionHistory/executionHistory.lock b/06/.gradle/6.8.3/executionHistory/executionHistory.lock
new file mode 100644
index 0000000000000000000000000000000000000000..5dc4f3e6c4294e7d473dea4b4fa168fabc85c55b
Binary files /dev/null and b/06/.gradle/6.8.3/executionHistory/executionHistory.lock differ
diff --git a/06/.gradle/6.8.3/fileChanges/last-build.bin b/06/.gradle/6.8.3/fileChanges/last-build.bin
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/06/.gradle/6.8.3/fileChanges/last-build.bin differ
diff --git a/06/.gradle/6.8.3/fileHashes/fileHashes.bin b/06/.gradle/6.8.3/fileHashes/fileHashes.bin
new file mode 100644
index 0000000000000000000000000000000000000000..f2f36b44266f523382c2075fff76b8c3d5451623
Binary files /dev/null and b/06/.gradle/6.8.3/fileHashes/fileHashes.bin differ
diff --git a/06/.gradle/6.8.3/fileHashes/fileHashes.lock b/06/.gradle/6.8.3/fileHashes/fileHashes.lock
new file mode 100644
index 0000000000000000000000000000000000000000..715b18b4b3fb3784d2ea9c5ca934ce72b7dc5f01
Binary files /dev/null and b/06/.gradle/6.8.3/fileHashes/fileHashes.lock differ
diff --git a/06/.gradle/6.8.3/fileHashes/resourceHashesCache.bin b/06/.gradle/6.8.3/fileHashes/resourceHashesCache.bin
new file mode 100644
index 0000000000000000000000000000000000000000..918d44e20463f9a387c8ba723a102fcfc6fa7ba4
Binary files /dev/null and b/06/.gradle/6.8.3/fileHashes/resourceHashesCache.bin differ
diff --git a/06/.gradle/6.8.3/gc.properties b/06/.gradle/6.8.3/gc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/06/.gradle/6.8.3/javaCompile/classAnalysis.bin b/06/.gradle/6.8.3/javaCompile/classAnalysis.bin
new file mode 100644
index 0000000000000000000000000000000000000000..51a8c08620dfa4ccaedc49624348c6e999bf2d3f
Binary files /dev/null and b/06/.gradle/6.8.3/javaCompile/classAnalysis.bin differ
diff --git a/06/.gradle/6.8.3/javaCompile/jarAnalysis.bin b/06/.gradle/6.8.3/javaCompile/jarAnalysis.bin
new file mode 100644
index 0000000000000000000000000000000000000000..ef4c0d9d25dee83ff02cc1d6ea572a2d9becb1e9
Binary files /dev/null and b/06/.gradle/6.8.3/javaCompile/jarAnalysis.bin differ
diff --git a/06/.gradle/6.8.3/javaCompile/javaCompile.lock b/06/.gradle/6.8.3/javaCompile/javaCompile.lock
new file mode 100644
index 0000000000000000000000000000000000000000..bf112645e2cea75794351e6415845df5a6308d66
Binary files /dev/null and b/06/.gradle/6.8.3/javaCompile/javaCompile.lock differ
diff --git a/06/.gradle/6.8.3/javaCompile/taskHistory.bin b/06/.gradle/6.8.3/javaCompile/taskHistory.bin
new file mode 100644
index 0000000000000000000000000000000000000000..cbba819d7999688a42da6185ac84c332973a2c2c
Binary files /dev/null and b/06/.gradle/6.8.3/javaCompile/taskHistory.bin differ
diff --git a/06/.gradle/8.2/checksums/checksums.lock b/06/.gradle/8.2/checksums/checksums.lock
new file mode 100644
index 0000000000000000000000000000000000000000..3eaea90c3f82365c47beffcb10909a6998922914
Binary files /dev/null and b/06/.gradle/8.2/checksums/checksums.lock differ
diff --git a/06/.gradle/8.2/checksums/md5-checksums.bin b/06/.gradle/8.2/checksums/md5-checksums.bin
new file mode 100644
index 0000000000000000000000000000000000000000..cd8ea0c31c5766de598bb6ecc11fecb272d94675
Binary files /dev/null and b/06/.gradle/8.2/checksums/md5-checksums.bin differ
diff --git a/06/.gradle/8.2/checksums/sha1-checksums.bin b/06/.gradle/8.2/checksums/sha1-checksums.bin
new file mode 100644
index 0000000000000000000000000000000000000000..89796d4a80c5f71696af79061e106b6e9bb10009
Binary files /dev/null and b/06/.gradle/8.2/checksums/sha1-checksums.bin differ
diff --git a/06/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock b/06/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock
new file mode 100644
index 0000000000000000000000000000000000000000..3ad7dcd024edb76ed5e46c11c7cad065f7283540
Binary files /dev/null and b/06/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock differ
diff --git a/06/.gradle/8.2/dependencies-accessors/gc.properties b/06/.gradle/8.2/dependencies-accessors/gc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/06/.gradle/8.2/executionHistory/executionHistory.bin b/06/.gradle/8.2/executionHistory/executionHistory.bin
new file mode 100644
index 0000000000000000000000000000000000000000..d873c881b9b3369e8293e1d5354b995f7fb88616
Binary files /dev/null and b/06/.gradle/8.2/executionHistory/executionHistory.bin differ
diff --git a/06/.gradle/8.2/executionHistory/executionHistory.lock b/06/.gradle/8.2/executionHistory/executionHistory.lock
new file mode 100644
index 0000000000000000000000000000000000000000..d5daa5233e057a55b8928c69f474e74d3335b6f1
Binary files /dev/null and b/06/.gradle/8.2/executionHistory/executionHistory.lock differ
diff --git a/06/.gradle/8.2/fileChanges/last-build.bin b/06/.gradle/8.2/fileChanges/last-build.bin
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/06/.gradle/8.2/fileChanges/last-build.bin differ
diff --git a/06/.gradle/8.2/fileHashes/fileHashes.bin b/06/.gradle/8.2/fileHashes/fileHashes.bin
new file mode 100644
index 0000000000000000000000000000000000000000..992241352d46832106e0b20a8c70542d1b206428
Binary files /dev/null and b/06/.gradle/8.2/fileHashes/fileHashes.bin differ
diff --git a/06/.gradle/8.2/fileHashes/fileHashes.lock b/06/.gradle/8.2/fileHashes/fileHashes.lock
new file mode 100644
index 0000000000000000000000000000000000000000..a55cfb581eeccac3186114df3d511fc5fc051669
Binary files /dev/null and b/06/.gradle/8.2/fileHashes/fileHashes.lock differ
diff --git a/06/.gradle/8.2/fileHashes/resourceHashesCache.bin b/06/.gradle/8.2/fileHashes/resourceHashesCache.bin
new file mode 100644
index 0000000000000000000000000000000000000000..808355b699fde87c2689de3bcba95546abaf50f2
Binary files /dev/null and b/06/.gradle/8.2/fileHashes/resourceHashesCache.bin differ
diff --git a/06/.gradle/8.2/gc.properties b/06/.gradle/8.2/gc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/06/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/06/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000000000000000000000000000000000000..22a5694332548630db53d518ebdf86c2abfe99b5
Binary files /dev/null and b/06/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/06/.gradle/buildOutputCleanup/cache.properties b/06/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000000000000000000000000000000000000..25219e7a3cd29dcff8b098778b19a6d6fd081237
--- /dev/null
+++ b/06/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Mon Jul 10 12:12:56 CEST 2023
+gradle.version=6.8.3
diff --git a/06/.gradle/buildOutputCleanup/outputFiles.bin b/06/.gradle/buildOutputCleanup/outputFiles.bin
new file mode 100644
index 0000000000000000000000000000000000000000..301b21436b8a7100aa93cfceaa5e096360295700
Binary files /dev/null and b/06/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/06/.gradle/checksums/checksums.lock b/06/.gradle/checksums/checksums.lock
new file mode 100644
index 0000000000000000000000000000000000000000..beaec4973ad14c847864a7735cbd5716031289a9
Binary files /dev/null and b/06/.gradle/checksums/checksums.lock differ
diff --git a/06/.gradle/checksums/md5-checksums.bin b/06/.gradle/checksums/md5-checksums.bin
new file mode 100644
index 0000000000000000000000000000000000000000..d5756eadbdbb27d739e0857c1a0a2fcc0ba4ad64
Binary files /dev/null and b/06/.gradle/checksums/md5-checksums.bin differ
diff --git a/06/.gradle/checksums/sha1-checksums.bin b/06/.gradle/checksums/sha1-checksums.bin
new file mode 100644
index 0000000000000000000000000000000000000000..0c19551b0eca08ff7814bcf4afd4f71e70bdc639
Binary files /dev/null and b/06/.gradle/checksums/sha1-checksums.bin differ
diff --git a/06/.gradle/configuration-cache/gc.properties b/06/.gradle/configuration-cache/gc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/06/.gradle/file-system.probe b/06/.gradle/file-system.probe
new file mode 100644
index 0000000000000000000000000000000000000000..9a0ac202a70aedeca37dbab869b4ec2e3d3eadec
Binary files /dev/null and b/06/.gradle/file-system.probe differ
diff --git a/06/.gradle/vcs-1/gc.properties b/06/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/06/.idea/.gitignore b/06/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/06/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/06/.idea/.name b/06/.idea/.name
new file mode 100644
index 0000000000000000000000000000000000000000..7d08cd38328b67bc452694d3ed626ad68c011d8f
--- /dev/null
+++ b/06/.idea/.name
@@ -0,0 +1 @@
+06-annotations-reflection
\ No newline at end of file
diff --git a/06/.idea/compiler.xml b/06/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb7f4a8a465d42b4a0390d464b83b99e8465bba7
--- /dev/null
+++ b/06/.idea/compiler.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <bytecodeTargetLevel target="11" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/06/.idea/gradle.xml b/06/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f9163b40e6f3594044b71ebcb4aee74d25d94ab4
--- /dev/null
+++ b/06/.idea/gradle.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/06/.idea/jarRepositories.xml b/06/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fdc392fe877c32ab51d532fa67f65ff2e75e9061
--- /dev/null
+++ b/06/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="MavenRepo" />
+      <option name="name" value="MavenRepo" />
+      <option name="url" value="https://repo.maven.apache.org/maven2/" />
+    </remote-repository>
+  </component>
+</project>
\ No newline at end of file
diff --git a/06/.idea/misc.xml b/06/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..861a66485407db89406cbfbcc35d2332e3a489b8
--- /dev/null
+++ b/06/.idea/misc.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="IDE SDK" project-jdk-type="JavaSDK" />
+</project>
\ No newline at end of file
diff --git a/06/.idea/vcs.xml b/06/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/06/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/06/LICENSE b/06/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..ed3a58dc8971785b81f4ad71d31109737fb8950d
--- /dev/null
+++ b/06/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 HS Rosenheim :: Informatik :: Programmieren 3
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/06/README.md b/06/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2c1c6ed67d4395ca3b1071d776c670f8f00a629c
--- /dev/null
+++ b/06/README.md
@@ -0,0 +1,183 @@
+_This is an assignment to the [Software Architecture](https://ohm-softa.github.io) class at the [Technische Hochschule Nürnberg](http://www.th-nuernberg.de)._
+
+
+# Assignment 6: Annotations and Reflection
+[![Travis CI](https://travis-ci.org/hsro-inf-prg3/06-annotations-reflection.svg?branch=master)](https://travis-ci.org/hsro-inf-prg3/06-annotations-reflection)
+
+In this assignment we will use Java annotations and reflection to interact with a remote REST ([Representational State Transfer](https://en.wikipedia.org/wiki/Representational_state_transfer)) API.
+As everyone (or maybe just me) loves Chuck Norris jokes we will implement a simple program to get random Chuck Norris jokes from the [CNJDB](https://api.chucknorris.io/) (**C**huck **N**orris **J**okes **D**ata**b**ase).
+
+## Setup
+
+1. Create a fork of this repository (button in the right upper corner)
+2. Clone the project (get the link by clicking the green _Clone or download button_)
+3. Import the project to your IDE (remember the guide in [assignment 1](https://github.com/hsro-inf-prg3/01-tools))
+4. Validate your environment by running the tests from your IntelliJ and by running `gradle test` on the command line.
+
+
+## Gradle and Dependency Management
+
+When we started to use Gradle we already talked about dependency management.
+In this assignment we will use Gradle to manage the required libraries.
+
+To complete this assignment you will need the following libraries:
+
+* [Retrofit](http://square.github.io/retrofit/) by Square
+* [Gson](https://github.com/google/gson) by Google
+
+With Gradle, project dependencies (both at compile and runtime) are specified in the `build.gradle` file, in the `dependencies` section.
+Open the existing [build.gradle](./build.gradle) file and inspect the `dependencies` object (Gradle uses [Groovy](http://groovy-lang.org/), a language similar to Java and Javascript).
+Every dependency has a scope where it will be available.
+To use a library across the whole project, declare it with the scope `implementation`.
+
+Gradle is designed to help you in all development phases and is extensible by plugins.
+In the given `build.gradle` are three plugins already applied:
+
+* `java`: brings Java support to Gradle e.g. compilation)
+* `application`: enable you to run and package the application you will develop in this assignment
+* `idea`: helps with IntelliJ import
+
+To run the `main` method in the `App` class without IntelliJ you can now use the following Gradle command on the command line:
+
+```bash
+gradle run
+```
+
+
+## Overview
+
+The hard part of this assigment is you need to combine three parts to form the whole program:
+
+- Gson for serialization
+- Retrofit for HTTP requests
+- A Gson type adapter to handle the status of the request response
+
+It is strongly advised to read through the whole assignment and related documentations first; having the complete picture before starting with the parts helps a lot!
+
+
+## Gson
+
+Google Gson is a library to serialize and deserialize [JSON](https://en.wikipedia.org/wiki/JSON) to or from Java objects.
+
+
+### Model
+
+The following code snippet shows the structure of a simple JSON object:
+
+```json
+{
+    "id": "id-13434",
+    "value": "Ghosts are actually caused by Chuck Norris killing people faster than Death can process them.",
+    "categories": []
+}
+```
+
+The most basic use case is to de/serialize objects; by defaut, Gson uses reflection to determine the properties.
+
+```java
+class Joke {
+  String id;
+  String value;
+  String[] categories;
+}
+```
+
+```java
+Gson gson = new Gson();
+
+// JSON String --> Object
+Joke j = gson.fromJson("{\"id\": 0, \"value\": \"Haha.\"}", Joke.class);
+// categories remains `null`
+
+// Objec --> JSON String
+String json = gson.toJson(j);
+```
+
+Gson makes use of annotations to map JSON keys to fields of your class.
+Have a look at the [docs](https://github.com/google/gson/blob/master/UserGuide.md) and complete the model described in the following UML:
+
+![Model spec](./assets/images/ModelSpec.svg)
+
+> Hint: the given JSON object describes the exact structure of the JSON objects we want to deserialize.
+> Use anntations to help gson map JSON fields to differently named Java field names.
+
+- Import Gson to your project
+- Familiarize yourself with Gson by trying a few examples
+- Get familiar with the `@SerializedName` annotation
+
+## Retrofit and Gson
+
+As you could see from the examples above, the actual response body of the CNJDB API looks like the following:
+
+```json
+{
+	"categories": ["nerdy"],
+	"id": "irKXY3NtTXGe6W529sVlOg",
+	"value": "Chuck Norris can delete the Recycling Bin."
+}
+```
+
+The actual joke (`Joke`) is wrapped inside a response object which indicates if the request was successfull.
+To be able to unwrap the jokes correctly (or throw an exception if there is no joke) you need to implement a Gson type adapter as shown in the following UML.
+
+![Gson type adapter](./assets/images/GsonSpec.svg)
+
+In a nutshell, a (Gson) type adapter is responsible to convert Java objects to JSON notation and vice versa.
+Key to this transformation is in the implementation of the following two methods:
+
+```java
+public abstract class TypeAdapter<T> {
+	public abstract T read(final JsonReader reader);
+ 	public abstract void write(final JsonWriter writer, final T inst);
+
+	// ...
+}
+```
+
+- Write a type adapter that accepts the response objects from CNJDB and outputs an instance of `Joke`.
+- Register the type adapter with your Retrofit instance
+Note that you can use annotations on the `Joke` class, but you will have to write custom code to unwrap the joke from the response object.
+For this, you have two options:
+
+* Implement a wrapper class, add appropriate fields, and return the `Joke` once unwrapped.
+* Unwrap the response object manually, by using the `reader`'s `.beginObject()`, `.endObject()` and `.next*()` methods to determine the number of jokes.
+
+> Note: There is no need to implement the `write` method, since we're only consuming the API, but not sending to it.
+
+Check out this extensive [tutorial on Gson type adapters](https://github.com/albertattard/gson-typeadapter-example/).
+
+
+## Retrofit
+
+Retrofit is a great library to implement HTTP clients.
+To create an HTTP client, create an interface containing some methods you will call later to perform HTTP requests.
+Retrofit also uses annotations to conveniently map these methods to API resource paths, e.g. `getJokesBySearch("horse")` can be mapped to `GET https://api.chucknorris.io/jokes/search?query=horse`.
+
+Read through the [Retrofit documentation](http://square.github.io/retrofit/) and implement the `CNJDBApi` interface as shown in the following UML:
+
+![Retrofic spec](./assets/images/RetrofitAdapter.svg)
+
+- Start by implementing the method `getRandomJoke()`; use the appropriate annotations to decodate the interface method.
+- Modify the `main` method in the `App` class to create an instance of the `CNJDBApi` using `Retrofit.Builder`. You need to add a converter factory that helps converting the JSON response to an object; you can set Gson using `GsonConverterFactory.create()`.
+- Print a random joke to `System.out`, and complete the test method `testCollision`. Recall that you work with `Call` objects that need to be executed before you can retrieve the response body.
+- After completing the `getRandomJoke()` method try to add the other methods.
+- If you are not sure if your query strings are correct you can test them within the command line using `curl` or in a browser extension such as [Postman](https://www.getpostman.com/).
+
+Most unix systems will provide the cURL program:
+
+```bash
+curl -X GET "https://api.chucknorris.io/jokes/random" -H "accept: application/json"
+```
+
+On Windows, you can use the PowerShell to accomplish the same like so:
+
+```ps
+(Invoke-WebRequest
+    -Uri https://api.chucknorris.io/jokes/random
+    -Headers @{"accept"="application/json"}
+    ).Content | ConvertFrom-Json | ConvertTo-Json
+```
+
+(The part `| ConvertFrom-Json | ConvertTo-Json` is only necessary for formatting.)
+
+_Remark: to execute this command you have to remove the newlines!_
diff --git a/06/assets/images/GsonSpec.svg b/06/assets/images/GsonSpec.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9ec97680779aef7db4e023633096f93d71815196
--- /dev/null
+++ b/06/assets/images/GsonSpec.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="222px" preserveAspectRatio="none" style="width:192px;height:222px;" version="1.1" viewBox="0 0 192 222" width="192px" zoomAndPan="magnify"><defs><filter height="300%" id="f1gg8nmrixnqu4" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><!--cluster com.google.gson--><polygon fill="#FFFFFF" filter="url(#f1gg8nmrixnqu4)" points="14,16,140,16,147,41.0679,152,41.0679,152,102,14,102,14,16" style="stroke: #000000; stroke-width: 1.5;"/><line style="stroke: #000000; stroke-width: 1.5;" x1="14" x2="147" y1="41.0679" y2="41.0679"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="120" x="18" y="32.9659">com.google.gson</text><!--cluster de.thro.inf.prg3.a06--><polygon fill="#FFFFFF" filter="url(#f1gg8nmrixnqu4)" points="17,124,160,124,167,149.0679,170,149.0679,170,210,17,210,17,124" style="stroke: #000000; stroke-width: 1.5;"/><line style="stroke: #000000; stroke-width: 1.5;" x1="17" x2="167" y1="149.0679" y2="149.0679"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="137" x="21" y="140.9659">de.thro.inf.prg3.a06</text><!--class TypeAdapter--><rect fill="#FEFECE" filter="url(#f1gg8nmrixnqu4)" height="48" id="TypeAdapter" style="stroke: #A80036; stroke-width: 1.5;" width="121" x="22.5" y="46"/><ellipse cx="37.5" cy="62" fill="#A9DCDF" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M40.4531,67.25 L39.5781,64.3594 L35.1563,64.3594 L34.2656,67.25 L31.5,67.25 L35.7813,55.0625 L38.9219,55.0625 L43.2344,67.25 L40.4531,67.25 Z M38.9688,62.2031 L38.0781,59.375 Q38,59.0938 37.8594,58.6484 Q37.7188,58.2031 37.5859,57.7422 Q37.4531,57.2813 37.3594,56.9531 Q37.2813,57.2813 37.1328,57.7891 Q36.9844,58.2969 36.8594,58.7422 Q36.7344,59.1875 36.6719,59.375 L35.7969,62.2031 L38.9688,62.2031 Z "/><ellipse cx="56.5" cy="61.5" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="68" x="62.5" y="66.656">TypeAdapter</text><rect fill="#FFFFFF" height="18.3441" style="stroke: #000000; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" width="8" x="138.5" y="43"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="6" x="139.5" y="56.8281">T</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="23.5" x2="142.5" y1="78" y2="78"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="23.5" x2="142.5" y1="86" y2="86"/><!--class JokeAdapter--><rect fill="#FEFECE" filter="url(#f1gg8nmrixnqu4)" height="48" id="JokeAdapter" style="stroke: #A80036; stroke-width: 1.5;" width="111" x="27.5" y="154"/><ellipse cx="42.5" cy="170" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M42.1875,166.3281 Q40.7031,166.3281 39.9219,167.4375 Q39.1406,168.5469 39.1406,170.4688 Q39.1406,172.4063 39.8594,173.4688 Q40.5781,174.5313 42.1875,174.5313 Q42.9219,174.5313 43.6641,174.3594 Q44.4063,174.1875 45.2813,173.875 L45.2813,176.0469 Q44.4688,176.3594 43.6875,176.5156 Q42.9063,176.6719 41.9375,176.6719 Q40.0781,176.6719 38.8594,175.8984 Q37.6406,175.125 37.0625,173.7188 Q36.4844,172.3125 36.4844,170.4531 Q36.4844,168.6094 37.1484,167.2031 Q37.8125,165.7969 39.0781,164.9922 Q40.3438,164.1875 42.1875,164.1875 Q43.0781,164.1875 43.9922,164.4219 Q44.9063,164.6563 45.7344,165.0469 L44.9063,167.1406 Q44.2188,166.8125 43.5313,166.5703 Q42.8438,166.3281 42.1875,166.3281 Z "/><ellipse cx="61.5" cy="169.5" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="68" x="67.5" y="174.656">JokeAdapter</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="28.5" x2="137.5" y1="186" y2="186"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="28.5" x2="137.5" y1="194" y2="194"/><!--link TypeAdapter to JokeAdapter--><path d="M83,114.2911 C83,127.8171 83,142.1835 83,153.8436 " fill="none" id="TypeAdapter-JokeAdapter" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="none" points="76.0001,114.2373,83,94.2373,90.0001,114.2373,76.0001,114.2373" style="stroke: #A80036; stroke-width: 1.0;"/><!--
+@startuml GsonSpec
+
+package com.google.gson {
+    +abstract class TypeAdapter<T> {
+    }
+}
+
+
+package de.thro.inf.prg3.a06 {
+    +class JokeAdapter extends TypeAdapter {
+    }
+}
+
+@enduml
+
+PlantUML version 1.2018.12(Sun Oct 21 12:15:15 CEST 2018)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 1.8.0_192-b26
+Operating System: Linux
+OS Version: 4.18.16-arch1-1-ARCH
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg>
\ No newline at end of file
diff --git a/06/assets/images/ModelSpec.svg b/06/assets/images/ModelSpec.svg
new file mode 100644
index 0000000000000000000000000000000000000000..a53c6f89c803afa0f5e5598648459eb212a54d12
--- /dev/null
+++ b/06/assets/images/ModelSpec.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="259px" preserveAspectRatio="none" style="width:331px;height:259px;background:#FFFFFF;" version="1.1" viewBox="0 0 331 259" width="331px" zoomAndPan="magnify"><defs/><g><!--cluster P1--><g id="cluster_P1"><path d="M9.5,6 L225.5,6 A5.25,5.25 0 0 1 229,9.5 L236,28.2969 L320.5,28.2969 A3.5,3.5 0 0 1 324,31.7969 L324,248.5 A3.5,3.5 0 0 1 320.5,252 L9.5,252 A3.5,3.5 0 0 1 6,248.5 L6,9.5 A3.5,3.5 0 0 1 9.5,6 " fill="none" style="stroke:#696969;stroke-width:1.0;"/><line style="stroke:#696969;stroke-width:1.0;" x1="6" x2="236" y1="28.2969" y2="28.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="217" x="10" y="20.9951">de.thro.inf.prg3.a06.model</text></g><!--class Joke--><g id="elem_Joke"><rect codeLine="3" fill="#F1F1F1" height="194.6719" id="Joke" rx="3.5" ry="3.5" style="stroke:#181818;stroke-width:0.5;" width="285" x="22.5" y="41"/><ellipse cx="139.75" cy="57" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M142.0938,52.6719 C141.1563,52.2344 140.5625,52.0938 139.6875,52.0938 C137.0625,52.0938 135.0625,54.1719 135.0625,56.8906 L135.0625,58.0156 C135.0625,60.5938 137.1719,62.4844 140.0625,62.4844 C141.2813,62.4844 142.4375,62.1875 143.1875,61.6406 C143.7656,61.2344 144.0938,60.7813 144.0938,60.3906 C144.0938,59.9375 143.7031,59.5469 143.2344,59.5469 C143.0156,59.5469 142.8125,59.625 142.625,59.8125 C142.1719,60.2969 142.1719,60.2969 141.9844,60.3906 C141.5625,60.6563 140.875,60.7813 140.1094,60.7813 C138.0625,60.7813 136.7656,59.6875 136.7656,57.9844 L136.7656,56.8906 C136.7656,55.1094 138.0156,53.7969 139.75,53.7969 C140.3281,53.7969 140.9375,53.9531 141.4063,54.2031 C141.8906,54.4844 142.0625,54.7031 142.1563,55.1094 C142.2188,55.5156 142.25,55.6406 142.3906,55.7656 C142.5313,55.9063 142.7656,56.0156 142.9844,56.0156 C143.25,56.0156 143.5156,55.875 143.6875,55.6563 C143.7969,55.5 143.8281,55.3125 143.8281,54.8906 L143.8281,53.4688 C143.8281,53.0313 143.8125,52.9063 143.7188,52.75 C143.5625,52.4844 143.2813,52.3438 142.9844,52.3438 C142.6875,52.3438 142.4844,52.4375 142.2656,52.75 L142.0938,52.6719 Z " fill="#000000"/><ellipse cx="165.25" cy="56.5" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="31" x="171.25" y="61.8467">Joke</text><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="306.5" y1="73" y2="73"/><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1.0;" width="6" x="30.5" y="83.6484"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="120" x="42.5" y="89.9951">identifier: String</text><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1.0;" width="6" x="30.5" y="99.9453"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="111" x="42.5" y="106.292">content: String</text><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1.0;" width="6" x="30.5" y="116.2422"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="112" x="42.5" y="122.5889">rubrics: String[]</text><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="306.5" y1="129.8906" y2="129.8906"/><ellipse cx="33.5" cy="143.5391" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="155" x="42.5" y="146.8857">getIdentifier(): String</text><ellipse cx="33.5" cy="159.8359" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="259" x="42.5" y="163.1826">setIdentifier(identifier: String): void</text><ellipse cx="33.5" cy="176.1328" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="148" x="42.5" y="179.4795">getContent(): String</text><ellipse cx="33.5" cy="192.4297" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="243" x="42.5" y="195.7764">setContent(content: String): void</text><ellipse cx="33.5" cy="208.7266" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="151" x="42.5" y="212.0732">getRubrics(): String[]</text><ellipse cx="33.5" cy="225.0234" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="237" x="42.5" y="228.3701">setRubrics(rubrics: String[]): void</text></g><!--SRC=[TO-n3e8m48PtdkBSDCH6O-BWwgIJqT4ubFQ02z2Ijh8OtjqgGS3gZVVTVVVVpELO8JIK6AvSL7DHy0n18dEvqOnKocgJRHXVRLcb9PR0BPpMy8Z0LonARYqSTO6-yswzQaaIbQEKqEpWuWofR612A-Tf2CmzCIHi3wwtGHXdw0uVvtmHBCTsCX3UzokD9ZanxhiaVtGz_ShxItJkaWyYdtsiwddmuLZMHkqJ]--></g></svg>
\ No newline at end of file
diff --git a/06/assets/images/RetrofitAdapter.svg b/06/assets/images/RetrofitAdapter.svg
new file mode 100644
index 0000000000000000000000000000000000000000..cce7f12e87530c29a996e921e7ce657503202e0f
--- /dev/null
+++ b/06/assets/images/RetrofitAdapter.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="177px" preserveAspectRatio="none" style="width:648px;height:177px;background:#FFFFFF;" version="1.1" viewBox="0 0 648 177" width="648px" zoomAndPan="magnify"><defs/><g><!--cluster P1--><g id="cluster_P1"><path d="M9.5,6 L127.5,6 A5.25,5.25 0 0 1 131,9.5 L138,28.2969 L637.5,28.2969 A3.5,3.5 0 0 1 641,31.7969 L641,166.5 A3.5,3.5 0 0 1 637.5,170 L9.5,170 A3.5,3.5 0 0 1 6,166.5 L6,9.5 A3.5,3.5 0 0 1 9.5,6 " fill="none" style="stroke:#696969;stroke-width:1.0;"/><line style="stroke:#696969;stroke-width:1.0;" x1="6" x2="138" y1="28.2969" y2="28.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="119" x="10" y="20.9951">ohm.softa.a06</text></g><!--class CNJDBApi--><g id="elem_CNJDBApi"><rect codeLine="4" fill="#F1F1F1" height="113.1875" id="CNJDBApi" rx="3.5" ry="3.5" style="stroke:#181818;stroke-width:0.5;" width="364" x="261" y="41"/><ellipse cx="399.25" cy="57" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M400.2031,53.7813 L401.9219,53.7813 C402.3125,53.7813 402.5,53.75 402.625,53.6719 C402.8906,53.5156 403.0313,53.2344 403.0313,52.9375 C403.0313,52.6719 402.9219,52.4063 402.6875,52.2344 C402.5156,52.125 402.375,52.0938 401.9219,52.0938 L396.7813,52.0938 C396.3438,52.0938 396.2188,52.1094 396.0625,52.2031 C395.8125,52.3594 395.6563,52.6563 395.6563,52.9375 C395.6563,53.2188 395.7969,53.4688 396.0156,53.6406 C396.1719,53.75 396.3594,53.7813 396.7813,53.7813 L398.5,53.7813 L398.5,60.2969 L396.7813,60.2969 C396.3438,60.2969 396.2188,60.3125 396.0625,60.4219 C395.8125,60.5781 395.6563,60.8594 395.6563,61.1563 C395.6563,61.4063 395.7969,61.6719 396.0156,61.8281 C396.1719,61.9531 396.375,62 396.7813,62 L401.9219,62 C402.6719,62 403.0313,61.7188 403.0313,61.1563 C403.0313,60.875 402.9219,60.625 402.6875,60.4531 C402.5156,60.3281 402.375,60.2969 401.9219,60.2969 L400.2031,60.2969 L400.2031,53.7813 Z " fill="#000000"/><ellipse cx="424.75" cy="56.5" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="68" x="430.75" y="61.8467">CNJDBApi</text><line style="stroke:#181818;stroke-width:0.5;" x1="262" x2="624" y1="73" y2="73"/><line style="stroke:#181818;stroke-width:0.5;" x1="262" x2="624" y1="81" y2="81"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="213" x="267" y="97.9951">getRandomJoke(): Call&lt;Joke&gt;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="352" x="267" y="114.292">getRandomJoke(categories: String[]): Call&lt;Joke&gt;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="331" x="267" y="130.5889">getJokesBySearch(query: String): Call&lt;Joke[]&gt;</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="220" x="267" y="146.8857">getJoke(id: String): Call&lt;Joke&gt;</text></g><!--class App--><g id="elem_App"><rect codeLine="11" fill="#F1F1F1" height="64.2969" id="App" rx="3.5" ry="3.5" style="stroke:#181818;stroke-width:0.5;" width="203" x="22.5" y="65.5"/><ellipse cx="99.25" cy="81.5" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M101.5938,77.1719 C100.6563,76.7344 100.0625,76.5938 99.1875,76.5938 C96.5625,76.5938 94.5625,78.6719 94.5625,81.3906 L94.5625,82.5156 C94.5625,85.0938 96.6719,86.9844 99.5625,86.9844 C100.7813,86.9844 101.9375,86.6875 102.6875,86.1406 C103.2656,85.7344 103.5938,85.2813 103.5938,84.8906 C103.5938,84.4375 103.2031,84.0469 102.7344,84.0469 C102.5156,84.0469 102.3125,84.125 102.125,84.3125 C101.6719,84.7969 101.6719,84.7969 101.4844,84.8906 C101.0625,85.1563 100.375,85.2813 99.6094,85.2813 C97.5625,85.2813 96.2656,84.1875 96.2656,82.4844 L96.2656,81.3906 C96.2656,79.6094 97.5156,78.2969 99.25,78.2969 C99.8281,78.2969 100.4375,78.4531 100.9063,78.7031 C101.3906,78.9844 101.5625,79.2031 101.6563,79.6094 C101.7188,80.0156 101.75,80.1406 101.8906,80.2656 C102.0313,80.4063 102.2656,80.5156 102.4844,80.5156 C102.75,80.5156 103.0156,80.375 103.1875,80.1563 C103.2969,80 103.3281,79.8125 103.3281,79.3906 L103.3281,77.9688 C103.3281,77.5313 103.3125,77.4063 103.2188,77.25 C103.0625,76.9844 102.7813,76.8438 102.4844,76.8438 C102.1875,76.8438 101.9844,76.9375 101.7656,77.25 L101.5938,77.1719 Z " fill="#000000"/><ellipse cx="124.75" cy="81" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="30" x="130.75" y="86.3467">App</text><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="224.5" y1="97.5" y2="97.5"/><line style="stroke:#181818;stroke-width:0.5;" x1="23.5" x2="224.5" y1="105.5" y2="105.5"/><ellipse cx="33.5" cy="119.1484" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" text-decoration="underline" textLength="177" x="42.5" y="122.4951">main(args: String[]): void</text></g><!--SRC=[TOyn2y9038Nt_eguLGJHnQ68e7Ng8697wH2lyHhQtjMxA1JfVrUnWgA-BSdxmdi3AQWckF31eP6WGLMY9h15FVRsA3Z6oGpGmtOAro20kqPiXDmH5K6yITQhPSFt4_JI93iqkQqJMr8uZ236gfe_XiKVZq8XRHsJZo0LnqRlix_SO-5NRKheL16UpkJQ5_NExBClAkJyb_Ffw_fggaBlOTaqRur6Loyeh3geaKs8Jdy6lLZE-oVT3G00]--></g></svg>
\ No newline at end of file
diff --git a/06/assets/uml/gson-spec.plantuml b/06/assets/uml/gson-spec.plantuml
new file mode 100644
index 0000000000000000000000000000000000000000..2cda1b7cacdfe4d08f2207b267051b9c367d711e
--- /dev/null
+++ b/06/assets/uml/gson-spec.plantuml
@@ -0,0 +1,14 @@
+@startuml GsonSpec
+
+package com.google.gson {
+    +abstract class TypeAdapter<T> {
+    }
+}
+
+
+package de.thro.inf.prg3.a06 {
+    +class JokeAdapter extends TypeAdapter {
+    }
+}
+
+@enduml
\ No newline at end of file
diff --git a/06/assets/uml/model-spec.plantuml b/06/assets/uml/model-spec.plantuml
new file mode 100644
index 0000000000000000000000000000000000000000..a33aa88be15fc7db6d468e392cc11d40f6d9ab6c
--- /dev/null
+++ b/06/assets/uml/model-spec.plantuml
@@ -0,0 +1,18 @@
+@startuml
+!theme vibrant
+package de.thro.inf.prg3.a06.model as P1 {
+    +class Joke {
+
+        -identifier: String
+        -content: String
+        -rubrics: String[]
+
+        +getIdentifier(): String
+        +setIdentifier(identifier: String): void
+        +getContent(): String
+        +setContent(content: String): void
+        +getRubrics(): String[]
+        +setRubrics(rubrics: String[]): void
+    }
+}
+@enduml
diff --git a/06/assets/uml/retrofit-spec.plantuml b/06/assets/uml/retrofit-spec.plantuml
new file mode 100644
index 0000000000000000000000000000000000000000..f7a59724e8f1f063a2e3fe1d5fa46dfb22887159
--- /dev/null
+++ b/06/assets/uml/retrofit-spec.plantuml
@@ -0,0 +1,16 @@
+@startuml
+!theme vibrant
+package ohm.softa.a06 as P1 {
+
+    +interface CNJDBApi {
+        getRandomJoke(): Call<Joke>
+        getRandomJoke(categories: String[]): Call<Joke>
+        getJokesBySearch(query: String): Call<Joke[]>
+        getJoke(id: String): Call<Joke>
+    }
+
+    +class App {
+        +{static} main(args: String[]): void
+    }
+}
+@enduml
diff --git a/06/build.gradle b/06/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..966887e8198d7ba6ec0cee01fc35b5e6a9e0fe5b
--- /dev/null
+++ b/06/build.gradle
@@ -0,0 +1,33 @@
+plugins {
+    id 'java'
+    id 'application'
+    id 'idea'
+}
+
+group 'ohm.softa'
+version '1.0-SNAPSHOT'
+
+sourceCompatibility = 11
+
+mainClassName = "ohm.softa.a06.App"
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    implementation("org.apache.commons:commons-lang3:$apacheCommonsLangVersion")
+    implementation("org.apache.logging.log4j:log4j-api:${log4j2Version}")
+    implementation("org.apache.logging.log4j:log4j-core:${log4j2Version}")
+
+    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
+    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
+    testRuntimeOnly("org.junit.jupiter:junit-jupiter-params:${junitVersion}")
+}
+
+test {
+    useJUnitPlatform()
+    testLogging {
+        events "passed", "skipped", "failed"
+    }
+}
diff --git a/06/build/classes/java/main/ohm/softa/a06/App$Test.class b/06/build/classes/java/main/ohm/softa/a06/App$Test.class
new file mode 100644
index 0000000000000000000000000000000000000000..238038cbbc5affe392bfaefec8ce9f6569ede90c
Binary files /dev/null and b/06/build/classes/java/main/ohm/softa/a06/App$Test.class differ
diff --git a/06/build/classes/java/main/ohm/softa/a06/App.class b/06/build/classes/java/main/ohm/softa/a06/App.class
new file mode 100644
index 0000000000000000000000000000000000000000..c387029a136be7c54fe49e972eb0591dc0c5b918
Binary files /dev/null and b/06/build/classes/java/main/ohm/softa/a06/App.class differ
diff --git a/06/build/classes/java/main/ohm/softa/a06/CNJDBApi.class b/06/build/classes/java/main/ohm/softa/a06/CNJDBApi.class
new file mode 100644
index 0000000000000000000000000000000000000000..b9340e941614eb338994cc272848792cb2881896
Binary files /dev/null and b/06/build/classes/java/main/ohm/softa/a06/CNJDBApi.class differ
diff --git a/06/build/classes/java/main/ohm/softa/a06/model/Joke.class b/06/build/classes/java/main/ohm/softa/a06/model/Joke.class
new file mode 100644
index 0000000000000000000000000000000000000000..2282454f05a6b7262b8b885112c13f83ea0e59b5
Binary files /dev/null and b/06/build/classes/java/main/ohm/softa/a06/model/Joke.class differ
diff --git a/06/build/classes/java/test/ohm/softa/a06/tests/CNJDBTests.class b/06/build/classes/java/test/ohm/softa/a06/tests/CNJDBTests.class
new file mode 100644
index 0000000000000000000000000000000000000000..74293c2e4f9bcfa318f9f2d4ae42defe60c9fcfe
Binary files /dev/null and b/06/build/classes/java/test/ohm/softa/a06/tests/CNJDBTests.class differ
diff --git a/06/build/resources/main/log4j2.xml b/06/build/resources/main/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..99d963ac06f0a6b14216ce4407d46f9eb6859a62
--- /dev/null
+++ b/06/build/resources/main/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="all">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/06/build/tmp/compileJava/source-classes-mapping.txt b/06/build/tmp/compileJava/source-classes-mapping.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1848dbb9e99e0c788e8c249e91128feefb24e89d
--- /dev/null
+++ b/06/build/tmp/compileJava/source-classes-mapping.txt
@@ -0,0 +1,7 @@
+ohm/softa/a06/model/Joke.java
+ ohm.softa.a06.model.Joke
+ohm/softa/a06/CNJDBApi.java
+ ohm.softa.a06.CNJDBApi
+ohm/softa/a06/App.java
+ ohm.softa.a06.App
+ ohm.softa.a06.App$Test
diff --git a/06/build/tmp/compileTestJava/source-classes-mapping.txt b/06/build/tmp/compileTestJava/source-classes-mapping.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8dd0cec1a84d49c2ff5bd0b05398617820bd730a
--- /dev/null
+++ b/06/build/tmp/compileTestJava/source-classes-mapping.txt
@@ -0,0 +1,2 @@
+ohm/softa/a06/tests/CNJDBTests.java
+ ohm.softa.a06.tests.CNJDBTests
diff --git a/06/gradle.properties b/06/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d703f3bea59ebe80392e2685e5e25c2305045186
--- /dev/null
+++ b/06/gradle.properties
@@ -0,0 +1,4 @@
+junitVersion=5.7.1
+log4j2Version=2.14.1
+apacheCommonsLangVersion=3.12.0
+squareRetrofitVersion=2.9.0
diff --git a/06/gradle/wrapper/gradle-wrapper.jar b/06/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f
Binary files /dev/null and b/06/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/06/gradle/wrapper/gradle-wrapper.properties b/06/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..442d9132ea32808ad980df4bd233b359f76341a7
--- /dev/null
+++ b/06/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/06/gradlew b/06/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..4f906e0c811fc9e230eb44819f509cd0627f2600
--- /dev/null
+++ b/06/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/06/gradlew.bat b/06/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..ac1b06f93825db68fb0c0b5150917f340eaa5d02
--- /dev/null
+++ b/06/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/06/settings.gradle b/06/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..c329d6f31e141cf18aedd83b4be1526f33c66ee0
--- /dev/null
+++ b/06/settings.gradle
@@ -0,0 +1,18 @@
+/*
+ * This settings file was generated by the Gradle 'init' task.
+ *
+ * The settings file is used to specify which projects to include in your build.
+ * In a single project build this file can be empty or even removed.
+ *
+ * Detailed information about configuring a multi-project build in Gradle can be found
+ * in the user guide at https://docs.gradle.org/4.3/userguide/multi_project_builds.html
+ */
+
+/*
+// To declare projects as part of a multi-project build use the 'include' method
+include 'shared'
+include 'api'
+include 'services:webservice'
+*/
+
+rootProject.name = '06-annotations-reflection'
diff --git a/06/src/main/java/ohm/softa/a06/App.java b/06/src/main/java/ohm/softa/a06/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..af1ec527453d55f4b58b8120ff5a40c004f6d833
--- /dev/null
+++ b/06/src/main/java/ohm/softa/a06/App.java
@@ -0,0 +1,15 @@
+package ohm.softa.a06;
+
+/**
+ * @author Peter Kurfer
+ * Created on 11/10/17.
+ */
+public class App {
+	public static void main(String[] args) {
+		// TODO fetch a random joke and print it to STDOUT
+	}
+	abstract class Test {
+
+		abstract <T> void    a(T t);
+	}
+}
diff --git a/06/src/main/java/ohm/softa/a06/CNJDBApi.java b/06/src/main/java/ohm/softa/a06/CNJDBApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..374b251b469335860ff3699d63ebe3d0bf247779
--- /dev/null
+++ b/06/src/main/java/ohm/softa/a06/CNJDBApi.java
@@ -0,0 +1,7 @@
+package ohm.softa.a06;
+
+
+public interface CNJDBApi {
+
+
+}
diff --git a/06/src/main/java/ohm/softa/a06/model/Joke.java b/06/src/main/java/ohm/softa/a06/model/Joke.java
new file mode 100644
index 0000000000000000000000000000000000000000..af6edc1537d09fd40aa12edca671c38ecb77323f
--- /dev/null
+++ b/06/src/main/java/ohm/softa/a06/model/Joke.java
@@ -0,0 +1,61 @@
+package ohm.softa.a06.model;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Peter Kurfer
+ * Created on 11/9/17.
+ */
+public final class Joke {
+
+	private String identifier;
+	private String content;
+	private List<String> rubrics;
+
+
+	public String getIdentifier() {
+		return identifier;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+
+		if (!(o instanceof Joke)) return false;
+
+		Joke joke1 = (Joke) o;
+
+		return new EqualsBuilder()
+			.append(getIdentifier(), joke1.getIdentifier())
+			.append(getContent(), joke1.getContent())
+			.append(rubrics, joke1.rubrics)
+			.isEquals();
+	}
+
+	@Override
+	public int hashCode() {
+		return new HashCodeBuilder(17, 37)
+			.append(getIdentifier())
+			.append(getContent())
+			.append(rubrics)
+			.toHashCode();
+	}
+
+	@Override
+	public String toString() {
+		return new ToStringBuilder(this)
+			.append("identifier", identifier)
+			.append("content", content)
+			.append("rubrics", rubrics)
+			.toString();
+	}
+}
diff --git a/06/src/main/resources/log4j2.xml b/06/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..99d963ac06f0a6b14216ce4407d46f9eb6859a62
--- /dev/null
+++ b/06/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="all">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/06/src/test/java/ohm/softa/a06/tests/CNJDBTests.java b/06/src/test/java/ohm/softa/a06/tests/CNJDBTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..b868bc0cec5a8354caea4d9d7cd1ff775f84cf1f
--- /dev/null
+++ b/06/src/test/java/ohm/softa/a06/tests/CNJDBTests.java
@@ -0,0 +1,50 @@
+package ohm.softa.a06.tests;
+
+import ohm.softa.a06.model.Joke;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Peter Kurfer
+ * Created on 11/10/17.
+ */
+class CNJDBTests {
+
+	private static final Logger logger = LogManager.getLogger(CNJDBTests.class);
+	private static final int REQUEST_COUNT = 10;
+
+	@Test
+	void testCollision() throws IOException {
+		Set<String> jokeNumbers = new HashSet<>();
+		int requests = 0;
+		boolean collision = false;
+
+		while (requests++ < REQUEST_COUNT) {
+			// TODO Prepare call object
+
+			// TODO Perform a synchronous request
+
+			// TODO Extract object
+
+			Joke j = null;
+
+			if (jokeNumbers.contains(j.getIdentifier())) {
+				logger.info(String.format("Collision at joke %s", j.getIdentifier()));
+				collision = true;
+				break;
+			}
+
+			jokeNumbers.add(j.getIdentifier());
+			logger.info(j.toString());
+		}
+
+		assertTrue(collision, String.format("Completed %d requests without collision; consider increasing REQUEST_COUNT", requests));
+	}
+}
diff --git a/.editorconfig b/11/.editorconfig
similarity index 100%
rename from .editorconfig
rename to 11/.editorconfig
diff --git a/.gitignore b/11/.gitignore
similarity index 100%
rename from .gitignore
rename to 11/.gitignore
diff --git a/.travis.yml b/11/.travis.yml
similarity index 100%
rename from .travis.yml
rename to 11/.travis.yml
diff --git a/LICENSE b/11/LICENSE
similarity index 100%
rename from LICENSE
rename to 11/LICENSE
diff --git a/README.md b/11/README.md
similarity index 100%
rename from README.md
rename to 11/README.md
diff --git a/assets/images/CanteenRetrievalFlow.svg b/11/assets/images/CanteenRetrievalFlow.svg
similarity index 100%
rename from assets/images/CanteenRetrievalFlow.svg
rename to 11/assets/images/CanteenRetrievalFlow.svg
diff --git a/assets/images/MealsRetrievalFlow.svg b/11/assets/images/MealsRetrievalFlow.svg
similarity index 100%
rename from assets/images/MealsRetrievalFlow.svg
rename to 11/assets/images/MealsRetrievalFlow.svg
diff --git a/assets/uml/CanteenRetrievalFlow.plantuml b/11/assets/uml/CanteenRetrievalFlow.plantuml
similarity index 100%
rename from assets/uml/CanteenRetrievalFlow.plantuml
rename to 11/assets/uml/CanteenRetrievalFlow.plantuml
diff --git a/assets/uml/MealsRetrievalFlow.plantuml b/11/assets/uml/MealsRetrievalFlow.plantuml
similarity index 100%
rename from assets/uml/MealsRetrievalFlow.plantuml
rename to 11/assets/uml/MealsRetrievalFlow.plantuml
diff --git a/build.gradle b/11/build.gradle
similarity index 100%
rename from build.gradle
rename to 11/build.gradle
diff --git a/gradle.properties b/11/gradle.properties
similarity index 100%
rename from gradle.properties
rename to 11/gradle.properties
diff --git a/gradle/wrapper/gradle-wrapper.jar b/11/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from gradle/wrapper/gradle-wrapper.jar
rename to 11/gradle/wrapper/gradle-wrapper.jar
diff --git a/gradle/wrapper/gradle-wrapper.properties b/11/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from gradle/wrapper/gradle-wrapper.properties
rename to 11/gradle/wrapper/gradle-wrapper.properties
diff --git a/gradlew b/11/gradlew
similarity index 100%
rename from gradlew
rename to 11/gradlew
diff --git a/gradlew.bat b/11/gradlew.bat
similarity index 100%
rename from gradlew.bat
rename to 11/gradlew.bat
diff --git a/settings.gradle b/11/settings.gradle
similarity index 100%
rename from settings.gradle
rename to 11/settings.gradle
diff --git a/src/main/java/ohm/softa/a11/App.java b/11/src/main/java/ohm/softa/a11/App.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/App.java
rename to 11/src/main/java/ohm/softa/a11/App.java
diff --git a/src/main/java/ohm/softa/a11/MenuSelection.java b/11/src/main/java/ohm/softa/a11/MenuSelection.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/MenuSelection.java
rename to 11/src/main/java/ohm/softa/a11/MenuSelection.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPI.java b/11/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPI.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/OpenMensaAPI.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPI.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPIService.java b/11/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPIService.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/OpenMensaAPIService.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/OpenMensaAPIService.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/model/Canteen.java b/11/src/main/java/ohm/softa/a11/openmensa/model/Canteen.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/model/Canteen.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/model/Canteen.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/model/Meal.java b/11/src/main/java/ohm/softa/a11/openmensa/model/Meal.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/model/Meal.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/model/Meal.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/model/PageInfo.java b/11/src/main/java/ohm/softa/a11/openmensa/model/PageInfo.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/model/PageInfo.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/model/PageInfo.java
diff --git a/src/main/java/ohm/softa/a11/openmensa/model/State.java b/11/src/main/java/ohm/softa/a11/openmensa/model/State.java
similarity index 100%
rename from src/main/java/ohm/softa/a11/openmensa/model/State.java
rename to 11/src/main/java/ohm/softa/a11/openmensa/model/State.java
diff --git a/src/test/java/ohm/softa/a11/tests/OpenMensaApiTests.java b/11/src/test/java/ohm/softa/a11/tests/OpenMensaApiTests.java
similarity index 100%
rename from src/test/java/ohm/softa/a11/tests/OpenMensaApiTests.java
rename to 11/src/test/java/ohm/softa/a11/tests/OpenMensaApiTests.java
diff --git a/src/test/resources/log4j2.xml b/11/src/test/resources/log4j2.xml
similarity index 100%
rename from src/test/resources/log4j2.xml
rename to 11/src/test/resources/log4j2.xml
diff --git a/playground/.gitignore b/playground/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b63da4551b2e169d28b20728d5d53c6ca1779da4
--- /dev/null
+++ b/playground/.gitignore
@@ -0,0 +1,42 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/playground/.idea/.gitignore b/playground/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/playground/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/playground/.idea/gradle.xml b/playground/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..14746e76663d64283939c97c4c25a1bea7131fa3
--- /dev/null
+++ b/playground/.idea/gradle.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleHome" value="" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/playground/.idea/misc.xml b/playground/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa6e631341f01f7a7be40b35a7293b07bc0bd460
--- /dev/null
+++ b/playground/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="IDE SDK" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/playground/.idea/vcs.xml b/playground/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/playground/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/playground/build.gradle b/playground/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..09ef45c0260feabd1387b89741d9da74cf0f9ad9
--- /dev/null
+++ b/playground/build.gradle
@@ -0,0 +1,23 @@
+plugins {
+    id 'java'
+}
+
+group = 'org.example'
+version = '1.0-SNAPSHOT'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    testImplementation platform('org.junit:junit-bom:5.9.1')
+    testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+    useJUnitPlatform()
+}
+
+compileJava {
+    options.compilerArgs << '-Xlint:unchecked'
+}
\ No newline at end of file
diff --git a/playground/gradle/wrapper/gradle-wrapper.jar b/playground/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196
Binary files /dev/null and b/playground/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/playground/gradle/wrapper/gradle-wrapper.properties b/playground/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..30fcd5c0eed4bac3725d5e5111bc7bbe423ebe2e
--- /dev/null
+++ b/playground/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Jul 10 15:29:33 CEST 2023
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/playground/gradlew b/playground/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..1b6c787337ffb79f0e3cf8b1e9f00f680a959de1
--- /dev/null
+++ b/playground/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/playground/gradlew.bat b/playground/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..ac1b06f93825db68fb0c0b5150917f340eaa5d02
--- /dev/null
+++ b/playground/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/playground/settings.gradle b/playground/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..a74a8ce471cad65ebc54016baa9d8c3805a9a7bd
--- /dev/null
+++ b/playground/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'playground'
+
diff --git a/playground/src/main/java/org/example/Main.java b/playground/src/main/java/org/example/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..473e17cd1443e324ab79126c29e6583fb133650f
--- /dev/null
+++ b/playground/src/main/java/org/example/Main.java
@@ -0,0 +1,74 @@
+package org.example;
+
+import java.util.HashMap;
+import java.util.stream.Stream;
+
+public class Main {
+    public static void main(String[] args) {
+        StatefulMessage m1 = new StatefulMessage("Hans");
+        StatefulMessage m2 = new StatefulMessage("Dampf");
+        System.out.println(m1.escalated());  // "HANS"
+        System.out.println(m2.escalated());  // "DAMPF"
+        System.out.println(m2.escalated());  // "DAMPF!"
+        System.out.println(m1.confuse());    // "HANS?"
+        System.out.println(m1.confuse());    // "HANS??"
+        System.out.println(m2.confuse());    // "DAMPF?"
+    }
+}
+
+class Container<T> {
+    private Class<T> clazz;
+    public String getContainedClass() {
+        if (clazz == null) return null;
+        return clazz.toString();
+    }
+}
+
+interface Stateful {
+    <T> T getState(Class clazz, T initial);
+    <T> void setState(Class clazz, T state);
+}
+class StatefulObject implements Stateful {
+    // object -> interface -> state object
+    private HashMap<Class, Object> state
+            = new HashMap<>();
+    @Override
+    public final <T> T getState(Class clazz, T initial) {
+        // cast necessary, since internally we store Object
+        return (T) state.getOrDefault(clazz, initial);
+    }
+    @Override
+    public final <T> void setState(Class clazz, T o) {
+        state.put(clazz, o);
+    }
+}
+
+interface StatefulEscalate2 extends Stateful {
+    String text();
+    default String escalated() {
+        // no typecast... generic methods ftw!
+        int n = getState(StatefulEscalate2.class, 0);
+        setState(StatefulEscalate2.class, n+1);
+        String bangs = Stream.generate(() -> "!")
+                .limit(n).reduce("", (a, b) -> a + b);
+        return text().toUpperCase() + bangs;
+    }
+}
+
+interface StatefulConfusable extends Stateful {
+    String text();
+    default String confuse() {
+        String s = getState(StatefulConfusable.class, "?");
+        setState(StatefulConfusable.class, s + s);
+        return text() + s;
+    }
+}
+class StatefulMessage extends StatefulObject
+        implements StatefulConfusable, StatefulEscalate2 {
+    private String m;
+    public StatefulMessage(String m) { this.m = m; }
+    @Override
+    public String text() {
+        return m;
+    }
+}
\ No newline at end of file