From 94cffe139a6c0fb837eb4483f626e30a089c4828 Mon Sep 17 00:00:00 2001
From: Martin Goik <goik@hdm-stuttgart.de>
Date: Mon, 31 Jan 2022 16:41:30 +0100
Subject: [PATCH] Exam winter 2021/22

---
 Doc/Sd1/Exam/2021/Winter/exam.xml             | 481 ++++++++++++++++++
 Doc/Sd1/appendix.xml                          |   4 +
 Klausuren/Sd1/2021winter/Exam/pom.xml         | 130 +++++
 .../Exam/src/main/assembly/assembly.xml       |  36 ++
 .../mi/sd1/task1/A_TrafficLight.java          |  66 +++
 .../mi/sd1/task1/B_StringHelper.java          |  44 ++
 .../mi/sd1/task1/C_ArrayHelper.java           |  42 ++
 .../mi/sd1/task1/D_TextFrame.java             |  69 +++
 .../mi/sd1/task1/package-info.java            |  17 +
 .../mi/sd1/task2/QuadratPolynom.java          | 142 ++++++
 .../mi/sd1/task4_no_unit_test/Mathextend.java |  31 ++
 .../main/javadoc/resources/fonts/dejavu.css   |   3 +
 .../main/javadoc/resources/jdocSupplement.css |  68 +++
 .../main/javadoc/resources/jdocSupplement.js  |   7 +
 .../Exam/src/main/resources/log4j2.xml        |  21 +
 .../mi/sd1/ShowReachedPoints.java             |  22 +
 .../mi/sd1/ignore_me/ObjectWrapper.java       | 231 +++++++++
 .../mi/sd1/task1/A_TrafficLightTest.java      |  25 +
 .../mi/sd1/task1/B_StringHelperTest.java      |  37 ++
 .../mi/sd1/task1/C_ArrayHelperTest.java       |  42 ++
 .../mi/sd1/task1/D_TextFrameTest.java         |  89 ++++
 .../mi/sd1/task2/Test_QuadratPolynom.java     | 226 ++++++++
 Klausuren/Sd1/2021winter/Solve/Doc/wurzel.ods | Bin 0 -> 16802 bytes
 Klausuren/Sd1/2021winter/Solve/pom.xml        | 130 +++++
 .../Solve/src/main/assembly/assembly.xml      |  36 ++
 .../mi/sd1/task1/A_TrafficLight.java          |  66 +++
 .../mi/sd1/task1/B_StringHelper.java          |  49 ++
 .../mi/sd1/task1/C_ArrayHelper.java           |  61 +++
 .../mi/sd1/task1/D_TextFrame.java             |  77 +++
 .../mi/sd1/task1/package-info.java            |  17 +
 .../mi/sd1/task2/QuadratPolynom.java          | 241 +++++++++
 .../mi/sd1/task4_no_unit_test/Mathextend.java |  31 ++
 .../main/javadoc/resources/fonts/dejavu.css   |   3 +
 .../main/javadoc/resources/jdocSupplement.css |  68 +++
 .../main/javadoc/resources/jdocSupplement.js  |   7 +
 .../Solve/src/main/resources/log4j2.xml       |  21 +
 .../mi/sd1/ShowReachedPoints.java             |  22 +
 .../mi/sd1/ignore_me/ObjectWrapper.java       | 231 +++++++++
 .../mi/sd1/task1/A_TrafficLightTest.java      |  25 +
 .../mi/sd1/task1/B_StringHelperTest.java      |  37 ++
 .../mi/sd1/task1/C_ArrayHelperTest.java       |  42 ++
 .../mi/sd1/task1/D_TextFrameTest.java         |  89 ++++
 .../mi/sd1/task2/Test_QuadratPolynom.java     | 226 ++++++++
 43 files changed, 3312 insertions(+)
 create mode 100644 Doc/Sd1/Exam/2021/Winter/exam.xml
 create mode 100644 Klausuren/Sd1/2021winter/Exam/pom.xml
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/assembly/assembly.xml
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/fonts/dejavu.css
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.css
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.js
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/main/resources/log4j2.xml
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/Doc/wurzel.ods
 create mode 100644 Klausuren/Sd1/2021winter/Solve/pom.xml
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/assembly/assembly.xml
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/fonts/dejavu.css
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.css
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.js
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/main/resources/log4j2.xml
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
 create mode 100644 Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java

diff --git a/Doc/Sd1/Exam/2021/Winter/exam.xml b/Doc/Sd1/Exam/2021/Winter/exam.xml
new file mode 100644
index 000000000..fa895dcca
--- /dev/null
+++ b/Doc/Sd1/Exam/2021/Winter/exam.xml
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section version="5.0" xml:id="sd1_exam_2021_winter" xml:lang="en"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:trans="http://docbook.org/ns/transclusion"
+         xmlns:svg="http://www.w3.org/2000/svg"
+         xmlns:m="http://www.w3.org/1998/Math/MathML"
+         xmlns:html="http://www.w3.org/1999/xhtml"
+         xmlns:db="http://docbook.org/ns/docbook">
+  <title>SD1 examination winter 2021</title>
+
+  <section xml:id="sd1_exam_2021_winter_task1">
+    <title>Implementing tasks</title>
+
+    <section xml:id="sd1_exam_2021_winter_task1_preparation">
+      <title>Preparation</title>
+
+      <para>Download and unzip the above file <filename>exam.zip</filename>.
+      Then import the resulting <filename>Exam</filename> Project into your
+      <productname>IDEA</productname> IDE by choosing »File --&gt; Open...«
+      for selecting the <filename>Exam/pom.xml</filename> file.</para>
+    </section>
+
+    <section xml:id="sd1_exam_2021_winter_task1_description">
+      <title>Description</title>
+
+      <para>Your imported project contains:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Partial implementations of classes and methods.</para>
+        </listitem>
+
+        <listitem>
+          <para><productname>Javadoc</productname> comments describing the
+          desired (not yet implemented) behaviour.</para>
+        </listitem>
+
+        <listitem>
+          <para><productname>Junit</productname> tests for testing the desired
+          behaviour.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section xml:id="sd1_exam_2021_winter_task1_tasks">
+      <title>Tasks</title>
+
+      <para>Complete the implementation of classes and methods in both
+      packages <package>de.hdm_stuttgart.mi.sd1.task1</package> and
+      <package>de.hdm_stuttgart.mi.sd1.task2</package>. Your project's
+      <filename>test</filename> branch contains corresponding
+      <productname>Junit</productname> tests for each class / method to be
+      implemented.</para>
+    </section>
+
+    <section xml:id="sd1_exam_2021_winter_task1_hints">
+      <title>Hints</title>
+
+      <itemizedlist>
+        <listitem>
+          <para>Your score solely depends on the number of successfully
+          executing unit tests. A »nearly correct« implementation failing with
+          respect to a given unit tests will not contribute any points at
+          all.</para>
+
+          <para>General advice: Implement less but correctly.</para>
+        </listitem>
+
+        <listitem>
+          <para>Mind special cases <abbrev>i.e.</abbrev> <code>null</code>
+          variable values or <code>null</code> values being contained in
+          arrays.</para>
+        </listitem>
+
+        <listitem>
+          <para>In case of test failures both the
+          <productname>IDEA</productname> debugger and logging statements are
+          your friend.</para>
+        </listitem>
+
+        <listitem>
+          <para>Executing
+          <package>de.hdm_stuttgart.mi.sd1</package>.<classname>ShowReachedPoints</classname>
+          in your project's <filename>test</filename> branch as a
+          <productname>Java</productname> application (not as
+          <productname>Junit</productname> test!) shows your number of points
+          reached so far.</para>
+        </listitem>
+
+        <listitem>
+          <para>Do not model your implementations along unit test definitions
+          i.e avoid <link
+          xlink:href="https://freedocs.mi.hdm-stuttgart.de/__slidesd1_appendix.html#/sd1_fig_testDontCheat">cheating
+          this way</link>! Such behaviour will be regarded as an attempt at
+          deception (<foreignphrase
+          xml:lang="de">Täuschungsversuch</foreignphrase>).</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section version="5.1" xml:id="sd1_exam_2021_winter_uploadFirst">
+      <title>Project upload</title>
+
+      <para>Export your project by hitting »File« --&gt; »Export« --&gt;
+      »Project to Zip File« in IDEA creating <abbrev>e.g.</abbrev> a file
+      <filename>solution-1.zip</filename>. Hit the <quote> choose file</quote>
+      button in your <productname>ILIAS</productname> browser tab and select
+      <filename>solution-1.zip</filename>. Subsequently click
+      <quote>upload</quote>. Do not forget to advance to the next question for
+      actually saving your upload. Common pitfalls:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Do not select the wrong archive! In particular avoid choosing
+          the original <filename>exam.zip</filename> file.</para>
+        </listitem>
+
+        <listitem>
+          <para>After uploading check for <filename>solution_1.zip</filename>
+          being visible in the examination system.</para>
+        </listitem>
+
+        <listitem>
+          <para>On advancing your implementation you may upload improved
+          versions i.e. <filename>solution_2.zip</filename> etc. of your
+          project at any time. Only your least uploaded archive will become
+          subject to marking.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section xml:id="sd1_exam_2021_winter_examCaveats">
+      <title>Caveats</title>
+
+      <itemizedlist>
+        <listitem>
+          <para>When approaching end of examination check your input for
+          completeness prior to being automatically logged out by the system.
+          Remember: There is 120 minutes for the examination and another 5
+          minutes to check for completeness.</para>
+        </listitem>
+
+        <listitem>
+          <para>Projects residing just on your local workstation's file system
+          cannot be recovered after finishing the exam.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+  </section>
+
+  <section xml:id="sd1_exam_2021_winter_task2">
+    <title><methodname>equals()</methodname> and
+    <methodname>hashCode()</methodname></title>
+
+    <qandaset defaultlabel="qanda" xml:id="sd1_exam_2021_winter_task2Qanda">
+      <qandadiv>
+        <qandaentry>
+          <question>
+            <para>Consider the following <classname>Person</classname>
+            class:</para>
+
+            <programlisting language="java">public class Person {
+
+    private String name, // Guaranteed never
+            comment;     // to be null
+
+    private  int ageInYears;
+
+    // Other methods omitted for brevity
+
+    @Override public boolean equals(Object o) {
+        if (o instanceof  Person) {
+            final Person p = (Person) o;
+            return ageInYears == p.ageInYears &amp;&amp;
+                    name.equals(p.name);
+        } else {
+            return false;
+        }
+    }
+
+    @Override public int hashCode() {
+        return ageInYears + 13 * comment.hashCode();
+    }
+}</programlisting>
+
+            <para>We assume the above <methodname>equals()</methodname>
+            implementation to be correct. Answer the following two
+            questions:</para>
+
+            <orderedlist>
+              <listitem>
+                <para>Is this implementation correct regarding the <link
+                xlink:href="https://freedocs.mi.hdm-stuttgart.de/doc/openjdk-17-doc/api/java.base/java/lang/Object.html#hashCode()">contract
+                between <methodname>equals()</methodname> and
+                <methodname>hashCode()</methodname></link>? Correct if
+                necessary.</para>
+              </listitem>
+
+              <listitem>
+                <para>After correcting possible flaws: Is the resulting
+                implementation »good« with respect to distinguishing objects?
+                Amend if possible.</para>
+              </listitem>
+            </orderedlist>
+
+            <para>Explain your answers.</para>
+          </question>
+
+          <answer>
+            <orderedlist>
+              <listitem>
+                <para>The <methodname>equals(...)</methodname> method defines
+                two <classname>Person</classname> instances to be equal when
+                having common age and Name. Thus two instances e.g. <code>(18,
+                "Eve Porter", "New Friend from holiday")</code> and <code>(18,
+                "Eve Porter", "Friendly person")</code>of common name and age
+                but having a different comment will still considered to be
+                equal.</para>
+
+                <para>Since equality is being defined solely on
+                <property>age</property> and <property>name</property> the
+                <property>comment</property> attribute must not be used for
+                implementing <methodname>hashCode()</methodname>. Otherwise
+                the above example will result in different hash values
+                contradicting the <methodname>equals(...)</methodname> /
+                <methodname>hashCode()</methodname> contract. We thus
+                have:</para>
+
+                <programlisting language="java">public class Person {
+  ...
+    @Override public int hashCode() {
+        return ageInYears;
+    }
+}</programlisting>
+              </listitem>
+
+              <listitem>
+                <para>The previously corrected
+                <methodname>hashCode()</methodname> implementation is correct
+                with respect to its related <methodname>equals()</methodname>
+                method. However all <classname>Person</classname> instances of
+                common <property>age</property> but different
+                <property>name</property> will be defined to be different by
+                our <methodname>equals(...)</methodname> method. But they will
+                all share the same <methodname>hashCode()</methodname> value
+                throughout. So our <methodname>hashCode()</methodname> method
+                is not particularly good when it comes to distinguish objects.
+                Adding the <property>name</property> property to our
+                <methodname>hashCode()</methodname> calculation solves this
+                issue:</para>
+
+                <programlisting language="java">public class Person {
+  ...
+    @Override public int hashCode() {
+        return ageInYears + 13 * name.hashCode();
+    }
+}</programlisting>
+              </listitem>
+            </orderedlist>
+          </answer>
+        </qandaentry>
+      </qandadiv>
+    </qandaset>
+  </section>
+
+  <section xml:id="sd1_exam_2021_winter_task3">
+    <title>The average of three byte values</title>
+
+    <qandaset defaultlabel="qanda" xml:id="sd1_exam_2021_winter_task3Qanda">
+      <qandadiv>
+        <qandaentry>
+          <question>
+            <para>A newbie programmer codes the following snippet:</para>
+
+            <programlisting language="java">/**
+ * The average of three values
+ *
+ * @param a First value
+ * @param b Second value
+ * @param c Third value
+ *
+ * @return Closest &lt;code&gt;byte&lt;/code&gt; value to â…“ (a + b + c)
+ */
+public static byte getAverage(byte a, final byte b, final byte c) {
+   a += b;
+   a += c;
+   a /= 3;
+   return a;
+}</programlisting>
+
+            <para>A senior programming companion warns about two possible
+            problems:</para>
+
+            <orderedlist>
+              <listitem>
+                <para>The implementation is prone to overflow errors.</para>
+              </listitem>
+
+              <listitem>
+                <para>The implementation will in many cases return
+                unnecessarily inaccurate results.</para>
+              </listitem>
+            </orderedlist>
+
+            <para>Explain both points in the answer box below.</para>
+
+            <para>In addition provide a solution by modifying the above code.
+            You may present your code in the answer box below as well.</para>
+
+            <para>Alternatively correct the implementation of
+            <package>de.hdm_stuttgart.mi.sd1.task4_no_unit_test</package>.<classname>Mathextend</classname>
+            within your downloaded and imported <filename>exam.zip</filename>
+            project using your IDEA IDE. In this case <emphasis role="red">Do
+            not forget to export and upload after finishing by using task 1 of
+            this examination</emphasis>.</para>
+
+            <tip>
+              <para><methodname
+              xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Math.html#round(double)">Math.round(double)</methodname>
+              might be your friend.</para>
+            </tip>
+          </question>
+
+          <answer>
+            <orderedlist>
+              <listitem>
+                <para>Biggest problem here: The operator <code
+                language="java">+=</code>'s way of cycling through a <code
+                language="java">byte</code>'s range when exceeding <code
+                language="java"
+                xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Byte.html#MAX_VALUE">Byte.MAX_VALUE</code>
+                or <code language="java"
+                xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Byte.html#MIN_VALUE">Byte.MIN_VALUE</code>
+                boundaries. Consider:</para>
+
+                <informaltable border="1">
+                  <colgroup width="76%"/>
+
+                  <colgroup width="24%"/>
+
+                  <tr>
+                    <th>Code</th>
+
+                    <th>Output</th>
+                  </tr>
+
+                  <tr>
+                    <td valign="top"><programlisting language="java">byte b = 127;
+b += 1;
+System.out.println("Result: " + b);</programlisting></td>
+
+                    <td valign="top"><screen>Result: -128</screen></td>
+                  </tr>
+
+                  <tr>
+                    <td valign="top"><programlisting language="java">byte b = -128;
+b += -1;
+System.out.println("Result: " + b);</programlisting></td>
+
+                    <td valign="top"><screen>Result: +127</screen></td>
+                  </tr>
+
+                  <tr>
+                    <td valign="top"><programlisting language="java">// Expecting 129 / 3 == +43
+System.out.println("Result: " +
+  getAverage((byte) 127, (byte) 1, (byte) 1));</programlisting></td>
+
+                    <td valign="top"><screen>Result: -42</screen></td>
+                  </tr>
+                </informaltable>
+              </listitem>
+
+              <listitem>
+                <para>Converting fractions to byte values is next on the list
+                of troubles. The <code language="java">/=</code> operator will
+                simply cut off fractional values rather then rounding them
+                properly.</para>
+
+                <para>Switching to real values we have <inlineequation>
+                    <m:math display="inline">
+                      <m:mrow>
+                        <m:mrow>
+                          <m:mfrac bevelled="true">
+                            <m:mi>1</m:mi>
+
+                            <m:mi>3</m:mi>
+                          </m:mfrac>
+
+                          <m:mo>⁢</m:mo>
+
+                          <m:mrow>
+                            <m:mo>(</m:mo>
+
+                            <m:mrow>
+                              <m:mi>1</m:mi>
+
+                              <m:mo>+</m:mo>
+
+                              <m:mi>1</m:mi>
+
+                              <m:mo>+</m:mo>
+
+                              <m:mi>0</m:mi>
+                            </m:mrow>
+
+                            <m:mo>)</m:mo>
+                          </m:mrow>
+                        </m:mrow>
+
+                        <m:mo>=</m:mo>
+
+                        <m:mi>0.66...</m:mi>
+                      </m:mrow>
+                    </m:math>
+                  </inlineequation> . Our byte valued method should thus
+                return a value of 1 rather than 0. However:</para>
+
+                <informaltable border="1">
+                  <colgroup width="76%"/>
+
+                  <colgroup width="24%"/>
+
+                  <tr>
+                    <th>Code</th>
+
+                    <th>Output</th>
+                  </tr>
+
+                  <tr>
+                    <td valign="top"><programlisting language="java">System.out.println("Result: " + 
+  getAverage((byte) 1, (byte) 1, (byte) 0));</programlisting></td>
+
+                    <td valign="top"><screen>Result: 0</screen></td>
+                  </tr>
+                </informaltable>
+              </listitem>
+            </orderedlist>
+
+            <para>Solving these flaws requires using a data type behaving free
+            of overflow errors with respect to the given context of summing up
+            three byte values. Choosing <code>short</code> is sufficient for
+            adding either <code language="java"
+            xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Byte.html#MAX_VALUE">Byte.MAX_VALUE</code>
+            or <code language="java"
+            xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Byte.html#MIN_VALUE">Byte.MIN_VALUE</code>
+            even three times in a row.</para>
+
+            <para>Dividing by 3 should be a floating point rather than an
+            integer operation to avoid cutting off fractional values. On top
+            we finally use the <classname
+            xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Math.html">Math</classname><code
+            language="java">.</code><methodname
+            xlink:href="https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Math.html#round(double)">round(double)</methodname>
+            method avoiding rounding errors like the one shown
+            previously.</para>
+
+            <para>Finally we need a cast for converting back the rounded
+            value's type <code language="java">double</code> to the method's
+            return type <code language="java">byte</code>. The final result
+            reads:</para>
+
+            <programlisting language="java">public static byte getAverage(final byte a, final byte b, final byte c) {
+
+   short sum = a;
+   sum += b;
+   sum += c;
+   final double avg = sum / 3.;   // Floating point rather than integer division
+   return (byte) Math.round(avg); 
+}
+
+// Note: final short sum = a + b + c does not even compile as being explained at
+// https://freedocs.mi.hdm-stuttgart.de/sd1_sect_arithmeticOperators.html#sd1_explainNoByteByteOperator</programlisting>
+          </answer>
+        </qandaentry>
+      </qandadiv>
+    </qandaset>
+  </section>
+</section>
diff --git a/Doc/Sd1/appendix.xml b/Doc/Sd1/appendix.xml
index 1d59125f4..164b17ff4 100644
--- a/Doc/Sd1/appendix.xml
+++ b/Doc/Sd1/appendix.xml
@@ -3100,6 +3100,10 @@ Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 sec</scree
   <section xml:id="sd1_exams">
     <title>Past Software Development 1 examinations</title>
 
