<?xml version="1.0" encoding="UTF-8"?>
<appendix version="5.0" xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xi="http://www.w3.org/2001/XInclude"
          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 xml:id="sd1Appendix">Appendix</title>

  <section xml:id="sd1ExaminationHints">
    <title>Examination hints</title>

    <para>Some programming tasks come with <xref linkend="glo_Junit"/> tests.
    Your personal score will depend on the number of successfully executing
    tests possibly weighted with factors modelling an individual test's
    significance.</para>

    <para>That said you should have a focus on completing units of work rather
    than <quote>nearly</quote> finishing a large number of tasks.</para>

    <caution>
      <para>Unit testing is quite relentless. It is different from high school
      where a wrong sign at the end of a calculation does not matter too much
      with respect to marking.</para>
    </caution>

    <para>You should <emphasis>actively</emphasis> train debugging programs:
    Watching a test fail is not so bad if you know how to
    <emphasis>systematically</emphasis> fix bugs. Several options are on
    offer:</para>

    <orderedlist>
      <listitem>
        <para>Use a debugger, typically the one provided by Eclipse. More
        specifically train debugging <xref linkend="glo_Junit"/> test cases
        individually to address failing tests one by one.</para>
      </listitem>

      <listitem>
        <para>Insert log statements into your implementation as being provided
        by log4j.</para>
      </listitem>
    </orderedlist>
  </section>

  <section xml:id="sd1ExternalSupplementaryExercises">
    <title>Recommended external exercises</title>

    <glosslist>
      <glossentry>
        <glossterm>Bradley Kjell's <quote>Introduction to Computer Science
        using Java</quote></glossterm>

        <glossdef>
          <para><link
          xlink:href="https://chortle.ccsu.edu/java5/index.html">Original
          English version</link> and <link
          xlink:href="http://www.gailer-net.de/tutorials/java/java-toc.html">German
          translation</link>.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm><uri
        xlink:href="http://www.codeabbey.com">codeabbey.com</uri></glossterm>

        <glossdef>
          <para><link
          xlink:href="http://www.codeabbey.com/index/task_list">Problem
          list</link>.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm><uri
        xlink:href="https://rosettacode.org">rosettacode.org</uri></glossterm>

        <glossdef>
          <para><link
          xlink:href="https://rosettacode.org/wiki/Category:Programming_Tasks">Programming
          tasks</link> (including solutions for multiple languages).</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>reddit.com</glossterm>

        <glossdef>
          <para><link
          xlink:href="https://www.reddit.com/r/dailyprogrammer">Daily
          Programmer</link>.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm xlink:href="https://projecteuler.net">Project
        Euler</glossterm>

        <glossdef>
          <para>You will have to register without requiring an E-Mail. This is
          only intended to provide a profile for keeping track of your
          exercises' status. The following exercises are meant to be useful
          with respect to the current lectures and have in part been added as
          regular exercises to these lecture notes as well:</para>

          <para><link
          xlink:href="https://projecteuler.net/problem=1">1</link>, <link
          xlink:href="https://projecteuler.net/problem=2">2</link>, <link
          xlink:href="https://projecteuler.net/problem=4">4</link>, <link
          xlink:href="https://projecteuler.net/problem=5">5</link>, <link
          xlink:href="https://projecteuler.net/problem=8">8</link>, <link
          xlink:href="https://projecteuler.net/problem=9">9</link>, <link
          xlink:href="https://projecteuler.net/problem=11">11</link>.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Java Programming Tutorial</glossterm>

        <glossdef>
          <para
          xlink:href="https://www3.ntu.edu.sg/home/ehchua/programming/java/J2a_BasicsExercises.html">Basic
          and more difficult exercises</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Java Programming Exercises</glossterm>

        <glossdef>
          <para>Take the <link
          xlink:href="https://www.home.hs-karlsruhe.de/~pach0003/informatik_1/aufgaben/en/java.html">easier
          exercises</link>.</para>
        </glossdef>
      </glossentry>
    </glosslist>
  </section>

  <section version="5.0" xml:id="sd1SectExamAmendingProjects">
    <title>Examination bonus point project</title>

    <para>Each participant may start a project to gain a bonus with respect to
    the final examination. This bonus is given as a percentage and will be
    added to your final examinations mark. Possible values depending on a
    project's achievements are:</para>

    <itemizedlist>
      <listitem>
        <para>0%</para>
      </listitem>

      <listitem>
        <para>5%</para>
      </listitem>

      <listitem>
        <para>10%</para>
      </listitem>
    </itemizedlist>

    <para>So if the examination's result is 85% a bonus of 10% will result in
    a mark corresponding to 95% of a regular exam result.</para>

    <section xml:id="sd1SectProjectCriteria">
      <title>Marking criteria / Hints</title>

      <orderedlist>
        <listitem>
          <para>You are expected to work as a team of three partners.</para>
        </listitem>

        <listitem>
          <para>Using the <link
          xlink:href="https://version.mi.hdm-stuttgart.de/">MI git SCM</link>
          is a plus with respect to the project's evaluation.</para>
        </listitem>

        <listitem>
          <para>Your team is expected to supply a Maven project based on the
          MI <quote>Maven archetype quickstart</quote> available from <uri
          xlink:href="https://maven.mi.hdm-stuttgart.de/archetype-catalog.xml">https://maven.mi.hdm-stuttgart.de</uri>.</para>
        </listitem>

        <listitem>
          <para>You are expected to provide good internal code documentation
          with respect both to method signatures (<xref
          linkend="glo_Javadoc"/>) and method implementation. Possible
          problems involve:</para>

          <glosslist>
            <glossentry>
              <glossterm>Compile time warnings</glossterm>

              <glossdef>
                <para>Activate most compiler warnings at
                <guimenuitem>Window</guimenuitem> --&gt;
                <guimenuitem>Preferences</guimenuitem> --&gt;
                <guimenuitem>Java</guimenuitem> --&gt;
                <guimenuitem>Compiler</guimenuitem>
                --&gt;<guimenuitem>Errors/Warnings</guimenuitem>. This will
                show potential compile time problems like dead / unnecessary /
                unreachable code, unused variable values, shadowing conflicts
                and so on:</para>

                <mediaobject>
                  <imageobject>
                    <imagedata fileref="Ref/Fig/bonusJavadocCompileTimeProblems.png"/>
                  </imageobject>
                </mediaobject>
              </glossdef>
            </glossentry>

            <glossentry xml:id="sd1BonusprojectActivateJavadocWarnings">
              <glossterm><xref linkend="glo_Javadoc"/> mismatches</glossterm>

              <glossdef>
                <para>Your method's formal parameters, their type and a
                method's return type must match your documentation. In the
                following code snippet the method
                <methodname>getPrimeFactors(...)</methodname> does have
                neither a parameter named <property>prime</property> nor
                <property>frequency</property>:</para>

                <mediaobject>
                  <imageobject>
                    <imagedata fileref="Ref/Fig/bonusJavadocMismatch.png"/>
                  </imageobject>
                </mediaobject>

                <tip>
                  <itemizedlist>
                    <listitem>
                      <para>Activate most <xref linkend="glo_Javadoc"/>
                      related warnings in your IDE globally per workspace
                      below <guimenuitem>Window</guimenuitem> --&gt;
                      <guimenuitem>Preferences</guimenuitem> --&gt;
                      <guimenuitem>Java</guimenuitem> --&gt;
                      <guimenuitem>Compiler</guimenuitem> --&gt;
                      <guimenuitem>Javadoc</guimenuitem>. You may as well
                      activate them as per project settings below
                      <guimenuitem>Project</guimenuitem> --&gt;
                      <guimenuitem>Properties</guimenuitem> --&gt;
                      <guimenuitem>Java Compiler</guimenuitem> --&gt;
                      <guimenuitem>Javadoc</guimenuitem> if ticking
                      <quote>Project specific settings</quote>.</para>
                    </listitem>

                    <listitem>
                      <para>Actually generate the <xref
                      linkend="glo_Javadoc"/> <xref linkend="glo_HTML"/> and
                      see whether it will be useful / sufficient to a
                      programmer using your <code>public</code>
                      interface.</para>
                    </listitem>
                  </itemizedlist>
                </tip>
              </glossdef>
            </glossentry>
          </glosslist>
        </listitem>

        <listitem>
          <para>You are expected to provide meaningful unit tests:</para>

          <itemizedlist>
            <listitem>
              <para>Try to cover all your implementation code and not just
              isolated modules / methods.</para>
            </listitem>

            <listitem>
              <para>If methods allow for null values write suitable
              tests.</para>
            </listitem>

            <listitem>
              <para>Test special cases: If a method expects i.e. an array of
              strings it may be allowed having zero length.</para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>Your resulting project should be easily installable /
          runnable.</para>

          <itemizedlist>
            <listitem>
              <para>Maven is a good starting point with respect both to test
              integration and cross platform (Unix / Windows / Apple)
              portability.</para>
            </listitem>

            <listitem>
              <para>Avoid dependencies to local filesystem resources like
              <filename>c:\users\xyz\testdata.txt</filename>.</para>
            </listitem>
          </itemizedlist>

          <tip>
            <para>Test the deployability of your project by installing it on
            an untouched target platform (possibly of a different
            hard/software architecture) and execute <command>mvn</command>
            <option>test</option> (provided you do have written meaningful
            unit tests).</para>
          </tip>
        </listitem>
      </orderedlist>
    </section>

    <section xml:id="sd1SectProjectGrep">
      <title>Poor man's <xref linkend="glo_UNIX"/> <command
      xlink:href="http://linux.die.net/man/1/grep">grep</command>.</title>

      <para>The <xref linkend="glo_UNIX"/> operating system provides a command
      <command xlink:href="http://linux.die.net/man/1/grep">grep</command>
      which allows for retrieving occurrences of a given string in text files.
      We consider an example text file <filename>input.txt</filename>
      containing four lines:</para>

      <programlisting language="none" linenumbering="numbered">Roses are nice flowers.
