diff --git a/05HTMLEngine/App.config b/05HTMLEngine/App.config
new file mode 100644
index 0000000000000000000000000000000000000000..4bfa00561852104b3e1ee79a1d9d5ea28c262642
--- /dev/null
+++ b/05HTMLEngine/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
+    </startup>
+</configuration>
diff --git a/05HTMLEngine/HTMLElements.cs b/05HTMLEngine/HTMLElements.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e554e7baa9322900493e96afac1efce4a47f02a2
--- /dev/null
+++ b/05HTMLEngine/HTMLElements.cs
@@ -0,0 +1,4 @@
+namespace HTML
+{
+  // TODO: Define classes for HTML tag elements (using interfaces "ITagged" and eventually "INested") here...
+}
\ No newline at end of file
diff --git a/05HTMLEngine/HTMLEngine.cs b/05HTMLEngine/HTMLEngine.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6d9cc7f2cd5066648ba6a2de5a16ee5359ff8010
--- /dev/null
+++ b/05HTMLEngine/HTMLEngine.cs
@@ -0,0 +1,22 @@
+namespace HTML
+{
+    // HTML engine for generation of a HTML string from an array of HTML tag elements:
+
+    public interface ITagged { string TagId { get; } }  // Used to define HTML tag element
+
+    public interface INested { object[] Elements { get; } }  // Used to "mark" a HTML tag element as nested
+    class Body : ITagged, INested
+    {
+        public string TagId => "body";
+        public Body(params object[] Elements) { this.Elements = Elements; }
+        public object[] Elements { get; private set; }
+    }
+
+    public static class Engine
+    {
+        //public static string Generate(params object[] elements)
+        //{
+        //    // TODO: Your code for (recursive) generation of a HTML string from array "elements" here...
+        //}
+    }
+}
\ No newline at end of file
diff --git a/05HTMLEngine/P29 HTMLEngine.csproj b/05HTMLEngine/P29 HTMLEngine.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..8b106790ea1f516af04feaf093809b5933892df2
--- /dev/null
+++ b/05HTMLEngine/P29 HTMLEngine.csproj	
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HTMLEngine</RootNamespace>
+    <AssemblyName>HTMLEngine</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="HTMLElements.cs" />
+    <Compile Include="HTMLEngine.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/05HTMLEngine/Program.cs b/05HTMLEngine/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2f542f73e0750afa147ef44f53a8577a18aed44c
--- /dev/null
+++ b/05HTMLEngine/Program.cs
@@ -0,0 +1,73 @@
+using HTML;
+
+class Program
+{
+    // Test program for HTML generation:
+
+    static void Main()
+    {
+        // Generate HTML document and store result in string:
+
+        //string html = Engine.Generate
+        //(
+        //  new DocumentType(),
+
+        //  new Html
+        //  (
+        //    new Head
+        //    (
+        //      new Title("Generated HTML Example")
+        //    ),
+
+        //    new Body
+        //    (
+        //      new Heading("Welcome to the Technical University of Nuremberg"),
+
+        //      new Paragraph
+        //      (
+        //        "We have a ", new Italic("distinct profile"), " and strive to maintain our ", new Italic("leading position"), " among comparable universities."
+        //      ),
+
+        //      new Heading("Study for your future"),
+
+        //      new Paragraph
+        //      (
+        //        12, " departments provide more than ", 40, " degree programs in ", new Bold("engineering, business, design and social sciences."),
+        //        new LineBreak(),
+        //        "If you have questions, please contact the ", new Italic("Student Counseling Service"), " or the ", new Italic("Student Office.")
+        //      )
+        //    )
+        //  )
+        //);
+
+        // Write resulting HTML string:
+
+        System.Console.WriteLine("GENERATED HTML DOCUMENT:");
+
+        System.Console.WriteLine(html);
+
+        System.Console.ReadKey(true);
+
+        /*
+          // Write reformatted HTML string:
+
+          System.Console.WriteLine("\nREFORMATTED HTML DOCUMENT:");
+
+          System.Console.WriteLine("\n<" + new DocumentType().TagId + ">\n" + System.Xml.Linq.XElement.Parse(html.Replace("\n", "")));
+
+          System.Console.ReadKey(true);
+        */
+
+        // Show (original) HTML string in default browser:
+
+        System.Console.WriteLine("\nSTARTING BROWSER WITH GENERATED DOCUMENT...");
+
+        System.IO.File.WriteAllText("Example.html", html);
+
+        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("Example.html");
+        startInfo.UseShellExecute = true;
+        System.Diagnostics.Process.Start(startInfo);
+        //System.Diagnostics.Process.Start("Example.html");
+    }
+}
+
diff --git a/05HTMLEngine/Properties/AssemblyInfo.cs b/05HTMLEngine/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2edcd507fd4de6caaed25f620f86667c1d407114
--- /dev/null
+++ b/05HTMLEngine/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HTMLEngine")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HTMLEngine")]
+[assembly: AssemblyCopyright("Copyright ©  2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("bced82d0-f95f-4d82-9019-2c63d6b3cc8a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/09DataDriven/P25 DataDriven.csproj b/09DataDriven/P25 DataDriven.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..538521b4701d7dd999be0b4d88eee3d5fd41d333
--- /dev/null
+++ b/09DataDriven/P25 DataDriven.csproj	
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>_09DataDriven</RootNamespace>
+  </PropertyGroup>
+
+</Project>
diff --git a/09DataDriven/Program.cs b/09DataDriven/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b7175fcd4a0ad07f019128620f0f1e73f401fc8b
--- /dev/null
+++ b/09DataDriven/Program.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace _09DataDriven
+{
+    delegate void Seiteneffekt(int x);
+    class MyInt
+    {
+        private int data;
+        public event Seiteneffekt Ausgabe;
+        public int Content
+        {
+            get
+            {
+                Console.WriteLine($"Get: {data}"); return data;
+            }
+            set
+            {
+                data = value;
+                Console.WriteLine($"Set: {data}"); 
+                Ausgabe?.Invoke(data);
+            }
+        }
+    }
+
+    class Ausgabeaufbereitungen
+    {
+        public static void Textausgabe(int x)
+        {
+            Console.WriteLine(x);
+        }
+        public static void Balkenanzeige(int x)
+        {
+            for (int i = 0; i < x; i++)
+            {
+                Console.Write('x');
+            }
+            Console.WriteLine();
+        }
+    }
+    class Program
+    {
+        
+        static void Main(string[] args)
+        {
+            MyInt x1 = new MyInt();
+            x1.Ausgabe += Ausgabeaufbereitungen.Balkenanzeige;
+            MyInt x2 = new MyInt();
+            x2.Ausgabe += Ausgabeaufbereitungen.Textausgabe;
+
+            x1.Content = 10;
+            x2.Content = 20;
+            x1.Content += 5;  // x1.Content.set(x1.Content.Get ())
+            x2.Content *= 3;
+            x1.Content = (int)(8 * Math.PI);
+
+        }
+    }
+}
diff --git a/10 Erweiterungsmethoden/P26 Erweiterungsmethoden.csproj b/10 Erweiterungsmethoden/P26 Erweiterungsmethoden.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..46a41d0759258230291e6be9ddb73293d5af8121
--- /dev/null
+++ b/10 Erweiterungsmethoden/P26 Erweiterungsmethoden.csproj	
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>_10_Erweiterungsmethoden</RootNamespace>
+  </PropertyGroup>
+
+</Project>
diff --git a/10 Erweiterungsmethoden/Program.cs b/10 Erweiterungsmethoden/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9f4367135ef42252b623db6e494860bb3c1c6064
--- /dev/null
+++ b/10 Erweiterungsmethoden/Program.cs	
@@ -0,0 +1,41 @@
+using System;
+using System.Linq;
+
+namespace _10_Erweiterungsmethoden
+{
+    public static class IntExt
+    {
+        /// <summary>
+        /// Beispiel für Erweiterungsfunktionen, hier für den Typ int
+        /// Beachten Sie bitte, den Einsatz von "this" in der Spezifizierung des Parametertyps
+        /// Für Erweiterungsmethoden muss die Klasse und die Methode static 
+        /// deklariert sein und vor dem Parameter, der ja später durch das
+        /// Objekt ersetzt werden soll, muss ein THIS stehen!
+        /// </summary>
+        public static int Abs(this int x) => (x > 0) ? x : -x; 
+
+        public static T[] Sortieren<T>(this T[] iFeld)
+        {
+            Array.Sort(iFeld);
+            return iFeld;
+        }
+    }
+
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            int ix = -25;
+            Console.WriteLine(ix.Abs());
+
+            int[] ints = { 10, 45, 15, 39, 21, 26 };
+            // var result = ints.OrderBy(g => -g);
+            var result = ints.Sortieren();
+            foreach (var i in result)
+            {
+                Console.Write(i + " ");
+            }
+            Console.WriteLine();
+        }
+    }
+}
diff --git a/10 LINQ_Intro/P27 LINQ_Intro.csproj b/10 LINQ_Intro/P27 LINQ_Intro.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..91947f5673d0592a61324fa488ba26c5aa99cea9
--- /dev/null
+++ b/10 LINQ_Intro/P27 LINQ_Intro.csproj	
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>_10_LINQ_Intro</RootNamespace>
+  </PropertyGroup>
+
+</Project>
diff --git a/10 LINQ_Intro/Program.cs b/10 LINQ_Intro/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ab3f62efdbf7c8273e7a04a51ffb8909313075af
--- /dev/null
+++ b/10 LINQ_Intro/Program.cs	
@@ -0,0 +1,70 @@
+using System;
+using System.Linq;
+
+namespace _10_LINQ_Intro
+{
+    class Program
+    {
+        /// <summary>
+        /// Zeigt die Erzeugung eines anonymen Typs und die Zuweisung an eine Variable,
+        /// die als var - Typ deklariert ist
+        /// </summary>
+        private static void AnonymousTypes()
+        {
+            var x = 123;
+
+            var r1 = new { Name = "Wienkop", Tel = "1614", Alter = 57 };
+            var r2 = new { Name = "Wienkop", Tel = "1614" };
+
+            Console.WriteLine(r1);
+            // r1.Name = r2.Name;     // geht nicht: Name ist read-only
+
+            Console.WriteLine(r2);
+            string s = r1.Name;
+            var result = new { Name = r1.Name, Laenge = r1.Name.Length };
+            Console.WriteLine(result);
+        }
+
+
+
+        /// <summary>
+        /// Beispiel für einen LINQ-Aufruf
+        /// </summary>
+        private static void Main(string[] args)
+        {
+            //AnonymousTypes();
+            string[] wörter = {
+                                  "Anton", "Berta", "Charles", "Dieter", "Emma", "Franz", "Gustav", "Heiner", "Ida",
+                                  "Johanna", "Klaus", "Ludwig", "Manni", "Norbert", "Otto", "Paul", "Quasimodo", "Rainer",
+                                  "Stefan", "Thorsten", "Uwe", "Victoria", "Willi", "Xaver", "Yvonne", "Zacharias"
+                              };
+
+
+            //var res = from w in wörter
+            //          where w.Length < 6
+            //          orderby w descending
+            //          select new { OrgName = w, GrossName = w.ToUpper(), Länge = w.Length };
+
+            //foreach (var r in res)
+            //{
+            //    Console.WriteLine(r);
+            //}
+
+            //Console.WriteLine("******************");
+
+
+            var res2 = from w in wörter
+                       where w.Length < 6
+                       group w by w.Length;
+
+            foreach (var group in res2)
+            {
+                Console.WriteLine("Länge: " + group.Key);
+                foreach (string r in group)
+                {
+                    Console.WriteLine("  " + r);
+                }
+            }
+        }
+    }
+}
diff --git a/11BinTreePersVerwaltung/App.config b/11BinTreePersVerwaltung/App.config
new file mode 100644
index 0000000000000000000000000000000000000000..4bfa00561852104b3e1ee79a1d9d5ea28c262642
--- /dev/null
+++ b/11BinTreePersVerwaltung/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
+    </startup>
+</configuration>
diff --git a/11BinTreePersVerwaltung/BinTree.cs b/11BinTreePersVerwaltung/BinTree.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6000af2faf19b3c8dc904a61bd49f58a87e8486c
--- /dev/null
+++ b/11BinTreePersVerwaltung/BinTree.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.Linq;
+using System.Text;
+
+namespace _11BinTreePersVerwaltung2
+{
+    class ListStack<TYP> 
+    {
+        class LElem<TElem>
+        {
+            public TElem d;
+            public LElem<TElem> nxt;
+
+            public LElem(TElem Data, LElem<TElem> Next) { d = Data; nxt = Next; }
+        }
+
+        LElem<TYP> root = null;
+        int count = 0;
+        public int Count
+        {
+            get { return count; }
+        }
+        public void Push(TYP Data)
+        {
+            LElem<TYP> le = new LElem<TYP>(Data, root);
+            root = le;
+            count++;
+        }
+        /// <summary>
+        /// Liefert das nächste Element des Stacks zurück
+        /// </summary>
+        /// <returns></returns>
+        public TYP Pop()
+        {
+            if (count == 0)
+                throw new IndexOutOfRangeException("Stack empty");
+            count--;
+            LElem<TYP> le = root;
+            root = root.nxt;
+            le.nxt = null;
+            return le.d;
+        }
+    }
+
+    /// <summary>
+    /// Generischer binärer Baum
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    class BinTree<T> : IEnumerable where T : IComparable<T>
+    {
+        /// <summary>
+        /// Datenstruktur für einen Knoten des binären Baums
+        /// </summary>
+        /// <typeparam name="NT"></typeparam>
+        class Node
+        {
+            public T data;
+            public Node left = null, right = null;
+
+            public Node(T Data) { data = Data; }
+            /// <summary>
+            /// Hilfsfunktion zum Traversieren des binären Baums. Liefert die Daten für die
+            /// foreach-Schleife zurück
+            /// </summary>
+            /// <returns></returns>
+            /// 
+            public IEnumerable<T> Enumerate()
+            {
+                if (left != null)
+                    foreach (T item in left.Enumerate())
+                        yield return item;
+                yield return data;
+                if (right != null)
+                    foreach (T item in right.Enumerate())
+                        yield return item;
+            }
+            /// <summary>
+            /// Gibt die Daten des binären Baums rekursiv aus
+            /// </summary>
+            public void PrintNode()   // Methode der Klasse Node
+            {
+                if (left != null) left.PrintNode();
+                Console.WriteLine(this.data);
+                if (right != null) right.PrintNode();
+            }
+        }
+        Node root = null;
+        public void Print()
+        {
+            if (root != null)
+                root.PrintNode();
+        }
+
+        public IEnumerator GetEnumerator()
+        {
+            foreach (T item in root.Enumerate())
+                yield return item;
+        }
+
+        public void Insert(params T[] Data)
+        {
+            foreach (var item in Data)
+                Insert(item);
+        }
+        public void Insert(T Data)
+        {
+            Node neu = new Node(Data);
+            if (root == null)           // Gibt es schon einen Baum?
+                root = neu;             // Nein: Neues Element ist Wurzel des Baums
+            else
+            {
+                Node tmp = root;        
+                bool found = false;
+                do      // Solange die Einfügeposition noch nicht gefunden ist, tue ...
+                {
+                    if (neu.data.CompareTo(tmp.data) < 0)
+                    {   // links oder rechts von dem aktuellen Element einfügen?
+                        // LINKS
+                        if (tmp.left == null)   
+                        {                   // Ist der linke Ast noch leer?
+                            tmp.left = neu;   // Dann hier einfügen
+                            found = true;
+                        }
+                        else
+                            tmp = tmp.left; // Sonst dem linken Ast folgen
+                    }
+                    else
+                    {       // RECHTS
+                        if (tmp.right == null)
+                        {                   // Ist der rechte Ast noch leer?
+                            tmp.right = neu;  // Dann hier einfügen
+                            found = true;
+                        }
+                        else                // Sonst dem rechten Ast folgen
+                            tmp = tmp.right;
+                    }
+                } while (!found);
+            }
+        }
+    }
+    
+}
diff --git a/11BinTreePersVerwaltung/ClassDiagram1.cd b/11BinTreePersVerwaltung/ClassDiagram1.cd
new file mode 100644
index 0000000000000000000000000000000000000000..7b894197b9d8d79b2ad4afafc2c11c60f33c4b42
--- /dev/null
+++ b/11BinTreePersVerwaltung/ClassDiagram1.cd
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram /> 
\ No newline at end of file
diff --git a/11BinTreePersVerwaltung/P28 BinTreePersVerwaltung.csproj b/11BinTreePersVerwaltung/P28 BinTreePersVerwaltung.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..0d2c5a3c1cf878eb54f5e9a4734cb21d80417a92
--- /dev/null
+++ b/11BinTreePersVerwaltung/P28 BinTreePersVerwaltung.csproj	
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{105A4EE2-C686-49AC-B634-F074D4F9EF46}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>_11BinTreePersVerwaltung2</RootNamespace>
+    <AssemblyName>11BinTreePersVerwaltung2</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BinTree.cs" />
+    <Compile Include="PersVerwaltung.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/11BinTreePersVerwaltung/PersVerwaltung.cs b/11BinTreePersVerwaltung/PersVerwaltung.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9dfa4398eb1061984942c3af3111c2c5088fab84
--- /dev/null
+++ b/11BinTreePersVerwaltung/PersVerwaltung.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace _11BinTreePersVerwaltung2
+{
+    abstract class Personal : IComparable<Personal>
+    {
+        protected string name;
+        public Personal(string Name) { name = Name; }
+        abstract public double Kosten { get; }
+        public string Name
+        {
+            get { return name; }
+        }
+        public int CompareTo(Personal p2) { return name.CompareTo(p2.name); }
+    }
+
+    class Mitarbeiter : Personal
+    {
+        protected double gehalt;
+        public Mitarbeiter(string Name, double Gehalt) : base(Name)
+        {
+            gehalt = Gehalt;
+        }
+        public override double Kosten
+        {
+            get { return 12.65 * gehalt; }
+        }
+    }
+
+    class Führungskraft : Personal
+    {
+        protected double gehalt;
+        protected double erfolgsbeteiligung;
+        public Führungskraft(string Name, double Gehalt, double Erfolgsbeteiligung) : base(Name)
+        {
+            gehalt = Gehalt;
+            erfolgsbeteiligung = Erfolgsbeteiligung;
+        }
+        public override double Kosten
+        {
+            get { return 12.65 * gehalt + erfolgsbeteiligung; }
+        }
+        public void Besonders() { }
+    }
+
+    class Werkvertragler : Personal
+    {
+        protected double betrag;
+        public Werkvertragler(string Name, double Betrag) : base(Name)
+        {
+            betrag = Betrag;
+        }
+        public override double Kosten
+        {
+            get { return betrag; }
+        }
+    }
+}
diff --git a/11BinTreePersVerwaltung/Program.cs b/11BinTreePersVerwaltung/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dc2843ab9dbf61f02ca6cdca4064a8ae916643ee
--- /dev/null
+++ b/11BinTreePersVerwaltung/Program.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace _11BinTreePersVerwaltung2
+{
+    class Program
+    {
+        static void InputData(BinTree<Personal> pt)
+        {
+            pt.Insert(
+                new Mitarbeiter("Dieter", 2000),
+                new Führungskraft("Anton", 5000, 10000),
+                new Werkvertragler("Gustav", 12000),
+                new Mitarbeiter("Heiner", 2000),
+                new Werkvertragler("Berta", 10000),
+                new Werkvertragler("Ludwig", 12000),
+                new Mitarbeiter("Klaus", 2000),
+                new Mitarbeiter("Ida", 2000),
+                new Führungskraft("Charles", 5000, 10000),
+                new Werkvertragler("Johanna", 10000),
+                new Mitarbeiter("Emma", 2000),
+                new Mitarbeiter("Franz", 10000),
+                new Werkvertragler("Norbert", 10000),
+                new Werkvertragler("Willi", 10000),
+                new Mitarbeiter("Quasimodo", 2500),
+                new Führungskraft("Manni", 5200, 15000),
+                new Mitarbeiter("Otto", 10000),
+                new Werkvertragler("Uwe", 10000),
+                new Werkvertragler("Stefan", 10000),
+                new Mitarbeiter("Victoria", 2500),
+                new Mitarbeiter("Thorsten", 10000),
+                new Werkvertragler("Rainer", 10000),
+                new Werkvertragler("Zacharias", 10000),
+                new Mitarbeiter("Yvonne", 3000),
+                new Führungskraft("Volker", 5100, 10000),
+                new Mitarbeiter("Xaver", 2500)
+            );
+        }
+        static void Main(string[] args)
+        {
+            BinTree<Personal> persBaum = new BinTree<Personal>();
+            InputData(persBaum);
+
+            foreach (Personal p in persBaum)
+                Console.WriteLine(p.Name + " " + p.GetType());
+            Console.WriteLine();
+            Console.WriteLine("-------------");
+
+            var res = from Personal p in persBaum
+                      where p is Führungskraft
+                      orderby p.Kosten
+                      select new { Name = p.Name.ToUpper(), Kosten = p.Kosten };
+            Console.WriteLine("Führungskräfte: ");
+            foreach (var p in res)
+                Console.WriteLine(p);
+            Console.WriteLine(  "------------");
+
+            // -----------------------
+
+            double FKosten = res.Sum(w => w.Kosten);
+            Console.WriteLine("Kosten für die Führungskräfte: " + FKosten.ToString());
+            int anz = res.Count();
+            Console.WriteLine(anz + " Führungskräfte");
+            Console.WriteLine("-------------------");
+
+
+            var res2 = from Personal p in persBaum
+                       where p.Kosten < 30000
+                       orderby p.Kosten descending, p.Name descending  // Sortierung nach Kosten, dann Name
+                       select new { Name = p.Name, K = p.Kosten };
+
+            foreach (var p in res2)
+                Console.WriteLine(p.Name + ": " + p.K.ToString());
+        }
+    }
+}
diff --git a/11BinTreePersVerwaltung/Properties/AssemblyInfo.cs b/11BinTreePersVerwaltung/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..152141ff461ad1b4e36be8161a10bd55f09ba820
--- /dev/null
+++ b/11BinTreePersVerwaltung/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("11BinTreePersVerwaltung2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("11BinTreePersVerwaltung2")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("105a4ee2-c686-49ac-b634-f074d4f9ef46")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OOP2024_AMP.sln b/OOP2024_AMP.sln
index 5e3c16eaa3aae3f6bf7beb5517f3581778a96b4e..d14a18025e6d831d4c0e57d09f25c925d7f2e0bd 100644
--- a/OOP2024_AMP.sln
+++ b/OOP2024_AMP.sln
@@ -45,9 +45,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P19 WPF_Demo", "P19 WPF_Dem
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P20 Liste mit Delegate", "P20 Liste mit Delegate\P20 Liste mit Delegate.csproj", "{FF28F272-A827-4234-B95C-947C69D26349}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P21 Ref", "P21 Ref\P21 Ref.csproj", "{BFA3D217-5696-43B1-94A5-2B90851732EA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P21 Ref", "P21 Ref\P21 Ref.csproj", "{BFA3D217-5696-43B1-94A5-2B90851732EA}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P22 DelVariableButton", "P22 DelVariableButton\P22 DelVariableButton.csproj", "{32D834E6-C426-432B-A162-78CE0E88E714}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P22 DelVariableButton", "P22 DelVariableButton\P22 DelVariableButton.csproj", "{32D834E6-C426-432B-A162-78CE0E88E714}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P23 MulticastDelegatesRef", "P23 MulticastDelegatesRef\P23 MulticastDelegatesRef.csproj", "{A0138C98-9057-4C66-99E5-F76BC3531252}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P24 GenericMulticastPipeline", "P24 MulticastPipeline\P24 GenericMulticastPipeline.csproj", "{2096CF26-79A8-4125-94DE-0F05EE234132}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P25 DataDriven", "09DataDriven\P25 DataDriven.csproj", "{81EEED7E-77BF-41BA-A49F-49B8B21B4E47}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P26 Erweiterungsmethoden", "10 Erweiterungsmethoden\P26 Erweiterungsmethoden.csproj", "{CAE85911-E807-4F15-9788-6672C8C228D4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "P27 LINQ_Intro", "10 LINQ_Intro\P27 LINQ_Intro.csproj", "{6FB54200-CE29-4FF6-A5A7-935D4AA9606B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P28 BinTreePersVerwaltung", "11BinTreePersVerwaltung\P28 BinTreePersVerwaltung.csproj", "{105A4EE2-C686-49AC-B634-F074D4F9EF46}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P29 HTMLEngine", "05HTMLEngine\P29 HTMLEngine.csproj", "{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -147,6 +161,34 @@ Global
 		{32D834E6-C426-432B-A162-78CE0E88E714}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{32D834E6-C426-432B-A162-78CE0E88E714}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{32D834E6-C426-432B-A162-78CE0E88E714}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A0138C98-9057-4C66-99E5-F76BC3531252}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A0138C98-9057-4C66-99E5-F76BC3531252}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A0138C98-9057-4C66-99E5-F76BC3531252}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A0138C98-9057-4C66-99E5-F76BC3531252}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2096CF26-79A8-4125-94DE-0F05EE234132}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2096CF26-79A8-4125-94DE-0F05EE234132}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2096CF26-79A8-4125-94DE-0F05EE234132}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2096CF26-79A8-4125-94DE-0F05EE234132}.Release|Any CPU.Build.0 = Release|Any CPU
