diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 0a6e50149b66f4c7739e673c931ea5d40ef24e1c..ea6c1b3d5862f81c04cb917c3ca4e0dfa64195d1 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,6 +6,7 @@
         <sourceOutputDir name="target/generated-sources/annotations" />
         <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
         <outputRelativeToContentRoot value="true" />
+        <module name="Aufgabe4Maven" />
       </profile>
     </annotationProcessing>
     <bytecodeTargetLevel>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 1700c77fc6e767cbe5727a663e192016b616193d..19804e8bfca96a99b64b042c6eac7d82dd777574 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/Aufgabe4Maven/pom.xml" />
+      </list>
+    </option>
+  </component>
   <component name="ProjectRootManager" version="2" languageLevel="JDK_15" default="true" project-jdk-name="15" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
diff --git a/Aufgabe4Maven/pom.xml b/Aufgabe4Maven/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ad360818e134385bc6054a48ca49d62e588b00a5
--- /dev/null
+++ b/Aufgabe4Maven/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>Aufgabe4Maven</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>15</maven.compiler.source>
+        <maven.compiler.target>15</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>5.9.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.java.contract</groupId>
+            <artifactId>cofoja</artifactId>
+            <version>1.1-r150</version>
+        </dependency>
+
+
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/Aufgabe4/Ast.java b/Aufgabe4Maven/src/Ast.java
similarity index 96%
rename from Aufgabe4/Ast.java
rename to Aufgabe4Maven/src/Ast.java
index 93ecf5b5eaafc9c6c3b791904a95893291f53570..2a14419f9f08b7338784b7b067c6a8d8f99bac15 100644
--- a/Aufgabe4/Ast.java
+++ b/Aufgabe4Maven/src/Ast.java
@@ -68,5 +68,5 @@ class AstDecimal extends Ast {
 
 class AstOperator extends Ast {
 
-    String astOperator;
+    String astOperatorContent;
 }
diff --git a/Aufgabe4/Evaluator.java b/Aufgabe4Maven/src/Evaluator.java
similarity index 97%
rename from Aufgabe4/Evaluator.java
rename to Aufgabe4Maven/src/Evaluator.java
index dd17f1944ee5ed157bc793d16419f07e50068d66..8dfd35b6a580810f9460cee0259d3557c9ec546e 100644
--- a/Aufgabe4/Evaluator.java
+++ b/Aufgabe4Maven/src/Evaluator.java
@@ -31,7 +31,7 @@ public class Evaluator {
 
         visit(node.astExpression1);
 
-        switch(node.astOperator.astOperator) {
+        switch(node.astOperator.astOperatorContent) {
 
             case "+":
                 return visit(node.astExpression1) + visit(node.astExpression2);
diff --git a/Aufgabe4/EvaluatorBackup.java b/Aufgabe4Maven/src/EvaluatorBackup.java
similarity index 94%
rename from Aufgabe4/EvaluatorBackup.java
rename to Aufgabe4Maven/src/EvaluatorBackup.java
index ba22527d283094a4543788ae381ed62c188cceb2..315984bdb15ce653da3888e69e838e0187008f29 100644
--- a/Aufgabe4/EvaluatorBackup.java
+++ b/Aufgabe4Maven/src/EvaluatorBackup.java
@@ -24,7 +24,7 @@ public class EvaluatorBackup {
     public void visit(AstBinaryOp node) {
 
         visit(node.astExpression1);
-        System.out.print(node.astOperator.astOperator);
+        System.out.print(node.astOperator.astOperatorContent);
         visit(node.astExpression2);
 
     }
diff --git a/Aufgabe4Maven/src/Exceptions.java b/Aufgabe4Maven/src/Exceptions.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2e042951a5e5cff31dc03035b0c4cea096457c4
--- /dev/null
+++ b/Aufgabe4Maven/src/Exceptions.java
@@ -0,0 +1,33 @@
+public class Exceptions {
+
+    public static Class<? extends Throwable> ParserException;
+
+    public static class ParserException extends RuntimeException {
+        private String message;
+
+        public ParserException(String string) {
+            this.message = string;
+        }
+
+        public String toString() {
+            return "parser failed: " + message;
+        }
+
+        /**
+         *
+         */
+        private static final long serialVersionUID = 1L;
+
+    }
+
+
+    @SuppressWarnings("serial")
+    public static class LexerException extends RuntimeException {
+        public LexerException() {
+        }
+
+        public LexerException(String string) {
+            super(string);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Aufgabe4/Lexer.java b/Aufgabe4Maven/src/Lexer.java
similarity index 97%
rename from Aufgabe4/Lexer.java
rename to Aufgabe4Maven/src/Lexer.java
index fc81483a99d20bde8f47e326a2f672f6e88fe89d..73240a07e7145bbbc20507a011af7219a42eeb00 100644
--- a/Aufgabe4/Lexer.java
+++ b/Aufgabe4Maven/src/Lexer.java
@@ -1,9 +1,11 @@
 import java.util.ArrayList;
 import java.util.Objects;
+import com.google.java.contract.*;
 
 public class Lexer {
 
 
+    @Requires({"s != null"})
     public ArrayList<Token> lex(String s) {
 
         ArrayList<String> separatedChars = separateChars(s);
diff --git a/Aufgabe4/Parser.java b/Aufgabe4Maven/src/Parser.java
similarity index 77%
rename from Aufgabe4/Parser.java
rename to Aufgabe4Maven/src/Parser.java
index 63d0511d43375f6988156982eaa07b120e049ae8..1bfbca27c64abe396f8025815e407d258b779607 100644
--- a/Aufgabe4/Parser.java
+++ b/Aufgabe4Maven/src/Parser.java
@@ -1,10 +1,11 @@
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 public class Parser {
 
-    public AstExpression parse (ArrayList<Token> tokenList) {
+    public AstExpression parse (ArrayList<Token> tokenList) throws Exception {
 
         AstExpression root;
 
@@ -13,7 +14,7 @@ public class Parser {
         return root;
     }
 
-    private AstExpression parseAstExpression (ArrayList<Token> tokenList) {
+    private AstExpression parseAstExpression (ArrayList<Token> tokenList) throws Exception {
 
         AstExpression toReturn = new AstExpression();
 
@@ -56,50 +57,57 @@ public class Parser {
 
         // Check if first and last tokens have "(" and ")" strings
 
-        if(tokenList.get(0).tokenString.equals("(") && tokenList.get(tokenList.size() - 1).tokenString.equals(")")) {
+        try {
+
+            if (tokenList.get(0).tokenString.equals("(") && tokenList.get(tokenList.size() - 1).tokenString.equals(")")) {
 
 
-            // Check if "false alarm", e.g. ( 1 + 2 ) + ( 1 + 2 ) <- starts and ends with ( and ) but is to be treated as binaryOp
+                // Check if "false alarm", e.g. ( 1 + 2 ) + ( 1 + 2 ) <- starts and ends with ( and ) but is to be treated as binaryOp
 
-            boolean falseAlarm = false;
+                boolean falseAlarm = false;
 
-            for(int i = tokenList.size() - 2; i > 0; i--) {
+                for (int i = tokenList.size() - 2; i > 0; i--) {
 
-                if(tokenList.get(i).tokenString.equals(")") || tokenList.get(i).tokenString.equals("(")) {
+                    if (tokenList.get(i).tokenString.equals(")") || tokenList.get(i).tokenString.equals("(")) {
 
-                    if(tokenList.get(i).tokenString.equals(")")) {
-                        falseAlarm = false;
+                        if (tokenList.get(i).tokenString.equals(")")) {
+                            falseAlarm = false;
 
-                    } else {
-                        falseAlarm = true;
+                        } else {
+                            falseAlarm = true;
+                        }
+                        break;
                     }
-                    break;
                 }
-            }
 
-            // Parse tokenList without first and last object and save it in toReturns astExpression
+                // Parse tokenList without first and last object and save it in toReturns astExpression
 
-            if(!falseAlarm) {
+                if (!falseAlarm) {
+
+                    toReturn.astExpression = parseAstExpression(
+                            (ArrayList<Token>) IntStream.range(1, tokenList.size() - 1)
+                                    .mapToObj(i -> tokenList.get(i))
+                                    .collect(Collectors.toList()) // https://www.baeldung.com/java-stream-indices
+                    );
+                    return toReturn;
+                }
 
-                toReturn.astExpression = parseAstExpression(
-                        (ArrayList<Token>) IntStream.range(1, tokenList.size() - 1)
-                                .mapToObj(i -> tokenList.get(i))
-                                .collect(Collectors.toList()) // https://www.baeldung.com/java-stream-indices
-                );
-                return toReturn;
             }
 
+        } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
+            throw new Exceptions.ParserException("String is not a valid function");
         }
 
+
         toReturn.astBinaryOp = parseBinaryOp(tokenList);
 
         return toReturn;
 
     }
 
-    //(5+2)+(1+2)
 
-    private AstBinaryOp parseBinaryOp (ArrayList<Token> tokenList) {
+
+    private AstBinaryOp parseBinaryOp (ArrayList<Token> tokenList) throws Exception {
 
 
         AstBinaryOp toReturn = new AstBinaryOp();
@@ -141,7 +149,7 @@ public class Parser {
     private AstOperator parseOperator (Token operator) {
 
         AstOperator toReturn = new AstOperator();
-        toReturn.astOperator = operator.tokenString;
+        toReturn.astOperatorContent = operator.tokenString;
 
         return toReturn;
     }
@@ -221,7 +229,15 @@ public class Parser {
 
         } else {
 
-            toReturn.astDigitBeforeComma = parseNumber(new ArrayList<> (decimalTokens.subList(0, positionOfDecimalPoint - 1)));
+
+            try {
+
+                toReturn.astDigitBeforeComma = parseNumber(new ArrayList<>(decimalTokens.subList(0, positionOfDecimalPoint - 1)));
+
+            } catch (IllegalArgumentException illegalArgumentException) {
+                throw new Exceptions.ParserException("String contains invalid char");
+            }
+
         }
 
 
diff --git a/Aufgabe4/Plotter.java b/Aufgabe4Maven/src/Plotter.java
similarity index 100%
rename from Aufgabe4/Plotter.java
rename to Aufgabe4Maven/src/Plotter.java
diff --git a/Aufgabe4/TokenType.java b/Aufgabe4Maven/src/TokenType.java
similarity index 100%
rename from Aufgabe4/TokenType.java
rename to Aufgabe4Maven/src/TokenType.java
diff --git a/Aufgabe4/ValuesToDraw.java b/Aufgabe4Maven/src/ValuesToDraw.java
similarity index 100%
rename from Aufgabe4/ValuesToDraw.java
rename to Aufgabe4Maven/src/ValuesToDraw.java
diff --git a/Aufgabe4/expressions.txt b/Aufgabe4Maven/src/expressions.txt
similarity index 100%
rename from Aufgabe4/expressions.txt
rename to Aufgabe4Maven/src/expressions.txt
diff --git a/Aufgabe4/main.java b/Aufgabe4Maven/src/main.java
similarity index 94%
rename from Aufgabe4/main.java
rename to Aufgabe4Maven/src/main.java
index dd2853fc03c5d1b02783a6e80ef21d7a9bedada9..444278943dff75930d358a653b3f2bfa0aae9b22 100644
--- a/Aufgabe4/main.java
+++ b/Aufgabe4Maven/src/main.java
@@ -1,11 +1,10 @@
 import java.io.*;
-import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Scanner;
 
 public class main {
 
-    public static void main(String[] args) throws IOException {
+    public static void main(String[] args) throws Exception {
 
 
 
@@ -13,7 +12,7 @@ public class main {
 
         ArrayList<String> stringsFromFile = new ArrayList<>();
 
-        String filePath = "./Aufgabe4/expressions.txt";
+        String filePath = "./Aufgabe4Maven/src/expressions.txt";
 
         Scanner scan = null;
         try {
@@ -116,7 +115,7 @@ public class main {
         }
 
         printAst(astExpression.astBinaryOp.astExpression1);
-        System.out.print(astExpression.astBinaryOp.astOperator.astOperator);
+        System.out.print(astExpression.astBinaryOp.astOperator.astOperatorContent);
         printAst(astExpression.astBinaryOp.astExpression2);
 
     }
diff --git a/Aufgabe4/test.java b/Aufgabe4Maven/src/test.java
similarity index 100%
rename from Aufgabe4/test.java
rename to Aufgabe4Maven/src/test.java
diff --git a/Aufgabe4Maven/tests/LexerTest.java b/Aufgabe4Maven/tests/LexerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..29f24acd71400f42b16fc2ba99aa1f5725034863
--- /dev/null
+++ b/Aufgabe4Maven/tests/LexerTest.java
@@ -0,0 +1,60 @@
+import org.junit.Test;
+import org.junit.jupiter.api.DisplayName;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.stream.IntStream;
+
+public class LexerTest {
+
+    @Test
+    @DisplayName("simpleExpression")
+    public void testSimpleExpression() {
+
+        Lexer lexer = new Lexer();
+
+        String expression = "5";
+
+        ArrayList<Token> lexResult = lexer.lex(expression);
+
+        ArrayList<Token> lexExpectedResult = new ArrayList<>();
+        lexExpectedResult.add(new Token(TokenType.number, "5"));
+
+
+        assertEquals(lexExpectedResult.get(0).tokenType, lexResult.get(0).tokenType);
+        assertEquals(lexExpectedResult.get(0).tokenString, lexResult.get(0).tokenString);
+    }
+
+    @Test
+    public void testComplicatedExpression() {
+        Lexer lexer = new Lexer();
+
+        String expression2 = "((22+3x)*5/3)";
+        ArrayList<Token> lexResult2 = lexer.lex(expression2);
+
+        ArrayList<Token> lexExpectedResult2 = new ArrayList<>();
+        lexExpectedResult2.add(new Token(TokenType.special, "("));
+        lexExpectedResult2.add(new Token(TokenType.special, "("));
+        lexExpectedResult2.add(new Token(TokenType.number, "22"));
+        lexExpectedResult2.add(new Token(TokenType.special, "+"));
+        lexExpectedResult2.add(new Token(TokenType.number, "3"));
+        lexExpectedResult2.add(new Token(TokenType.var, "x"));
+        lexExpectedResult2.add(new Token(TokenType.special, ")"));
+        lexExpectedResult2.add(new Token(TokenType.special, "*"));
+        lexExpectedResult2.add(new Token(TokenType.number, "5"));
+        lexExpectedResult2.add(new Token(TokenType.special, "/"));
+        lexExpectedResult2.add(new Token(TokenType.number, "3"));
+        lexExpectedResult2.add(new Token(TokenType.special, ")"));
+
+        for (int i = 0; i < lexResult2.size() ; i++) {
+            assertEquals(lexResult2.get(i).getTokenString(), lexExpectedResult2.get(i).getTokenString());
+            assertEquals(lexResult2.get(i).getTokenType(), lexExpectedResult2.get(i).getTokenType());
+        }
+
+    }
+
+
+
+}
+
diff --git a/out/production/inf3_git/Token.class b/out/production/inf3_git/Token.class
deleted file mode 100644
index 6ac75ca8d00a94234fb7504e3c701205235d5dfa..0000000000000000000000000000000000000000
Binary files a/out/production/inf3_git/Token.class and /dev/null differ
diff --git a/out/production/inf3_git/TokenType.class b/out/production/inf3_git/TokenType.class
deleted file mode 100644
index f51f9e10ede5de0de035d649744243b0ba634ef8..0000000000000000000000000000000000000000
Binary files a/out/production/inf3_git/TokenType.class and /dev/null differ
diff --git a/out/production/inf3_git/main.class b/out/production/inf3_git/main.class
deleted file mode 100644
index a4e8897c9a16d33fbd487695fe33cf6e329876c6..0000000000000000000000000000000000000000
Binary files a/out/production/inf3_git/main.class and /dev/null differ