+
+    <xi:include href="Exam/2021/Winter/exam.xml" xpointer="element(/1)"
+                ns:idfixup="auto"/>
+
     <xi:include href="Exam/2021/Summer/exam.xml" xpointer="element(/1)"
                 ns:idfixup="auto"/>
 
diff --git a/Klausuren/Sd1/2021winter/Exam/pom.xml b/Klausuren/Sd1/2021winter/Exam/pom.xml
new file mode 100644
index 000000000..0c0738ff7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/pom.xml
@@ -0,0 +1,130 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>de.hdm-stuttgart.mi.sd1</groupId>
+    <artifactId>sd1_2021winter_exam</artifactId>
+    <version>0.9</version>
+    <packaging>jar</packaging>
+
+    <name>sd1_2021winter_exam</name>
+
+    <url>https://freedocs.mi.hdm-stuttgart.de/sd1_sect_mavenCli.html</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+    	<maven.compiler.target>17</maven.compiler.target>
+        <maven.compiler.source>17</maven.compiler.source>
+
+        <freedocs.url>https://freedocs.mi.hdm-stuttgart.de</freedocs.url>
+        <jdk.api_17.url>${freedocs.url}/doc/openjdk-17-doc/api/</jdk.api_17.url>
+        <mathjax.url>${freedocs.url}/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML</mathjax.url>
+        <libhighlight.url>${freedocs.url}/lib/highlight.js</libhighlight.url>
+    </properties>
+
+    <repositories>
+        <repository>
+            <id>hdm-mi-internal-maven-repo</id>
+            <url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.17.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>de.hdm_stuttgart.mi.exam</groupId>
+            <artifactId>unitmarking</artifactId>
+            <version>1.1</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+		        <artifactId>maven-javadoc-plugin</artifactId>
+		        <version>3.3.0</version>
+
+                <configuration>
+                    <!-- Tweak: Get rid of Error message
+                      »fetching link: .../target/javadoc-bundle-options. Ignored it«
+                      corresponding to api_11 below -->
+                    <release>11</release>
+                    <doclint>all</doclint>
+                    <show>public</show>
+                    <docfilessubdirs>true</docfilessubdirs>
+                    <addStylesheets>
+                        <stylesheet>resources/jdocSupplement.css</stylesheet>
+                    </addStylesheets>
+
+                    <javaApiLinks>
+                        <property>
+                            <name>api_11</name>
+                            <value>${jdk.api_17.url}</value>
+                        </property>
+                    </javaApiLinks>
+
+                    <additionalOptions>
+                        <additionalOption>-html5 --allow-script-in-comments</additionalOption>
+                    </additionalOptions>
+                    <nohelp>true</nohelp>
+
+                    <header><![CDATA[
+            <script type="text/javascript" src="${mathjax.url}"></script>
+            <script type="text/javascript" src="{@docRoot}/resources/jdocSupplement.js"></script>
+            <link rel="stylesheet" href="${libhighlight.url}/styles/idea.css">
+            <script src="${libhighlight.url}/highlight.js"></script>
+            <script type="text/javascript">hljs.initHighlightingOnLoad();</script>]]>
+                    </header>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.3.0</version>
+                <configuration>
+                    <descriptors>
+                        <descriptor>src/main/assembly/assembly.xml</descriptor>
+                    </descriptors>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    <mainClass>de.hdm_stuttgart.mi.sd1.ShowReachedPoints</mainClass>
+                                </manifest>
+                            </archive>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/assembly/assembly.xml b/Klausuren/Sd1/2021winter/Exam/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..85268e296
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/assembly/assembly.xml
@@ -0,0 +1,36 @@
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>fat-tests</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory/>
+            <useProjectArtifact>true</useProjectArtifact>
+            <unpack>true</unpack>
+            <scope>test</scope>
+        </dependencySet>
+    </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}/test-classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.build.directory}/classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
new file mode 100644
index 000000000..c94ac78bd
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
@@ -0,0 +1,66 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * <p>Stop and go at trafficlights.</p>
+ */
+public class A_TrafficLight {
+    /**
+     * <p>Traffic light stop / go indications.</p>
+     *
+     * <p>German traffic lights feature three different colours red, yellow and green. We assume the following rules:</p>
+     *
+     * <table style="border-spacing: 10ex 0;">
+     *     <caption>German traffic light states</caption>
+     *     <tr>
+     *         <td
+     *         style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:red;"></li>
+     *             <li style="color:black;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:red;"></li>
+     *             <li style="color:yellow;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:black;"></li>
+     *             <li style="color:black;"></li>
+     *             <li style="color:green;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:black;"></li>
+     *             <li style="color:yellow;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *     </tr>
+     *     <tr>
+     *         <td>Stop</td>
+     *         <td>Go</td>
+     *         <td>Go</td>
+     *         <td>Stop</td>
+     *     </tr>
+     *
+     * </table>
+     *
+     * @param red <code>true</code> represents »on«, <code>false</code> represents »off«.
+     * @param yellow <code>true</code> represents »on«, <code>false</code> represents »off«.
+     * @param green <code>true</code> represents »on«, <code>false</code> represents »off«.
+     *
+     * @return <code>true</code> represents »you must stop«, <code>false</code> represents »go«.
+     */
+    static public boolean mustStop(boolean red, boolean yellow, boolean green) {
+        return false; // TODO: Implement me correctly
+    }
+
+    private A_TrafficLight(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
new file mode 100644
index 000000000..642a280e8
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
@@ -0,0 +1,44 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * String related helper method. Currently {@link #getMaxLength(String[])} is on offer.
+ */
+public class B_StringHelper {
+
+    /**
+     * <p>Get the maximum string length among an array of strings. In the following example the longest of three
+     * strings is <code class="java">"Longman"</code> having length 7:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>Finding the longest string</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final String[] names =
+     *     {"Eve", "Longman", "Peter"};
+     *
+     * System.out.println("Longest name's length: " +
+     *     getMaxLength(names));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> Longest name's length: 7</code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * @param strings A non-empty array possibly containing both strings and <code>null</code> values.
+     * @return The greatest length of all strings. <code>null</code> values will be treated like empty strings.
+     */
+    static public int getMaxLength(final String[] strings) {
+
+        return 123;// TODO: Implement me correctly
+    }
+
+    private B_StringHelper(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
new file mode 100644
index 000000000..dc6226838
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
@@ -0,0 +1,42 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * <p>Array related helper method</p>
+ */
+public class C_ArrayHelper {
+
+    /**
+     * <p>Collect all values from a given array being above its average value. The following example
+     * features an array of five values resulting in an average of 6. Only the values 8, 12 and 8
+     * are strictly above average:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>Finding values above average</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final int[] values = {-4, 6, 8, 12, 8};
+     * System.out.println( "Above average: " +
+     *     Arrays.toString(getAboveAverage(values)));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> Above average: [8, 12, 8] </code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * @param values A list of values.
+     * @return All values from the list being strictly above the list's average thereby preserving
+     * the original array's order of appearance.
+     */
+    static public int[] getAboveAverage (int[] values) {
+        return null;// TODO: Implement me correctly
+    }
+    private C_ArrayHelper(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
new file mode 100644
index 000000000..7441a36e7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
@@ -0,0 +1,69 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * <p>ASCII art related method.</p>
+ */
+public class D_TextFrame {
+
+    /**
+     * <p>Arranging a list of strings line by line and surrounding it by a rectangular frame. The following
+     * example transforms an array containing two strings into a corresponding framed output:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>ASCII art frame</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final String[] words = {"This is a first", "sample"};
+     * System.out.println(createTextFrame(words));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> *******************
+     * * This is a first *
+     * * sample          *
+     * *******************</code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * <p>Note the additional empty spaces »<span style="color:red;font-weight:bold;">_</span>« between each
+     * starting * and before each ending *:</p>
+     *
+     * <pre><code class="nohighlight"> *******************
+     * *<span style="color:red;font-weight:bold;">_</span>This is a first<span style="color:red;font-weight:bold;">_</span>*
+     * *<span style="color:red;font-weight:bold;">_</span>sample         <span style="color:red;font-weight:bold;">_</span>*
+     * *******************</code></pre>
+     *
+     * @param strings A non-empty array possibly containing both strings and <code>null</code> values.
+     * @return An ASCII frame surrounding lines of text.
+     *
+     * <section class="implementationHints">
+     *    <h4 class="implementationHints">Hints:</h4>
+     *
+     * <ul>
+     *     <li>You may use {@link B_StringHelper#getMaxLength(String[])} to get the longest
+     *     string length in the list for sizing your frame.</li>
+     *
+     *     <li>{@link String#repeat(int)} for repeating both <code>"*"</code> and empty spaces <code>" "</code>
+     *     using e.g. <code>"*".repeat(10)</code>.</li>
+     *
+     *     <li>Watch out for spaces and invisible newlines at end of your returned string. These are difficult to spot
+     *     and may cause tests to fail.</li>
+     *
+     * </ul>
+     *
+     * </section>
+     */
+    static public String createTextFrame(final String[] strings) {
+
+
+        return "***"; // TODO: Implement me correctly
+    }
+
+    private D_TextFrame(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
new file mode 100644
index 000000000..fb7bb58c2
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
@@ -0,0 +1,17 @@
+/**
+ * <p>This package mostly (if not completely) contains static methods.</p>
+ *
+ * <p>The ordering being implied by class names reflects the author's opinion with respect to ascending implementation
+ * difficulty. Hints:</p>
+ *
+ * <ul>
+ *     <li>Run <code>mvn javadoc:javadoc</code> and open the generated
+ *     <code>/home/.../target/site/apidocs/index.html</code> file in your browser of choice.</li>
+ *
+ *     <li>Use the corresponding unit tests to check your implementation's consistency and class
+ *     <code>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</code> from your project's “unit test” branch.</li>
+ *
+ * </ul>
+ *
+ */
+package de.hdm_stuttgart.mi.sd1.task1;
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
new file mode 100644
index 000000000..6d7026006
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
@@ -0,0 +1,142 @@
+package de.hdm_stuttgart.mi.sd1.task2;
+
+/**
+ * <p>Providing zeroes (German: "Nullstellen") of quadratic polynomials.</p>
+ *
+ * <p>A quadratic polynomial \( p(x)  = a x² + b x + c \) is being defined by its three coefficients
+ * \(a\), \(b\) and \(c\). This class limits coefficients \(a\), \(b\) and \(c\) to type <code>int</code>. A general
+ * solution is being provided by:</p>
+ *
+ * <p>\[ x_{1,2} = {{-b \pm \sqrt{b^2 - 4 ac}} \over {2a}} \]</p>
+ *
+ * <p>Depending on \( b^2 - 4 ac \) being positive, zero or negative we have either two, one or no real solutions.</p>
+ *
+ * <p>The following sample illustrates zeroes calculation depending on given values of \(a\), \(b\) and \(c\):</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Sample code illustrating zero values calculation</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> final QuadratPolynom poly =         // Representing
+ *     new QuadratPolynom(4, -3, -10); // p(x) = 4x² - 3x - 10
+ *
+ * double[] zeroes = poly.getZeroes();
+ *
+ * System.out.println("Found " + zeroes.length + " zeroes:");
+ *
+ * System.out.println("x_1 = " + zeroes[0]);
+ * System.out.println("x_2 = " + zeroes[1]);</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> Found 2 zeroes:
+ * x_1 = -1.25
+ * x_2 = 2.0</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>We allow for re-setting a polynomial's coefficients. Continuing from the above example we have:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Changing coefficients</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(1);  // Representing
+ * poly.setB(-8); // p(x) = x² -8x + 16
+ * poly.setC(16);
+ *
+ * zeroes = poly.getZeroes();
+ * System.out.println("Found " + zeroes.length + " zero:");
+ *
+ * System.out.println("x_1 = " + zeroes[0]);</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Found 1 zero:
+ * x_1 = 4.0</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Some polynomials do not have any (real valued) solution:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Changing coefficients again</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(1);  // Representing
+ * poly.setB(0);  // p(x) = x² + 1
+ * poly.setC(1);  // (No zero solution)
+ *
+ * zeroes = poly.getZeroes();
+ * System.out.println("Found " + zeroes.length + " zero");</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Found 0 zero</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Finally setting \(a=0\) in \(ax²\) leaves us with just a linear polynomial \(bx + c\). To
+ * avoid unpredictable results the attempt shall result in throwing an
+ * <a href="https://freedocs.mi.hdm-stuttgart.de/doc/openjdk-17-doc/api/java.base/java/lang/ArithmeticException.html"
+ *  ><code>ArithmeticException</code></a>:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Dealing with 0 value at square coefficient.</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(0);  // Trying to represent p(x) = 1</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Exception in thread "main" java.lang.ArithmeticException:
+ *     Square coefficient must not be zero</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Likewise a <code>new QuadratPolynom(0, ..., ...)</code> constructor call setting \(a=0\) shall raise an
+ * <a href="https://freedocs.mi.hdm-stuttgart.de/doc/openjdk-17-doc/api/java.base/java/lang/ArithmeticException.html">
+ * <code>ArithmeticException</code></a> as well.</p>
+ *
+ * <section class="implementationHints">
+ *    <h2 class="implementationHints">Hint:</h2>
+ *
+ * <p>This class is yet unimplemented. The above code snippets provide a clue to an implementation
+ *    satisfying the corresponding unit tests.</p>
+ *
+ * </section>
+ */
+public class QuadratPolynom {
+    // TODO: Implement me
+    private QuadratPolynom(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
new file mode 100644
index 000000000..f254528aa
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
@@ -0,0 +1,31 @@
+package de.hdm_stuttgart.mi.sd1.task4_no_unit_test;
+
+/**
+ * <p>This class corresponds to your examination's task 3. Read its description in your web browser.</p>
+ *
+ * <p>In particular no unit tests are being associated with this class.</p>
+ *
+ * <p>If you correct the implementation of {@link #getAverage(byte, byte, byte)} using your IDEA IDE please
+ * <em style="color: red;">do not forget</em> to export and upload your project afterwards.</p>
+ *
+ */
+public class Mathextend {
+
+    /**
+     * <p>Compute the average of three values.</p>
+     *
+     * @param a First value
+     * @param b Second value
+     * @param c Third value
+     *
+     * @return Closest <code>byte</code> value to â…“ (a + b + c)
+     */
+    public static byte getAverage(byte a, final byte b, final byte c) {
+        a += b;
+        a += c;
+        a /= 3;
+        return a;
+    }
+
+    private Mathextend(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/fonts/dejavu.css b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/fonts/dejavu.css
new file mode 100644
index 000000000..4fec2b593
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/fonts/dejavu.css
@@ -0,0 +1,3 @@
+/* shame on you, javadoc! Still providing
+@import url('resources/fonts/dejavu.css') line in stylesheet.css
+*/
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.css b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.css
new file mode 100644
index 000000000..9f39b10d8
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.css
@@ -0,0 +1,68 @@
+/* Javadoc extensions: */
+
+table.goikTableDefaults,
+table.goikTableDefaults>caption,
+table.goikTableDefaults>tr>th,
+table.goikTableDefaults>tr>td,
+table.goikTableDefaults>tbody>tr>th,
+table.goikTableDefaults>tbody>tr>td {
+    border: 2px solid black;
+    border-collapse: collapse;
+    padding: 1ex;
+    vertical-align: top;
+}
+
+table.goikTableDefaults>caption {
+    /* border-top-style: solid; border-left-style: solid; border-right-style: solid' */
+    border-bottom-style: none;
+    font-weight: bold;
+    background:#dee3e9;
+    text-align:left;
+    padding:8px 3px 3px 7px;
+}
+
+table.goikTableDefaults>tbody>tr>td {
+    vertical-align:top;
+}
+table.goikTableDefaults {
+    border-spacing: 0px !important;
+}
+
+table.indexTable {
+    border-collapse: collapse;
+    border-style: hidden;
+}
+
+table.indexTable caption {
+    text-align: left;
+}
+
+table.indexTable td, table.indexTable th {
+    border: 1px solid black;
+    padding: 0.5ex;
+}
+
+em {
+    font-weight: bold;
+    font-style: normal;
+}
+section.implementationHints>h3 {
+    font-weight: bold;
+    background-color: rgb(222, 227, 233);
+}
+
+code {
+    white-space: pre;
+}
+
+.implementationHints {
+    background-color: hsl(120, 100%, 95%) !important;
+}
+
+.myRed {
+    color: red;
+}
+
+.myGreen {
+    color: limegreen;
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.js b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.js
new file mode 100644
index 000000000..97911e558
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/javadoc/resources/jdocSupplement.js
@@ -0,0 +1,7 @@
+for(var i in document.links) {
+   var link = document.links[i];
+   if (link.href && link.href.indexOf('http') === 0) { 
+       link.target = '_blank';
+   }
+}
+
diff --git a/Klausuren/Sd1/2021winter/Exam/src/main/resources/log4j2.xml b/Klausuren/Sd1/2021winter/Exam/src/main/resources/log4j2.xml
new file mode 100644
index 000000000..130f87a14
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/main/resources/log4j2.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <File name="A1" fileName="A1.log" append="false">
+            <PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
+        </File>
+        <Console name="STDOUT" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+
+        <!-- You my want to define class or package level per-logger rules -->
+        <Logger name="de.hdm_stuttgart.mi.sd1.App" level="debug">
+            <AppenderRef ref="A1"/>
+        </Logger>
+        <Root level="info">
+            <AppenderRef ref="STDOUT"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
new file mode 100644
index 000000000..ae8720eb0
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
@@ -0,0 +1,22 @@
+package de.hdm_stuttgart.mi.sd1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.RunTests;
+
+import de.hdm_stuttgart.mi.sd1.task1.*;
+import de.hdm_stuttgart.mi.sd1.task2.Test_QuadratPolynom;
+
+public class ShowReachedPoints {
+
+  /**
+   * Revealing total number of reached points fromm all tasks.
+   *
+   * @param args Unused
+   */
+  public static void main(String[] args) {
+    RunTests.exec(
+      "Task 1"
+            , A_TrafficLightTest.class, B_StringHelperTest.class, C_ArrayHelperTest.class, D_TextFrameTest.class
+      );
+    RunTests.exec("Task 2", Test_QuadratPolynom.class);
+  }
+}
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
new file mode 100644
index 000000000..85ea78ca4
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
@@ -0,0 +1,231 @@
+package de.hdm_stuttgart.mi.sd1.ignore_me;
+
+import org.junit.Assert;
+
+import java.lang.reflect.*;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+public class ObjectWrapper<T> {
+
+  private final Class classz;
+  private final T instance;
+
+  static public void assertFinal(final Class classZ, final String fieldName) {
+    try {
+      final int modifier = classZ.getDeclaredField(fieldName).getModifiers();
+      Assert.assertTrue("»" + fieldName + "« can be modified, no immutable!", Modifier.isFinal(modifier));
+
+    } catch (NoSuchFieldException e) {
+      Assert.fail("No such field »" + fieldName + "«");
+    }
+  }
+
+  public ObjectWrapper(final Class<T> classz, final Object ... parameter) {
+    this.classz = classz;
+    T tmpInstance = null;
+    final Constructor<?>[] candidates = Arrays.
+            stream(classz.getConstructors()).
+            filter(c -> matchesArgumentList(c, parameter)).
+            toArray(Constructor<?>[]::new);
+    if (0 == candidates.length) {
+      Assert.fail("No suitable constructor in class »" + classz.getName() + "« matching arguments »(" +
+              Arrays.stream(parameter).map(Object::toString).collect(Collectors.joining(", ")) +
+              ")«");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple constructor matches due to ambiguous signature");
+    } else {
+      try {
+        tmpInstance = (T) candidates[0].newInstance(
+                Arrays.stream(parameter).toArray());
+      } catch (Exception e) {
+        Assert.fail("Unable to instantiate instance of class »" + classz.getName() + "«: "+ e);
+      }
+    }
+    instance = tmpInstance;
+  }
+
+  public ObjectWrapper(final Class<T> classz, final Class<? extends Throwable> expectedException, final Object ... parameter) {
+    this.classz = classz;
+    T tmpInstance = null;
+    final Constructor<?>[] candidates = Arrays.
+            stream(classz.getConstructors()).
+            filter(c -> matchesArgumentList(c, parameter)).
+            toArray(Constructor<?>[]::new);
+    if (0 == candidates.length) {
+      Assert.fail("No suitable constructor in class »" + classz.getName() + "« matching arguments »(" +
+              Arrays.stream(parameter).map(Object::toString).collect(Collectors.joining(", ")) +
+              ")«");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple constructor matches due to ambiguous signature");
+    } else {
+      try {
+        tmpInstance = (T) candidates[0].newInstance(
+                Arrays.stream(parameter).toArray());
+        Assert.fail("Expected exception of type »" + expectedException.getName() + "« to be thrown");
+      } catch (InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) {
+        if (e.getCause().getClass() != expectedException) {
+          Assert.fail("Unable to instantiate: " + e + ", cause:\n  Expected exception of type »" +
+                  expectedException.getName() + "« but was »"+ e.getCause().getClass().getName() + "«");
+        }
+      }
+    }
+    instance = tmpInstance;
+  }
+
+  public <R> void assertFieldExists(final Class<R> valueType, final String name) {
+    try {
+      final Field field = classz.getField(name);
+      if (!valueType.equals(field.getType())) {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                valueType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    }
+  }
+
+  public <R> R get(final Class<R> valueType, final String name) {
+
+    try {
+      final Field field = classz.getField(name);
+      if (valueType.equals(field.getType())) {
+        return (R) field.get(instance);
+      } else {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                valueType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    } catch (final IllegalAccessException e) {
+      Assert.fail("Unable to access field »" + name + "« in class »" + classz.getName() + "«: " + e.getMessage());
+    }
+    return null;
+  }
+  public void set(final String name, final Object value) {
+
+    try {
+      final Field field = classz.getField(name);
+      final Class  argumentType = value.getClass();
+      if (field.getType().equals(argumentType) ||
+              field.getType().equals(getPrimitiveType(argumentType))){
+       field.set(instance, value);
+      } else {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                argumentType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    } catch (final IllegalAccessException e) {
+      Assert.fail("Unable to access field »" + name + "« in class »" + classz.getName() + "«: " + e.getMessage());
+    }
+  }
+
+  public <R> R invoke(final Class<R> returnType, final String name, final Object ... parameter) {
+
+    final Method[] candidates = Arrays.
+            stream(classz.getMethods()).
+            filter(m-> m.getName().equals(name) && matchesArgumentList(m, parameter)).
+            toArray(Method[]::new);
+
+    if (0 == candidates.length) {
+      Assert.fail("No suitable method found");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple method matches due to ambiguous signature");
+    } else {
+      final Method method = candidates[0];
+      if (method.getReturnType().equals(returnType)) {
+        try {
+          return (R) method.invoke(instance, parameter);
+        } catch (final IllegalAccessException| IllegalArgumentException|InvocationTargetException e) {
+          Assert.fail("Unable to execute method: " + e + ", cause:" + e.getCause());
+        }
+      } else {
+        Assert.fail("Method »" + method.getName() + "« does have return type »"  + method.getReturnType() + "«" +
+                "rather then »" + returnType.getName() + "«");
+      }
+    }
+    return null;
+  }
+  public <R> R invoke(final Class<R> returnType, final String name,
+                                       final Class<? extends Throwable> expectedException, final Object ... parameter) {
+
+    final Method[] candidates = Arrays.
+            stream(classz.getMethods()).
+            filter(m-> m.getName().equals(name) && matchesArgumentList(m, parameter)).
+            toArray(Method[]::new);
+
+    if (0 == candidates.length) {
+      Assert.fail("No suitable method found");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple method matches due to ambiguous signature");
+    } else {
+      final Method method = candidates[0];
+      if (method.getReturnType().equals(returnType)) {
+        try {
+          R ret = (R) method.invoke(instance, parameter);
+          Assert.fail("Expected exception of type »" + expectedException.getName() + "«");
+          return ret;
+        } catch (final IllegalAccessException| IllegalArgumentException|InvocationTargetException e) {
+          if (e.getCause().getClass() != expectedException) {
+            Assert.fail("Unable to execute method: " + e + ", cause:\n  Expected exception of type »" +
+                    expectedException.getName() + "« but was »"+ e.getCause().getClass().getName() + "«");
+          }
+        }
+      } else {
+        Assert.fail("Method »" + method.getName() + "« does have return type »"  + method.getReturnType() + "«" +
+                "rather then »" + returnType.getName() + "«");
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check for a given array of objects matching an {@link Executable}'s argument list.
+   *
+   * @param executable
+   * @param parameter
+   * @return <code>true</code> if parameters match the {@link Executable}'s argument list, <code>false</code>
+   * otherwise.
+   */
+  private boolean matchesArgumentList(final Executable executable, final Object ... parameter) {
+
+    if (executable.getParameterCount() != parameter.length) {
+      return false;
+    } else {
+      final Class<?>[] formalArgumentTypes = executable.getParameterTypes();
+      for (int i = 0; i < formalArgumentTypes.length; i++) {
+        final Class parametersClass = parameter[i].getClass();
+
+        if (!formalArgumentTypes[i].equals(parametersClass) &&
+                !formalArgumentTypes[i].equals(getPrimitiveType(parametersClass))) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  static private Class<?> getPrimitiveType (final Class<?> in) {
+    if (in.equals(Byte.class)) {
+      return byte.class;
+    } else if (in.equals(Short.class)) {
+      return short.class;
+    } else if (in.equals(Integer.class)) {
+      return int.class;
+    } else if (in.equals(Long.class)) {
+      return long.class;
+    } else if (in.equals(Float.class)) {
+      return float.class;
+    } else if (in.equals(Double.class)) {
+      return double.class;
+    } else if (in.equals(Boolean.class)) {
+      return boolean.class;
+    } else if (in.equals(Character.class)) {
+      return char.class;
+    } else {
+      return in;            // Type is no primitive
+    }
+  }
+
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
new file mode 100644
index 000000000..fae220dd2
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
@@ -0,0 +1,25 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.A_TrafficLight.mustStop;
+
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class A_TrafficLightTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 16)
+    public void test_100() {
+        Assert.assertTrue( mustStop(true, false, false)); // Red           :Stop
+        Assert.assertFalse(mustStop(true, true, false));  // Red + yellow  :Go
+
+        Assert.assertFalse(mustStop(false, false, true)); // Green         :Go
+        Assert.assertTrue( mustStop(false, true, false)); // Yellow        :Stop
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
new file mode 100644
index 000000000..176ccc7ed
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
@@ -0,0 +1,37 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.B_StringHelper.getMaxLength;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class B_StringHelperTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+        Assert.assertEquals(0, getMaxLength(new String[]{null}));
+        Assert.assertEquals(0, getMaxLength(new String[]{""}));
+    }
+
+    @Test
+    @Marking(points = 6)
+    public void test_200_single() {
+        Assert.assertEquals(1, getMaxLength(new String[]{"a"}));
+        Assert.assertEquals(11, getMaxLength(new String[]{"csd wde dwe"}));
+    }
+
+    @Test
+    @Marking(points = 6)
+    public void test_300_multi() {
+        Assert.assertEquals(1, getMaxLength(new String[]{"a", "b", "c"}));
+        Assert.assertEquals(5, getMaxLength(new String[]{"Eve", "Peter", "Jill", "Tom"}));
+        Assert.assertEquals(12, getMaxLength(new String[]{"Looooooooong", "Loooooong", null, "Looong", null}));
+        Assert.assertEquals(12, getMaxLength(new String[]{null, "Loooooong", "Looooooooong", "Looong", null}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
new file mode 100644
index 000000000..bb48553fe
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
@@ -0,0 +1,42 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.C_ArrayHelper.getAboveAverage;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class C_ArrayHelperTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{1}));
+    }
+
+    @Test
+    @Marking(points = 4)
+    public void test_200_equal() {
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{20, 20}));
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{7, 7, 7, 7}));
+    }
+
+    @Test
+    @Marking(points = 4)
+    public void test_200_regular() {
+        Assert.assertArrayEquals(new int[]{1}, getAboveAverage(new int[]{1, 0}));
+        Assert.assertArrayEquals(new int[]{1}, getAboveAverage(new int[]{0, 1}));
+        Assert.assertArrayEquals(new int[]{5, 4}, getAboveAverage(new int[]{1, 2, 3, 5, 4}));
+        Assert.assertArrayEquals(new int[]{55, 100}, getAboveAverage(new int[]{-30, 2, 4, 55, 100, 9}));
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_200_big() {
+        Assert.assertArrayEquals(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE}, getAboveAverage(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE, 0}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
new file mode 100644
index 000000000..c003f80e7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
@@ -0,0 +1,89 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.D_TextFrame.createTextFrame;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class D_TextFrameTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+
+        final String expected = """
+                ****
+                *  *
+                ****""";
+
+        Assert.assertEquals(expected, createTextFrame(new String[]{null}));
+        Assert.assertEquals(expected, createTextFrame(new String[]{""}));
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_200_one() {
+
+        {
+            final String expected = """
+                    *****
+                    *   *
+                    *****""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{" "}));
+        }
+        {
+            final String expected = """
+                    *****
+                    * j *
+                    *****""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"j"}));
+        }
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_300_multi() {
+
+        {
+            final String expected = """
+                    ******************
+                    * This is a very *
+                    * simple test.   *
+                    ******************""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"This is a very", "simple test."}));
+        }
+        {
+            final String expected = """
+                    *******************
+                    * An example      *
+                    * featuring three *
+                    * lines           *
+                    *******************""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"An example", "featuring three", "lines"}));
+        }
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_400_null() {
+
+        final String expected = """
+                    **********************
+                    * Sometimes there is *
+                    *                    *
+                    * a hole.            *
+                    *                    *
+                    **********************""";
+
+        Assert.assertEquals(expected, createTextFrame(new String[]{"Sometimes there is", null, "a hole.", null}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java
new file mode 100644
index 000000000..055651ad7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java
@@ -0,0 +1,226 @@
+package de.hdm_stuttgart.mi.sd1.task2;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import de.hdm_stuttgart.mi.sd1.ignore_me.ObjectWrapper;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+
+public class Test_QuadratPolynom extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 5)
+    public void test_100_NoZero() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 1, 1);
+        assertNoZero(poly, composeDescription(1,2,1).toString());
+
+        final ObjectWrapper<QuadratPolynom> poly2 = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 3);
+        assertNoZero(1, 6, 20, poly2);
+        assertNoZero(2, 13, 41, poly2);
+    }
+
+    @Test
+    @Marking(points = 5)
+    public void test_200_OneZero() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 1);
+        assertOneZero(poly, -1, composeDescription(1,2,1).toString());
+
+        final ObjectWrapper<QuadratPolynom> poly2 = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 3);
+        assertOneZero(6, -84, 294, poly2, 7);
+        assertOneZero(21, 126, 189, poly2, -3);
+    }
+
+    @Test
+    @Marking(points = 5)
+    public void test_300_twoZeroes() {
+
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 3, 2);
+        assertTwoZeroes(poly, -2, -1, "x² + 3x + 2");
+
+        assertTwoZeroes(3, 7, 4, poly, -4./3, -1);
+
+        assertTwoZeroes(-2, 1, 3, poly, -1, 1.5);
+
+        assertTwoZeroes(-1, 5, 6, poly, -1, 6);
+
+        assertTwoZeroes(7, 11, 4, poly, -1, -4./7);
+
+        assertTwoZeroes(4, -3, -10, poly, -1.25, 2);
+
+        assertTwoZeroes(5, 6, 1, poly, -1, -0.2);
+
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_400_Exception() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, -200, 2);
+
+        final Class<ArithmeticException> expectedArithmeticException = ArithmeticException.class;
+
+        // Coefficient ax² must not be 0
+        poly.invoke(void.class, "setA", expectedArithmeticException, 0);
+        new ObjectWrapper<>(QuadratPolynom.class, expectedArithmeticException, 0, 88, 99);
+    }
+
+    @Test
+    @Marking(points = 3)
+    public void test_500_TwoZeroExzess() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,
+                46010, 598130,-1960026000);
+        assertTwoZeroes(poly,-213,200,
+                composeDescription(46010, 598130,-1960026000).toString());
+    }
+
+    // End of tests -------------------------------------------------------------------------------------------------
+    // Test helper methods
+    //
+    static private final double delta = 1.E-12;
+
+    static private StringBuffer composeDescription(final int a, final int b, final int c) {
+        final StringBuffer ret = new StringBuffer();
+        ret.append(a).append("x²");
+        if (0 < b) {
+            ret.append(" + ").append(b).append("x");
+        } else if (b < 0) {
+            ret.append(" ").append(b).append("x");
+        }
+        // Slight code duplication avoiding a method definition. Yepp: I'm lazy sometimes!
+        if (0 < c) {
+            ret.append(" + ").append(c);
+        } else if (c < 0) {
+            ret.append(" ").append(c);
+        }
+        return ret;
+    }
+
+    /**
+     * Testing given polynomial for no real zero value.
+     *
+     * @param poly Polynomial to be tested
+     * @param description E.g. "-2x² + 4x -3"
+     */
+    static private void assertNoZero(final ObjectWrapper<QuadratPolynom> poly, final String description) {
+
+        Assert.assertEquals("No zero expected for polynom »" + description + "«",
+                0, poly.invoke(double[].class, "getZeroes").length);
+    }
+
+    /**
+     * Testing for no real valued zero solution.
+     *
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     */
+    static private void assertNoZero(final int a,
+                                      final int b,
+                                      final int c,
+                                      final ObjectWrapper<QuadratPolynom> poly) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        Assert.assertEquals("One zero expected for polynom »" + composeDescription(a, b, c) + "«",
+                0, poly.invoke(double[].class, "getZeroes").length);
+
+
+    }
+
+        /**
+         * Testing given polynomial for one zeroes to be returned
+         *
+         * @param poly Polynomial to be tested
+         * @param expected zero value
+         * @param description E.g. "-2x² + 4x -3"
+         */
+    static private void assertOneZero(final ObjectWrapper<QuadratPolynom> poly,
+                                      double expected,
+                                      final String description) {
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        Assert.assertEquals("One zero expected for polynom »" + description + "«",
+                1, result.length);
+        Assert.assertEquals("Expected zero of »" + description +"« to be " + expected, expected, result[0], delta);
+    }
+
+    /**
+     * Like {@link #assertOneZero(ObjectWrapper, double, String)} but re-setting coefficients beforehand,
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     */
+    static private void assertOneZero(final int a,
+                                      final int b,
+                                      final int c,
+                                      final ObjectWrapper<QuadratPolynom> poly,
+                                      double expected) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        final StringBuffer polynomDescription = composeDescription(a, b, c);
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + polynomDescription + "«",
+                1, result.length);
+        Assert.assertEquals("Expected zero of »" + polynomDescription +"« to be " + expected,
+                expected, result[0], delta);
+    }
+
+    /**
+     * Testing given polynomial for two zeroes to be returned
+     *
+     * @param poly Polynomial to be tested
+     * @param expectedLower Lower zero value
+     * @param expectedUpper Upper zero value
+     * @param description E.g. "-2x² + 4x -3"
+     */
+    static private void assertTwoZeroes(final ObjectWrapper<QuadratPolynom> poly,
+                                        double expectedLower,
+                                        double expectedUpper,
+                                        final String description) {
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + description + "«",
+                2, result.length);
+        Assert.assertEquals("Expected lower zero of »" + description +"« to be " + expectedLower,
+                expectedLower, result[0], delta);
+        Assert.assertEquals("Expected upper zero of »" + description +"« to be " + expectedUpper,
+                expectedUpper, result[1], delta);
+    }
+
+    /**
+     * Like {@link #assertTwoZeroes(ObjectWrapper, double, double, String)} but re-setting coeficients beforehand,
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     * @param expectedLower Expected lower zero value
+     * @param expectedUpper Expected upper zero value
+     */
+    static private void assertTwoZeroes(final int a,
+                                        final int b,
+                                        final int c,
+                                        final ObjectWrapper<QuadratPolynom> poly,
+                                        double expectedLower,
+                                        double expectedUpper) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        final StringBuffer polynomDescription = composeDescription(a, b, c);
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + polynomDescription + "«",
+                2, result.length);
+        Assert.assertEquals("Expected lower zero of »" + polynomDescription +"« to be " + expectedLower,
+                expectedLower, result[0], delta);
+        Assert.assertEquals("Expected upper zero of »" + polynomDescription +"« to be " + expectedUpper,
+                expectedUpper, result[1], delta);
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/Doc/wurzel.ods b/Klausuren/Sd1/2021winter/Solve/Doc/wurzel.ods
new file mode 100644
index 0000000000000000000000000000000000000000..2a290ccd9f4fabf32cf1218c4fcba096fcb485fe
GIT binary patch
literal 16802
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
V3>@P3V@SU~fM1IaDaY^J{{dpJjp+aY

literal 0
HcmV?d00001

diff --git a/Klausuren/Sd1/2021winter/Solve/pom.xml b/Klausuren/Sd1/2021winter/Solve/pom.xml
new file mode 100644
index 000000000..d447ccb00
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/pom.xml
@@ -0,0 +1,130 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>de.hdm-stuttgart.mi.sd1</groupId>
+    <artifactId>sd1_2021winter_solve</artifactId>
+    <version>0.9</version>
+    <packaging>jar</packaging>
+
+    <name>sd1_2021winter_solve</name>
+
+    <url>https://freedocs.mi.hdm-stuttgart.de/sd1_sect_mavenCli.html</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+    	<maven.compiler.target>17</maven.compiler.target>
+        <maven.compiler.source>17</maven.compiler.source>
+
+        <freedocs.url>https://freedocs.mi.hdm-stuttgart.de</freedocs.url>
+        <jdk.api_17.url>${freedocs.url}/doc/openjdk-17-doc/api/</jdk.api_17.url>
+        <mathjax.url>${freedocs.url}/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML</mathjax.url>
+        <libhighlight.url>${freedocs.url}/lib/highlight.js</libhighlight.url>
+    </properties>
+
+    <repositories>
+        <repository>
+            <id>hdm-mi-internal-maven-repo</id>
+            <url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.17.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>de.hdm_stuttgart.mi.exam</groupId>
+            <artifactId>unitmarking</artifactId>
+            <version>1.1</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+		        <artifactId>maven-javadoc-plugin</artifactId>
+		        <version>3.3.0</version>
+
+                <configuration>
+                    <!-- Tweak: Get rid of Error message
+                      »fetching link: .../target/javadoc-bundle-options. Ignored it«
+                      corresponding to api_11 below -->
+                    <release>11</release>
+                    <doclint>all</doclint>
+                    <show>public</show>
+                    <docfilessubdirs>true</docfilessubdirs>
+                    <addStylesheets>
+                        <stylesheet>resources/jdocSupplement.css</stylesheet>
+                    </addStylesheets>
+
+                    <javaApiLinks>
+                        <property>
+                            <name>api_11</name>
+                            <value>${jdk.api_17.url}</value>
+                        </property>
+                    </javaApiLinks>
+
+                    <additionalOptions>
+                        <additionalOption>-html5 --allow-script-in-comments</additionalOption>
+                    </additionalOptions>
+                    <nohelp>true</nohelp>
+
+                    <header><![CDATA[
+            <script type="text/javascript" src="${mathjax.url}"></script>
+            <script type="text/javascript" src="{@docRoot}/resources/jdocSupplement.js"></script>
+            <link rel="stylesheet" href="${libhighlight.url}/styles/idea.css">
+            <script src="${libhighlight.url}/highlight.js"></script>
+            <script type="text/javascript">hljs.initHighlightingOnLoad();</script>]]>
+                    </header>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.3.0</version>
+                <configuration>
+                    <descriptors>
+                        <descriptor>src/main/assembly/assembly.xml</descriptor>
+                    </descriptors>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    <mainClass>de.hdm_stuttgart.mi.sd1.ShowReachedPoints</mainClass>
+                                </manifest>
+                            </archive>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/assembly/assembly.xml b/Klausuren/Sd1/2021winter/Solve/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..85268e296
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/assembly/assembly.xml
@@ -0,0 +1,36 @@
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>fat-tests</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory/>
+            <useProjectArtifact>true</useProjectArtifact>
+            <unpack>true</unpack>
+            <scope>test</scope>
+        </dependencySet>
+    </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}/test-classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.build.directory}/classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
new file mode 100644
index 000000000..fff60a3b2
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLight.java
@@ -0,0 +1,66 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * <p>Stop and go at trafficlights.</p>
+ */
+public class A_TrafficLight {
+    /**
+     * <p>Traffic light stop / go indications.</p>
+     *
+     * <p>German traffic lights feature three different colours red, yellow and green. We assume the following rules:</p>
+     *
+     * <table style="border-spacing: 10ex 0;">
+     *     <caption>German traffic light states</caption>
+     *     <tr>
+     *         <td
+     *         style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:red;"></li>
+     *             <li style="color:black;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:red;"></li>
+     *             <li style="color:yellow;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:black;"></li>
+     *             <li style="color:black;"></li>
+     *             <li style="color:green;"></li>
+     *           </ul>
+     *         </td>
+     *         <td style="border: 2px solid black;border-radius: 10px;font-size:40px;background:black;">
+     *           <ul>
+     *             <li style="color:black;"></li>
+     *             <li style="color:yellow;"></li>
+     *             <li style="color:black;"></li>
+     *           </ul>
+     *         </td>
+     *     </tr>
+     *     <tr>
+     *         <td>Stop</td>
+     *         <td>Go</td>
+     *         <td>Go</td>
+     *         <td>Stop</td>
+     *     </tr>
+     *
+     * </table>
+     *
+     * @param red <code>true</code> represents »on«, <code>false</code> represents »off«.
+     * @param yellow <code>true</code> represents »on«, <code>false</code> represents »off«.
+     * @param green <code>true</code> represents »on«, <code>false</code> represents »off«.
+     *
+     * @return <code>true</code> represents »you must stop«, <code>false</code> represents »go«.
+     */
+    static public boolean mustStop(boolean red, boolean yellow, boolean green) {
+        return (red && !yellow) || (yellow && !red);
+    }
+
+    private A_TrafficLight(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
new file mode 100644
index 000000000..7b3910a4d
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelper.java
@@ -0,0 +1,49 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+/**
+ * String related helper method. Currently {@link #getMaxLength(String[])} is on offer.
+ */
+public class B_StringHelper {
+
+    /**
+     * <p>Get the maximum string length among an array of strings. In the following example the longest of three
+     * strings is <code class="java">"Longman"</code> having length 7:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>Finding the longest string</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final String[] names =
+     *     {"Eve", "Longman", "Peter"};
+     *
+     * System.out.println("Longest name's length: " +
+     *     getMaxLength(names));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> Longest name's length: 7</code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * @param strings A non-empty array possibly containing both strings and <code>null</code> values.
+     * @return The greatest length of all strings. <code>null</code> values will be treated like empty strings.
+     */
+    static public int getMaxLength(final String[] strings) {
+        int maxLength = 0;
+        for (final String s: strings) {
+            if (null != s) {
+                maxLength = Math.max(maxLength, s.length());
+            }
+        }
+        return maxLength;
+    }
+
+    private B_StringHelper(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
new file mode 100644
index 000000000..5997a5dc4
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelper.java
@@ -0,0 +1,61 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import java.util.Arrays;
+
+/**
+ * <p>Array related helper method</p>
+ */
+public class C_ArrayHelper {
+
+    /**
+     * <p>Collect all values from a given array being above its average value. The following example
+     * features an array of five values resulting in an average of 6. Only the values 8, 12 and 8
+     * are strictly above average:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>Finding values above average</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final int[] values = {-4, 6, 8, 12, 8};
+     * System.out.println( "Above average: " +
+     *     Arrays.toString(getAboveAverage(values)));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> Above average: [8, 12, 8] </code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * @param values A list of values.
+     * @return All values from the list being strictly above the list's average thereby preserving
+     * the original array's order of appearance.
+     */
+    static public int[] getAboveAverage (int[] values) {
+
+        final int length = values.length;
+        long sum = 0;
+
+        for (final int v: values) {
+            sum += v;
+        }
+
+        final int[] result = new int[length];
+        int index = 0;
+
+        for (final int vTmp: values) {
+            final long v = vTmp; // Tribute to values exceeding Integer.INT_MAX
+            if (sum < length * v) {
+                result[index++] = vTmp;
+            }
+        }
+        return Arrays.copyOf(result, index);
+    }
+    private C_ArrayHelper(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
new file mode 100644
index 000000000..d6cb4dd86
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrame.java
@@ -0,0 +1,77 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+
+/**
+ * <p>ASCII art related method.</p>
+ */
+public class D_TextFrame {
+
+    /**
+     * <p>Arranging a list of strings line by line and surrounding it by a rectangular frame. The following
+     * example transforms an array containing two strings into a corresponding framed output:</p>
+     *
+     * <table class="goikTableDefaults">
+     *     <caption>ASCII art frame</caption>
+     *     <tbody>
+     *         <tr>
+     *             <th>Code</th>
+     *             <th>Result</th>
+     *         </tr>
+     *         <tr>
+     *             <td>
+     *                 <pre><code class="java"> final String[] words = {"This is a first", "sample"};
+     * System.out.println(createTextFrame(words));</code></pre>
+     *             </td>
+     *             <td>
+     *                 <pre><code class="nohighlight"> *******************
+     * * This is a first *
+     * * sample          *
+     * *******************</code></pre>
+     *             </td>
+     *         </tr>
+     *     </tbody>
+     * </table>
+     *
+     * <p>Note the additional empty spaces »<span style="color:red;font-weight:bold;">_</span>« between each
+     * starting * and before each ending *:</p>
+     *
+     * <pre><code class="nohighlight"> *******************
+     * *<span style="color:red;font-weight:bold;">_</span>This is a first<span style="color:red;font-weight:bold;">_</span>*
+     * *<span style="color:red;font-weight:bold;">_</span>sample         <span style="color:red;font-weight:bold;">_</span>*
+     * *******************</code></pre>
+     *
+     * @param strings A non-empty array possibly containing both strings and <code>null</code> values.
+     * @return An ASCII frame surrounding lines of text.
+     *
+     * <section class="implementationHints">
+     *    <h4 class="implementationHints">Hints:</h4>
+     *
+     * <ul>
+     *     <li>You may use {@link B_StringHelper#getMaxLength(String[])} to get the longest
+     *     string length in the list for sizing your frame.</li>
+     *
+     *     <li>{@link String#repeat(int)} for repeating both <code>"*"</code> and empty spaces <code>" "</code>
+     *     using e.g. <code>"*".repeat(10)</code>.</li>
+     *
+     *     <li>Watch out for spaces and invisible newlines at end of your returned string. These are difficult to spot
+     *     and may cause tests to fail.</li>
+     *
+     * </ul>
+     *
+     * </section>
+     */
+    static public String createTextFrame(final String[] strings) {
+
+        final int maxLength = B_StringHelper.getMaxLength(strings);
+
+        final StringBuffer ret = new StringBuffer("*".repeat(maxLength + 4)).append('\n');
+        for (final String s: strings) {
+            final String insert = null == s ? "" : s;
+            ret.append("* ").append(insert).append(" ".repeat(maxLength - insert.length())).append(" *\n");
+        }
+        ret.append("*".repeat(maxLength + 4));
+        return ret.toString();
+    }
+
+    private D_TextFrame(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
new file mode 100644
index 000000000..fb7bb58c2
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task1/package-info.java
@@ -0,0 +1,17 @@
+/**
+ * <p>This package mostly (if not completely) contains static methods.</p>
+ *
+ * <p>The ordering being implied by class names reflects the author's opinion with respect to ascending implementation
+ * difficulty. Hints:</p>
+ *
+ * <ul>
+ *     <li>Run <code>mvn javadoc:javadoc</code> and open the generated
+ *     <code>/home/.../target/site/apidocs/index.html</code> file in your browser of choice.</li>
+ *
+ *     <li>Use the corresponding unit tests to check your implementation's consistency and class
+ *     <code>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</code> from your project's “unit test” branch.</li>
+ *
+ * </ul>
+ *
+ */
+package de.hdm_stuttgart.mi.sd1.task1;
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
new file mode 100644
index 000000000..954eb1529
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task2/QuadratPolynom.java
@@ -0,0 +1,241 @@
+package de.hdm_stuttgart.mi.sd1.task2;
+
+/**
+ * <p>Providing zeroes (German: "Nullstellen") of quadratic polynomials.</p>
+ *
+ * <p>A quadratic polynomial \( p(x)  = a x² + b x + c \) is being defined by its three coefficients
+ * \(a\), \(b\) and \(c\). This class limits coefficients \(a\), \(b\) and \(c\) to type <code>int</code>. A general
+ * solution is being provided by:</p>
+ *
+ * <p>\[ x_{1,2} = {{-b \pm \sqrt{b^2 - 4 ac}} \over {2a}} \]</p>
+ *
+ * <p>Depending on \( b^2 - 4 ac \) being positive, zero or negative we have either two, one or no real solutions.</p>
+ *
+ * <p>The following sample illustrates zeroes calculation depending on given values of \(a\), \(b\) and \(c\):</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Sample code illustrating zero values calculation</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> final QuadratPolynom poly =         // Representing
+ *     new QuadratPolynom(4, -3, -10); // p(x) = 4x² - 3x - 10
+ *
+ * double[] zeroes = poly.getZeroes();
+ *
+ * System.out.println("Found " + zeroes.length + " zeroes:");
+ *
+ * System.out.println("x_1 = " + zeroes[0]);
+ * System.out.println("x_2 = " + zeroes[1]);</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> Found 2 zeroes:
+ * x_1 = -1.25
+ * x_2 = 2.0</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>We allow for re-setting a polynomial's coefficients. Continuing from the above example we have:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Changing coefficients</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(1);  // Representing
+ * poly.setB(-8); // p(x) = x² -8x + 16
+ * poly.setC(16);
+ *
+ * zeroes = poly.getZeroes();
+ * System.out.println("Found " + zeroes.length + " zero:");
+ *
+ * System.out.println("x_1 = " + zeroes[0]);</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Found 1 zero:
+ * x_1 = 4.0</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Some polynomials do not have any (real valued) solution:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Changing coefficients again</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(1);  // Representing
+ * poly.setB(0);  // p(x) = x² + 1
+ * poly.setC(1);  // (No zero solution)
+ *
+ * zeroes = poly.getZeroes();
+ * System.out.println("Found " + zeroes.length + " zero");</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Found 0 zero</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Finally setting \(a=0\) in \(ax²\) leaves us with just a linear polynomial \(bx + c\). To
+ * avoid unpredictable results the attempt shall result in throwing an
+ * <a href="https://freedocs.mi.hdm-stuttgart.de/doc/openjdk-17-doc/api/java.base/java/lang/ArithmeticException.html"
+ *  ><code>ArithmeticException</code></a>:</p>
+ *
+ * <table class="goikTableDefaults">
+ *     <caption>Dealing with 0 value at square coefficient.</caption>
+ *     <tbody>
+ *         <tr>
+ *             <th>Code</th>
+ *             <th>Result</th>
+ *         </tr>
+ *         <tr>
+ *             <td>
+ *                 <pre><code class="java"> ...
+ * poly.setA(0);  // Trying to represent p(x) = 1</code></pre>
+ *             </td>
+ *             <td>
+ *                 <pre><code class="nohighlight"> ...
+ * Exception in thread "main" java.lang.ArithmeticException:
+ *     Square coefficient must not be zero</code></pre>
+ *             </td>
+ *         </tr>
+ *     </tbody>
+ * </table>
+ *
+ * <p>Likewise a <code>new QuadratPolynom(0, ..., ...)</code> constructor call setting \(a=0\) shall raise an
+ * <a href="https://freedocs.mi.hdm-stuttgart.de/doc/openjdk-17-doc/api/java.base/java/lang/ArithmeticException.html">
+ * <code>ArithmeticException</code></a> as well.</p>
+ *
+ * <section class="implementationHints">
+ *    <h2 class="implementationHints">Hint:</h2>
+ *
+ * <p>This class is yet unimplemented. The above code snippets provide a clue to an implementation
+ *    satisfying the corresponding unit tests.</p>
+ *
+ * </section>
+ */
+public class QuadratPolynom {
+
+    private int a, b, c;
+
+    /**
+     * <p>Defining a polynomial \( p(x) = a x² + b x + c  \).</p>
+     *
+     * @param a Square coefficient.
+     * @param b Linear coefficient.
+     * @param c Constant coefficient.
+     * @throws ArithmeticException  The square coefficient \( a x² \) must not be zero
+     */
+    public QuadratPolynom(int a, int b, int c) throws ArithmeticException {
+        setA(a);
+        setB(b);
+        setC(c);
+    }
+
+    /**
+     * <p>Re- setting the square coefficient in \( a x² \).</p>
+     * @param a The desired new value.
+     * @throws ArithmeticException  The square coefficient \( a x² \) must not be zero
+     */
+    public void setA(final int a) throws ArithmeticException {
+        if (0 == a) {
+            throw new ArithmeticException("Square coefficient must not be zero");
+        }
+        this.a = a;
+    }
+    /**
+     * <p>Re- setting the linear coefficient in \( b x \).</p>
+     * @param b The desired new value.
+     */
+    public void setB(final int b) {
+        this.b = b;
+    }
+    /**
+     * <p>Re- setting the constant coefficient \( c \).</p>
+     * @param c The desired new value.
+     */
+    public void setC(final int c) {
+        this.c = c;
+    }
+
+    /**
+     * <p>Zeroes are all values of \(x\) solving \(a x² + b x + c = 0\).</p>
+     *
+     * <p>Zeros are being calculated using:</p>
+     *
+     * <p>\[ x = {{ -b \pm \sqrt {b² - 4 a c}} \over {2 a}} \]</p>
+     *
+     * <p>Modifying returned array values does not affect the called instance's internal state.</p>
+     *
+     * @return <p>Three distinct cases:</p>
+     *
+     * <dl>
+     *
+     *     <dt>\( b² - 4 a c &lt; 0\):</dt>
+     *     <dd><p>An <code>double[0]</code> empty array indicating the non-existence of any real valued solution.</p></dd>
+     *
+     *     <dt>\( b² - 4 a c = 0\):</dt>
+     *     <dd><p>An <code>double[1]</code> array containing the single zero {\(-b \over {2 a} \)}.</p></dd>
+     *
+     *     <dt>\( b² - 4 a c &gt; 0\):</dt>
+     *     <dd><p>An <code>double[2]</code> array containing two distinct zeroes
+     *     \( {1\over {2 a}}\left( -b - \sqrt {b² - 4 a c}\right) \)
+     *     and \( {1\over {2 a}}\left( -b + \sqrt {b² - 4 a c}\right) \) ordered by size.</p></dd>
+     *
+     * </dl>
+     *
+     * <section class = "implementationHints">
+     *   <h4>Implementation hints:</h4>
+     *
+     *   <ul>
+     *       <li><a href=
+     *       "https://freedocs.mi.hdm-stuttgart.de/lib/openjdk-17-doc/api/java.base/java/lang/Math.html#sqrt(double)"
+     *       >Math.sqrt(...)</a></li>
+     *
+     *   </ul>
+     *
+     * </section>
+     */
+    public double[] getZeroes() {
+        final long radicand = ((long) b) * ((long) b) - 4 * ((long) a) * ((long) c) ;
+//        final int radicand = b * b - 4 * a * c; // failing at higher values due to overflow
+
+        if (0 > radicand) {
+            return new double[]{};
+        } else if (0 == radicand) {
+            return  new double[]{-b / 2. / a};
+        } else {
+            final double radicandRoot = Math.sqrt(radicand);
+
+            if (0 < a) {
+                return new double[]{(-b - radicandRoot) / 2 / a, (-b + radicandRoot) / 2 / a};
+            } else {
+                return new double[]{(-b + radicandRoot) / 2 / a, (-b - radicandRoot) / 2 / a};
+            }
+
+        }
+    }
+    private QuadratPolynom(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
new file mode 100644
index 000000000..f254528aa
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/task4_no_unit_test/Mathextend.java
@@ -0,0 +1,31 @@
+package de.hdm_stuttgart.mi.sd1.task4_no_unit_test;
+
+/**
+ * <p>This class corresponds to your examination's task 3. Read its description in your web browser.</p>
+ *
+ * <p>In particular no unit tests are being associated with this class.</p>
+ *
+ * <p>If you correct the implementation of {@link #getAverage(byte, byte, byte)} using your IDEA IDE please
+ * <em style="color: red;">do not forget</em> to export and upload your project afterwards.</p>
+ *
+ */
+public class Mathextend {
+
+    /**
+     * <p>Compute the average of three values.</p>
+     *
+     * @param a First value
+     * @param b Second value
+     * @param c Third value
+     *
+     * @return Closest <code>byte</code> value to â…“ (a + b + c)
+     */
+    public static byte getAverage(byte a, final byte b, final byte c) {
+        a += b;
+        a += c;
+        a /= 3;
+        return a;
+    }
+
+    private Mathextend(){/* Ignore me: My sole purpose is suppressing default constructor javadoc generation */}
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/fonts/dejavu.css b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/fonts/dejavu.css
new file mode 100644
index 000000000..4fec2b593
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/fonts/dejavu.css
@@ -0,0 +1,3 @@
+/* shame on you, javadoc! Still providing
+@import url('resources/fonts/dejavu.css') line in stylesheet.css
+*/
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.css b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.css
new file mode 100644
index 000000000..9f39b10d8
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.css
@@ -0,0 +1,68 @@
+/* Javadoc extensions: */
+
+table.goikTableDefaults,
+table.goikTableDefaults>caption,
+table.goikTableDefaults>tr>th,
+table.goikTableDefaults>tr>td,
+table.goikTableDefaults>tbody>tr>th,
+table.goikTableDefaults>tbody>tr>td {
+    border: 2px solid black;
+    border-collapse: collapse;
+    padding: 1ex;
+    vertical-align: top;
+}
+
+table.goikTableDefaults>caption {
+    /* border-top-style: solid; border-left-style: solid; border-right-style: solid' */
+    border-bottom-style: none;
+    font-weight: bold;
+    background:#dee3e9;
+    text-align:left;
+    padding:8px 3px 3px 7px;
+}
+
+table.goikTableDefaults>tbody>tr>td {
+    vertical-align:top;
+}
+table.goikTableDefaults {
+    border-spacing: 0px !important;
+}
+
+table.indexTable {
+    border-collapse: collapse;
+    border-style: hidden;
+}
+
+table.indexTable caption {
+    text-align: left;
+}
+
+table.indexTable td, table.indexTable th {
+    border: 1px solid black;
+    padding: 0.5ex;
+}
+
+em {
+    font-weight: bold;
+    font-style: normal;
+}
+section.implementationHints>h3 {
+    font-weight: bold;
+    background-color: rgb(222, 227, 233);
+}
+
+code {
+    white-space: pre;
+}
+
+.implementationHints {
+    background-color: hsl(120, 100%, 95%) !important;
+}
+
+.myRed {
+    color: red;
+}
+
+.myGreen {
+    color: limegreen;
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.js b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.js
new file mode 100644
index 000000000..97911e558
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/javadoc/resources/jdocSupplement.js
@@ -0,0 +1,7 @@
+for(var i in document.links) {
+   var link = document.links[i];
+   if (link.href && link.href.indexOf('http') === 0) { 
+       link.target = '_blank';
+   }
+}
+
diff --git a/Klausuren/Sd1/2021winter/Solve/src/main/resources/log4j2.xml b/Klausuren/Sd1/2021winter/Solve/src/main/resources/log4j2.xml
new file mode 100644
index 000000000..130f87a14
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/main/resources/log4j2.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <File name="A1" fileName="A1.log" append="false">
+            <PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
+        </File>
+        <Console name="STDOUT" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+
+        <!-- You my want to define class or package level per-logger rules -->
+        <Logger name="de.hdm_stuttgart.mi.sd1.App" level="debug">
+            <AppenderRef ref="A1"/>
+        </Logger>
+        <Root level="info">
+            <AppenderRef ref="STDOUT"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
new file mode 100644
index 000000000..ae8720eb0
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ShowReachedPoints.java
@@ -0,0 +1,22 @@
+package de.hdm_stuttgart.mi.sd1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.RunTests;
+
+import de.hdm_stuttgart.mi.sd1.task1.*;
+import de.hdm_stuttgart.mi.sd1.task2.Test_QuadratPolynom;
+
+public class ShowReachedPoints {
+
+  /**
+   * Revealing total number of reached points fromm all tasks.
+   *
+   * @param args Unused
+   */
+  public static void main(String[] args) {
+    RunTests.exec(
+      "Task 1"
+            , A_TrafficLightTest.class, B_StringHelperTest.class, C_ArrayHelperTest.class, D_TextFrameTest.class
+      );
+    RunTests.exec("Task 2", Test_QuadratPolynom.class);
+  }
+}
\ No newline at end of file
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
new file mode 100644
index 000000000..85ea78ca4
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/ignore_me/ObjectWrapper.java
@@ -0,0 +1,231 @@
+package de.hdm_stuttgart.mi.sd1.ignore_me;
+
+import org.junit.Assert;
+
+import java.lang.reflect.*;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+public class ObjectWrapper<T> {
+
+  private final Class classz;
+  private final T instance;
+
+  static public void assertFinal(final Class classZ, final String fieldName) {
+    try {
+      final int modifier = classZ.getDeclaredField(fieldName).getModifiers();
+      Assert.assertTrue("»" + fieldName + "« can be modified, no immutable!", Modifier.isFinal(modifier));
+
+    } catch (NoSuchFieldException e) {
+      Assert.fail("No such field »" + fieldName + "«");
+    }
+  }
+
+  public ObjectWrapper(final Class<T> classz, final Object ... parameter) {
+    this.classz = classz;
+    T tmpInstance = null;
+    final Constructor<?>[] candidates = Arrays.
+            stream(classz.getConstructors()).
+            filter(c -> matchesArgumentList(c, parameter)).
+            toArray(Constructor<?>[]::new);
+    if (0 == candidates.length) {
+      Assert.fail("No suitable constructor in class »" + classz.getName() + "« matching arguments »(" +
+              Arrays.stream(parameter).map(Object::toString).collect(Collectors.joining(", ")) +
+              ")«");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple constructor matches due to ambiguous signature");
+    } else {
+      try {
+        tmpInstance = (T) candidates[0].newInstance(
+                Arrays.stream(parameter).toArray());
+      } catch (Exception e) {
+        Assert.fail("Unable to instantiate instance of class »" + classz.getName() + "«: "+ e);
+      }
+    }
+    instance = tmpInstance;
+  }
+
+  public ObjectWrapper(final Class<T> classz, final Class<? extends Throwable> expectedException, final Object ... parameter) {
+    this.classz = classz;
+    T tmpInstance = null;
+    final Constructor<?>[] candidates = Arrays.
+            stream(classz.getConstructors()).
+            filter(c -> matchesArgumentList(c, parameter)).
+            toArray(Constructor<?>[]::new);
+    if (0 == candidates.length) {
+      Assert.fail("No suitable constructor in class »" + classz.getName() + "« matching arguments »(" +
+              Arrays.stream(parameter).map(Object::toString).collect(Collectors.joining(", ")) +
+              ")«");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple constructor matches due to ambiguous signature");
+    } else {
+      try {
+        tmpInstance = (T) candidates[0].newInstance(
+                Arrays.stream(parameter).toArray());
+        Assert.fail("Expected exception of type »" + expectedException.getName() + "« to be thrown");
+      } catch (InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) {
+        if (e.getCause().getClass() != expectedException) {
+          Assert.fail("Unable to instantiate: " + e + ", cause:\n  Expected exception of type »" +
+                  expectedException.getName() + "« but was »"+ e.getCause().getClass().getName() + "«");
+        }
+      }
+    }
+    instance = tmpInstance;
+  }
+
+  public <R> void assertFieldExists(final Class<R> valueType, final String name) {
+    try {
+      final Field field = classz.getField(name);
+      if (!valueType.equals(field.getType())) {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                valueType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    }
+  }
+
+  public <R> R get(final Class<R> valueType, final String name) {
+
+    try {
+      final Field field = classz.getField(name);
+      if (valueType.equals(field.getType())) {
+        return (R) field.get(instance);
+      } else {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                valueType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    } catch (final IllegalAccessException e) {
+      Assert.fail("Unable to access field »" + name + "« in class »" + classz.getName() + "«: " + e.getMessage());
+    }
+    return null;
+  }
+  public void set(final String name, final Object value) {
+
+    try {
+      final Field field = classz.getField(name);
+      final Class  argumentType = value.getClass();
+      if (field.getType().equals(argumentType) ||
+              field.getType().equals(getPrimitiveType(argumentType))){
+       field.set(instance, value);
+      } else {
+        Assert.fail("Field »" + name + "« in class »" + classz.getName() +  "« is not of type »" +
+                argumentType.getName() + "«");
+      }
+    } catch (final NoSuchFieldException e) {
+      Assert.fail("No such field »" + name + "« in class »" + classz.getName() + "«");
+    } catch (final IllegalAccessException e) {
+      Assert.fail("Unable to access field »" + name + "« in class »" + classz.getName() + "«: " + e.getMessage());
+    }
+  }
+
+  public <R> R invoke(final Class<R> returnType, final String name, final Object ... parameter) {
+
+    final Method[] candidates = Arrays.
+            stream(classz.getMethods()).
+            filter(m-> m.getName().equals(name) && matchesArgumentList(m, parameter)).
+            toArray(Method[]::new);
+
+    if (0 == candidates.length) {
+      Assert.fail("No suitable method found");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple method matches due to ambiguous signature");
+    } else {
+      final Method method = candidates[0];
+      if (method.getReturnType().equals(returnType)) {
+        try {
+          return (R) method.invoke(instance, parameter);
+        } catch (final IllegalAccessException| IllegalArgumentException|InvocationTargetException e) {
+          Assert.fail("Unable to execute method: " + e + ", cause:" + e.getCause());
+        }
+      } else {
+        Assert.fail("Method »" + method.getName() + "« does have return type »"  + method.getReturnType() + "«" +
+                "rather then »" + returnType.getName() + "«");
+      }
+    }
+    return null;
+  }
+  public <R> R invoke(final Class<R> returnType, final String name,
+                                       final Class<? extends Throwable> expectedException, final Object ... parameter) {
+
+    final Method[] candidates = Arrays.
+            stream(classz.getMethods()).
+            filter(m-> m.getName().equals(name) && matchesArgumentList(m, parameter)).
+            toArray(Method[]::new);
+
+    if (0 == candidates.length) {
+      Assert.fail("No suitable method found");
+    } else if (1 < candidates.length) {
+      Assert.fail("Multiple method matches due to ambiguous signature");
+    } else {
+      final Method method = candidates[0];
+      if (method.getReturnType().equals(returnType)) {
+        try {
+          R ret = (R) method.invoke(instance, parameter);
+          Assert.fail("Expected exception of type »" + expectedException.getName() + "«");
+          return ret;
+        } catch (final IllegalAccessException| IllegalArgumentException|InvocationTargetException e) {
+          if (e.getCause().getClass() != expectedException) {
+            Assert.fail("Unable to execute method: " + e + ", cause:\n  Expected exception of type »" +
+                    expectedException.getName() + "« but was »"+ e.getCause().getClass().getName() + "«");
+          }
+        }
+      } else {
+        Assert.fail("Method »" + method.getName() + "« does have return type »"  + method.getReturnType() + "«" +
+                "rather then »" + returnType.getName() + "«");
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check for a given array of objects matching an {@link Executable}'s argument list.
+   *
+   * @param executable
+   * @param parameter
+   * @return <code>true</code> if parameters match the {@link Executable}'s argument list, <code>false</code>
+   * otherwise.
+   */
+  private boolean matchesArgumentList(final Executable executable, final Object ... parameter) {
+
+    if (executable.getParameterCount() != parameter.length) {
+      return false;
+    } else {
+      final Class<?>[] formalArgumentTypes = executable.getParameterTypes();
+      for (int i = 0; i < formalArgumentTypes.length; i++) {
+        final Class parametersClass = parameter[i].getClass();
+
+        if (!formalArgumentTypes[i].equals(parametersClass) &&
+                !formalArgumentTypes[i].equals(getPrimitiveType(parametersClass))) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  static private Class<?> getPrimitiveType (final Class<?> in) {
+    if (in.equals(Byte.class)) {
+      return byte.class;
+    } else if (in.equals(Short.class)) {
+      return short.class;
+    } else if (in.equals(Integer.class)) {
+      return int.class;
+    } else if (in.equals(Long.class)) {
+      return long.class;
+    } else if (in.equals(Float.class)) {
+      return float.class;
+    } else if (in.equals(Double.class)) {
+      return double.class;
+    } else if (in.equals(Boolean.class)) {
+      return boolean.class;
+    } else if (in.equals(Character.class)) {
+      return char.class;
+    } else {
+      return in;            // Type is no primitive
+    }
+  }
+
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
new file mode 100644
index 000000000..fae220dd2
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/A_TrafficLightTest.java
@@ -0,0 +1,25 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.A_TrafficLight.mustStop;
+
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class A_TrafficLightTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 16)
+    public void test_100() {
+        Assert.assertTrue( mustStop(true, false, false)); // Red           :Stop
+        Assert.assertFalse(mustStop(true, true, false));  // Red + yellow  :Go
+
+        Assert.assertFalse(mustStop(false, false, true)); // Green         :Go
+        Assert.assertTrue( mustStop(false, true, false)); // Yellow        :Stop
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
new file mode 100644
index 000000000..176ccc7ed
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/B_StringHelperTest.java
@@ -0,0 +1,37 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.B_StringHelper.getMaxLength;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class B_StringHelperTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+        Assert.assertEquals(0, getMaxLength(new String[]{null}));
+        Assert.assertEquals(0, getMaxLength(new String[]{""}));
+    }
+
+    @Test
+    @Marking(points = 6)
+    public void test_200_single() {
+        Assert.assertEquals(1, getMaxLength(new String[]{"a"}));
+        Assert.assertEquals(11, getMaxLength(new String[]{"csd wde dwe"}));
+    }
+
+    @Test
+    @Marking(points = 6)
+    public void test_300_multi() {
+        Assert.assertEquals(1, getMaxLength(new String[]{"a", "b", "c"}));
+        Assert.assertEquals(5, getMaxLength(new String[]{"Eve", "Peter", "Jill", "Tom"}));
+        Assert.assertEquals(12, getMaxLength(new String[]{"Looooooooong", "Loooooong", null, "Looong", null}));
+        Assert.assertEquals(12, getMaxLength(new String[]{null, "Loooooong", "Looooooooong", "Looong", null}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
new file mode 100644
index 000000000..bb48553fe
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/C_ArrayHelperTest.java
@@ -0,0 +1,42 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.C_ArrayHelper.getAboveAverage;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class C_ArrayHelperTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{1}));
+    }
+
+    @Test
+    @Marking(points = 4)
+    public void test_200_equal() {
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{20, 20}));
+        Assert.assertArrayEquals(new int[]{}, getAboveAverage(new int[]{7, 7, 7, 7}));
+    }
+
+    @Test
+    @Marking(points = 4)
+    public void test_200_regular() {
+        Assert.assertArrayEquals(new int[]{1}, getAboveAverage(new int[]{1, 0}));
+        Assert.assertArrayEquals(new int[]{1}, getAboveAverage(new int[]{0, 1}));
+        Assert.assertArrayEquals(new int[]{5, 4}, getAboveAverage(new int[]{1, 2, 3, 5, 4}));
+        Assert.assertArrayEquals(new int[]{55, 100}, getAboveAverage(new int[]{-30, 2, 4, 55, 100, 9}));
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_200_big() {
+        Assert.assertArrayEquals(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE}, getAboveAverage(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE, 0}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
new file mode 100644
index 000000000..c003f80e7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task1/D_TextFrameTest.java
@@ -0,0 +1,89 @@
+package de.hdm_stuttgart.mi.sd1.task1;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import static de.hdm_stuttgart.mi.sd1.task1.D_TextFrame.createTextFrame;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class D_TextFrameTest extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 2)
+    public void test_100_minimum() {
+
+        final String expected = """
+                ****
+                *  *
+                ****""";
+
+        Assert.assertEquals(expected, createTextFrame(new String[]{null}));
+        Assert.assertEquals(expected, createTextFrame(new String[]{""}));
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_200_one() {
+
+        {
+            final String expected = """
+                    *****
+                    *   *
+                    *****""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{" "}));
+        }
+        {
+            final String expected = """
+                    *****
+                    * j *
+                    *****""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"j"}));
+        }
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_300_multi() {
+
+        {
+            final String expected = """
+                    ******************
+                    * This is a very *
+                    * simple test.   *
+                    ******************""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"This is a very", "simple test."}));
+        }
+        {
+            final String expected = """
+                    *******************
+                    * An example      *
+                    * featuring three *
+                    * lines           *
+                    *******************""";
+
+            Assert.assertEquals(expected, createTextFrame(new String[]{"An example", "featuring three", "lines"}));
+        }
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_400_null() {
+
+        final String expected = """
+                    **********************
+                    * Sometimes there is *
+                    *                    *
+                    * a hole.            *
+                    *                    *
+                    **********************""";
+
+        Assert.assertEquals(expected, createTextFrame(new String[]{"Sometimes there is", null, "a hole.", null}));
+    }
+}
diff --git a/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java
new file mode 100644
index 000000000..055651ad7
--- /dev/null
+++ b/Klausuren/Sd1/2021winter/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/task2/Test_QuadratPolynom.java
@@ -0,0 +1,226 @@
+package de.hdm_stuttgart.mi.sd1.task2;
+
+import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults;
+import de.hdm_stuttgart.mi.exam.unitmarking.Marking;
+import de.hdm_stuttgart.mi.sd1.ignore_me.ObjectWrapper;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+
+public class Test_QuadratPolynom extends ExaminationTestDefaults {
+
+    @Test
+    @Marking(points = 5)
+    public void test_100_NoZero() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 1, 1);
+        assertNoZero(poly, composeDescription(1,2,1).toString());
+
+        final ObjectWrapper<QuadratPolynom> poly2 = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 3);
+        assertNoZero(1, 6, 20, poly2);
+        assertNoZero(2, 13, 41, poly2);
+    }
+
+    @Test
+    @Marking(points = 5)
+    public void test_200_OneZero() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 1);
+        assertOneZero(poly, -1, composeDescription(1,2,1).toString());
+
+        final ObjectWrapper<QuadratPolynom> poly2 = new ObjectWrapper<>(QuadratPolynom.class,1, 2, 3);
+        assertOneZero(6, -84, 294, poly2, 7);
+        assertOneZero(21, 126, 189, poly2, -3);
+    }
+
+    @Test
+    @Marking(points = 5)
+    public void test_300_twoZeroes() {
+
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, 3, 2);
+        assertTwoZeroes(poly, -2, -1, "x² + 3x + 2");
+
+        assertTwoZeroes(3, 7, 4, poly, -4./3, -1);
+
+        assertTwoZeroes(-2, 1, 3, poly, -1, 1.5);
+
+        assertTwoZeroes(-1, 5, 6, poly, -1, 6);
+
+        assertTwoZeroes(7, 11, 4, poly, -1, -4./7);
+
+        assertTwoZeroes(4, -3, -10, poly, -1.25, 2);
+
+        assertTwoZeroes(5, 6, 1, poly, -1, -0.2);
+
+    }
+
+    @Test
+    @Marking(points = 2)
+    public void test_400_Exception() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,1, -200, 2);
+
+        final Class<ArithmeticException> expectedArithmeticException = ArithmeticException.class;
+
+        // Coefficient ax² must not be 0
+        poly.invoke(void.class, "setA", expectedArithmeticException, 0);
+        new ObjectWrapper<>(QuadratPolynom.class, expectedArithmeticException, 0, 88, 99);
+    }
+
+    @Test
+    @Marking(points = 3)
+    public void test_500_TwoZeroExzess() {
+        final ObjectWrapper<QuadratPolynom> poly = new ObjectWrapper<>(QuadratPolynom.class,
+                46010, 598130,-1960026000);
+        assertTwoZeroes(poly,-213,200,
+                composeDescription(46010, 598130,-1960026000).toString());
+    }
+
+    // End of tests -------------------------------------------------------------------------------------------------
+    // Test helper methods
+    //
+    static private final double delta = 1.E-12;
+
+    static private StringBuffer composeDescription(final int a, final int b, final int c) {
+        final StringBuffer ret = new StringBuffer();
+        ret.append(a).append("x²");
+        if (0 < b) {
+            ret.append(" + ").append(b).append("x");
+        } else if (b < 0) {
+            ret.append(" ").append(b).append("x");
+        }
+        // Slight code duplication avoiding a method definition. Yepp: I'm lazy sometimes!
+        if (0 < c) {
+            ret.append(" + ").append(c);
+        } else if (c < 0) {
+            ret.append(" ").append(c);
+        }
+        return ret;
+    }
+
+    /**
+     * Testing given polynomial for no real zero value.
+     *
+     * @param poly Polynomial to be tested
+     * @param description E.g. "-2x² + 4x -3"
+     */
+    static private void assertNoZero(final ObjectWrapper<QuadratPolynom> poly, final String description) {
+
+        Assert.assertEquals("No zero expected for polynom »" + description + "«",
+                0, poly.invoke(double[].class, "getZeroes").length);
+    }
+
+    /**
+     * Testing for no real valued zero solution.
+     *
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     */
+    static private void assertNoZero(final int a,
+                                      final int b,
+                                      final int c,
+                                      final ObjectWrapper<QuadratPolynom> poly) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        Assert.assertEquals("One zero expected for polynom »" + composeDescription(a, b, c) + "«",
+                0, poly.invoke(double[].class, "getZeroes").length);
+
+
+    }
+
+        /**
+         * Testing given polynomial for one zeroes to be returned
+         *
+         * @param poly Polynomial to be tested
+         * @param expected zero value
+         * @param description E.g. "-2x² + 4x -3"
+         */
+    static private void assertOneZero(final ObjectWrapper<QuadratPolynom> poly,
+                                      double expected,
+                                      final String description) {
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        Assert.assertEquals("One zero expected for polynom »" + description + "«",
+                1, result.length);
+        Assert.assertEquals("Expected zero of »" + description +"« to be " + expected, expected, result[0], delta);
+    }
+
+    /**
+     * Like {@link #assertOneZero(ObjectWrapper, double, String)} but re-setting coefficients beforehand,
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     */
+    static private void assertOneZero(final int a,
+                                      final int b,
+                                      final int c,
+                                      final ObjectWrapper<QuadratPolynom> poly,
+                                      double expected) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        final StringBuffer polynomDescription = composeDescription(a, b, c);
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + polynomDescription + "«",
+                1, result.length);
+        Assert.assertEquals("Expected zero of »" + polynomDescription +"« to be " + expected,
+                expected, result[0], delta);
+    }
+
+    /**
+     * Testing given polynomial for two zeroes to be returned
+     *
+     * @param poly Polynomial to be tested
+     * @param expectedLower Lower zero value
+     * @param expectedUpper Upper zero value
+     * @param description E.g. "-2x² + 4x -3"
+     */
+    static private void assertTwoZeroes(final ObjectWrapper<QuadratPolynom> poly,
+                                        double expectedLower,
+                                        double expectedUpper,
+                                        final String description) {
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + description + "«",
+                2, result.length);
+        Assert.assertEquals("Expected lower zero of »" + description +"« to be " + expectedLower,
+                expectedLower, result[0], delta);
+        Assert.assertEquals("Expected upper zero of »" + description +"« to be " + expectedUpper,
+                expectedUpper, result[1], delta);
+    }
+
+    /**
+     * Like {@link #assertTwoZeroes(ObjectWrapper, double, double, String)} but re-setting coeficients beforehand,
+     * @param a Square coefficient
+     * @param b Linear coefficient
+     * @param c Constant coefficient
+     * @param poly Square polynomial
+     * @param expectedLower Expected lower zero value
+     * @param expectedUpper Expected upper zero value
+     */
+    static private void assertTwoZeroes(final int a,
+                                        final int b,
+                                        final int c,
+                                        final ObjectWrapper<QuadratPolynom> poly,
+                                        double expectedLower,
+                                        double expectedUpper) {
+        poly.invoke(void.class, "setA", a);
+        poly.invoke(void.class, "setB", b);
+        poly.invoke(void.class, "setC", c);
+        final double[] result = poly.invoke(double[].class, "getZeroes");
+
+        final StringBuffer polynomDescription = composeDescription(a, b, c);
+
+        Assert.assertEquals(2 + " zeroes expected for polynom »" + polynomDescription + "«",
+                2, result.length);
+        Assert.assertEquals("Expected lower zero of »" + polynomDescription +"« to be " + expectedLower,
+                expectedLower, result[0], delta);
+        Assert.assertEquals("Expected upper zero of »" + polynomDescription +"« to be " + expectedUpper,
+                expectedUpper, result[1], delta);
+    }
+}
-- 
GitLab