diff --git a/build.gradle.kts b/build.gradle.kts
index e87b3b6c174c848b59ffb3add5ddf86966b25aac..3d3abeb58ba6f9bab9b718cbc930a51ccea31b1a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,3 +1,4 @@
+
 /*
  * This file was generated by the Gradle 'init' task.
  *
@@ -31,12 +32,21 @@ dependencies {
     // json converter
     implementation("com.google.code.gson" ,"gson" ,"2.8.6")
 
-    // Use the Kotlin test library.
-    testImplementation("org.jetbrains.kotlin:kotlin-test")
 
-    // Use the Kotlin JUnit integration.
-    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
+    // https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-test-junit5
+    testImplementation(kotlin("test-junit5"))
+
+    // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
+    testImplementation("org.junit.jupiter","junit-jupiter-engine" ,  "5.7.0-M1")
+
+
 }
+
+tasks.test {
+    useJUnitPlatform()
+}
+
+
 application {
     // Define the main class for the application.
     mainClassName = "b.language.server.AppKt"
diff --git a/src/main/kotlin/b/language/server/App.kt b/src/main/kotlin/b/language/server/App.kt
index b88299a03240f5c7b9b69da9c3663aeaadc94ea0..75b38eab50ef0fd2cc5085067083c92d9958d914 100644
--- a/src/main/kotlin/b/language/server/App.kt
+++ b/src/main/kotlin/b/language/server/App.kt
@@ -1,6 +1,3 @@
-/*
- * This Kotlin source file was generated by the Gradle 'init' task.
- */
 package b.language.server
 
 import org.eclipse.lsp4j.jsonrpc.Launcher
@@ -11,23 +8,14 @@ import java.io.OutputStream
 import java.util.concurrent.Future
 
 
