diff --git a/javafx-template/.gitignore b/hal-calc/.gitignore
similarity index 100%
rename from javafx-template/.gitignore
rename to hal-calc/.gitignore
diff --git a/javafx-template/pom.xml b/hal-calc/pom.xml
similarity index 96%
rename from javafx-template/pom.xml
rename to hal-calc/pom.xml
index c8ab5e7e41571fa995c2dc55458977955ab5ee6b..6b83cfefe79b67ffbfde6e7fc3ab7fc3623fceed 100644
--- a/javafx-template/pom.xml
+++ b/hal-calc/pom.xml
@@ -2,7 +2,7 @@
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>it1901</groupId>
-    <artifactId>javafx-template</artifactId>
+    <artifactId>hal-calc</artifactId>
     <version>0.0.1-SNAPSHOT</version>
 
     <properties>
@@ -93,7 +93,7 @@
                         <!-- Usage: mvn clean javafx:run -->
                         <id>default-cli</id>
                         <configuration>
-                            <mainClass>app.App</mainClass>
+                            <mainClass>hal.calc.CalcApp</mainClass>
                         </configuration>
                     </execution>
                 </executions>
diff --git a/javafx-template/src/main/java/app/Calc.java b/hal-calc/src/main/java/hal/calc/Calc.java
similarity index 99%
rename from javafx-template/src/main/java/app/Calc.java
rename to hal-calc/src/main/java/hal/calc/Calc.java
index 231878cb2fcd5500d19f51a1f68facc5203e2828..a37cf26ee5931ee82e2845719ac7a914dc58f05e 100644
--- a/javafx-template/src/main/java/app/Calc.java
+++ b/hal-calc/src/main/java/hal/calc/Calc.java
@@ -1,4 +1,4 @@
-package app;
+package hal.calc;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/modules-template/ui/src/main/java/ui/App.java b/hal-calc/src/main/java/hal/calc/CalcApp.java
similarity index 85%
rename from modules-template/ui/src/main/java/ui/App.java
rename to hal-calc/src/main/java/hal/calc/CalcApp.java
index acead69e8eac41010e6843e4529e834868b979d3..aada3d523434b3d603889fcf6c856f3642677537 100644
--- a/modules-template/ui/src/main/java/ui/App.java
+++ b/hal-calc/src/main/java/hal/calc/CalcApp.java
@@ -1,4 +1,4 @@
-package ui;
+package hal.calc;
 
 import javafx.application.Application;
 import javafx.fxml.FXMLLoader;
@@ -11,11 +11,11 @@ import java.io.IOException;
 /**
  * JavaFX App
  */
