diff --git a/mooc-java-programming-i/part05-Part05_01.OneMinute/.tmcproject.yml b/mooc-java-programming-i/part05-Part05_01.OneMinute/.tmcproject.yml
new file mode 100644
index 0000000..d2446da
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_01.OneMinute/.tmcproject.yml
@@ -0,0 +1 @@
+force_new_sandbox: true
diff --git a/mooc-java-programming-i/part05-Part05_01.OneMinute/pom.xml b/mooc-java-programming-i/part05-Part05_01.OneMinute/pom.xml
new file mode 100644
index 0000000..759c313
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_01.OneMinute/pom.xml
@@ -0,0 +1,73 @@
+
+
+ 4.0.0
+ tkt
+ Part05_01.OneMinute
+ Part05_01.OneMinute
+ 1.0-SNAPSHOT
+ jar
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ fi.helsinki.cs.tmc
+ edu-test-utils
+ 0.4.2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.6.0
+
+
+
+
+
+
+ tmc
+ TMC repo
+ https://maven.mooc.fi/releases
+
+ true
+
+
+ true
+
+
+
+
+
+
+ tmc
+ TMC repo
+ https://maven.mooc.fi/releases
+
+ true
+
+
+ true
+
+
+
+
diff --git a/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/ClockHand.java b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/ClockHand.java
new file mode 100644
index 0000000..92b3e4c
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/ClockHand.java
@@ -0,0 +1,31 @@
+
+public class ClockHand {
+
+ private int value;
+ private int limit;
+
+ public ClockHand(int limit) {
+ this.limit = limit;
+ this.value = 0;
+ }
+
+ public void advance() {
+ this.value = this.value + 1;
+
+ if (this.value >= this.limit) {
+ this.value = 0;
+ }
+ }
+
+ public int value() {
+ return this.value;
+ }
+
+ public String toString() {
+ if (this.value < 10) {
+ return "0" + this.value;
+ }
+
+ return "" + this.value;
+ }
+}
diff --git a/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/Program.java b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/Program.java
new file mode 100644
index 0000000..7dc1139
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/main/java/Program.java
@@ -0,0 +1,11 @@
+
+import java.util.Scanner;
+
+public class Program {
+
+ public static void main(String[] args) {
+ // You can test your program here
+
+
+ }
+}
diff --git a/mooc-java-programming-i/part05-Part05_01.OneMinute/src/test/java/TimerTest.java b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/test/java/TimerTest.java
new file mode 100644
index 0000000..4c5a6a4
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_01.OneMinute/src/test/java/TimerTest.java
@@ -0,0 +1,144 @@
+
+import fi.helsinki.cs.tmc.edutestutils.MockStdio;
+import fi.helsinki.cs.tmc.edutestutils.Points;
+import fi.helsinki.cs.tmc.edutestutils.Reflex;
+import java.util.Random;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+@Points("05-01")
+public class TimerTest {
+
+ @Rule
+ public MockStdio io = new MockStdio();
+
+ @Test
+ public void classAndConstructor() {
+ createTimer();
+ }
+
+ @Test
+ public void toStringInTheBeginning() {
+ Object timer = createTimer();
+
+ String toStringFromTimer = callToString(timer);
+
+ assertEquals("Printing the result of toString of a newly created timer should result in \"00:00\". Now the output was " + toStringFromTimer + "\nTry it out yourself:\n"
+ + "Timer t = new Timer();\n"
+ + "System.out.println(t);", "00:00", toStringFromTimer);
+ }
+
+ @Test
+ public void advanceMethodExists() {
+ Object timer = createTimer();
+ Reflex.reflect("Timer").method("advance").returningVoid().takingNoParams().requirePublic();
+
+ try {
+ Reflex.reflect("Timer").method("advance").returningVoid().takingNoParams().invokeOn(timer);
+ } catch (Throwable t) {
+ fail("An error occurred when calling the method 'advance'. The error was: " + t.getMessage() + "\nTry it out:\n"
+ + "Timer t = new Timer();\n"
+ + "t.advance();");
+ }
+
+ String toStringFromTimer = callToString(timer);
+
+ assertEquals("After a timer has advanced once, the result of toString should be \"00:01\". Now it was " + toStringFromTimer + "Try it out yourself:\n"
+ + "Timer t = new Timer();\n"
+ + "t.advance();\n"
+ + "System.out.println(t);", "00:01", toStringFromTimer);
+ }
+
+ @Test
+ public void advanceFar() {
+ Object timer = createTimer();
+
+ int randomAdvancementTime = new Random().nextInt(1000) + 1000;
+ for (int i = 1; i <= randomAdvancementTime; i++) {
+ try {
+ Reflex.reflect("Timer").method("advance").returningVoid().takingNoParams().invokeOn(timer);
+ } catch (Throwable t) {
+ fail("An error occurred when calling the 'advance' method. The error was: " + t.getMessage() + "\nTry calling the advance method " + (i) + " times.");
+ }
+ }
+
+ int seconds = ((randomAdvancementTime / 100) % 60);
+ int hundredths = (randomAdvancementTime % 100);
+
+ String s = seconds < 10 ? "0" + seconds : "" + seconds;
+ String hos = hundredths < 10 ? "0" + hundredths : "" + hundredths;
+
+ String toStringFromTimer = callToString(timer);
+ String expectedPrint = "" + s + ":" + hos;
+
+ assertEquals("When the advance method is called " + randomAdvancementTime + " times, the print should be \"" + expectedPrint + "\".\nNow it was " + toStringFromTimer + "\nTry it out:\n"
+ + "Timer t = new Timer();\n"
+ + "int i = 0;\n"
+ + "while (i < " + randomAdvancementTime + ") {\n"
+ + " t.advance();\n"
+ + "}"
+ + "System.out.println(t);", expectedPrint, toStringFromTimer);
+ }
+
+ @Test
+ public void advanceVeryFar() {
+ Object timer = createTimer();
+
+ int randomAdvancementTime = new Random().nextInt(10000) + 360000;
+ for (int i = 1; i <= randomAdvancementTime; i++) {
+ try {
+ Reflex.reflect("Timer").method("advance").returningVoid().takingNoParams().invokeOn(timer);
+ } catch (Throwable t) {
+ fail("An error occurred when calling the 'advance' method. The error was: " + t.getMessage() + "\nTry calling the advance method " + (i) + " times.");
+ }
+ }
+
+ int seconds = ((randomAdvancementTime / 100) % 60);
+ int hundredths = (randomAdvancementTime % 100);
+
+ String s = seconds < 10 ? "0" + seconds : "" + seconds;
+ String hos = hundredths < 10 ? "0" + hundredths : "" + hundredths;
+
+ String toStringFromTimer = callToString(timer);
+ String expectedPrint = "" + s + ":" + hos;
+
+ assertEquals("When the advance method is called " + randomAdvancementTime + " times, the print should be \"" + expectedPrint + "\".\nNow it was " + toStringFromTimer + "\nTry it out:\n"
+ + "Timer t = new Timer();\n"
+ + "int i = 0;\n"
+ + "while (i < " + randomAdvancementTime + ") {\n"
+ + " t.advance();\n"
+ + "}"
+ + "System.out.println(t);", expectedPrint, toStringFromTimer);
+ }
+
+ private String callToString(Object timer) {
+ String out = io.getSysOut();
+
+ String toStringFromTimer = null;
+
+ try {
+ toStringFromTimer = timer.toString();
+ } catch (Throwable e) {
+ fail("Error when calling the toString method of the timer. Try:\n"
+ + "Timer timer = new Timer();\n"
+ + "timer.toString();\n"
+ + "The error that occurred: " + e.getMessage());
+ }
+
+ assertEquals("Calling the method toString shouldn't print anything. It is only to return a string.", out, io.getSysOut());
+
+ return toStringFromTimer;
+ }
+
+ private Object createTimer() {
+ Reflex.reflect("Timer").ctor().takingNoParams().requirePublic();
+ try {
+ return Reflex.reflect("Timer").ctor().takingNoParams().invoke();
+ } catch (Throwable ex) {
+ fail("An error occured while testing the program. Try:\nTimer timer = new Timer();\nError: " + ex.getMessage());
+ }
+ return null;
+ }
+
+
+}
diff --git a/mooc-java-programming-i/part05-Part05_02.Book/.tmcproject.yml b/mooc-java-programming-i/part05-Part05_02.Book/.tmcproject.yml
new file mode 100644
index 0000000..d2446da
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_02.Book/.tmcproject.yml
@@ -0,0 +1 @@
+force_new_sandbox: true
diff --git a/mooc-java-programming-i/part05-Part05_02.Book/pom.xml b/mooc-java-programming-i/part05-Part05_02.Book/pom.xml
new file mode 100644
index 0000000..0014a72
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_02.Book/pom.xml
@@ -0,0 +1,73 @@
+
+
+ 4.0.0
+ tkt
+ Part05_02.Book
+ Part05_02.Book
+ 1.0-SNAPSHOT
+ jar
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ fi.helsinki.cs.tmc
+ edu-test-utils
+ 0.4.2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.6.0
+
+
+
+
+
+
+ tmc
+ TMC repo
+ https://maven.mooc.fi/releases
+
+ true
+
+
+ true
+
+
+
+
+
+
+ tmc
+ TMC repo
+ https://maven.mooc.fi/releases
+
+ true
+
+
+ true
+
+
+
+
diff --git a/mooc-java-programming-i/part05-Part05_02.Book/src/main/java/Program.java b/mooc-java-programming-i/part05-Part05_02.Book/src/main/java/Program.java
new file mode 100644
index 0000000..421d74b
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_02.Book/src/main/java/Program.java
@@ -0,0 +1,14 @@
+
+public class Program {
+
+ public static void main(String[] args) {
+ // This is simply an empty main method where you are
+ // free to experiment with your Book class.
+ // An example that you can use for testing:
+
+
+// Book b = new Book("J. K. Rowling", "Harry Potter and the Sorcerer's Stone", 223);
+// System.out.println(b);
+
+ }
+}
diff --git a/mooc-java-programming-i/part05-Part05_02.Book/src/test/java/BookTest.java b/mooc-java-programming-i/part05-Part05_02.Book/src/test/java/BookTest.java
new file mode 100644
index 0000000..4e0b79a
--- /dev/null
+++ b/mooc-java-programming-i/part05-Part05_02.Book/src/test/java/BookTest.java
@@ -0,0 +1,257 @@
+
+import fi.helsinki.cs.tmc.edutestutils.Points;
+import fi.helsinki.cs.tmc.edutestutils.ReflectionUtils;
+import fi.helsinki.cs.tmc.edutestutils.MockInOut;
+import fi.helsinki.cs.tmc.edutestutils.Reflex;
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.junit.Before;
+import static org.junit.Assert.*;
+
+@Points("05-02")
+public class BookTest {
+
+ Reflex.ClassRef