+		{81EEED7E-77BF-41BA-A49F-49B8B21B4E47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{81EEED7E-77BF-41BA-A49F-49B8B21B4E47}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{81EEED7E-77BF-41BA-A49F-49B8B21B4E47}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{81EEED7E-77BF-41BA-A49F-49B8B21B4E47}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CAE85911-E807-4F15-9788-6672C8C228D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CAE85911-E807-4F15-9788-6672C8C228D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CAE85911-E807-4F15-9788-6672C8C228D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CAE85911-E807-4F15-9788-6672C8C228D4}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6FB54200-CE29-4FF6-A5A7-935D4AA9606B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6FB54200-CE29-4FF6-A5A7-935D4AA9606B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6FB54200-CE29-4FF6-A5A7-935D4AA9606B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6FB54200-CE29-4FF6-A5A7-935D4AA9606B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{105A4EE2-C686-49AC-B634-F074D4F9EF46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{105A4EE2-C686-49AC-B634-F074D4F9EF46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{105A4EE2-C686-49AC-B634-F074D4F9EF46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{105A4EE2-C686-49AC-B634-F074D4F9EF46}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BCED82D0-F95F-4D82-9019-2C63D6B3CC8A}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/P13 Generics/Program.cs b/P13 Generics/Program.cs
index a447cdb876823022e94294e01ba1d9ec3ba3eff2..d3342f22dd4671004cfe1b570f7cd1e5d0e61747 100644
--- a/P13 Generics/Program.cs	
+++ b/P13 Generics/Program.cs	
@@ -2,10 +2,10 @@
 {
     class Person : IComparable<Person>
     {
-        public string Name { get; set; }
+        public string? Name { get; set; }
         public int Alter { get; set; }
         public override string ToString()=>$"{Name}, {Alter}";
-        public int CompareTo(Person other) => Name.CompareTo(other.Name);
+        public int CompareTo(Person? other) => Name!.CompareTo(other?.Name);
         //public int CompareTo(Person other) => Alter - other.Alter;
     }
     internal class Program
diff --git a/P14 GenericList/DblList.cs b/P14 GenericList/DblList.cs
index b87403415422476e210428a06ba1bd04ef0aeb52..a50a75a9bdb4af28ed8e61ffa76f5c6ef2d08053 100644
--- a/P14 GenericList/DblList.cs	
+++ b/P14 GenericList/DblList.cs	
@@ -20,7 +20,7 @@ namespace P14_GenericList
         }
         LItem? first = null, last = null;
         int anz = 0;
-        public int CompareTo(DblList<T> other) => anz - other.anz;
+        public int CompareTo(DblList<T>? other) => anz - other!.anz;
         public override string ToString() => $"DblList, {anz} Elemente";
         public void AddLast(T? data)
         {
@@ -74,7 +74,7 @@ namespace P14_GenericList
                     // Durchlaufen der Liste
                     // Wenn Name des nächsten Elements kleiner ist => weitergehen
                     // tmp verweist auf das Element VOR DEM eingefügt wird
-                    while (tmp!.data.CompareTo(data) < 0)
+                    while (tmp!.data?.CompareTo(data) < 0)
                         tmp = tmp.next;
 
                     // Einfügen des Elements
diff --git a/P14 GenericList/Person.cs b/P14 GenericList/Person.cs
index 3742fcf6aff7ec689fe5c2b0509548490b9055ed..55d2586c3e7f28ade5fa647f0598f4a10a0c2d86 100644
--- a/P14 GenericList/Person.cs	
+++ b/P14 GenericList/Person.cs	
@@ -17,7 +17,7 @@ namespace P14_GenericList
             Alter = alter;
         }
 
-        public int CompareTo(Person other) => this.Name.CompareTo(other.Name);
-        //public int CompareTo(Person other) => this.Alter - other.Alter;
+        public int CompareTo(Person? other) => this.Name.CompareTo(other?.Name);
+        //public int CompareTo(Person? other) => this.Alter - other?.Alter;
     }
 }