Red wine is tasty
The red cross acts worldwide
Mayflower used to be a ship.</programlisting>

      <para>We search this file <filename>input.txt</filename> for the
      occurrence of the string <quote>flower</quote> being contained in lines
      1 and 4:</para>

      <programlisting language="none">&gt; grep <emphasis role="bold">flower</emphasis> input.txt 
Roses are nice <emphasis role="bold">flower</emphasis>s.
May<emphasis role="bold">flower</emphasis> used to be a ship.</programlisting>

      <para>Thus the <command
      xlink:href="http://linux.die.net/man/1/grep">grep</command> command
      echoes all lines containing the search string in question to standard
      output. Adding the command line option <option>-i</option> allows for
      case insensitive searches:</para>

      <programlisting language="none" linenumbering="unnumbered">&gt; grep <option>-i</option> <emphasis
          role="bold">red</emphasis> input.txt
<emphasis role="bold">Red</emphasis> wine is tasty
The <emphasis role="bold">red</emphasis> cross acts worldwide</programlisting>

      <para>This time all possible variants like <quote>Red</quote>,
      <quote>red</quote>, <quote>RED</quote> and so on will match.</para>

      <para><command
      xlink:href="http://linux.die.net/man/1/grep">grep</command> also allows
      for searching multiple files. Consider a second file
      <filename>inputSecond.txt</filename>:</para>

      <programlisting language="none" linenumbering="numbered">Errors will show up in red.