-public class App extends Application {
+public class CalcApp extends Application {
 
     @Override
     public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
+        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("Calc.fxml"));
         Parent parent = fxmlLoader.load();
         stage.setScene(new Scene(parent));
         stage.show();
diff --git a/javafx-template/src/main/java/app/AppController.java b/hal-calc/src/main/java/hal/calc/CalcController.java
similarity index 97%
rename from javafx-template/src/main/java/app/AppController.java
rename to hal-calc/src/main/java/hal/calc/CalcController.java
index d47da69d76a9dbbfd1678a5d6787a9f53466b019..7c5cbd40d2c1481c897adc00f7f0d5e84c1d2222 100644
--- a/javafx-template/src/main/java/app/AppController.java
+++ b/hal-calc/src/main/java/hal/calc/CalcController.java
@@ -1,4 +1,4 @@
-package app;
+package hal.calc;
 
 import java.util.List;
 import java.util.function.BinaryOperator;
@@ -10,11 +10,11 @@ import javafx.scene.control.Label;
 import javafx.scene.control.Labeled;
 import javafx.scene.control.ListView;
 
-public class AppController {
+public class CalcController {
 
     private Calc calc;
 
-    public AppController() {
+    public CalcController() {
         calc = new Calc(0.0, 0.0, 0.0);
     }
 
diff --git a/modules-template/ui/src/main/resources/ui/App.fxml b/hal-calc/src/main/resources/hal/calc/Calc.fxml
similarity index 97%
rename from modules-template/ui/src/main/resources/ui/App.fxml
rename to hal-calc/src/main/resources/hal/calc/Calc.fxml
index ff280afc86fa85400985adee515112e7f73247eb..58221ae51bb01328d3a94ea23d36de387fcb8d33 100644
--- a/modules-template/ui/src/main/resources/ui/App.fxml
+++ b/hal-calc/src/main/resources/hal/calc/Calc.fxml
@@ -5,7 +5,7 @@
 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.ListView?>
 
-<GridPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.AppController"
+<GridPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="hal.calc.CalcController"
          alignment="CENTER" hgap="10.0" vgap="10.0" >
 
    <ListView fx:id="operandsView" prefHeight="80.0"
diff --git a/javafx-template/src/test/java/app/README.md b/hal-calc/src/test/java/hal/README.md
similarity index 100%
rename from javafx-template/src/test/java/app/README.md
rename to hal-calc/src/test/java/hal/README.md
diff --git a/packages-template/src/test/java/ui/AppTest.java b/hal-calc/src/test/java/hal/calc/AppTest.java
similarity index 97%
rename from packages-template/src/test/java/ui/AppTest.java
rename to hal-calc/src/test/java/hal/calc/AppTest.java
index 3c6e9917b8cd6957b969f3ea2dfd694df77a3f94..8a6a845882c65240b3b31c421d3d83333150bc3a 100644
--- a/packages-template/src/test/java/ui/AppTest.java
+++ b/hal-calc/src/test/java/hal/calc/AppTest.java
@@ -1,4 +1,4 @@
-package ui;
+package hal.calc;
 
 import javafx.fxml.FXMLLoader;
 import javafx.scene.Parent;
@@ -24,12 +24,12 @@ import org.testfx.matcher.control.LabeledMatchers;
  */
 public class AppTest extends ApplicationTest {
 
-    private AppController controller;
+    private CalcController controller;
     private Parent root;
 
     @Override
     public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
+        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("Calc.fxml"));
         root = fxmlLoader.load();
         controller = fxmlLoader.getController();
         stage.setScene(new Scene(root));
diff --git a/javafx-template/src/test/java/app/CalcTest.java b/hal-calc/src/test/java/hal/calc/CalcTest.java
similarity index 99%
rename from javafx-template/src/test/java/app/CalcTest.java
rename to hal-calc/src/test/java/hal/calc/CalcTest.java
index 150778d7a4ae829cbe155aeff824f279b2192294..38b01a856f66753b2d52ea455baad1585daa5d30 100644
--- a/javafx-template/src/test/java/app/CalcTest.java
+++ b/hal-calc/src/test/java/hal/calc/CalcTest.java
@@ -1,4 +1,4 @@
-package app;
+package hal.calc;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/javafx-template/src/main/java/app/App.java b/javafx-template/src/main/java/app/App.java
deleted file mode 100644
index b27d0955105d0cb84b7fa7ee21086953ac6391ca..0000000000000000000000000000000000000000
--- a/javafx-template/src/main/java/app/App.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package app;
-
-import javafx.application.Application;
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-import java.io.IOException;
-
-/**
- * JavaFX App
- */
-public class App extends Application {
-
-    @Override
-    public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
-        Parent parent = fxmlLoader.load();
-        stage.setScene(new Scene(parent));
-        stage.show();
-    }
-
-    public static void main(String[] args) {
-        launch();
-    }
-}
\ No newline at end of file
diff --git a/javafx-template/src/main/resources/app/App.fxml b/javafx-template/src/main/resources/app/App.fxml
deleted file mode 100644
index 7356474389da1d59fbedba33e5186b44f993c4f3..0000000000000000000000000000000000000000
--- a/javafx-template/src/main/resources/app/App.fxml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.layout.GridPane?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ListView?>
-
-<GridPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.AppController"
-         alignment="CENTER" hgap="10.0" vgap="10.0" >
-
-   <ListView fx:id="operandsView" prefHeight="80.0"
-      GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="4"/>
-   <Label text="" fx:id="operandView"
-      GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="4"/>
-
-   <!-- multi-line button label with XML entity for newline -->
-   <Button text="E&#10;n&#10;t&#10;e&#10;r" onAction="#handleEnter"
-      GridPane.rowIndex="2" GridPane.columnIndex="3" GridPane.rowSpan="3"/>
-
-   <Button text="7" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="0"/>
-   <Button text="8" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="1"/>
-   <Button text="9" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="2"/>
-   
-   <Button text="4" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="0"/>
-   <Button text="5" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="1"/>
-   <Button text="6" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="2"/>
-   
-   <Button text="1" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="0"/>
-   <Button text="2" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="1"/>
-   <Button text="3" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="2"/>
-   
-   <Button text="0" onAction="#handleDigit"
-      GridPane.rowIndex="5" GridPane.columnIndex="0"/>
-   <Button text="." onAction="#handlePoint"
-      GridPane.rowIndex="5" GridPane.columnIndex="1"/>
-   <Button text="C" onAction="#handleClear"
-      GridPane.rowIndex="5" GridPane.columnIndex="2"/>
-   <Button text="~" onAction="#handleSwap"
-      GridPane.rowIndex="5" GridPane.columnIndex="3"/>
-
-   <Button text="+" onAction="#handleOpAdd"
-      GridPane.rowIndex="6" GridPane.columnIndex="0"/>
-   <Button text="-" onAction="#handleOpSub"
-      GridPane.rowIndex="6" GridPane.columnIndex="1"/>
-   <Button text="*" onAction="#handleOpMult"
-      GridPane.rowIndex="6" GridPane.columnIndex="2"/>
-
-   <!-- TODO -->
-   <Button text="/"
-      GridPane.rowIndex="6" GridPane.columnIndex="3"/>
-   <Button text="√"
-      GridPane.rowIndex="7" GridPane.columnIndex="0"/>
-   <Button text="π"
-      GridPane.rowIndex="7" GridPane.columnIndex="1"/>
-</GridPane>
diff --git a/javafx-template/src/test/java/app/AppTest.java b/javafx-template/src/test/java/app/AppTest.java
deleted file mode 100644
index 209ebfc63ace75f7894281ca73ec606f61da4798..0000000000000000000000000000000000000000
--- a/javafx-template/src/test/java/app/AppTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package app;
-
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.scene.control.Label;
-import javafx.scene.control.ListView;
-import javafx.stage.Stage;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.stream.Stream;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.testfx.framework.junit5.ApplicationTest;
-import org.testfx.matcher.control.LabeledMatchers;
-
-/**
- * TestFX App test
- */
-public class AppTest extends ApplicationTest {
-
-    private AppController controller;
-    private Parent root;
-
-    @Override
-    public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
-        root = fxmlLoader.load();
-        controller = fxmlLoader.getController();
-        stage.setScene(new Scene(root));
-        stage.show();
-    }
-
-    public Parent getRootNode() {
-        return root;
-    }
-
-    private String enterLabel = """
-        E
-        n
-        t
-        e
-        r
-        """.stripTrailing();
-
-    private void click(String... labels) {
-        for (var label : labels) {
-            clickOn(LabeledMatchers.hasText(label));
-        }
-    }
-
-    private String getOperandString() {
-        return ((Label) getRootNode().lookup("#operandView")).getText();
-    }
-
-    private ListView<Double> getOperandsView() {
-        return (ListView<Double>) getRootNode().lookup("#operandsView");
-    }
-
-    private void checkView(double... operands) {
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], controller.getCalc().peekOperand(i), "Wrong value at #" + i + " of operand stack");
-        }
-        List<Double> viewItems = getOperandsView().getItems();
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], viewItems.get(viewItems.size() - i - 1), "Wrong value at #" + i + " of operands view");
-        }
-    }
-
-    private void checkView(String operandString, double... operands) {
-        Assertions.assertEquals(operandString, getOperandString());
-        checkView(operands);
-    }
-
-    // see https://www.baeldung.com/parameterized-tests-junit-5
-    // about @ParameterizedTest
-
-    @ParameterizedTest
-    @MethodSource
-    public void testClicksOperand(String labels, String operandString) {
-        for (var label : labels.split(" ")) {
-            click(label);
-        }
-        checkView(operandString);
-    }
-
-    private static Stream<Arguments> testClicksOperand() {
-        return Stream.of(
-            Arguments.of("2 7", "27"),
-            Arguments.of("2 7 .", "27."),
-            Arguments.of("2 7 . 5", "27.5"),
-            Arguments.of("2 7 . 5 .", "27.")
-        );
-    }
-    
-    @ParameterizedTest
-    @MethodSource
-    public void testClicksOperands(String labels, String operandsString) {
-        for (var label : labels.split(" ")) {
-            click(label.equals("\n") ? enterLabel : label);
-        }
-        checkView("", Stream.of(operandsString.split(" ")).mapToDouble(Double::valueOf).toArray());
-    }
-
-    private static Stream<Arguments> testClicksOperands() {
-        return Stream.of(
-            Arguments.of("2 7 . 5 \n", "27.5"),
-            Arguments.of("2 7 \n", "27.0"),
-            Arguments.of("2 \n 7 \n 5 \n", "5.0", "7.0", "2.0"),
-            Arguments.of("2 7 . \n", "27.0"),
-            Arguments.of("2 7 . 5 \n", "27.5"),
-            Arguments.of("2 \n 7 +", "9.0"),
-            Arguments.of("2 \n 7 -", "-5.0"),
-            Arguments.of("2 \n 7 *", "14.0"),
-            Arguments.of("6 \n 3 /", "2.0"),
-            Arguments.of("2 5 \n √", "5.0")
-        );
-    }
-
-    @Test
-    public void testPi() {
-        click("π");
-        checkView("", Math.PI);
-    }
-}
diff --git a/modules-template/.gitignore b/modules-template/.gitignore
deleted file mode 100644
index f06b4660049b36b357966d36fa5581276fb4cec4..0000000000000000000000000000000000000000
--- a/modules-template/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# ignore maven build folder
-target/
-
-# pom-derived eclipse jdt files
-.project
-.classpath
-org.eclipse.*.prefs
diff --git a/modules-template/core/pom.xml b/modules-template/core/pom.xml
deleted file mode 100644
index abaca3ef9701d5cdeea0f847482f8c86d62b5ca2..0000000000000000000000000000000000000000
--- a/modules-template/core/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>it1901</groupId>
-    <artifactId>modules-core</artifactId>
-
-    <parent>
-        <groupId>it1901</groupId>
-        <artifactId>modules-template</artifactId>
-        <version>0.0.1-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-
-    <dependencies>
-
-        <!-- junit testing with jupiter -->
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-engine</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-params</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-        		<artifactId>maven-surefire-plugin</artifactId>
-	        </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/modules-template/core/src/main/java/core/Calc.java b/modules-template/core/src/main/java/core/Calc.java
deleted file mode 100644
index 9b0f4c976eb8e418641811e6d4c56d2d5ce0fdb5..0000000000000000000000000000000000000000
--- a/modules-template/core/src/main/java/core/Calc.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package core;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.BinaryOperator;
-import java.util.function.UnaryOperator;
-
-public class Calc {
-    
-    private final List<Double> operandStack;
-
-    public Calc(double... operands) {
-        operandStack = new ArrayList<>(operands.length + 2);
-        for (var d : operands) {
-            operandStack.add(d);
-        }
-    }
-
-    /**
-     * @return the number of operands on the stack
-     */
-    public int getOperandCount() {
-        return operandStack.size();
-    }
-
-    /**
-     * Pushes a new operand onto top of the stack.
-     * @param d the new operand
-     */
-    public void pushOperand(double d) {
-        operandStack.add(d);
-    }
-
-    /**
-     * @param n the place (from the top) to peek
-     * @return the n'th operand from the top
-     * @throws IllegalArgumentException if n is larger than the operand count
-     */
-    public double peekOperand(int n) {
-        if (n >= getOperandCount()) {
-            throw new IllegalArgumentException("Cannot peek at position " + n + " when the operand count is " + getOperandCount());
-        }
-        return operandStack.get(getOperandCount() - n - 1);
-    }
-
-    /**
-     * @return the top operand
-     */
-    public double peekOperand() {
-        return peekOperand(0);
-    }
-
-    /**
-     * Removes and returns the top operand.
-     * @return the top operand
-     * @throws IllegalStateException if the stack is empty
-     */
-    public double popOperand() {
-        if (getOperandCount() == 0) {
-            throw new IllegalStateException("Cannot pop from an empty stack");
-        }
-        return operandStack.remove(operandStack.size() - 1);
-    }
-    
-    /**
-     * Performs the provided operation in the top operand, and
-     * replaces it with the result.
-     * @param op the operation to perform
-     * @return the result of performing the operation
-     * @throws IllegalStateException if the operand stack is empty
-     */
-    public double performOperation(UnaryOperator<Double> op) throws IllegalStateException {
-        // TODO
-        return 0.0;
-    }
-
-    /**
-     * Performs the provided operation in the two topmost operands, and
-     * replaces them with the result.
-     * @param op the operation to perform
-     * @return the result of performing the operation
-     * @throws IllegalStateException if the operand count is less than two
-     */
-    public double performOperation(BinaryOperator<Double> op) throws IllegalStateException {
-        if (getOperandCount() < 2) {
-            throw new IllegalStateException("Too few operands (" + getOperandCount() + ") on the stack");
-        }
-        var op1 = popOperand();
-        var op2 = popOperand();
-        var result = op.apply(op1, op2);
-        pushOperand(result);
-        return result;
-    }
-
-    /**
-     * Swaps the two topmost operands.
-     */
-    public void swap() {
-        // TODO
-    }
-
-    /**
-     * Duplicates the top operand.
-     */
-    public void dup() {
-        // TODO
-    }
-}
\ No newline at end of file
diff --git a/modules-template/core/src/test/java/core/CalcTest.java b/modules-template/core/src/test/java/core/CalcTest.java
deleted file mode 100644
index 11df4696f42eb88a32ac9d21ae65720105f3739c..0000000000000000000000000000000000000000
--- a/modules-template/core/src/test/java/core/CalcTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package core;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class CalcTest {
-
-    private static void checkCalc(Calc calc, double... operands) {
-        Assertions.assertEquals(operands.length, calc.getOperandCount(), "Wrong operand count");
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], calc.peekOperand(i), "Wrong value at #" + i + " of operand stack");
-        }
-    }
-
-    @Test
-    public void testCalc() {
-        checkCalc(new Calc());
-        checkCalc(new Calc(1.0), 1.0);
-        checkCalc(new Calc(3.14, 1.0), 1.0, 3.14);
-    }
-
-    @Test
-    public void testPushOperand() {
-        Calc calc = new Calc();
-        calc.pushOperand(1.0);
-        checkCalc(calc, 1.0);
-        calc.pushOperand(3.14);
-        checkCalc(calc, 3.14, 1.0);
-    }
-
-    @Test
-    public void testPeekOperand() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.peekOperand());
-        Assertions.assertThrows(IllegalArgumentException.class, () -> new Calc().peekOperand());
-    }
-
-    @Test
-    public void testPeekOperandN() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.peekOperand(0));
-        Assertions.assertEquals(1.0, calc.peekOperand(1));
-        Assertions.assertThrows(IllegalArgumentException.class, () -> calc.peekOperand(2));
-    }
-
-    @Test
-    public void testPopOperand() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.popOperand());
-        checkCalc(calc, 1.0);
-        Assertions.assertEquals(1.0, calc.popOperand());
-        checkCalc(calc);
-    }
-
-    @Test
-    public void testPopOperand_emptyStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().popOperand());
-    }
-
-    @Test
-    public void testPerformOperation1() {
-        Calc calc = new Calc(1.0);
-        Assertions.assertEquals(-1.0, calc.performOperation(n -> -n));
-        checkCalc(calc, -1.0);
-    }
-
-    @Test
-    public void testPerformOperation1_emptyOperandStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().performOperation(n -> -n));
-    }
-
-
-    @Test
-    public void testPerformOperation2() {
-        Calc calc = new Calc(1.0, 3.0);
-        Assertions.assertEquals(-2.0, calc.performOperation((n1, n2) -> n1 - n2));
-        checkCalc(calc, -2.0);
-    }
-
-    @Test
-    public void testPerformOperation2_lessThanTwoOperands() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc(1.0).performOperation((n1, n2) -> n1 - n2));
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().performOperation((n1, n2) -> n1 - n2));
-    }
-
-    @Test
-    public void testSwap() {
-        Calc calc = new Calc(1.0, 3.14);
-        checkCalc(calc, 3.14, 1.0);
-        calc.swap();
-        checkCalc(calc, 1.0, 3.14);
-        calc.swap();
-        checkCalc(calc, 3.14, 1.0);
-    }
-
-    @Test
-    public void testSwap_lessThanTwoOperands() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc(1.0).swap());
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().swap());
-    }
-
-    @Test
-    public void testDup() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.popOperand());
-        checkCalc(calc, 1.0);
-        Assertions.assertEquals(1.0, calc.popOperand());
-        checkCalc(calc);
-    }
-
-    @Test
-    public void testDup_emptyOperandStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().dup());
-    }
-}
diff --git a/modules-template/pom.xml b/modules-template/pom.xml
deleted file mode 100644
index f0e8d587a352450f92fbbe56fa7e86b57cf41b60..0000000000000000000000000000000000000000
--- a/modules-template/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>it1901</groupId>
-    <artifactId>modules-template</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <packaging>pom</packaging>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <maven.compiler.source>16</maven.compiler.source>
-        <maven.compiler.target>16</maven.compiler.target>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.junit.jupiter</groupId>
-                <artifactId>junit-jupiter-api</artifactId>
-                <version>5.7.2</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.junit.jupiter</groupId>
-                <artifactId>junit-jupiter-engine</artifactId>
-                <version>5.7.2</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.junit.jupiter</groupId>
-                <artifactId>junit-jupiter-params</artifactId>
-                <version>5.7.2</version>
-                <scope>test</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-compiler-plugin</artifactId>
-                    <version>3.8.1</version>
-                    <configuration>
-                        <release>16</release>
-                    </configuration>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <version>3.0.0-M5</version>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-
-    <modules>
-        <module>core</module>
-        <module>ui</module>
-    </modules>
-</project>
diff --git a/modules-template/ui/pom.xml b/modules-template/ui/pom.xml
deleted file mode 100644
index 45f4dec3086954adb442313d77ae2edc2c12da57..0000000000000000000000000000000000000000
--- a/modules-template/ui/pom.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>it1901</groupId>
-    <artifactId>modules-ui</artifactId>
-
-    <parent>
-        <groupId>it1901</groupId>
-        <artifactId>modules-template</artifactId>
-        <version>0.0.1-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-
-    <dependencies>
-
-        <dependency>
-            <groupId>it1901</groupId>
-            <artifactId>modules-core</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-        </dependency>
-
-        <!-- javafx -->
-        <dependency>
-            <groupId>org.openjfx</groupId>
-            <artifactId>javafx-controls</artifactId>
-            <version>16</version>
-        </dependency>
-        <dependency>
-            <groupId>org.openjfx</groupId>
-            <artifactId>javafx-fxml</artifactId>
-            <version>16</version>
-        </dependency>
-
-        <!-- junit testing with jupiter -->
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-engine</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-params</artifactId>
-        </dependency>
-
-        <!-- test javafx with TextFX -->
-		<dependency>
-			<groupId>org.testfx</groupId>
-			<artifactId>testfx-core</artifactId>
-			<version>4.0.16-alpha</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.testfx</groupId>
-			<artifactId>testfx-junit5</artifactId>
-			<version>4.0.16-alpha</version>
-			<scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest</artifactId>
-            <version>2.2</version>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-        		<artifactId>maven-surefire-plugin</artifactId>
-	        </plugin>
-
-            <plugin>
-                <groupId>org.openjfx</groupId>
-                <artifactId>javafx-maven-plugin</artifactId>
-                <version>0.0.6</version>
-                <executions>
-                    <execution>
-                        <!-- Default configuration for running -->
-                        <!-- Usage: mvn clean javafx:run -->
-                        <id>default-cli</id>
-                        <configuration>
-                            <mainClass>ui.App</mainClass>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/modules-template/ui/src/main/java/ui/AppController.java b/modules-template/ui/src/main/java/ui/AppController.java
deleted file mode 100644
index 2002d483fceb57bf7da4d4b65f04ee9a8b3f81b1..0000000000000000000000000000000000000000
--- a/modules-template/ui/src/main/java/ui/AppController.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package ui;
-
-import core.Calc;
-
-import java.util.List;
-import java.util.function.BinaryOperator;
-import java.util.function.UnaryOperator;
-
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.control.Labeled;
-import javafx.scene.control.ListView;
-
-public class AppController {
-
-    private Calc calc;
-
-    public AppController() {
-        calc = new Calc(0.0, 0.0, 0.0);
-    }
-
-    public Calc getCalc() {
-        return calc;
-    }
-
-    public void setCalc(Calc calc) {
-        this.calc = calc;
-        updateOperandsView();
-    }
-
-    @FXML
-    private ListView<Double> operandsView;
-
-    @FXML
-    private Label operandView;
-
-    @FXML
-    void initialize() {
-        updateOperandsView();
-    }
-
-    private void updateOperandsView() {
-        List<Double> operands = operandsView.getItems();
-        operands.clear();
-        int elementCount = Math.min(calc.getOperandCount(), 3);
-        for (int i = 0; i < elementCount; i++) {
-            operands.add(calc.peekOperand(elementCount - i - 1));
-        }
-    }
-
-    private String getOperandString() {
-        return operandView.getText();
-    }
-
-    private boolean hasOperand() {
-        return ! getOperandString().isBlank();
-    }
-
-    private double getOperand() {
-        return Double.valueOf(operandView.getText());
-    }
-    
-    private void setOperand(String operandString) {
-        operandView.setText(operandString);
-    }
-
-    @FXML
-    void handleEnter() {
-        if (hasOperand()) {
-            calc.pushOperand(getOperand());
-        } else {
-            calc.dup();
-        }
-        setOperand("");
-        updateOperandsView();
-    }
-
-    private void appendToOperand(String s) {
-        // TODO
-    }
-
-    @FXML
-    void handleDigit(ActionEvent ae) {
-        if (ae.getSource() instanceof Labeled l) {
-            // TODO append button label to operand
-        }
-    }
-
-    @FXML
-    void handlePoint() {
-        var operandString = getOperandString();
-        if (operandString.contains(".")) {
-            // TODO remove characters after point
-        } else {
-            // TODO append point
-        }
-    }
-
-    @FXML
-    void handleClear() {
-        // TODO clear operand
-    }
-
-    @FXML
-    void handleSwap() {
-        // TODO clear operand
-    }
-
-    private void performOperation(UnaryOperator<Double> op) {
-        // TODO
-    }
-
-    private void performOperation(boolean swap, BinaryOperator<Double> op) {
-        if (hasOperand()) {
-            // TODO push operand first
-        }
-        // TODO perform operation, but swap first if needed
-    }
-
-    @FXML
-    void handleOpAdd() {
-        // TODO
-    }
-
-    @FXML
-    void handleOpSub() {
-        // TODO
-    }
-
-    @FXML
-    void handleOpMult() {
-        // TODO
-    }
-}
diff --git a/modules-template/ui/src/test/java/ui/AppTest.java b/modules-template/ui/src/test/java/ui/AppTest.java
deleted file mode 100644
index 3c6e9917b8cd6957b969f3ea2dfd694df77a3f94..0000000000000000000000000000000000000000
--- a/modules-template/ui/src/test/java/ui/AppTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package ui;
-
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.scene.control.Label;
-import javafx.scene.control.ListView;
-import javafx.stage.Stage;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.stream.Stream;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.testfx.framework.junit5.ApplicationTest;
-import org.testfx.matcher.control.LabeledMatchers;
-
-/**
- * TestFX App test
- */
-public class AppTest extends ApplicationTest {
-
-    private AppController controller;
-    private Parent root;
-
-    @Override
-    public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
-        root = fxmlLoader.load();
-        controller = fxmlLoader.getController();
-        stage.setScene(new Scene(root));
-        stage.show();
-    }
-
-    public Parent getRootNode() {
-        return root;
-    }
-
-    private String enterLabel = """
-        E
-        n
-        t
-        e
-        r
-        """.stripTrailing();
-
-    private void click(String... labels) {
-        for (var label : labels) {
-            clickOn(LabeledMatchers.hasText(label));
-        }
-    }
-
-    private String getOperandString() {
-        return ((Label) getRootNode().lookup("#operandView")).getText();
-    }
-
-    private ListView<Double> getOperandsView() {
-        return (ListView<Double>) getRootNode().lookup("#operandsView");
-    }
-
-    private void checkView(double... operands) {
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], controller.getCalc().peekOperand(i), "Wrong value at #" + i + " of operand stack");
-        }
-        List<Double> viewItems = getOperandsView().getItems();
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], viewItems.get(viewItems.size() - i - 1), "Wrong value at #" + i + " of operands view");
-        }
-    }
-
-    private void checkView(String operandString, double... operands) {
-        Assertions.assertEquals(operandString, getOperandString());
-        checkView(operands);
-    }
-
-    // see https://www.baeldung.com/parameterized-tests-junit-5
-    // about @ParameterizedTest
-
-    @ParameterizedTest
-    @MethodSource
-    public void testClicksOperand(String labels, String operandString) {
-        for (var label : labels.split(" ")) {
-            click(label);
-        }
-        checkView(operandString);
-    }
-
-    private static Stream<Arguments> testClicksOperand() {
-        return Stream.of(
-            Arguments.of("2 7", "27"),
-            Arguments.of("2 7 .", "27."),
-            Arguments.of("2 7 . 5", "27.5"),
-            Arguments.of("2 7 . 5 .", "27.")
-        );
-    }
-    
-    @ParameterizedTest
-    @MethodSource
-    public void testClicksOperands(String labels, String operandsString) {
-        for (var label : labels.split(" ")) {
-            click(label.equals("\n") ? enterLabel : label);
-        }
-        checkView("", Stream.of(operandsString.split(" ")).mapToDouble(Double::valueOf).toArray());
-    }
-
-    private static Stream<Arguments> testClicksOperands() {
-        return Stream.of(
-            Arguments.of("2 7 . 5 \n", "27.5"),
-            Arguments.of("2 7 \n", "27.0"),
-            Arguments.of("2 \n 7 \n 5 \n", "5.0", "7.0", "2.0"),
-            Arguments.of("2 7 . \n", "27.0"),
-            Arguments.of("2 7 . 5 \n", "27.5"),
-            Arguments.of("2 \n 7 +", "9.0"),
-            Arguments.of("2 \n 7 -", "-5.0"),
-            Arguments.of("2 \n 7 *", "14.0"),
-            Arguments.of("6 \n 3 /", "2.0"),
-            Arguments.of("2 5 \n √", "5.0")
-        );
-    }
-
-    @Test
-    public void testPi() {
-        click("π");
-        checkView("", Math.PI);
-    }
-}
diff --git a/modules-template/ui/src/test/java/ui/README.md b/modules-template/ui/src/test/java/ui/README.md
deleted file mode 100644
index 0cc59802a04720e2dfddaa5c14c029328b91ef33..0000000000000000000000000000000000000000
--- a/modules-template/ui/src/test/java/ui/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Tests for the RPN calculator
-
-This folder/package contains tests based on TestFX for the RPN Calculator (currently only one test class).
-
-As can be seen when launching, the app contains a list (top) showing the operands
-(topmost operand at the bottom), a text field (below list, initially empty) for a new operand and
-the buttons for digits, enter, decimal point, operations etc.
-
-## What is tested
-
-The tests simulate clicks on the buttons and checks that the underlying Calc object,
-the list (a view of the Calc object's operand stack) and the text field are updated as expected.
-E.g. if you click buttons `2 3 . 5` the string `23.5` should be shown,
-while the list is not affected. If you then click `enter`, the text field should be emptied, the operand stack should have `23.5` at the top and the list should have `23.5` at the bottom 
-(logically the top of the operand stack).
-
-Below are the specific cases that are tested.
-
-buttons to click `=>` text field content:
-
-- `2 7` => `27`
-- `2 7 .` => `27.`
-- `2 7 . 5` => `27.5`
-- `2 7 . 5 .` => `27.` (cut at decimal point)
-
-buttons to click `=>` operand stack/list content (from the bottom):
-
-- `2 7 . 5 enter"` => `27.5`
-- `2 7 enter` => `27.0"`
-- `2 enter 7 enter 5 enter` => `5.0 7.0 2.0` 
-- `2 7 . enter` => `27.0` 
-- `2 7 . 5 enter` => `27.5` 
-- `2 enter 7 +` => `9.0` 
-- `2 enter 7 -` => `-5.0` 
-- `2 enter 7 *` => `14.0` 
-- `6 enter 3 /` => `2.0` 
-- `2 5 enter √` => `5.0` 
-- `π` => `3.1415...` (the value of the `Math.PI` constant)
diff --git a/packages-template/.gitignore b/packages-template/.gitignore
deleted file mode 100644
index f06b4660049b36b357966d36fa5581276fb4cec4..0000000000000000000000000000000000000000
--- a/packages-template/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# ignore maven build folder
-target/
-
-# pom-derived eclipse jdt files
-.project
-.classpath
-org.eclipse.*.prefs
diff --git a/packages-template/pom.xml b/packages-template/pom.xml
deleted file mode 100644
index ccbf72dbe2307556270dc7c6dd6d2d6108431df5..0000000000000000000000000000000000000000
--- a/packages-template/pom.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>it1901</groupId>
-    <artifactId>packages-template</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <maven.compiler.source>16</maven.compiler.source>
-        <maven.compiler.target>16</maven.compiler.target>
-    </properties>
-
-    <dependencies>
-
-        <!-- javafx -->
-        <dependency>
-            <groupId>org.openjfx</groupId>
-            <artifactId>javafx-controls</artifactId>
-            <version>16</version>
-        </dependency>
-        <dependency>
-            <groupId>org.openjfx</groupId>
-            <artifactId>javafx-fxml</artifactId>
-            <version>16</version>
-        </dependency>
-
-        <!-- junit testing with jupiter -->
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-api</artifactId>
-            <version>5.7.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-engine</artifactId>
-            <version>5.7.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-params</artifactId>
-            <version>5.7.2</version>
-            <scope>test</scope>
-        </dependency>
-
-        <!-- test javafx with TextFX -->
-		<dependency>
-			<groupId>org.testfx</groupId>
-			<artifactId>testfx-core</artifactId>
-			<version>4.0.16-alpha</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.testfx</groupId>
-			<artifactId>testfx-junit5</artifactId>
-			<version>4.0.16-alpha</version>
-			<scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest</artifactId>
-            <version>2.2</version>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.8.1</version>
-                <configuration>
-                    <release>16</release>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-        		<artifactId>maven-surefire-plugin</artifactId>
-		        <version>3.0.0-M5</version>
-	        </plugin>
-
-            <plugin>
-                <groupId>org.openjfx</groupId>
-                <artifactId>javafx-maven-plugin</artifactId>
-                <version>0.0.6</version>
-                <executions>
-                    <execution>
-                        <!-- Default configuration for running -->
-                        <!-- Usage: mvn clean javafx:run -->
-                        <id>default-cli</id>
-                        <configuration>
-                            <mainClass>ui.App</mainClass>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/packages-template/src/main/java/core/Calc.java b/packages-template/src/main/java/core/Calc.java
deleted file mode 100644
index 9b0f4c976eb8e418641811e6d4c56d2d5ce0fdb5..0000000000000000000000000000000000000000
--- a/packages-template/src/main/java/core/Calc.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package core;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.BinaryOperator;
-import java.util.function.UnaryOperator;
-
-public class Calc {
-    
-    private final List<Double> operandStack;
-
-    public Calc(double... operands) {
-        operandStack = new ArrayList<>(operands.length + 2);
-        for (var d : operands) {
-            operandStack.add(d);
-        }
-    }
-
-    /**
-     * @return the number of operands on the stack
-     */
-    public int getOperandCount() {
-        return operandStack.size();
-    }
-
-    /**
-     * Pushes a new operand onto top of the stack.
-     * @param d the new operand
-     */
-    public void pushOperand(double d) {
-        operandStack.add(d);
-    }
-
-    /**
-     * @param n the place (from the top) to peek
-     * @return the n'th operand from the top
-     * @throws IllegalArgumentException if n is larger than the operand count
-     */
-    public double peekOperand(int n) {
-        if (n >= getOperandCount()) {
-            throw new IllegalArgumentException("Cannot peek at position " + n + " when the operand count is " + getOperandCount());
-        }
-        return operandStack.get(getOperandCount() - n - 1);
-    }
-
-    /**
-     * @return the top operand
-     */
-    public double peekOperand() {
-        return peekOperand(0);
-    }
-
-    /**
-     * Removes and returns the top operand.
-     * @return the top operand
-     * @throws IllegalStateException if the stack is empty
-     */
-    public double popOperand() {
-        if (getOperandCount() == 0) {
-            throw new IllegalStateException("Cannot pop from an empty stack");
-        }
-        return operandStack.remove(operandStack.size() - 1);
-    }
-    
-    /**
-     * Performs the provided operation in the top operand, and
-     * replaces it with the result.
-     * @param op the operation to perform
-     * @return the result of performing the operation
-     * @throws IllegalStateException if the operand stack is empty
-     */
-    public double performOperation(UnaryOperator<Double> op) throws IllegalStateException {
-        // TODO
-        return 0.0;
-    }
-
-    /**
-     * Performs the provided operation in the two topmost operands, and
-     * replaces them with the result.
-     * @param op the operation to perform
-     * @return the result of performing the operation
-     * @throws IllegalStateException if the operand count is less than two
-     */
-    public double performOperation(BinaryOperator<Double> op) throws IllegalStateException {
-        if (getOperandCount() < 2) {
-            throw new IllegalStateException("Too few operands (" + getOperandCount() + ") on the stack");
-        }
-        var op1 = popOperand();
-        var op2 = popOperand();
-        var result = op.apply(op1, op2);
-        pushOperand(result);
-        return result;
-    }
-
-    /**
-     * Swaps the two topmost operands.
-     */
-    public void swap() {
-        // TODO
-    }
-
-    /**
-     * Duplicates the top operand.
-     */
-    public void dup() {
-        // TODO
-    }
-}
\ No newline at end of file
diff --git a/packages-template/src/main/java/ui/App.java b/packages-template/src/main/java/ui/App.java
deleted file mode 100644
index acead69e8eac41010e6843e4529e834868b979d3..0000000000000000000000000000000000000000
--- a/packages-template/src/main/java/ui/App.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package ui;
-
-import javafx.application.Application;
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-import java.io.IOException;
-
-/**
- * JavaFX App
- */
-public class App extends Application {
-
-    @Override
-    public void start(Stage stage) throws IOException {
-        FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("App.fxml"));
-        Parent parent = fxmlLoader.load();
-        stage.setScene(new Scene(parent));
-        stage.show();
-    }
-
-    public static void main(String[] args) {
-        launch();
-    }
-}
\ No newline at end of file
diff --git a/packages-template/src/main/java/ui/AppController.java b/packages-template/src/main/java/ui/AppController.java
deleted file mode 100644
index 2002d483fceb57bf7da4d4b65f04ee9a8b3f81b1..0000000000000000000000000000000000000000
--- a/packages-template/src/main/java/ui/AppController.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package ui;
-
-import core.Calc;
-
-import java.util.List;
-import java.util.function.BinaryOperator;
-import java.util.function.UnaryOperator;
-
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.control.Labeled;
-import javafx.scene.control.ListView;
-
-public class AppController {
-
-    private Calc calc;
-
-    public AppController() {
-        calc = new Calc(0.0, 0.0, 0.0);
-    }
-
-    public Calc getCalc() {
-        return calc;
-    }
-
-    public void setCalc(Calc calc) {
-        this.calc = calc;
-        updateOperandsView();
-    }
-
-    @FXML
-    private ListView<Double> operandsView;
-
-    @FXML
-    private Label operandView;
-
-    @FXML
-    void initialize() {
-        updateOperandsView();
-    }
-
-    private void updateOperandsView() {
-        List<Double> operands = operandsView.getItems();
-        operands.clear();
-        int elementCount = Math.min(calc.getOperandCount(), 3);
-        for (int i = 0; i < elementCount; i++) {
-            operands.add(calc.peekOperand(elementCount - i - 1));
-        }
-    }
-
-    private String getOperandString() {
-        return operandView.getText();
-    }
-
-    private boolean hasOperand() {
-        return ! getOperandString().isBlank();
-    }
-
-    private double getOperand() {
-        return Double.valueOf(operandView.getText());
-    }
-    
-    private void setOperand(String operandString) {
-        operandView.setText(operandString);
-    }
-
-    @FXML
-    void handleEnter() {
-        if (hasOperand()) {
-            calc.pushOperand(getOperand());
-        } else {
-            calc.dup();
-        }
-        setOperand("");
-        updateOperandsView();
-    }
-
-    private void appendToOperand(String s) {
-        // TODO
-    }
-
-    @FXML
-    void handleDigit(ActionEvent ae) {
-        if (ae.getSource() instanceof Labeled l) {
-            // TODO append button label to operand
-        }
-    }
-
-    @FXML
-    void handlePoint() {
-        var operandString = getOperandString();
-        if (operandString.contains(".")) {
-            // TODO remove characters after point
-        } else {
-            // TODO append point
-        }
-    }
-
-    @FXML
-    void handleClear() {
-        // TODO clear operand
-    }
-
-    @FXML
-    void handleSwap() {
-        // TODO clear operand
-    }
-
-    private void performOperation(UnaryOperator<Double> op) {
-        // TODO
-    }
-
-    private void performOperation(boolean swap, BinaryOperator<Double> op) {
-        if (hasOperand()) {
-            // TODO push operand first
-        }
-        // TODO perform operation, but swap first if needed
-    }
-
-    @FXML
-    void handleOpAdd() {
-        // TODO
-    }
-
-    @FXML
-    void handleOpSub() {
-        // TODO
-    }
-
-    @FXML
-    void handleOpMult() {
-        // TODO
-    }
-}
diff --git a/packages-template/src/main/resources/ui/App.fxml b/packages-template/src/main/resources/ui/App.fxml
deleted file mode 100644
index ff280afc86fa85400985adee515112e7f73247eb..0000000000000000000000000000000000000000
--- a/packages-template/src/main/resources/ui/App.fxml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.layout.GridPane?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ListView?>
-
-<GridPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.AppController"
-         alignment="CENTER" hgap="10.0" vgap="10.0" >
-
-   <ListView fx:id="operandsView" prefHeight="80.0"
-      GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="4"/>
-   <Label text="" fx:id="operandView"
-      GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="4"/>
-
-   <!-- multi-line button label with XML entity for newline -->
-   <Button text="E&#10;n&#10;t&#10;e&#10;r" onAction="#handleEnter"
-      GridPane.rowIndex="2" GridPane.columnIndex="3" GridPane.rowSpan="3"/>
-
-   <Button text="7" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="0"/>
-   <Button text="8" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="1"/>
-   <Button text="9" onAction="#handleDigit"
-      GridPane.rowIndex="2" GridPane.columnIndex="2"/>
-   
-   <Button text="4" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="0"/>
-   <Button text="5" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="1"/>
-   <Button text="6" onAction="#handleDigit"
-      GridPane.rowIndex="3" GridPane.columnIndex="2"/>
-   
-   <Button text="1" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="0"/>
-   <Button text="2" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="1"/>
-   <Button text="3" onAction="#handleDigit"
-      GridPane.rowIndex="4" GridPane.columnIndex="2"/>
-   
-   <Button text="0" onAction="#handleDigit"
-      GridPane.rowIndex="5" GridPane.columnIndex="0"/>
-   <Button text="." onAction="#handlePoint"
-      GridPane.rowIndex="5" GridPane.columnIndex="1"/>
-   <Button text="C" onAction="#handleClear"
-      GridPane.rowIndex="5" GridPane.columnIndex="2"/>
-   <Button text="~" onAction="#handleSwap"
-      GridPane.rowIndex="5" GridPane.columnIndex="3"/>
-
-   <Button text="+" onAction="#handleOpAdd"
-      GridPane.rowIndex="6" GridPane.columnIndex="0"/>
-   <Button text="-" onAction="#handleOpSub"
-      GridPane.rowIndex="6" GridPane.columnIndex="1"/>
-   <Button text="*" onAction="#handleOpMult"
-      GridPane.rowIndex="6" GridPane.columnIndex="2"/>
-
-   <!-- TODO -->
-   <Button text="/"
-      GridPane.rowIndex="6" GridPane.columnIndex="3"/>
-   <Button text="√"
-      GridPane.rowIndex="7" GridPane.columnIndex="0"/>
-   <Button text="π"
-      GridPane.rowIndex="7" GridPane.columnIndex="1"/>
-</GridPane>
diff --git a/packages-template/src/test/java/core/CalcTest.java b/packages-template/src/test/java/core/CalcTest.java
deleted file mode 100644
index 11df4696f42eb88a32ac9d21ae65720105f3739c..0000000000000000000000000000000000000000
--- a/packages-template/src/test/java/core/CalcTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package core;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class CalcTest {
-
-    private static void checkCalc(Calc calc, double... operands) {
-        Assertions.assertEquals(operands.length, calc.getOperandCount(), "Wrong operand count");
-        for (int i = 0; i < operands.length; i++) {
-            Assertions.assertEquals(operands[i], calc.peekOperand(i), "Wrong value at #" + i + " of operand stack");
-        }
-    }
-
-    @Test
-    public void testCalc() {
-        checkCalc(new Calc());
-        checkCalc(new Calc(1.0), 1.0);
-        checkCalc(new Calc(3.14, 1.0), 1.0, 3.14);
-    }
-
-    @Test
-    public void testPushOperand() {
-        Calc calc = new Calc();
-        calc.pushOperand(1.0);
-        checkCalc(calc, 1.0);
-        calc.pushOperand(3.14);
-        checkCalc(calc, 3.14, 1.0);
-    }
-
-    @Test
-    public void testPeekOperand() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.peekOperand());
-        Assertions.assertThrows(IllegalArgumentException.class, () -> new Calc().peekOperand());
-    }
-
-    @Test
-    public void testPeekOperandN() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.peekOperand(0));
-        Assertions.assertEquals(1.0, calc.peekOperand(1));
-        Assertions.assertThrows(IllegalArgumentException.class, () -> calc.peekOperand(2));
-    }
-
-    @Test
-    public void testPopOperand() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.popOperand());
-        checkCalc(calc, 1.0);
-        Assertions.assertEquals(1.0, calc.popOperand());
-        checkCalc(calc);
-    }
-
-    @Test
-    public void testPopOperand_emptyStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().popOperand());
-    }
-
-    @Test
-    public void testPerformOperation1() {
-        Calc calc = new Calc(1.0);
-        Assertions.assertEquals(-1.0, calc.performOperation(n -> -n));
-        checkCalc(calc, -1.0);
-    }
-
-    @Test
-    public void testPerformOperation1_emptyOperandStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().performOperation(n -> -n));
-    }
-
-
-    @Test
-    public void testPerformOperation2() {
-        Calc calc = new Calc(1.0, 3.0);
-        Assertions.assertEquals(-2.0, calc.performOperation((n1, n2) -> n1 - n2));
-        checkCalc(calc, -2.0);
-    }
-
-    @Test
-    public void testPerformOperation2_lessThanTwoOperands() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc(1.0).performOperation((n1, n2) -> n1 - n2));
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().performOperation((n1, n2) -> n1 - n2));
-    }
-
-    @Test
-    public void testSwap() {
-        Calc calc = new Calc(1.0, 3.14);
-        checkCalc(calc, 3.14, 1.0);
-        calc.swap();
-        checkCalc(calc, 1.0, 3.14);
-        calc.swap();
-        checkCalc(calc, 3.14, 1.0);
-    }
-
-    @Test
-    public void testSwap_lessThanTwoOperands() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc(1.0).swap());
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().swap());
-    }
-
-    @Test
-    public void testDup() {
-        Calc calc = new Calc(1.0, 3.14);
-        Assertions.assertEquals(3.14, calc.popOperand());
-        checkCalc(calc, 1.0);
-        Assertions.assertEquals(1.0, calc.popOperand());
-        checkCalc(calc);
-    }
-
-    @Test
-    public void testDup_emptyOperandStack() {
-        Assertions.assertThrows(IllegalStateException.class, () -> new Calc().dup());
-    }
-}
diff --git a/packages-template/src/test/java/ui/README.md b/packages-template/src/test/java/ui/README.md
deleted file mode 100644
index 0cc59802a04720e2dfddaa5c14c029328b91ef33..0000000000000000000000000000000000000000
--- a/packages-template/src/test/java/ui/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Tests for the RPN calculator
-
-This folder/package contains tests based on TestFX for the RPN Calculator (currently only one test class).
-
-As can be seen when launching, the app contains a list (top) showing the operands
-(topmost operand at the bottom), a text field (below list, initially empty) for a new operand and
-the buttons for digits, enter, decimal point, operations etc.
-
-## What is tested
-
-The tests simulate clicks on the buttons and checks that the underlying Calc object,
-the list (a view of the Calc object's operand stack) and the text field are updated as expected.
-E.g. if you click buttons `2 3 . 5` the string `23.5` should be shown,
-while the list is not affected. If you then click `enter`, the text field should be emptied, the operand stack should have `23.5` at the top and the list should have `23.5` at the bottom 
-(logically the top of the operand stack).
-
-Below are the specific cases that are tested.
-
-buttons to click `=>` text field content:
-
-- `2 7` => `27`
-- `2 7 .` => `27.`
-- `2 7 . 5` => `27.5`
-- `2 7 . 5 .` => `27.` (cut at decimal point)
-
-buttons to click `=>` operand stack/list content (from the bottom):
-
-- `2 7 . 5 enter"` => `27.5`
-- `2 7 enter` => `27.0"`
-- `2 enter 7 enter 5 enter` => `5.0 7.0 2.0` 
-- `2 7 . enter` => `27.0` 
-- `2 7 . 5 enter` => `27.5` 
-- `2 enter 7 +` => `9.0` 
-- `2 enter 7 -` => `-5.0` 
-- `2 enter 7 *` => `14.0` 
-- `6 enter 3 /` => `2.0` 
-- `2 5 enter √` => `5.0` 
-- `π` => `3.1415...` (the value of the `Math.PI` constant)