diff --git a/README.md b/README.md
index bb1a4992b08e3f7693cf16d606137b0f755b2c4d..2ebc977978a917e99db3c2efe19db81b4c372b47 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,27 @@
 # Computer Science 3 Lab Exercises C++
 
-This repo documents the transition of the third CS3 lab exercises from Java to C++.
+This repo documents the transition of the third Computer Science lab exercises from Java to C++.
 The Course is about programming concepts rather than a specific language.
 
 ## Changes
 
+### Worksheet 2
+**Background**
+  - `commandlib.h` was introduced as a stand in for `hsrt.mec.controldeveloper.core.com.command`. For simplicity everything is defined in one header.
+  - Diverging from the class diagram the other interfaces dont inherit from `ICommand` as that would leed to weird inheritance loops where e.g. `Gear` inherits from `Command` which inherits from `ICommand`, but also from `IDirection` which also already inherits from `ICommand`. Maybe the class diagram could be simplified if `ICommand` would be replaced by the partially virtual `Command`.
+**Commands**
+  - `Gear`, `Pause` and `Direction` use multiple inheritance to allow the use of interfaces.
+  This is fine, but it should be good practice to inherit from one base class only and only virtual classes otherwise.
+**CommandList:**
+  - `CommandList` now needs a default constructor for `Element` because `Command` is now virtual and can no longer be use for the root `Element`.
+  - `CommandList` and `Element` use template functions to allow adding multiple types of `Command`s. This sort of is compile-time polymorphism.
+  - There is no checking if the template got the right type though. Possibly there is a solution using `static_assert` and `std::is_...`.
+  - For variable types templates should use `typename` rather than `class`.
+**Class vs Member variables**
+  - To call a static function without an object it is necessary to use the namespace operator `MyClass::foo()` rather than `MyClass.foo()`.
+**Doxygen**
+  - see Trivia
+
 ### Worksheet 1
 **Element:**
   - In Element every mention of Element is replaced with `std::shared_ptr<Element>`.
@@ -20,21 +37,60 @@ The Course is about programming concepts rather than a specific language.
   - `getPos()` now returns `std::make_shared<Command>`.
   - Where appropriate the funtion parameter `int` has been replaced with `unsigned int` to prohibit passing negative values.
   - In `add(Command cmd)` `std::make_shared<Element>(cmd)` is used to create a new `Element`.
-  Here is easily visible how std::make_shared<T>() is the C++ equivalent to Java`s `new` operator.
+  Here is easily visible how std::make_shared<T>() is the C++ equivalent to Java's `new` operator.
   - The `std::bad_alloc`-Exception possibly thrown by `std::make_shared<Element>()` is not catched in `add()`, to not introduce `try{} catch{}` too early.
   Thus add() wont return `nullptr`, but crash the program if an error occures.
 
 
 ## Trivia
 
+### inline keyword
+Although `inline` can be used to influence performance, but this is
+[not how it should be used](https://www.youtube.com/watch?v=GldFtXZkgYo).
+Much rather it can be used to deal with linking declarations over multiple translation units.
+For variables it is a way to give the compiler ["a place and a time"](https://www.youtube.com/watch?v=m7hwL0gHuP4) to initialize a static variable.
+
 ### smart pointers
   - smart pointers point to NULL on construction.
   - They can easily be checked for content with
-  ```
-    if (mySmartPointer)
-        //has content
-    else
-        //is empty
-  ```
+
+        if (mySmartPointer)
+            //has content
+        else
+            //is empty
+
   - A unique pointer will be destroyed at the end of it's scope.
-  - A smart pointer will be destroyed when all of it's references are overwritten or the scope of the last reference ends.
\ No newline at end of file
+  - A smart pointer will be destroyed when all of it's references are overwritten or the scope of the last reference ends.
+
+### std::optional or "return a value or null"
+One task when implementing the linked list is to return the Command modified Element.
+Or, if for whatever reason the operation fails to return null to signal an error to the user of the list.
+This isnt possible right away in C++ as null cant be casted to any type.
+To solve this problem in a concise and easy way `std::optional<T>` was introduced in C++17.
+It contains not only its given type T, but also a boolean to keep track if it is empty.
+Example:
+
+    std::optional<Gear> opt = std::optional<Gear>(); // <- empty
+    opt = Gear(1, 2); // <- filled with value
+    if (opt)
+      cout << opt.value.getConfig();
+    else
+      cout << "is empty";
+
+### Doxygen
+Basically Javadoc for C++ and many other languages.  
+Call `doxygen -g` to generate a standard Doxyfile  
+Or `doxygen -g my_conf` for a custom name  
+Then simply run `doxygen` or `doxygen my_conf` to execute.  
+CMake also allows to call doxygen as part of the build routine, see `CMakeLists.txt`.
+
+Basic settings in `Doxyfile`:
+  - Project_name, _brief, _logo for project info
+  - Output_directory to specify a subfolder (here docs/)
+  - Optimize_output_for_C seems a good choice
+  - INPUT every directory or file to show up in the documentation (here src/ include/ README.md)
+  - RECURSIVE to also document subdirectories
+  - USE_MDFILE_AS_MAINPAGE because it would be empty otherwise (here README.md) (specify file in INPUT)
+  - SOURCE_BROWSER and INLINE_SOURCES for source code in documentation
+  - GENERATE_TREEVIEW for the sidebar well-known from Javadoc
+  - GENERATE_LATEX to spare generation of latex files
\ No newline at end of file