Let's start bug fixing</programlisting>

      <para>We may search for case insensitive (<option>-i</option> again)
      appearances of <quote>red</quote> within both files:</para>

      <programlisting language="none" linenumbering="unnumbered">&gt; grep -i <emphasis
          role="bold">red</emphasis> input.txt  inputSecond.txt 
input.txt:<emphasis role="bold">Red</emphasis> wine is tasty
input.txt:The <emphasis role="bold">red</emphasis> cross acts worldwide
inputSecond.txt:Errors will show up in <emphasis role="bold">red</emphasis>.</programlisting>

      <para>Finally the <option>-l</option> option will filter individual
      appearances just showing filenames containing matches:</para>

      <programlisting language="none">&gt; grep -l Red input.txt  inputSecond.txt 
input.txt</programlisting>

      <para>In contrast a case insensitive search combining both
      <option>-i</option> and <option>-l</option> options yields:</para>

      <programlisting language="none">&gt; grep -i -l Red input.txt  inputSecond.txt 
input.txt
inputSecond.txt</programlisting>

      <para>The <command
      xlink:href="http://linux.die.net/man/1/grep">grep</command> command may
      read its input from standard input allowing for <link
      xlink:href="https://en.wikipedia.org/wiki/Pipeline_(Unix)">pipes</link>.
      This way another command's output feeds into a subsequently executed
      command. As an example consider a recursive search for HTML files using
      the <link xlink:href="http://linux.die.net/man/1/find">find</link>
      command:</para>

      <programlisting language="none">&gt; find . -name \*.html