diff --git a/P15 GenericSort/Program.cs b/P15 GenericSort/Program.cs
index 4f906088d437189a2079a5afe57389d8f5ad01a0..1ce47297784b3dae8a07d607ef57b080f45e0a17 100644
--- a/P15 GenericSort/Program.cs	
+++ b/P15 GenericSort/Program.cs	
@@ -4,7 +4,8 @@
     {
         static void Sort<T>(T[] array) where T : IComparable<T>
         {
-            if (array[i].CompareTo(array[j])<0)
+            // Selbst programmieren ...
+            if (array[0].CompareTo(array[0])<0)
                 Console.WriteLine("....");
         }
         static void Main(string[] args)
diff --git a/P16 GenericKeyValueList/Program.cs b/P16 GenericKeyValueList/Program.cs
index 220c91858dbbde904fe1098de5a21ef5af121920..3e89160e65e2f9f4b9be801e1089816867b87943 100644
--- a/P16 GenericKeyValueList/Program.cs	
+++ b/P16 GenericKeyValueList/Program.cs	
@@ -13,9 +13,9 @@
         public int Wert1 { get; set; }
         public string Wert2 { get; set; }
         public ComplexKey(int Wert1, string Wert2) { this.Wert1 = Wert1; this.Wert2 = Wert2; }
-        public int CompareTo(ComplexKey other)
+        public int CompareTo(ComplexKey? other)
         {
-            int diff = Wert1.CompareTo(other.Wert1);
+            int diff = Wert1.CompareTo(other!.Wert1);
             if (diff != 0)
                 return diff;
             return Wert2.CompareTo(other.Wert2);
diff --git a/P22 DelVariableButton/Program.cs b/P22 DelVariableButton/Program.cs
index ae9fbcf13c5398b011e2895eecf932ebba001367..45f683b3a2463f1e85bf8da9e396e62f5f276fab 100644
--- a/P22 DelVariableButton/Program.cs	
+++ b/P22 DelVariableButton/Program.cs	
@@ -3,19 +3,22 @@
     public delegate void OnClickDelegate(string s);
     class Button
     {
-        public event OnClickDelegate onClick; 
+        public event OnClickDelegate? OnClick; 
         // Event ~ Einschränkung des Del.-Zugriffs:
         // nur += und -= sowie Del.Aufruf aus der definierenden Klasse
         public void FireClick(string msg)
         {
-            //if (onClick != null)
-            //    onClick(msg);
-            onClick?.Invoke(msg);
+            //if (OnClick != null)
+            //    OnClick(msg);
+            OnClick?.Invoke(msg);
 
-            foreach (var item in onClick.GetInvocationList()) {
-                ((OnClickDelegate) item)(msg);
+            if (OnClick != null)
+            {
+                foreach (var delFunction in OnClick.GetInvocationList())
+                {
+                    ((OnClickDelegate)delFunction)(msg);
+                }
             }
-            
         }
     }
     class Program
@@ -30,13 +33,15 @@
             //button.FireClick("Klick");
 
             // Registrierung der interessierten Event-Handler
-            button.onClick += MeinClickHandler;
-            button.onClick += s => Console.WriteLine($"Mich interessiert die Message >{s}< ebenso");
+            button.OnClick += MeinClickHandler;
+            button.OnClick += s => Console.WriteLine($"Mich interessiert die Message >{s}< ebenso");
             // button.onClick = MeinClickHandler; -- Bei Events ist = verboten
+            // ACHTUNG: anonym.Methoden und Lambda-Ausdrücke können
+            //          nicht per -= entfernt werden
 
             // Aufruf der Delegate-Variablen
             button.FireClick("Klick");
-            //button.onClick("Hallo Welt");
+            //button.OnClick("Hallo Welt");
         }
     }
 }
