diff --git a/app/data/authors.yaml b/app/data/authors.yaml
index 174a1a2..33afcb6 100644
--- a/app/data/authors.yaml
+++ b/app/data/authors.yaml
@@ -57,3 +57,15 @@
website: https://horstmann.com
description: |
Cay Placeholder.
+
+- name: Dr Heinz M. Kabutz
+ email: heinz@javaspecialists.eu
+ photo_url: https://javaspecialists.eu/pics/gb/heinz2-300x300.jpg
+ github: kabutz
+ twitter: kabutz
+ website: https://www.javaspecialists.eu
+ description: |
+ Heinz is the author of [The Java Specialists' Newsletter](https://www.javaspecialists.eu),
+ a monthly newsletter that has been in publication since the end of 2000. In it, he explores
+ many useful tips and tricks that have enthralled tens of thousands of enthusiastic fans for
+ over two decades. He was one of the first [Java Champions](https://www.javachampions.org).
diff --git a/app/pages/learn/01_tutorial/04_mastering-the-api/01_reflection/00_reflection.md b/app/pages/learn/01_tutorial/04_mastering-the-api/01_reflection/00_reflection.md
new file mode 100644
index 0000000..14f1aa8
--- /dev/null
+++ b/app/pages/learn/01_tutorial/04_mastering-the-api/01_reflection/00_reflection.md
@@ -0,0 +1,353 @@
+---
+id: api.reflection
+title: "Introduction to java.lang.reflect.*"
+slug: learn/introduction_to_java_reflection
+type: tutorial
+category: api
+category_order: 1
+layout: learn/tutorial.html
+subheader_select: tutorials
+main_css_id: learn
+description: "TODO"
+author: ["DrHeinzM.Kabutz"]
+---
+
+
+
+## Reflection
+
+The face looking back from the mirror this morning told a story.
+I urgently needed a shave (and still do). And yesterday, whilst sitting
+outside in our garden, I should have worn sunscreen, or at least
+a hat. I had tried my hand at making my own bacon, not being able
+to find such delicacies on Crete, and the five hours of smoking
+in the Weber were put to good use writing a Java Specialists
+Newsletter about parallel streams and virtual threads (Issue 311).
+The reflection in the mirror blinked. Enough time staring, it was
+time to start writing about what I had just witnessed - reflection.
+
+Java reflection allows an object to look in the mirror and discover
+what fields, methods, and constructors it has. We can read and
+write fields, invoke methods, and even create new objects by
+calling the constructors. Just like the stubble on my face and
+the slight sunburn, we can see ourselves through others' eyes.
+
+Why should you care to read this tutorial? If you already know
+reflection, you might want to peek through for entertainment
+value. But if you have never heard of reflection, well, it's time
+to take a good look in the mirror and discover a new magic that will
+allow you to sometimes save thousands of fingerbreaking lines of code
+with a few well-positioned chunks of reflection poetry. Oh and did I
+mention that some employers post nasty interview questions that
+have an easy solution via reflection? I hope you will enjoy it and
+that you will try out the code snippets in the tutorial. Thank you
+for joining me on this journey.
+
+## The Class `Class`
+
+No, this is not a typo. There is a class called `Class`. And it is a
+subclass of `Object`. And `Object` has a `Class`. A nice circular dependency.
+
+How can we get hold of our object's Class? Each object has a
+`getClass()` method that it inherits from `java.lang.Object`.
+When we call that, we get back the actual implementation `Class`.
+
+For example, consider the following code. Note that for our code
+snippets we are using the new unnamed classes, which are a preview
+feature of Java 21. See [JEP 445](https://openjdk.org/jeps/445).
+We can run them directly with `java --enable-preview --source 21 GetClassDemo.java`
+
+```java
+// GetClassDemo.java
+import java.util.List;
+import java.util.ArrayList;
+
+// Using new Unnamed Classes which is a preview feature of Java 21.
+// See JEP 445
+void main() {
+ List list1 = new ArrayList<>();
+ System.out.println(list1.getClass());
+ var list2 = new ArrayList();
+ System.out.println(list2.getClass());
+}
+```
+
+In other words, it does not matter how the variable is declared, we
+always get the actual implementation object's class. How can we get
+the List class? That is fairly easy, using class literatls. We simply
+write the name of the class, followed by `.class`, like so:
+
+```java
+// ClassLiteral.java
+void main() {
+ System.out.println(Number.class); // class java.lang.Number
+ System.out.println(java.util.List.class); // interface java.util.List
+}
+```
+
+We can also load classes by name as `String`, without even knowing
+whether the class will be available at runtime. For example, here
+we are loading whatever class we are entering on the `Console`:
+
+```java
+// ClassForName.java
+void main() throws ClassNotFoundException {
+ var console = System.console();
+ String className = console.readLine("Enter class name: ");
+ System.out.println(Class.forName(className));
+}
+```
+
+For example:
+
+```output
+heinz$ java --enable-preview --source 21 ClassForName.java
+Note: ClassForName.java uses preview features of Java SE 21.
+Note: Recompile with -Xlint:preview for details.
+Enter class name: java.util.Iterator
+interface java.util.Iterator
+```
+
+Each class is loaded into a `ClassLoader`. The JDK classes all
+reside in the bootstrap class loader, whereas our classes are in
+the system class loader, also called application class loader.
+We can see the class loaders here:
+
+```java
+// ClassLoaderDemo.java
+void main() {
+ System.out.println(String.class.getClassLoader());
+ System.out.println(this.getClass().getClassLoader());
+}
+```
+
+Interesting is that depending on how we invoke this code, we get
+different results. For example, if we call it using the
+`java ClassLoaderDemo.java`, then the type of class loader is a
+`MemoryClassLoader`, whereas if we first compile it and then call
+it with `java ClassLoaderDemo`, it is an `AppClassLoader`. The
+class loader for JDK classes comes back as `null`.
+
+```output
+heinz$ java --enable-preview --source 21 ClassLoaderDemo.java
+null
+com.sun.tools.javac.launcher.Main$MemoryClassLoader@6483f5ae
+```
+
+And
+
+```output
+heinz$ javac --enable-preview --source 21 ClassLoaderDemo.java
+heinz$ java --enable-preview ClassLoaderDemo
+null
+jdk.internal.loader.ClassLoaders$AppClassLoader@3d71d552
+```
+
+The purpose of class loaders is to partition classes for security
+reasons. Classes in the JDK cannot see our classes at all, and
+similarly, classes in the `AppClassLoader` have no relation to
+classes in the `MemoryClassLoader`. This can cause some surprises
+when we compile our classes and then also launch them with
+the single-file command `java SomeClass.java`
+
+## Shallow Reflective Access
+
+Once we have the class, we can find out a lot of information about
+it, such as who the superclasses are, what public members it has,
+what interfaces it has implemented. If it is a `sealed` type, we
+can even find the subtypes.
+
+Let's try find the methods defined on java.util.Iterator:
+
+```java
+// MethodsOnIterator.java
+import java.util.Iterator;
+import java.util.stream.Stream;
+
+void main() {
+ Stream.of(Iterator.class.getMethods())
+ .forEach(System.out::println);
+}
+```
+
+We see four methods, two of which are `default` interface methods:
+
+```java
+heinz$ java --enable-preview --source 21 MethodsOnIterator.java
+public default void java.util.Iterator.remove()
+public default void java.util.Iterator.forEachRemaining(java.util.function.Consumer)
+public abstract boolean java.util.Iterator.hasNext()
+public abstract java.lang.Object java.util.Iterator.next()
+```
+
+If we make an object of type `java.util.Iterator`, we would even be able to call these methods. In the next example, we look for the method
+called `"forEachRemaining"` and which takes a `Consumer` as a parameter. We then create an `Iterator` from a `List.of()` and
+invoke the `forEachRemaining` method using reflection. Note that
+several things could go wrong, most notably that the method does not
+exist (`NoSuchMethodException`) and that we are not allowed to call
+the method (`IllegalAccessException`). Since Java 7, we have a blanket
+exception that covers everything that can go wrong with reflection,
+the `ReflectiveOperationException`.
+
+```java
+// MethodsOnIteratorCalling.java
+import java.util.List;
+import java.util.Iterator;
+import java.util.function.Consumer;
+
+void main() throws ReflectiveOperationException {
+ var iterator = List.of("Hello", "Dev", "Java").iterator();
+ var forEachRemainingMethod = Iterator.class.getMethod(
+ "forEachRemaining", Consumer.class);
+ Consumer> println = System.out::println;
+ forEachRemainingMethod.invoke(iterator, println);
+}
+```
+
+Our next example is even more interesting, if I may say so myself.
+We are going to take a `List` of items and then search through
+the `Collections` class to see whether we can find any methods
+that we can give the method to. We invoke the method and see what
+happens to our list. Since the methods are declared `static` in `Collections`, the first parameter of our `invoke()` method will
+be `null`. We could use a stream, but they don't "play nice" with
+checked exceptions, thus the plain old for-in loop it will have
+to be:
+
+```java
+// CollectionsListMethods.java
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+void main() throws ReflectiveOperationException {
+ var pi = "3141592653589793".chars()
+ .map(i -> i - '0')
+ .boxed().collect(Collectors.toList());
+ System.out.println(pi);
+ for (var method : Collections.class.getMethods()) {
+ if (method.getReturnType() == void.class
+ && method.getParameterCount() == 1
+ && method.getParameterTypes()[0] == List.class) {
+ System.out.println("Calling " + method.getName() + "()");
+ method.invoke(null, pi);
+ System.out.println(pi);
+ }
+ }
+}
+```
+
+This works nicely and we find three methods that match our
+requirements: `sort()`, `shuffle()` and `reverse()`. The order of these
+methods is not guaranteed. For example, in the `Collections.java`
+file in OpenJDK 21, they are ordered as `sort()`, `reverse()`,
+`shuffle()`. However, when I run the code, they appear as:
+
+```output
+heinz$ java --enable-preview --source 21 CollectionsListMethods.java
+[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3]
+Calling reverse()
+[3, 9, 7, 9, 8, 5, 3, 5, 6, 2, 9, 5, 1, 4, 1, 3]
+Calling sort()
+[1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 9, 9, 9]
+Calling shuffle()
+[5, 7, 4, 9, 9, 9, 2, 1, 6, 5, 3, 3, 1, 5, 3, 8]
+```
+
+## Deep Reflective Access
+
+Up to now, we did not do anything that was particularly
+dangerous. All the methods we discovered and called were `public`.
+The only part that was a bit dangerous was that we did not have a
+compiler check that these methods exist and are accessible.
+However, we can also stare more deeply into the mirror.
+
+For example, let's consider our `Person` class:
+
+```java
+public class Person {
+ private final String name;
+ private final int age;
+
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String toString() {
+ return name + " (" + age + ")";
+ }
+}
+```
+
+Since we are now working with two separate classes, we will need
+to compile them. We can use an unnamed class as before for the demo,
+but we should still compile them both. It would be a mistake to use a
+single-file call, because in that case `Person` and the demo would
+exist in different class loaders. This can cause hard to understand
+runtime errors. I once spent a day chasing this exact error. Don't
+be me.
+
+Here is our `FountainOfYouth.java` file:
+
+```java
+// FountainOfYouth.java
+import java.lang.reflect.*;
+
+void main() throws ReflectiveOperationException {
+ var person = new Person("Heinz Kabutz", 51);
+ System.out.println(person);
+ Field ageField = Person.class.getDeclaredField("age");
+ ageField.setAccessible(true); // deep reflection engaged!
+ int age = (int) ageField.get(person);
+ age *= .9;
+ ageField.set(person, age);
+ System.out.println(person);
+}
+```
+
+We first compile the `FountainOfYouth` class, which transitively
+compiles `Person.java`. We then run it, and *voila*, I've shaved
+10% off my age.
+
+```output
+heinz$ javac --enable-preview --source 21 FountainOfYouth.java
+heinz$ java --enable-preview FountainOfYouth
+Heinz Kabutz (51)
+Heinz Kabutz (45)
+```
+
+Note that the `age` field is `private` *and* `final`, and yet we
+were able to change it. If we convert `Person` to a record, then
+it will no longer allow us to change the properties via deep
+reflection.
+
+### The Java Module System
+
+Deep reflection only works if the module in which the class resides
+is *open* to us. Ideally we should ask the author of the module
+to open the package to our module. They will likely refuse, and
+with good reason. By opening up their package, they allow
+unfettered access to their most intimate implementation detail.
+What if, in the near or distant future, they want to change
+field names or types? The deep reflective code would likely stop
+working, and they would be forever having to fix other modules.
+
+We can open up a package in another module for deep reflection
+with a command line parameter `--add-opens`, but we should only
+use that as an absolute last resort. It is so undesirable, that
+I merely mention it here in disgust, but won't show more details
+of how to use it.
+
+## Conclusion
+
+We hope that you got a bit of insight into how reflection works
+in this tutorial. There are many other topics to explore: arrays,
+dynamic proxies, generics, sealed classes, etc. How we can read
+the properties of a record, how parameter names can be preserved.
+But this is long enough and will hopefully get you started in the
+right direction.
+
+For many more deep dives into the Java Programming Language, be
+sure to subscribe to
+[The Java Specialists' Newsletter](https://www.javaspecialists.eu),
+a newsletter for anyone who wants to become more proficient in Java.