./Sd1/Wc/wc/Testdata/input.html
./Sda1/rdbmsXml2Html/TestData/climbingprice.html
./Sda1/NoCast/src/main/resources/gallery.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExampleNew.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExample.html
./Sda1/VerifyImgAccess/fileextref.html</programlisting>

      <para>We want to restrict the above list to pathnames containing the
      string <quote>Example</quote>. This may be achieved by <link
      xlink:href="https://en.wikipedia.org/wiki/Pipeline_(Unix)">piping</link>
      the <link xlink:href="http://linux.die.net/man/1/find">find</link>
      command's output as input to <command
      xlink:href="http://linux.die.net/man/1/grep">grep</command> searching
      for the occurrence of the string <quote>Example</quote>. Technically
      both processes get connected by means of the pipe symbol
      <quote>|</quote>:</para>

      <programlisting language="none">&gt; find . -name \*.html|grep Example
./Sda1/Jdom/Html2Html/src/main/resources/imageExampleNew.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExample.html</programlisting>

      <tip>
        <orderedlist>
          <listitem>
            <para>Read about reading from files by using instances of
            <classname
            xlink:href="http://www.tutorialspoint.com/java/io/bufferedreader_readline.htm">java.io.BufferedReader</classname>.</para>
          </listitem>

          <listitem>
            <para>Reading from standard input may be achieved by:</para>

            <programlisting language="java">final BufferedReader source = new BufferedReader(new InputStreamReader(System.in));
...</programlisting>
          </listitem>

          <listitem>
            <para>You may create an executable jar archive using Maven.
            Starting from the <code>mi-mavem-archetype-quickstart</code> your
            <filename>pom.xml</filename> already contains a blueprint. Just
            insert your class containing the entry
            <methodname>main(...)</methodname> method (i.e.
            <classname>de.hdm_stuttgart.mi.sd1.grep.Grep</classname> in the
            current example) accordingly:</para>

            <programlisting language="xml">&lt;plugin&gt;
  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
  &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
  &lt;version&gt;2.4.1&lt;/version&gt;
  &lt;configuration&gt;
    &lt;transformers&gt;
      &lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&gt;
        &lt;manifestEntries&gt;
          &lt;Main-Class&gt;<emphasis role="bold">de.hdm_stuttgart.mi.sd1.grep.Grep</emphasis>&lt;/Main-Class&gt;
        &lt;/manifestEntries&gt;
      &lt;/transformer&gt;
    &lt;/transformers&gt;
  &lt;/configuration&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;phase&gt;package&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;shade&lt;/goal&gt;
        &lt;/goals&gt;
     &lt;/execution&gt;
  &lt;/executions&gt;
&lt;/plugin&gt;</programlisting>

            <para>Running <command>mvn</command> <option>install</option> will
            create an executable jar file like e.g.
            <filename>~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar</filename>
            with <quote>~</quote> denoting your home directory:</para>

            <programlisting language="none">&gt; mvn install
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building grep 0.9
[INFO] ------------------------------------------------------------------------

...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.hdm_stuttgart.mi.sd1.grep.CommandLineTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.757 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0