diff --git a/P23 MulticastDelegatesRef/P23 MulticastDelegatesRef.csproj b/P23 MulticastDelegatesRef/P23 MulticastDelegatesRef.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..fbb6e37bf35bd206a61d40f63a2cf363507ea4ad
--- /dev/null
+++ b/P23 MulticastDelegatesRef/P23 MulticastDelegatesRef.csproj	
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>P23_MulticastDelegatesRef</RootNamespace>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>
diff --git a/P23 MulticastDelegatesRef/Program.cs b/P23 MulticastDelegatesRef/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..15d5f29d951542dd320eb779c5ea08e637bddc54
--- /dev/null
+++ b/P23 MulticastDelegatesRef/Program.cs	
@@ -0,0 +1,26 @@
+namespace P23_MulticastDelegatesRef
+{
+    public delegate void DoItDelegate<T>(ref T s);
+    class Pipeline<T>
+    {
+        public event DoItDelegate<T>? Action;
+        public void Process(ref T obj)
+        {
+            Action?.Invoke(ref obj);
+        }
+    }
+    internal class Program
+    {
+        public static void ToUpper(ref string s) { s = s.ToUpper(); }
+        public static void First3(ref string s) { s = s.Substring(0,3); }
+        static void Main(string[] args)
+        {
+            Pipeline<string> pip = new Pipeline<string>();
+            pip.Action += ToUpper;
+            pip.Action += First3;
+            string msg = "Hallo Welt";
+            pip.Process(ref msg);
+            Console.WriteLine(  msg);
+        }
+    }
+}
diff --git a/P24 MulticastPipeline/P24 GenericMulticastPipeline.csproj b/P24 MulticastPipeline/P24 GenericMulticastPipeline.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..c25f5e1ed8e368a64a677e3e510f1558c5786a84
--- /dev/null
+++ b/P24 MulticastPipeline/P24 GenericMulticastPipeline.csproj	
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>P24_MulticastPipeline</RootNamespace>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>
diff --git a/P24 MulticastPipeline/Program.cs b/P24 MulticastPipeline/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a53466ceeed1820bdf1f18407be2c5848c21f9ad
--- /dev/null
+++ b/P24 MulticastPipeline/Program.cs	
@@ -0,0 +1,32 @@
+namespace P24_MulticastPipeline
+{
+    class Image { }
+
+    class Pipeline<T>
+    {
+        public event Action<T>? Action;
+        public void Process(T image)
+        {
+            Action?.Invoke(image);
+        }
+    }
+    internal class Program
+    {
+        static void BelichtungErhoehen(Image image) { Console.WriteLine("Belichtung erhöhen"); }
+        static void SchaerfeErhoehen(Image image) { Console.WriteLine("Schärfe erhöhen"); }
+        static void SchwarzwertVermindern(Image image) { Console.WriteLine("Schwarzwert vermindern"); }
+        
+        
+        static void Main(string[] args)
+        {
+            Image img1 = new Image();
+            
+            Pipeline<Image> pipe = new Pipeline<Image>();
+            pipe.Action += BelichtungErhoehen;
+            pipe.Action += SchaerfeErhoehen;
+            pipe.Action += SchwarzwertVermindern;
+
+            pipe.Process(img1);
+        }
+    }
+}