-class App {
-    val greeting: String
-        get() {
-            return "Hello world."
-        }
-}
-
-fun main(args: Array<String>) {
-    startServer(System.`in`, System.out);
-
+fun main() {
+    startServer(System.`in`, System.out)
 }
 
 fun startServer(inputStream: InputStream, outputStream: OutputStream){
-    val server : Server = Server()
+    val server = Server()
     val launcher : Launcher<LanguageClient> = LSPLauncher.createServerLauncher(server, inputStream, outputStream)
     val startListing : Future<*> = launcher.startListening()
     server.setRemoteProxy(launcher.remoteProxy)
     startListing.get()
-
 }
diff --git a/src/main/kotlin/b/language/server/BDocumentService.kt b/src/main/kotlin/b/language/server/BDocumentService.kt
index 57534bc7263571726e44c0e90d8c48a36e0f26ab..cf0d28cd5a6c1b5964e99dde62519b23eea372f4 100644
--- a/src/main/kotlin/b/language/server/BDocumentService.kt
+++ b/src/main/kotlin/b/language/server/BDocumentService.kt
@@ -1,16 +1,17 @@
 package b.language.server
 
-import b.language.server.dataStorage.Problem
+import b.language.server.proBMangement.CommandCouldNotBeExecutedException
+import b.language.server.proBMangement.PathCouldNotBeCreatedException
+import b.language.server.proBMangement.ProBCommandLineAccess
+import b.language.server.proBMangement.ProBInterface
 import org.eclipse.lsp4j.*
 import org.eclipse.lsp4j.services.TextDocumentService
-import java.io.File
-import java.net.URI
 import java.util.concurrent.ConcurrentHashMap
 
 class BDocumentService(private val server: Server) : TextDocumentService {
 
     private val documents = ConcurrentHashMap<String, String>()
-    private val issueTracker : ConcurrentHashMap<String, ArrayList<String>> = ConcurrentHashMap()
+    private val issueTracker : ConcurrentHashMap<String, Set<String>> = ConcurrentHashMap()
 
     /**
      * The document open notification is sent from the client to the server to
@@ -32,29 +33,35 @@ class BDocumentService(private val server: Server) : TextDocumentService {
      */
     override fun didSave(params: DidSaveTextDocumentParams?) {
 
-
-        val uri = URI(params!!.textDocument.uri)
-
-        val path = File(uri.path)
-
-        val errorPath = File(path.parent + "/tmp/_error.json")
-        val errorDict = File(path.parent + "/tmp")
-
-        val clientSettings = server.getDocumentSettings(params.textDocument.uri)
-
-        clientSettings.thenAccept{ setting ->
-            val probInterface = ProBInterface(setting.probHome, path, errorDict, errorPath, server = server)
-            probInterface.createFolder()
-            probInterface.performActionOnDocument()
-
-            val problemHandler = ProblemHandler()
-
-            val problemList: List<Problem> = problemHandler.readProblems(errorPath.absolutePath)
-            val diagnostics: List<Diagnostic> = problemHandler.transformProblems(problemList)
-
-            server.languageClient.publishDiagnostics(PublishDiagnosticsParams(params.textDocument.uri, diagnostics))
+        val currentUri = params!!.textDocument.uri
+        val clientSettings = server.getDocumentSettings(currentUri)
+
+        clientSettings.thenAccept{ settings ->
+            val prob : ProBInterface = ProBCommandLineAccess()
+
+            try{
+                val diagnostics: List<Diagnostic> = prob.checkDocument(currentUri, settings)
+                server.languageClient.publishDiagnostics(PublishDiagnosticsParams(currentUri, diagnostics))
+                val filesWithProblems = diagnostics.map { diagnostic -> diagnostic.source }
+                calculateToInvalidate(currentUri, filesWithProblems)
+                        .forEach{uri -> server.languageClient.publishDiagnostics(PublishDiagnosticsParams(uri, listOf()))}
+                issueTracker[currentUri] = filesWithProblems.toSet()
+            }catch (e : PathCouldNotBeCreatedException ){
+                server.languageClient.showMessage(MessageParams(MessageType.Error, e.message))
+            }catch (e : CommandCouldNotBeExecutedException){
+                server.languageClient.showMessage(MessageParams(MessageType.Error, e.message))
+            }
         }
+    }
 
+    /**
+     * Gets all uris that are no longer contain problems
+     * @param currentUri the uri of the current main file
+     * @param filesWithProblems uris of files containing problems
+     */
+    fun calculateToInvalidate(currentUri : String, filesWithProblems : List<String>) : List<String>{
+        val currentlyDisplayed = issueTracker[currentUri].orEmpty()
+        return currentlyDisplayed.subtract(filesWithProblems).toList()
     }
 
     /**
@@ -79,13 +86,4 @@ class BDocumentService(private val server: Server) : TextDocumentService {
       //Nothing
     }
 
-
-
-
-
-
-
-
-
-
 }
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/ProBInterface.kt b/src/main/kotlin/b/language/server/ProBInterface.kt
deleted file mode 100644
index 745f17673d400510bf7428fe5b9c6214727ebfba..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/ProBInterface.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-package b.language.server
-
-import org.eclipse.lsp4j.MessageParams
-import org.eclipse.lsp4j.MessageType
-import java.io.File
-import java.io.FileWriter
-import java.io.InputStream
-
-/**
- * Interacts with ProB via Commandline
- * @param probHome the target ProbCli
- * @param fileToCheck the main machine to start evaluating
- * @param errorDict the path to store errors
- * @param wdActive is wd checks enabled?
- * @param strictActive is strict enabled?
- * @param performanceHintsActive are performance hints activated?
- * @param server the server used to connect with
- */
-class ProBInterface(probHome : File,
-                    fileToCheck : File,
-                    val errorDict : File,
-                    val errorPath : File,
-                    wdActive : Boolean = false,
-                    strictActive : Boolean = false,
-                    performanceHintsActive : Boolean = false,
-                    private val server : Server){
-
-
-    private val configuration : String = " -p MAX_INITIALISATIONS 0 -version "
-    private val ndjson : String = " -p NDJSON_ERROR_LOG_FILE "
-    private val wd : String = if(wdActive){
-        " -wd-check -release_java_parser "
-    }else{
-        " "
-    }
-    private val strict : String = if(strictActive){
-        " -p STRICT_CLASH_CHECKING TRUE -p TYPE_CHECK_DEFINITIONS TRUE -lint "
-    }else{
-        " "
-    }
-    private val performanceHints : String = if(performanceHintsActive){
-        " -p PERFORMANCE_INFO TRUE "
-    }else{
-        " "
-    }
-
-    private val command : String
-
-    init {
-        command = probHome.path +
-                configuration +
-                performanceHints +
-                strict +
-                wd +
-                fileToCheck.absoluteFile +
-                ndjson +
-                errorPath.absoluteFile
-    }
-
-
-    fun createFolder() : Boolean{
-        errorDict.mkdirs()
-        FileWriter(errorPath, false).close()
-        return errorDict.mkdirs()
-    }
-
-    /**
-     * Executes the command and returns and sends an error message if something fails
-     */
-    fun performActionOnDocument() {
-        val process : Process = Runtime.getRuntime().exec(command)
-        val output : InputStream = process.inputStream
-
-        process.waitFor() //we must wait here to ensure correct behavior when reading an error
-
-        val outputAsString  = String(output.readAllBytes())
-        if(!outputAsString.contains("ProB Command Line Interface")){
-            server.languageClient.showMessage(
-                    MessageParams(MessageType.Error, "Something went wrong when calling probcli $command"))
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/ProblemHandler.kt b/src/main/kotlin/b/language/server/ProblemHandler.kt
deleted file mode 100644
index da05b457db95d3da0555373c1faa15a164c9e517..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/ProblemHandler.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-package b.language.server
-
-import b.language.server.dataStorage.Problem
-import com.google.gson.Gson
-import org.eclipse.lsp4j.Diagnostic
-import org.eclipse.lsp4j.DiagnosticSeverity
-import org.eclipse.lsp4j.Position
-import org.eclipse.lsp4j.Range
-import java.io.*
-
-
-
-/**
- * Responsible for reading Errors from the corresponding JSON File and sending transforming them into a object
- */
-class ProblemHandler {
-
-    /**
-     * Reads the errors and transforms them to java objects
-     * @param path the path to the error document
-     * @return the list of read errors
-     */
-    fun readProblems(path : String): List<Problem> {
-        val jsonStrings : ArrayList<String> = ArrayList()
-        BufferedReader(FileReader(path)).use { br ->
-            var line: String?
-            while (br.readLine().also { line = it } != null) {
-                jsonStrings.add(line!!)
-            }
-        }
-
-
-        return jsonStrings.toList().map { string -> Gson().fromJson(string, Problem::class.java) }
-    }
-
-    /**
-     * Transforms errors to error messages
-     * @param problems the list of errors to transform
-     * @return the transformed errors
-     */
-    fun transformProblems(problems : List<Problem>): List<Diagnostic> {
-        return problems.
-                /**
-                 * Some errors from prob_cli have negative values when there is no exact error location - we set them
-                 * to the first line
-                 */
-                map{ problem ->
-                    if (problem.start.line == -1 && problem.start.character == -1 &&
-                            problem.end.line == -1 && problem.end.character == -1)
-                    {
-                        Problem(problem.type,
-                                problem.message,
-                                problem.reason,
-                                problem.file,
-                                Position(1, 0),
-                                Position(1, Integer.MAX_VALUE),
-                                problem.version)
-                    }
-                    else{
-                        problem
-                    }
-                }
-                .map { problem -> Diagnostic(Range(problem.start, problem.end), problem.message,
-                when (problem.type) {
-                    "error" -> {
-                        DiagnosticSeverity.Error
-                    }
-                    "warning" -> {
-                        DiagnosticSeverity.Warning
-                    }
-                    "information" -> {
-                        DiagnosticSeverity.Information
-                    }
-                    else -> {
-                        DiagnosticSeverity.Hint
-                    }
-                },
-                problem.file,
-                "probcli v.${problem.version}")}
-    }
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/Server.kt b/src/main/kotlin/b/language/server/Server.kt
index eab11966a738a43bf82e22329180103a63e2a533..241dfc84deecdcb746b47e83e40767d12a0d0d71 100644
--- a/src/main/kotlin/b/language/server/Server.kt
+++ b/src/main/kotlin/b/language/server/Server.kt
@@ -19,7 +19,7 @@ class Server : LanguageServer {
     lateinit var languageClient : LanguageClient
     var globalSettings : Settings = Settings()
     val documentSettings : HashMap<String, CompletableFuture<Settings>> = HashMap()
-    var configurationAbility : Boolean = true;
+    var configurationAbility : Boolean = true
 
     init {
         textDocumentService = BDocumentService(this)
@@ -101,8 +101,6 @@ class Server : LanguageServer {
      * @return settings of the document requested
      */
     fun getDocumentSettings(uri : String) : CompletableFuture<Settings> {
-        this.languageClient.showMessage(
-                MessageParams(MessageType.Log, "uri $uri " ))
         if(!configurationAbility){
             val returnValue = CompletableFuture<Settings>()
             returnValue.complete(globalSettings)
diff --git a/src/main/kotlin/b/language/server/Util.kt b/src/main/kotlin/b/language/server/Util.kt
index 9687ebd2f6a97bb166c2d60ef9eb05e3393c0032..4c6f406cc72f900f4a6c1aa6e0c55fe7f8a101c7 100644
--- a/src/main/kotlin/b/language/server/Util.kt
+++ b/src/main/kotlin/b/language/server/Util.kt
@@ -1,14 +1,25 @@
 package b.language.server
 
+import b.language.server.dataStorage.Problem
 import b.language.server.dataStorage.Settings
 import com.google.gson.Gson
 import com.google.gson.JsonObject
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.Range
 import java.io.File
 
+
+/**
+ * Takes a json and tries to cast it into a settings objects
+ * @param json the json object
+ * @return the settings object
+ */
 fun castJsonToSetting(json : JsonObject) : Settings {
     return Settings(Gson().fromJson(json.get("maxNumberOfProblems"), Int::class.java),
             Gson().fromJson(json.get("wdChecks"), Boolean::class.java),
             Gson().fromJson(json.get("strictChecks"), Boolean::class.java),
             Gson().fromJson(json.get("performanceHints"), Boolean::class.java),
             File(Gson().fromJson(json.get("probHome"), String::class.java)))
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/b/language/server/dataStorage/Position.kt b/src/main/kotlin/b/language/server/dataStorage/Position.kt
new file mode 100644
index 0000000000000000000000000000000000000000..14e00846910be7754a8e37eaef51b9d21f26d946
--- /dev/null
+++ b/src/main/kotlin/b/language/server/dataStorage/Position.kt
@@ -0,0 +1,4 @@
+package b.language.server.dataStorage
+
+
+class Position(var line : Int, var col : Int)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/dataStorage/Problem.kt b/src/main/kotlin/b/language/server/dataStorage/Problem.kt
index 631fd69ee24ee25abb3c3b77c7a083479c7130db..75648c672771ab97bb1f3ca6423b704172cc2f89 100644
--- a/src/main/kotlin/b/language/server/dataStorage/Problem.kt
+++ b/src/main/kotlin/b/language/server/dataStorage/Problem.kt
@@ -1,6 +1,5 @@
 package b.language.server.dataStorage
 
-import org.eclipse.lsp4j.Position
 
 /**
  * kotlin representation of prob ndjson problems
diff --git a/src/main/kotlin/b/language/server/proBMangement/CommandCouldNotBeExecutedException.kt b/src/main/kotlin/b/language/server/proBMangement/CommandCouldNotBeExecutedException.kt
new file mode 100644
index 0000000000000000000000000000000000000000..01c9b006b379f66fbaffa656aeff0f81da69c1f2
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/CommandCouldNotBeExecutedException.kt
@@ -0,0 +1,3 @@
+package b.language.server.proBMangement
+
+class CommandCouldNotBeExecutedException(message: String?) : Exception(message)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/PathCouldNotBeCreatedException.kt b/src/main/kotlin/b/language/server/proBMangement/PathCouldNotBeCreatedException.kt
new file mode 100644
index 0000000000000000000000000000000000000000..57f2ddefbe8df4fb3dbdf319dd6b5cd9d71fdc24
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/PathCouldNotBeCreatedException.kt
@@ -0,0 +1,3 @@
+package b.language.server.proBMangement
+
+class PathCouldNotBeCreatedException(message: String?) : Exception(message)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt b/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4daf213f471f435fe39da5d4f72d6e9db22c888d
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt
@@ -0,0 +1,185 @@
+package b.language.server.proBMangement
+
+import b.language.server.dataStorage.Problem
+import b.language.server.dataStorage.Settings
+import com.google.gson.Gson
+import org.eclipse.lsp4j.*
+import java.io.*
+import java.net.URI
+
+
+/**
+ * Access ProB via command line
+ */
+class ProBCommandLineAccess : ProBInterface{
+    /**
+     * Checks the given document with the help of ProB; Will setup all needed steps to ensure a clean process
+     * @param uri the source to check
+     * @return a list of all problems found
+     */
+    override fun checkDocument(uri : String, settings: Settings): List<Diagnostic> {
+        val realUri = URI(uri)
+        val path = File(realUri.path)
+        val errorPath = File(path.parent + "/tmp/_error.json")
+        val errorDict = File(path.parent + "/tmp")
+
+        val result = createFolder(errorDict, errorPath)
+         if(!result){
+            throw PathCouldNotBeCreatedException("The Path leading to $errorPath could has not been created due some issue.")
+        }
+        val command = buildCommand(settings, path, errorPath)
+
+        performActionOnDocument(command)
+
+        val problems = readProblems(errorPath.path)
+
+        return transformProblems(problems)
+    }
+
+
+    /**
+     * Constructs the commandline call to proB depending on the given settings
+     * @param settings the settings for the document
+     * @param fileToCheck the current documents address
+     * @param errorPath the path to dump the ndjson message
+     * @return the execution ready command
+     */
+    fun buildCommand(settings : Settings, fileToCheck : File, errorPath : File) : String{
+        val configuration = " -p MAX_INITIALISATIONS 0 -version "
+        val ndjson = " -p NDJSON_ERROR_LOG_FILE "
+        val wd : String = if(settings.wdChecks){
+            " -wd-check -release_java_parser "
+        }else{
+            " "
+        }
+        val strict : String = if(settings.strictChecks){
+            " -p STRICT_CLASH_CHECKING TRUE -p TYPE_CHECK_DEFINITIONS TRUE -lint "
+        }else{
+            " "
+        }
+        val performanceHints : String = if(settings.performanceHints){
+            " -p PERFORMANCE_INFO TRUE "
+        }else{
+            " "
+        }
+
+        val probHome = settings.probHome
+
+        return probHome.path +
+                configuration +
+                performanceHints +
+                strict +
+                wd +
+                fileToCheck.absoluteFile +
+                ndjson +
+                errorPath.absoluteFile
+
+    }
+
+
+    /**
+     * Creates the tmp folder and an empty ndjson file; will recreate an empty ndjson file to ensure clean messages
+     * @param errorDict the path of the tmp dict
+     * @param errorPath the path to the error file
+     * @return success of the action
+     */
+    fun createFolder(errorDict : File, errorPath: File) : Boolean{
+        errorDict.mkdirs()
+        FileWriter(errorPath, false).close()
+        return errorDict.exists() && errorPath.exists()
+    }
+
+    /**
+     * Executes the given command
+     * @param command to execute
+     * @throws CommandCouldNotBeExecutedException the command failed to reach probcli
+     */
+    fun performActionOnDocument(command : String) {
+        val process : Process = Runtime.getRuntime().exec(command)
+        val output : InputStream = process.inputStream
+
+        process.waitFor() //we must wait here to ensure correct behavior when reading an error
+
+        val outputAsString  = String(output.readAllBytes())
+        if(!outputAsString.contains("ProB Command Line Interface")){
+            throw CommandCouldNotBeExecutedException("Error when trying to call probcli with command $command")
+        }
+    }
+
+
+    /**
+     * Reads the errors and transforms them to java objects
+     * @param path the path to the error document
+     * @return the list of read errors
+     */
+    fun readProblems(path : String): List<Problem> {
+        val jsonStrings : ArrayList<String> = ArrayList()
+        BufferedReader(FileReader(path)).use { br ->
+            var line: String?
+            while (br.readLine().also { line = it } != null) {
+                jsonStrings.add(line!!)
+            }
+        }
+
+        val strings =  jsonStrings.toList().map { string -> Gson().fromJson(string, Problem::class.java) }
+        return strings
+
+    }
+
+    /**
+     * Transforms errors to error messages
+     * @param problems the list of errors to transform
+     * @return the transformed errors
+     */
+    fun transformProblems(problems : List<Problem>): List<Diagnostic> {
+        return problems.
+                /**
+                 * Some errors from prob_cli have negative values when there is no exact error location - we set them
+                 * to the first line
+                 */
+        map{ problem ->
+            if (problem.start.line == -1 && problem.start.col == -1 &&
+                    problem.end.line == -1 && problem.end.col == -1)
+            {
+                print(Integer.MAX_VALUE)
+                Problem(problem.type,
+                        problem.message,
+                        problem.reason,
+                        problem.file,
+                        b.language.server.dataStorage.Position(1,0),
+                        b.language.server.dataStorage.Position(1, Integer.MAX_VALUE),
+                        problem.version)
+            }
+            else{
+                /**
+                 * Lines are off by one when they get out of vscode
+                 */
+                problem.start.line = problem.start.line - 1
+                problem.end.line = problem.end.line - 1
+
+                problem
+            }
+        }
+                .map { problem -> Diagnostic(
+                        Range(
+                                Position(problem.start.line, problem.start.col),
+                                Position(problem.end.line, problem.end.col)), problem.message,
+                        when (problem.type) {
+                            "error" -> {
+                                DiagnosticSeverity.Error
+                            }
+                            "warning" -> {
+                                DiagnosticSeverity.Warning
+                            }
+                            "information" -> {
+                                DiagnosticSeverity.Information
+                            }
+                            else -> {
+                                DiagnosticSeverity.Hint
+                            }
+                        },
+                        problem.file,
+                        " probcli v.${problem.version}")
+                }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt b/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8c16106da28290fc85b37587012407f21af2db07
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt
@@ -0,0 +1,15 @@
+package b.language.server.proBMangement
+
+import b.language.server.dataStorage.Settings
+import org.eclipse.lsp4j.Diagnostic
+
+interface ProBInterface {
+
+    /**
+     * Checks the given document with the help of ProB
+     * @param uri the source to check
+     * @return a list of all problems found
+     */
+    abstract fun checkDocument(uri : String, settings: Settings) : List<Diagnostic>
+
+}
\ No newline at end of file
diff --git a/src/test/kotlin/b/language/server/AppTest.kt b/src/test/kotlin/b/language/server/AppTest.kt
deleted file mode 100644
index 898b91cb22e908c9325dcb997e8f150623f48a9c..0000000000000000000000000000000000000000
--- a/src/test/kotlin/b/language/server/AppTest.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This Kotlin source file was generated by the Gradle 'init' task.
- */
-package b.language.server
-
-import kotlin.test.Test
-import kotlin.test.assertNotNull
-
-class AppTest {
-    @Test fun testAppHasAGreeting() {
-        val classUnderTest = App()
-        assertNotNull(classUnderTest.greeting, "app should have a greeting")
-    }
-}
diff --git a/src/test/kotlin/b/language/server/ProBCommandLineTest.kt b/src/test/kotlin/b/language/server/ProBCommandLineTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..16e3b123d1d3a4186d3ba62843db14b728768deb
--- /dev/null
+++ b/src/test/kotlin/b/language/server/ProBCommandLineTest.kt
@@ -0,0 +1,185 @@
+package b.language.server
+
+import b.language.server.dataStorage.Position
+import b.language.server.dataStorage.Problem
+import b.language.server.dataStorage.Settings
+import b.language.server.proBMangement.ProBCommandLineAccess
+import com.google.gson.Gson
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.Range
+import kotlin.test.Test
+import org.junit.jupiter.api.io.TempDir
+import java.io.File
+import kotlin.test.assertEquals
+
+class ProBCommandLineTest{
+
+    @Test
+    fun test_readProblems(@TempDir tempPath : File = File("tmp"))
+    {
+        val file = File(tempPath.path+"/tmp.txt")
+        val problemToWrite = Problem(message = "Test", file = "test.mch", reason = "test reason", version = "test",
+                start = Position(1,1), end = Position(1,1), type = "test")
+        file.writeText(Gson().toJson(problemToWrite))
+
+        val problems = ProBCommandLineAccess().readProblems(file.path)
+
+        val problem = problems.first()
+
+        assertEquals(problemToWrite.version, problem.version)
+        assertEquals(problemToWrite.end.col, problem.end.col)
+        assertEquals(problemToWrite.end.line, problemToWrite.end.line)
+        assertEquals(problemToWrite.start.col, problem.start.col)
+        assertEquals(problemToWrite.start.line, problemToWrite.start.line)
+        assertEquals(problemToWrite.file, problem.file)
+        assertEquals(problemToWrite.message, problem.message)
+        assertEquals(problemToWrite.reason, problem.reason)
+
+    }
+
+    @Test
+    fun test_buildCommand_everything_activated(@TempDir tempPath : File = File("tmp")){
+        val testSettings = Settings()
+        val tempFile = File(tempPath.path+"/m.mch")
+        val command = ProBCommandLineAccess().buildCommand(testSettings, tempFile, tempPath)
+        assertEquals("~/prob_prolog/probcli.sh -p MAX_INITIALISATIONS 0 " +
+                "-version  " +
+                "-p PERFORMANCE_INFO TRUE  " +
+                "-p STRICT_CLASH_CHECKING TRUE " +
+                "-p TYPE_CHECK_DEFINITIONS TRUE -lint  " +
+                "-wd-check -release_java_parser ${tempFile.path} " +
+                "-p NDJSON_ERROR_LOG_FILE $tempPath", command)
+    }
+
+    @Test
+    fun test_buildCommand_everything_not_strict(@TempDir tempPath : File = File("tmp")){
+        val testSettings = Settings(strictChecks = false)
+        val tempFile = File(tempPath.path+"/m.mch")
+        val command = ProBCommandLineAccess().buildCommand(testSettings, tempFile, tempPath)
+        assertEquals("~/prob_prolog/probcli.sh -p MAX_INITIALISATIONS 0 " +
+                "-version  " +
+                "-p PERFORMANCE_INFO TRUE   " +
+                "-wd-check -release_java_parser ${tempFile.path} " +
+                "-p NDJSON_ERROR_LOG_FILE $tempPath", command)
+    }
+
+
+    @Test
+    fun test_buildCommand_everything_not_wd(@TempDir tempPath : File = File("tmp")){
+        val testSettings = Settings(wdChecks = false)
+        val tempFile = File(tempPath.path+"/m.mch")
+        val command = ProBCommandLineAccess().buildCommand(testSettings, tempFile, tempPath)
+        assertEquals("~/prob_prolog/probcli.sh -p MAX_INITIALISATIONS 0 " +
+                "-version  " +
+                "-p PERFORMANCE_INFO TRUE  " +
+                "-p STRICT_CLASH_CHECKING TRUE " +
+                "-p TYPE_CHECK_DEFINITIONS TRUE -lint  " +
+                "${tempFile.path} " +
+                "-p NDJSON_ERROR_LOG_FILE $tempPath", command)
+    }
+
+
+    @Test
+    fun test_buildCommand_everything_not_performanceHints(@TempDir tempPath : File = File("tmp")){
+        val testSettings = Settings(performanceHints = false)
+        val tempFile = File(tempPath.path+"/m.mch")
+        val command = ProBCommandLineAccess().buildCommand(testSettings, tempFile, tempPath)
+        assertEquals("~/prob_prolog/probcli.sh -p MAX_INITIALISATIONS 0 " +
+                "-version   " +
+                "-p STRICT_CLASH_CHECKING TRUE " +
+                "-p TYPE_CHECK_DEFINITIONS TRUE -lint  " +
+                "-wd-check -release_java_parser ${tempFile.path} " +
+                "-p NDJSON_ERROR_LOG_FILE $tempPath", command)
+    }
+
+
+    @Test
+    fun test_transformProblems_negative_range(){
+        val problemFile = "test.mch"
+        val message = "Test"
+        val version = "test"
+        val testProblem =  Problem(message = message, file = problemFile, reason = "test reason", version = version,
+                start = Position(-1,-1), end = Position(-1,-1), type = "error")
+
+        val transformedProblem = ProBCommandLineAccess().transformProblems(listOf(testProblem)).first()
+
+        val diagnostic = Diagnostic(Range(
+                org.eclipse.lsp4j.Position(1,0),
+                org.eclipse.lsp4j.Position(1, Integer.MAX_VALUE)), message,  DiagnosticSeverity.Error, problemFile, " probcli v.$version" )
+        assertEquals(diagnostic, transformedProblem)
+
+    }
+
+
+    @Test
+    fun test_transformProblems_error(){
+        val problemFile = "test.mch"
+        val message = "Test"
+        val version = "test"
+        val testProblem =  Problem(message = message, file = problemFile, reason = "test reason", version = version,
+                start = Position(32,54), end = Position(54,65), type = "error")
+
+        val transformedProblem = ProBCommandLineAccess().transformProblems(listOf(testProblem)).first()
+
+        val diagnostic = Diagnostic(Range(
+                org.eclipse.lsp4j.Position(31,54),
+                org.eclipse.lsp4j.Position(53, 65)), message,  DiagnosticSeverity.Error, problemFile, " probcli v.$version" )
+        assertEquals(diagnostic, transformedProblem)
+
+    }
+
+
+    @Test
+    fun test_transformProblems_warning(){
+        val problemFile = "test.mch"
+        val message = "Test"
+        val version = "test"
+        val testProblem =  Problem(message = message, file = problemFile, reason = "test reason", version = version,
+                start = Position(32,54), end = Position(54,65), type = "warning")
+
+        val transformedProblem = ProBCommandLineAccess().transformProblems(listOf(testProblem)).first()
+
+        val diagnostic = Diagnostic(Range(
+                org.eclipse.lsp4j.Position(31,54),
+                org.eclipse.lsp4j.Position(53, 65)), message,  DiagnosticSeverity.Warning, problemFile, " probcli v.$version" )
+        assertEquals(diagnostic, transformedProblem)
+
+    }
+
+    @Test
+    fun test_transformProblems_information(){
+        val problemFile = "test.mch"
+        val message = "Test"
+        val version = "test"
+        val testProblem =  Problem(message = message, file = problemFile, reason = "test reason", version = version,
+                start = Position(32,54), end = Position(54,65), type = "information")
+
+        val transformedProblem = ProBCommandLineAccess().transformProblems(listOf(testProblem)).first()
+
+        val diagnostic = Diagnostic(Range(
+                org.eclipse.lsp4j.Position(31,54),
+                org.eclipse.lsp4j.Position(53, 65)), message,  DiagnosticSeverity.Information, problemFile, " probcli v.$version" )
+        assertEquals(diagnostic, transformedProblem)
+
+    }
+
+
+    @Test
+    fun test_transformProblems_hint(){
+        val problemFile = "test.mch"
+        val message = "Test"
+        val version = "test"
+        val testProblem =  Problem(message = message, file = problemFile, reason = "test reason", version = version,
+                start = Position(32,54), end = Position(54,65), type = "something else")
+
+        val transformedProblem = ProBCommandLineAccess().transformProblems(listOf(testProblem)).first()
+
+        val diagnostic = Diagnostic(Range(
+                org.eclipse.lsp4j.Position(31,54),
+                org.eclipse.lsp4j.Position(53, 65)), message,  DiagnosticSeverity.Hint, problemFile, " probcli v.$version" )
+        assertEquals(diagnostic, transformedProblem)
+
+    }
+
+}
\ No newline at end of file