...
[INFO] Installing /home/goik/workspace/sd-project-summer/grep/target/grep-0.9.jar to 
     /home/goik/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
...
</programlisting>

            <para>Due to our
            <code>&lt;Main-Class&gt;de.hdm_stuttgart.mi.sd1.grep.Grep&lt;/Main-Class&gt;</code>
            declaration in <filename>pom.xml</filename> this jar file is
            executable:</para>

            <programlisting language="none">&gt; java -jar ~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</programlisting>

            <para>There are further simplification steps:</para>

            <orderedlist>
              <listitem>
                <para>Making the jar file executable using <command
                xlink:href="http://linux.die.net/man/1/chmod">chmod</command>
                allows for omitting the <command>java</command>
                command:</para>

                <programlisting language="none">&gt; chmod +x ~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
&gt; ~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</programlisting>

                <para>Notice <quote>~</quote> representing a user's home
                directory.</para>
              </listitem>

              <listitem>
                <para>We may copy the jar archive to a standard location
                containing executable commands:</para>

                <programlisting language="none">&gt; mkdir ~/bin
&gt; 
&gt; cp ~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar ~/bin/jgrep
&gt; 
&gt; ~/bin/jgrep 
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</programlisting>
              </listitem>

              <listitem>
                <para>We may add this directory to the set of directories
                being searched by the operating system's command line
                interpreter for executable commands. This is being achieved by
                either creating or modifying a file
                <filename>~/.profile</filename> in the user's home directory
                using a text editor. <filename>~/.profile</filename> should
                contain:</para>

                <programlisting language="none">PATH="$HOME/bin:$PATH"</programlisting>

                <para>After logging out and on again your PATH environment
                variable should contain your <filename>~/bin</filename>
                component:</para>

                <programlisting language="none">&gt; echo $PATH
<emphasis role="bold">/home/goik/bin</emphasis>:/usr/local/sbin:/usr/local/bin:/usr/...</programlisting>

                <para>You should now be able to call <command>jgrep</command>
                from arbitrary filesystem locations:</para>

                <programlisting language="none">&gt; cd Desktop/
&gt; cat Testdata/input.txt | ./bin/mygrep red
The red cross acts worldwide</programlisting>
              </listitem>
            </orderedlist>
          </listitem>

          <listitem xml:id="sd1ProjectGrepUnitTestingHint">
            <para>Testing requires capturing of output being generated by e.g.
            <methodname
            xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out">System.out</methodname><code>.</code><methodname
            xlink:href="https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#println-java.lang.String-">println(...)</methodname>
            calls. Consider the following code writing the string <quote>Hello
            World!</quote> to standard output:</para>

            <programlisting language="java">public class App {
    /**
     * @param args Unused
     */
    public static void main( String[] args ) {
        System.out.print( "Hello World!" );
    }
}</programlisting>

            <para>We want to set up a <productname>Junit</productname> test
            which captures the output to compare it with the expected string
            value <code>"Hello World!"</code>. Following <uri
            xlink:href="http://stackoverflow.com/questions/1119385/junit-test-for-system-out-println">http://stackoverflow.com/questions/1119385/junit-test-for-system-out-println</uri>
            we redefine the standard output stream by a private instance of
            <classname
            xlink:href="https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayOutputStream.html">java.io.ByteArrayOutputStream</classname>.
            Due to <productname>Junit</productname>'s <classname
            xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Before.html">@Before</classname>
            and <classname
            xlink:href="http://junit.sourceforge.net/javadoc/org/junit/After.html">@After</classname>
            annotations this instance replaces <classname
            xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out">System.out</classname>
            during our tests:</para>

            <programlisting language="java">import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit test for simple App.
 */
public class AppTest {
   private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

   <classname xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Before.html">@Before</classname>
   public void setUpStreams() {
       System.setOut(new PrintStream(outContent));
   }

   <classname xlink:href="http://junit.sourceforge.net/javadoc/org/junit/After.html">@After</classname>
   public void cleanUpStreams() {
       System.setOut(null);
       outContent.reset();
   }
   
    /**
     * Test method accessing output generated by System.out.println(...) calls.
     */
    @Test
    public void testApp() {
       App.main(new String[]{}); // Calling main() method printing "Hello World!"
       Assert.assertEquals("Hello World!", outContent.toString());
    }
}</programlisting>
          </listitem>
        </orderedlist>
      </tip>
    </section>

    <section xml:id="sd1ProjectSieveErathostenes">
      <title>Project <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler's
      sieve</link> (Winter 2015)</title>

      <para>The project's goal is about:</para>

      <itemizedlist>
        <listitem>
          <para>Generating all prime numbers of type <code>int</code>.</para>
        </listitem>

        <listitem>
          <para>Using this set of pregenerated prime numbers for decomposing
          arbitrary <code>int</code> values into prime factors e.g.:</para>

          <para>1050 = 2 * 3 * 5 * 5 * 7</para>
        </listitem>
      </itemizedlist>

      <para>We start with the first task by implementing the <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
      sieve algorithm</link>. We may use a boolean array representing e.g. the
      first 100 primes:</para>

      <programlisting language="java">boolean[] nonPrimes = new boolean[100];</programlisting>

      <para>This array will initially be filled with 100 <code>false</code>
      values. The idea is using the <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
      sieve algorithm</link> to turn all non-prime value to <code>true
      (t)</code> and leaving al prime index values at <code>false
      (f)</code>:</para>

      <programlisting language="non">Index | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14 ...
------+--+--+--+--+--+--+--+--+--+--+---+---+---+---+--- ...
value | t| t| f| f| t| f| t| f| t| t|  t|  f|  t|  f|  t ...</programlisting>

      <para>Since we intend to deal with a large number <code
      xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE</code>
      of values (rather than just 100 ) we only consider odd values since even
      numbers are never prime except for the value 2. Thus 0 will represent 1,
      1 will represent 3 and n will represent 2 * n + 1:</para>

      <programlisting language="non">Index      | 0| 1| 2| 3| 4|  5|  6|  7| ...
-----------+--+--+--+--+--+---+---+---+ ...
represents | 1| 3| 5| 7| 9| 11| 13| 15| ... 
-----------+--+--+--+--+--+---+---+---+ ...
value      | t| f| f| f| t|  f|  f|  t| ...</programlisting>

      <para>This requires a boolean array of just <code
      xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE
      / 2</code>. Start from the following skeleton:</para>

      <programlisting language="java">public class Sieve {

   final boolean[] nonPrimes;
   final int numPrimesFound;

   /**
    * Creating a prime number Euler variant sieve 
    * 
    * @param limit The last value to be considered. May or may not be prime.
    * 
    */
   public Sieve(final int limit) {
      ...// initialize nonPrimes and numPrimesFound.
   }
  ...

   /**
    * Test if a given value is prime or not
    * 
    * @param candidate The value in question.
    * 
    * @return True if value is prime, false otherwise.
    */
   public boolean isPrime(final int candidate) {
     // Based on nonPrimes array
     ...
   }
}</programlisting>

      <tip>
        <para>Decompose the <link
        xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
        sieve algorithm</link> into smaller tasks and write appropriate tests.
        Start with small <code>limit</code> values (like 20) and extend to
        <code
        xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE</code>
        step by step.</para>
      </tip>

      <para>Once you've finished implementing the sieve continue by
      implementing the second task of prime decomposition. We recall the
      initial example:</para>

      <para>1050 = 2 * 3 * 5 * 5 * 7</para>

      <para>So the primes 2, 3 and 7 appear with frequency 1 whereas 5 appears
      with frequency 2. For meaningful operations we introduce a new class
      combining a prime number and its corresponding frequency of appearance
      to represent prime factor decompositions appropriately:</para>

      <programlisting language="java">/**
 * Representing a single prime factor among with its
 * frequency.
 *
 */
public class PrimeFrequency {
   
   /**
    * The prime's immutable value.
    */
   public final int prime;
   
   /**
    * The prime's frequency of appearance. 
    */
   int frequency;
   
   /**
    * @param prime {@link #prime} 
    * @param frequency The prime's frequency of appearance.
    */
   public PrimeFrequency(final int prime, final int frequency) {
      this.prime = prime;
      this.frequency = frequency;
   }

   /**
    * @return The prime factor's frequency of appearance.
    */
   public int getFrequency() {
      return frequency;
   }
   
   /**
    * change the given frequency value.
    * @param frequency change by this value.
    */
   public void addFrequency(@SuppressWarnings("hiding") final int frequency) {
      this.frequency += frequency;
   }

   @Override
   public boolean equals(final Object obj) {
      ...
   }   
}</programlisting>

      <para>Now 2 * 3 * 5 * 5 * 7 may be represented by three (not four!)
      instances of <code>PrimeFrequency</code>. In order to represent the
      whole product implement a second container:</para>

      <programlisting language="java">/**
 * Representing integer values by an ordered set of prime factors among with
 * their frequencies of appearance.
 *
 */
public class PrimeFrequencySet {

   private final static int initialCapacity = 16;
   
   private PrimeFrequency[] store = new PrimeFrequency[initialCapacity]; // May grow due to new factors.

   /**
    * Searching for the existence of a {@link PrimeFrequency} with a matching
    * prime value (frequency may be different!).
    * 
    * Example: If the set contains the prime values {3, 7, 11} (we ignore
    * frequencies) then searching for:
    * &lt;ul&gt;
    *   &lt;li&gt;3 return index 0&lt;/li&gt;
    *   &lt;li&gt;11 returns index 2&lt;/li&gt;
    *   &lt;li&gt;5 return -2&lt;/li&gt;
    *   &lt;li&gt;13 returns -3&lt;/li&gt;
    *   &lt;li&gt;2 returns -1&lt;/li&gt;
    * &lt;/ul&gt;
    * 
    * @param primeFrequency The candidate to be looked up.
    * 
    * @return If a prime value match exists return its index. If no match
    * exists return the negative value of the first index belonging to a set
    * value having a larger prime value than the candidate (the "natural"
    * insertion point) minus 1 (see example).
    */
   public int find(final PrimeFrequency primeFrequency) {
     ...
   }
   
   /**
    * Either add a new prime or just add a prime's frequency to an existing one.
    * 
    * @param primeFrequency If the prime is already in the current set, add its
    * frequency. Otherwise insert the new element preserving the order of prime
    * values.
    */
   public void add(final PrimeFrequency primeFrequency) {
     ...
   }
   
   /**
    * @return The count of all prime factors.
    */
   public int getLength() {
      ...
   }

   /**
    * The prime factor corresponding to a given index.
    * @param index .
    * @return .
    */
   public PrimeFrequency get(int index) {
      ...
   }
   
   /**
    * @return All prime factors among with their respective frequencies.
    */
   public PrimeFrequency[] get() {
     ...
   }
}</programlisting>

      <para>This allows for decomposing arbitrary <code>int</code> values into
      their prime factors. We show a unit test example:</para>

      <programlisting language="java">/**
 * Prime factor decomposition.
 */
public class FactorTest {

   final Sieve sieve = new Sieve(100000);

   @Test
   public void test2 () {
      PrimeFrequencySet pfs = sieve.getPrimeFactors(12); <co
          linkends="sd1ListingTestPrimeFactorDecompose-1"
          xml:id="sd1ListingTestPrimeFactorDecompose-1-co"/>
      Assert.assertEquals(2, pfs.getLength()); <co
          linkends="sd1ListingTestPrimeFactorDecompose-2"
          xml:id="sd1ListingTestPrimeFactorDecompose-2-co"/>
      Assert.assertEquals(new PrimeFrequency(2, 2), pfs.get(0)); <co
          linkends="sd1ListingTestPrimeFactorDecompose-3"
          xml:id="sd1ListingTestPrimeFactorDecompose-3-co"/>
      Assert.assertEquals(new PrimeFrequency(3, 1), pfs.get(1)); <co
          linkends="sd1ListingTestPrimeFactorDecompose-4"
          xml:id="sd1ListingTestPrimeFactorDecompose-4-co"/>
   }
}</programlisting>

      <calloutlist>
        <callout arearefs="sd1ListingTestPrimeFactorDecompose-1-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-1">
          <para>Decomposing 12 into 2 * 2 * 3.</para>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-2-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-2">
          <para>We expect two factors:</para>

          <orderedlist>
            <listitem>
              <para>Prime factor 2 having frequency 2.</para>
            </listitem>

            <listitem>
              <para>Prime factor 3 having frequency 1.</para>
            </listitem>
          </orderedlist>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-3-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-3">
          <para>Check for first prime factor 2 of frequency 2.</para>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-4-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-4">
          <para>Check for second prime factor 3 of frequency 1.</para>
        </callout>
      </calloutlist>

      <para>For better illustration we provide the following example:</para>

      <programlisting language="java">public class Driver {

   /**
    * @param args Unused
    */
   public static void main( String[] args ) {
      
      final Sieve sieve = new Sieve(Integer.MAX_VALUE);

      
      int value = Integer.MAX_VALUE;
      System.out.println("Value " + value + " is " + 
        (sieve.isPrime(value)? "" : "not") + " prime.");

      value--; // Even Value
      
      System.out.println("Value " + value + " is " + 
            (sieve.isPrime(value)? "" : "not") + " prime.");

      value --; // Non-prime as well.
      System.out.println("Value " + value + " is " + 
            (sieve.isPrime(value)? "" : "not") + " prime.");


      value = Integer.MAX_VALUE - 1;
      final PrimeFrequencySet pfs = sieve.getPrimeFactors(value);
      
      System.out.print(value + " = ");
      String separator = "";
      for (PrimeFrequency pf : pfs.get()) {
         for (int i = 0; i &lt; pf.getFrequency(); i++) {
            System.out.print(separator + pf.prime);
            separator = " * ";
         }
      }
      System.out.println();
   }
}</programlisting>

      <para>This yields the following output:</para>

      <programlisting language="none">Value 2147483647 is  prime.
Value 2147483646 is not prime.
Value 2147483645 is not prime.
2147483646 = 2 * 3 * 3 * 7 * 11 * 31 * 151 * 331</programlisting>

      <para>Depending on your implementation you may encounter the following
      heap memory related error:</para>

      <programlisting language="none">Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at de.hdm_stuttgart.mi.prim.sieve.Sieve.initSieve(Sieve.java:75)
	at de.hdm_stuttgart.mi.prim.sieve.Sieve.&lt;init&gt;(Sieve.java:60)
	at de.hdm_stuttgart.mi.prim.Driver.main(Driver.java:19)</programlisting>

      <para>The <xref linkend="glo_Java"/> virtual machine by default may not
      provide enough heap space. You may enlarge the default allocation by
      setting the <option>-Xmx</option>. Eclipse provides a convenient way by
      means of a run time configuration (Menu Run --&gt; Run
      Configurations):</para>

      <informalfigure>
        <mediaobject>
          <imageobject>
            <imagedata fileref="Ref/Fig/primDriverRunConfigOverview.bmp"/>
          </imageobject>
        </mediaobject>
      </informalfigure>

      <para>Clicking the <quote>Arguments</quote> tab allows for setting the
      respective VM heap setting:</para>

      <informalfigure>
        <mediaobject>
          <imageobject>
            <imagedata fileref="Ref/Fig/primDriverRunConfigVmOptions.bmp"/>
          </imageobject>
        </mediaobject>
      </informalfigure>

      <para>This allows for running your application with a maximum of 4
      gigabytes of heap space.</para>

      <para>With respect to automated unit testing (<command>mvn</command>
      <option>test</option>)you may want to set the same value in you
      <filename>pom.xml</filename> file</para>

      <programlisting language="xml">&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.19&lt;/version&gt;
    &lt;configuration&gt;
      <emphasis role="bold">&lt;argLine&gt;-Xmx4G&lt;/argLine&gt;</emphasis>
  &lt;/configuration&gt;
&lt;/plugin&gt;</programlisting>
    </section>
  </section>
</appendix>