diff --git a/README.md b/README.md
index 9e9e2b76fae8e52b816354ed174c04cdc6fc1683..265d685ddda22909eb312da9b427b2b1fd3c9912 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,29 @@
 # b-language-server
-A language server implementation for B, using ProB as backend, based on Java/Kotlin
+A language server implementation for B, using ProB as backend, based on Java/Kotlin. This language server comes with his
+own version of probcli.
+
+## Usage
+After starting the server; either from an IDE via main or by building and executing a shadowjar, a language client can 
+connect to it via port 55555.
+
+## Capabilities
+
+- Calling ProB Java Kernel with additional options
+- Options need to be specified by the client; They are requested by the server
+- Options are: 
+    *   val strictChecks : Boolean = true  
+    *   val wdChecks : Boolean = true
+    *   val performanceHints : Boolean = true 
+    *   val probHome : String = "DEFAULT"
+    *   val debugMode : Boolean = true
+    
+- Setting probHome to a different target then DEFAULT can cause all sorts of bad stuff. Ensure that the path points to the
+correct directory. Note that any probcli other version then the version used by prob java kernel can cause uncaught errors.
+If you want to use another version probcli point to the directory, not to probcli.sh e.g.:
+```
+/home/sebastian/prob_prolog
+```
+    
+## Clients
+
+- VSCode: https://marketplace.visualstudio.com/items?itemName=SeeBasTStick.b-language-extension
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index afd2a57b632cba5a5dc2c49ed222135a1bcee920..64696b8038502ae674ee0739e9297584712d9534 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -7,7 +7,7 @@
 
 plugins {
     // Apply the Kotlin JVM plugin to add support for Kotlin.
-    id("org.jetbrains.kotlin.jvm") version "1.3.72"
+    kotlin("jvm") version "1.4.0"
     idea
     // Apply the application plugin to add support for building a CLI application.
     application
@@ -19,8 +19,13 @@ plugins {
 repositories {
     // Use jcenter for resolving dependencies.
     jcenter()
+
+    maven("https://oss.sonatype.org/content/repositories/snapshots")
+
 }
 
+
+
 dependencies {
     // Align versions of all Kotlin components
     implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
@@ -28,6 +33,10 @@ dependencies {
     // Use the Kotlin JDK 8 standard library.
     implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
 
+
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
+
+
     // eclipse lsp implementation
     implementation("org.eclipse.lsp4j", "org.eclipse.lsp4j",  "0.9.0")
 
@@ -41,15 +50,32 @@ dependencies {
     // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
     testImplementation("org.junit.jupiter","junit-jupiter-engine" ,  "5.7.0-M1")
 
+    implementation("de.hhu.stups:de.prob2.kernel:4.0.0-SNAPSHOT")
+
+    implementation( "com.google.guava", "guava", "28.2-jre")
+
+
+    // https://mvnrepository.com/artifact/org.zeromq/jeromq
+    implementation ("org.zeromq",   "jeromq", "0.5.2")
+
 
 }
 
 
+
+
+
 tasks.test {
     useJUnitPlatform()
 }
 
 val gitVersion: groovy.lang.Closure<*> by extra
+
+tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>(){
+    kotlinOptions.jvmTarget = "1.8"
+}
+
+
 tasks.shadowJar{
   //  this.version = gitVersion().toString()
 }
diff --git a/package.json b/package.json
index 69e2f5dfd8bca802113c5031604ac995f488546b..e2584051a9b8b91f3fa0063e746af11d5a0f7cae 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "b-language-server",
-  "version": "1.0.0",
+  "version": "2.0.0",
   "description": "a java based language server implementing the lsp",
   "main": "index.js",
   "scripts": {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 260c6a0f7a1f9c9158a3c4e6d8446e7bbe56b020..feec1793567b5d0ec0cdcbe26602d82a00dd890a 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -8,3 +8,4 @@
  */
 
 rootProject.name = "b-language-server"
+//includeBuild("../prob2_kernel/de.prob2.kernel")
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/App.kt b/src/main/kotlin/b/language/server/App.kt
index 014cb395c7398e42d9f1ac5f07ef89818d3175ef..b22a97c6bd72322f572bb97d28c32b6bd41e01dc 100644
--- a/src/main/kotlin/b/language/server/App.kt
+++ b/src/main/kotlin/b/language/server/App.kt
@@ -3,16 +3,22 @@ package b.language.server
 import org.eclipse.lsp4j.jsonrpc.Launcher
 import org.eclipse.lsp4j.launch.LSPLauncher
 import org.eclipse.lsp4j.services.LanguageClient
-import java.io.InputStream
-import java.io.OutputStream
+import java.io.*
+import java.net.ServerSocket
 import java.util.concurrent.Future
 
 
 fun main() {
-    startServer(System.`in`, System.out)
+    val socket = ServerSocket(0)
+
+    println("<${socket.localPort}> is the port; opening connection and listening")
+    val channel = socket.accept()
+    //println("accepted connection from ${channel.inetAddress}")
+    startServer(channel.getInputStream(), channel.getOutputStream())
 }
 
 fun startServer(inputStream: InputStream, outputStream: OutputStream){
+
     val server = Server()
     val launcher : Launcher<LanguageClient> = LSPLauncher.createServerLauncher(server, inputStream, outputStream)
     val startListing : Future<*> = launcher.startListening()
diff --git a/src/main/kotlin/b/language/server/BDocumentService.kt b/src/main/kotlin/b/language/server/BDocumentService.kt
index 065066c6a2cf862beb9be97aa8192c4090c7f360..3e09911c7f120f84a59a4fa8d86a18e8c2c729b1 100644
--- a/src/main/kotlin/b/language/server/BDocumentService.kt
+++ b/src/main/kotlin/b/language/server/BDocumentService.kt
@@ -1,17 +1,15 @@
 package b.language.server
 
 import b.language.server.communication.CommunicatorInterface
-import b.language.server.proBMangement.probCli.CommandCouldNotBeExecutedException
-import b.language.server.proBMangement.probCli.PathCouldNotBeCreatedException
 import b.language.server.proBMangement.ProBInterface
-import b.language.server.proBMangement.probCli.ProBCommandLineAccess
+import b.language.server.proBMangement.prob.CouldNotFindProBHomeException
 import org.eclipse.lsp4j.*
 import org.eclipse.lsp4j.services.TextDocumentService
-import java.io.IOException
-import java.net.URI
 import java.util.concurrent.ConcurrentHashMap
 
-class BDocumentService(private val server: Server, private val communicator: CommunicatorInterface) : TextDocumentService {
+class BDocumentService(private val server: Server,
+                       private val communicator: CommunicatorInterface,
+                       private val proBInterface: ProBInterface) : TextDocumentService {
 
     private val documents = ConcurrentHashMap<String, String>()
     private val issueTracker : ConcurrentHashMap<String, Set<String>> = ConcurrentHashMap()
@@ -36,7 +34,7 @@ class BDocumentService(private val server: Server, private val communicator: Com
      */
     override fun didSave(params: DidSaveTextDocumentParams?) {
 
-        communicator.bufferDebugMessage("document ${params!!.textDocument.uri} was saved", MessageType.Info)
+        communicator.sendDebugMessage("document ${params!!.textDocument.uri} was saved", MessageType.Info)
         val currentUri = params.textDocument.uri
         checkDocument(currentUri)
 
@@ -49,7 +47,7 @@ class BDocumentService(private val server: Server, private val communicator: Com
     fun checkDocument(currentUri : String){
 
         val clientSettings = server.getDocumentSettings(currentUri)
-        communicator.bufferDebugMessage("waiting for document settings", MessageType.Info)
+        communicator.sendDebugMessage("waiting for document settings", MessageType.Info)
 
         clientSettings.thenAccept{ settings ->
             communicator.setDebugMode(settings.debugMode)
@@ -69,15 +67,9 @@ class BDocumentService(private val server: Server, private val communicator: Com
                 communicator.sendDebugMessage("invalidating old files $invalidFiles", MessageType.Info)
                 issueTracker[currentUri] = filesWithProblems.toSet()
 
-            }catch (e : PathCouldNotBeCreatedException){
-                communicator.sendDebugMessage("error path could not be created", MessageType.Info)
-                communicator.showMessage(e.message!!, MessageType.Error)
-            }catch (e : CommandCouldNotBeExecutedException){
-                communicator.sendDebugMessage("command could not be executed", MessageType.Info)
-                communicator.showMessage(e.message!!, MessageType.Error)
-            }catch (e : IOException){
-                communicator.sendDebugMessage("command could not be executed", MessageType.Info)
-                communicator.showMessage(e.message!!, MessageType.Error)
+            }catch (e : CouldNotFindProBHomeException){
+                communicator.sendDebugMessage(e.message!!, MessageType.Info)
+                communicator.showMessage(e.message, MessageType.Error)
             }
         }
 
@@ -113,7 +105,7 @@ class BDocumentService(private val server: Server, private val communicator: Com
      * Registration Options: TextDocumentChangeRegistrationOptions
      */
     override fun didChange(params: DidChangeTextDocumentParams?) {
-        communicator.bufferDebugMessage("document ${params!!.textDocument.uri} was changed", MessageType.Info)
+        communicator.sendDebugMessage("document ${params!!.textDocument.uri} was changed", MessageType.Info)
         val currentUri = params.textDocument.uri
         checkDocument(currentUri)
     }
diff --git a/src/main/kotlin/b/language/server/BWorkspaceService.kt b/src/main/kotlin/b/language/server/BWorkspaceService.kt
index 603b6dad7bc4a52768419d0f987e8fa4c7f47a6c..6ed6d36fb5b84f20ff3321132083b81a23e119d6 100644
--- a/src/main/kotlin/b/language/server/BWorkspaceService.kt
+++ b/src/main/kotlin/b/language/server/BWorkspaceService.kt
@@ -1,22 +1,20 @@
 package b.language.server
 
 import b.language.server.communication.Communicator
-import b.language.server.dataStorage.Settings
-import com.google.gson.Gson
 import com.google.gson.JsonObject
 import org.eclipse.lsp4j.DidChangeConfigurationParams
 import org.eclipse.lsp4j.DidChangeWatchedFilesParams
 import org.eclipse.lsp4j.MessageType
 import org.eclipse.lsp4j.services.WorkspaceService
-import java.io.File
 
-class BWorkspaceService(private val server : Server) : WorkspaceService {
+
+class BWorkspaceService(private val server: Server, val communicator: Communicator) : WorkspaceService {
     /**
      * The watched files notification is sent from the client to the server when
      * the client detects changes to file watched by the language client.
      */
     override fun didChangeWatchedFiles(params: DidChangeWatchedFilesParams?) {
-        Communicator.bufferDebugMessage("changed watched files", MessageType.Info)
+         communicator.sendDebugMessage("----------changed watched files", MessageType.Info)
 
         // Not needed
     }
@@ -26,7 +24,7 @@ class BWorkspaceService(private val server : Server) : WorkspaceService {
      * configuration settings.
      */
     override fun didChangeConfiguration(params: DidChangeConfigurationParams?) {
-        Communicator.bufferDebugMessage("received change in configuration settings", MessageType.Info)
+        communicator.sendDebugMessage("received change in configuration settings", MessageType.Info)
         if(server.configurationAbility) {
             server.documentSettings.clear()
         }else{
diff --git a/src/main/kotlin/b/language/server/Server.kt b/src/main/kotlin/b/language/server/Server.kt
index 274196fc846eae6d7fac39a1d18c45c9aae2ab81..4820acbcce74adcae54c6ec2ac99e422d03ebb8e 100644
--- a/src/main/kotlin/b/language/server/Server.kt
+++ b/src/main/kotlin/b/language/server/Server.kt
@@ -2,35 +2,33 @@ package b.language.server
 
 import b.language.server.communication.Communicator
 import b.language.server.dataStorage.Settings
+import b.language.server.proBMangement.prob.ProBKernelManager
 import com.google.gson.JsonObject
 import org.eclipse.lsp4j.*
 import org.eclipse.lsp4j.jsonrpc.messages.Either
-import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
 import org.eclipse.lsp4j.services.*
 import java.util.concurrent.CompletableFuture
 import kotlin.collections.HashMap
 import kotlin.system.exitProcess
-import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint
 
 class Server : LanguageServer{
 
-    private val textDocumentService : TextDocumentService = BDocumentService(this, Communicator)
-    private val bWorkspaceService : WorkspaceService = BWorkspaceService(this)
-     lateinit var languageClient : LanguageClient
+    private val textDocumentService : TextDocumentService = BDocumentService(this, Communicator, ProBKernelManager(Communicator))
+    private val bWorkspaceService : WorkspaceService = BWorkspaceService(this, Communicator)
+    private lateinit var languageClient : LanguageClient
     var globalSettings : Settings = Settings()
     val documentSettings : HashMap<String, CompletableFuture<Settings>> = HashMap()
     var configurationAbility : Boolean = true
 
 
+
+
     override fun initialize(params: InitializeParams?): CompletableFuture<InitializeResult> {
         val res = InitializeResult(ServerCapabilities())
         res.capabilities.textDocumentSync = Either.forLeft(TextDocumentSyncKind.Full)
         res.capabilities.workspace = WorkspaceServerCapabilities(WorkspaceFoldersOptions())
         res.capabilities.workspace.workspaceFolders.supported = true
-
-      //  languageClient.registerCapability(
-        //        RegistrationParams(listOf(Registration("all_config_changes", "didChangeConfiguration" , bWorkspaceService))))
-
+       // res.capabilities.completionProvider = CompletionOptions()
         return CompletableFuture.supplyAsync { res }
     }
 
@@ -73,9 +71,6 @@ class Server : LanguageServer{
     }
 
 
-
-
-
     /**
      * Get the settings for the current document - will fallback to global settings eventually; If setting not cached
      * method will try to get setting from the client
@@ -83,7 +78,7 @@ class Server : LanguageServer{
      * @return settings of the document requested
      */
     fun getDocumentSettings(uri : String) : CompletableFuture<Settings> {
-        Communicator.bufferDebugMessage("received configuration data of the document $uri", MessageType.Info)
+        Communicator.sendDebugMessage("requesting configuration for document: $uri", MessageType.Info)
         return if(!configurationAbility){
             val returnValue = CompletableFuture<Settings>()
             returnValue.complete(globalSettings)
@@ -93,6 +88,7 @@ class Server : LanguageServer{
             val configurationItem = ConfigurationItem()
             configurationItem.scopeUri = uri
             configurationItem.section = "languageServer"
+
             val requestedConfig = languageClient.configuration(ConfigurationParams(listOf(configurationItem)))
             documentSettings[uri] = CompletableFuture.allOf(requestedConfig).thenApply{ castJsonToSetting(requestedConfig.get().first() as JsonObject) }
             documentSettings[uri]!!
@@ -100,4 +96,7 @@ class Server : LanguageServer{
     }
 
 
+
+
+
 }
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/Util.kt b/src/main/kotlin/b/language/server/Util.kt
index d6798327e62bf97e58832cca9878201aec41e2c3..3a19addfe6be97581eae0ffdf58d9b2172a5b29d 100644
--- a/src/main/kotlin/b/language/server/Util.kt
+++ b/src/main/kotlin/b/language/server/Util.kt
@@ -4,8 +4,6 @@ import b.language.server.dataStorage.Settings
 import com.google.gson.Gson
 import com.google.gson.JsonObject
 
-import java.io.File
-
 
 /**
  * Takes a json and tries to cast it into a settings objects
@@ -17,6 +15,8 @@ fun castJsonToSetting(json : JsonObject) : Settings {
             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)),
+            Gson().fromJson(json.get("proBHome"), String::class.java),
             Gson().fromJson(json.get("debugMode"), Boolean::class.java))
 }
+
+
diff --git a/src/main/kotlin/b/language/server/communication/Communicator.kt b/src/main/kotlin/b/language/server/communication/Communicator.kt
index 1d7e97c3983082a30d949e5377f1113056818d06..4e8e8c3eab8cdf618a65a7b72961547ed60876c8 100644
--- a/src/main/kotlin/b/language/server/communication/Communicator.kt
+++ b/src/main/kotlin/b/language/server/communication/Communicator.kt
@@ -1,6 +1,5 @@
 package b.language.server.communication
 
-import org.eclipse.lsp4j.Diagnostic
 import org.eclipse.lsp4j.MessageParams
 import org.eclipse.lsp4j.MessageType
 import org.eclipse.lsp4j.PublishDiagnosticsParams
@@ -16,15 +15,14 @@ object Communicator : CommunicatorInterface {
     lateinit var client : LanguageClient
 
     private var debugMode : Boolean = true
-    private val storedMessages = mutableListOf<Pair<String, MessageType>>()
 
     /**
      * Sends the diagnostics
      *
      * @param diagnostics object containing the Diagnostics
      */
-    override fun publishDiagnostics(target :String, diagnostics : List<Diagnostic>) {
-        client.publishDiagnostics(PublishDiagnosticsParams(target, diagnostics))
+    override fun publishDiagnostics(diagnostics: PublishDiagnosticsParams) {
+        client.publishDiagnostics(diagnostics)
     }
 
     /**
@@ -34,13 +32,8 @@ object Communicator : CommunicatorInterface {
      * @param severity the Severity of the message (Error/Info/Warning)
      */
     override fun sendDebugMessage(message: String, severity: MessageType) {
-
-
         if(debugMode) {
-            if(storedMessages.isNotEmpty()) {
-                storedMessages.toList().forEach { element -> client.logMessage(MessageParams(element.second, element.first)) }
-                storedMessages.clear()
-            }
+            println("Debug messages: $message")
             client.logMessage(MessageParams(severity, message))
         }
 
@@ -65,17 +58,4 @@ object Communicator : CommunicatorInterface {
     override fun setDebugMode(mode : Boolean){
         debugMode = mode
     }
-
-    /**
-     * Can be used to store a messages until a "sendDebugMessage" command is sent. The messages will be sent as FIFO
-     * @param message the message to send
-     * @param severity tne message severity
-     */
-    override fun bufferDebugMessage(message: String, severity: MessageType) {
-        if(debugMode) {
-            storedMessages.add(Pair(message, severity))
-        }
-    }
-
-
 }
\ 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
deleted file mode 100644
index 14e00846910be7754a8e37eaef51b9d21f26d946..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/dataStorage/Position.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-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/ProBSettings.kt b/src/main/kotlin/b/language/server/dataStorage/ProBSettings.kt
new file mode 100644
index 0000000000000000000000000000000000000000..21828a5f228cf7b3c29d753b47717e8872cc16c1
--- /dev/null
+++ b/src/main/kotlin/b/language/server/dataStorage/ProBSettings.kt
@@ -0,0 +1,3 @@
+package b.language.server.dataStorage
+
+data class ProBSettings(val wdChecks : Boolean, val strictChecks : Boolean, val performanceHints : Boolean)
\ 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
deleted file mode 100644
index 75648c672771ab97bb1f3ca6423b704172cc2f89..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/dataStorage/Problem.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package b.language.server.dataStorage
-
-
-/**
- * kotlin representation of prob ndjson problems
- */
-/**
- * @param type type of the problem (error/warning/information(
- * @param message problem message
- * @param reason reason for the problem to occur
- * @param file the file where the problem occurred
- * @param start start position of the problem
- * @param end end position of the problem
- * @version version of porbcli
- */
-data class Problem(val type : String , val message: String, val reason : String, val file : String, val start : Position,
-                   val end : Position, val version : String)
-
diff --git a/src/main/kotlin/b/language/server/dataStorage/Settings.kt b/src/main/kotlin/b/language/server/dataStorage/Settings.kt
index 16e6730db74edd2ce3a6dbc40e27675f580e80b5..40708a60950e5603a7d112f26b9dfd53afd867f0 100644
--- a/src/main/kotlin/b/language/server/dataStorage/Settings.kt
+++ b/src/main/kotlin/b/language/server/dataStorage/Settings.kt
@@ -1,7 +1,6 @@
 package b.language.server.dataStorage
 
-import java.io.File
 
 data class Settings(val strictChecks : Boolean = true,  val wdChecks : Boolean = true,
-                    val performanceHints : Boolean = true , val probHome : File = File("~/prob_prolog/probcli.sh"),
+                    val performanceHints : Boolean = true , val probHome : String = "DEFAULT",
                     val debugMode : Boolean = true)
diff --git a/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt b/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt
index 8c16106da28290fc85b37587012407f21af2db07..75060beb895e631bf9e62dfd79068537a2c350c1 100644
--- a/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt
+++ b/src/main/kotlin/b/language/server/proBMangement/ProBInterface.kt
@@ -8,8 +8,9 @@ interface ProBInterface {
     /**
      * Checks the given document with the help of ProB
      * @param uri the source to check
+     * @param settings the settings for this document
      * @return a list of all problems found
      */
-    abstract fun checkDocument(uri : String, settings: Settings) : List<Diagnostic>
+    fun checkDocument(uri : String, settings: Settings) : List<Diagnostic>
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/CouldNotFindProBHomeException.kt b/src/main/kotlin/b/language/server/proBMangement/prob/CouldNotFindProBHomeException.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e4adfa316c5d0fae6fab84e783f691ca17013495
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/CouldNotFindProBHomeException.kt
@@ -0,0 +1,3 @@
+package b.language.server.proBMangement.prob
+
+class CouldNotFindProBHomeException(message : String) : Exception(message)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernel.kt b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4f351af266b9272f2f30e8a070f5b7228ad8a190
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernel.kt
@@ -0,0 +1,158 @@
+package b.language.server.proBMangement.prob
+
+
+import b.language.server.communication.Communicator
+import b.language.server.communication.CommunicatorInterface
+import b.language.server.dataStorage.ProBSettings
+import com.google.inject.Inject
+import com.google.inject.Injector
+import de.prob.animator.ReusableAnimator
+import de.prob.animator.command.CheckWellDefinednessCommand
+import de.prob.animator.command.GetMachineOperationInfos
+import de.prob.animator.domainobjects.ErrorItem
+import de.prob.exception.ProBError
+import de.prob.scripting.ClassicalBFactory
+import de.prob.scripting.FactoryProvider
+import de.prob.scripting.ModelFactory
+import de.prob.scripting.ModelTranslationError
+import de.prob.statespace.AnimationSelector
+import de.prob.statespace.StateSpace
+import de.prob.statespace.Trace
+import kotlinx.coroutines.flow.flowViaChannel
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.MessageType
+import java.io.IOException
+
+/**
+ * Represents the interface to communicate with prob kernel
+ * Is called via injector
+ * @see ProBKernelManager
+ */
+class ProBKernel @Inject constructor(private val injector : Injector,
+                                     val classicalBFactory : ClassicalBFactory,
+                                     private val animationSelector: AnimationSelector,
+                                     private val animator : ReusableAnimator,
+                                     private val communicator : CommunicatorInterface) {
+
+
+    /**
+     * Checks the given machine file; prepares all necessary object
+     * @param path the file to check
+     * @param settings the settings under which the check takes place
+     * @return a list with the problems found
+     */
+    fun check(path : String, settings : ProBSettings) : List<Diagnostic>{
+        Communicator.sendDebugMessage("unloading old machine", MessageType.Info)
+        unloadMachine()
+
+        val factory = injector.getInstance(FactoryProvider.factoryClassFromExtension(path.substringAfterLast(".")))
+
+        val informationListener = InformationListener(path)
+        animator.addWarningListener(informationListener)
+
+        Communicator.sendDebugMessage("loading new machine", MessageType.Info)
+
+        val problems = loadMachine(settings, path, factory)
+
+        communicator.sendDebugMessage("returning from kernel problems are ${problems.toString()}", MessageType.Info)
+
+        return listOf(informationListener.getInformation(), problems).flatten()
+    }
+
+    /**
+     * Does the main work
+     * @param newTraceCreator a anonymous function dealing with the state space
+     * @param settings the settings to be applied
+     */
+    private fun loadMachine(settings: ProBSettings, path : String, factory : ModelFactory<*>): List<Diagnostic> {
+        communicator.sendDebugMessage("creating new state space", MessageType.Info)
+
+        val newStateSpace = animator.createStateSpace()
+        communicator.sendDebugMessage("setting preferences", MessageType.Info)
+        newStateSpace.changePreferences(prepareAdditionalSettings(settings))
+
+        val errors = mutableListOf<ErrorItem>()
+
+        try {
+            factory.extract(path).loadIntoStateSpace(newStateSpace)
+        } catch (e: IOException) {
+            communicator.sendDebugMessage("IOException ${e.message}", MessageType.Info)
+        } catch (e: ModelTranslationError) {
+            communicator.sendDebugMessage("ModelTranslationError ${e.message}", MessageType.Info)
+        } catch (e : ProBError){
+            errors.addAll(e.errors)
+        }
+
+        if(errors.none { errorItem -> errorItem.type == ErrorItem.Type.ERROR }) {
+            communicator.sendDebugMessage("No fatal errors found, continuing with option steps...", MessageType.Info)
+
+            if (settings.strictChecks) {
+                errors.addAll(newStateSpace.performExtendedStaticChecks())
+            }
+
+            try {
+                communicator.sendDebugMessage("executing optional steps", MessageType.Info)
+                executeAdditionalOptions(settings)
+            } catch (e: RuntimeException) {
+                communicator.sendDebugMessage("something bad happened, statespace was killed", MessageType.Warning)
+                newStateSpace.kill()
+            }
+
+        }
+
+        communicator.sendDebugMessage("processing errors", MessageType.Info)
+        newStateSpace.kill()
+        return convertErrorItems(errors, path)
+    }
+
+
+    /**
+     * executes additional commands, which are defined as separate command, all others are executed at
+     * @see prepareAdditionalSettings
+     * @param settings the settings to be executed as command
+     */
+    private fun executeAdditionalOptions(settings : ProBSettings){
+        if(settings.wdChecks){
+            communicator.sendDebugMessage("doing WD checks", MessageType.Info)
+           animator.execute(CheckWellDefinednessCommand())
+        }
+    }
+
+    /**
+     * to clean up a machine
+     */
+    private fun unloadMachine() {
+        val oldTrace = animationSelector.currentTrace
+        if (oldTrace != null) {
+            assert(oldTrace.stateSpace === animator.currentStateSpace)
+            animationSelector.changeCurrentAnimation(null)
+            oldTrace.stateSpace.kill()
+        }
+    }
+
+
+    /**
+     * prepares a map with additional settings
+     * note that the -lint option is an extra call to the state space and must be performed elsewhere
+     * @param proBSettings the settings to put in the map
+     * @return the settings map
+     */
+    private fun prepareAdditionalSettings(proBSettings: ProBSettings): MutableMap<String, String> {
+        val settings = mutableMapOf<String, String>()
+        if(proBSettings.performanceHints) {
+            settings["STRICT_CLASH_CHECKING"] = "TRUE"
+            settings["TYPE_CHECK_DEFINITIONS"] = "TRUE"
+        }else{
+            settings["STRICT_CLASH_CHECKING"] = "TRUE"
+            settings["TYPE_CHECK_DEFINITIONS"] = "TRUE"
+        }
+        if (proBSettings.strictChecks) {
+            settings["PERFORMANCE_INFO"] = "TRUE"
+        }else{
+            settings["PERFORMANCE_INFO"] = "TRUE"
+        }
+        return settings
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelManager.kt b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cc610a9cd61620dce0a562eab1b76d55ac1967ff
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelManager.kt
@@ -0,0 +1,97 @@
+package b.language.server.proBMangement.prob
+
+import b.language.server.communication.CommunicatorInterface
+import b.language.server.dataStorage.ProBSettings
+import b.language.server.dataStorage.Settings
+import b.language.server.proBMangement.ProBInterface
+import com.google.inject.Guice
+import com.google.inject.Stage
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.MessageType
+import java.io.File
+import java.net.URI
+
+/**
+ * Creates the prob kernel access and maintenance
+ */
+class ProBKernelManager(private val communicator : CommunicatorInterface) : ProBInterface {
+
+    private var kernel : ProBKernel
+    private var probHome = "DEFAULT"
+
+    init{
+        kernel = setup()
+    }
+
+
+    /**
+     * @return an instance of prob kernel
+     */
+    private fun setup() : ProBKernel {
+        val injector = Guice.createInjector(Stage.PRODUCTION, ProBKernelModule(communicator))
+        val kernel : ProBKernel
+        try{
+            kernel = injector.getInstance(ProBKernel::class.java)
+        }catch (e : de.prob.exception.CliError){
+            throw Exception("wrong path to prob $probHome")
+        }
+        return kernel
+    }
+
+    /**
+     * Checks if the given prob home matches - if not a knew prob kernel will be initialized
+     * @param probNewHome the potential new proB home
+     * @return changes was successful/no change at all
+     */
+    private fun checkProBVersionSetting(probNewHome : String) : Boolean{
+        return if(probNewHome != probHome)
+        {
+            if(probNewHome == "DEFAULT"){ //Use default prob
+                System.setProperty("prob.home", "null")
+                kernel = setup()
+                true
+            }
+            else {
+
+                val dict = File(probNewHome)
+                if (dict.exists() && dict.isDirectory) { // Use custom prob
+                    System.setProperty("prob.home", probNewHome)
+                    kernel = setup()
+                    probHome = probNewHome
+                    true
+                } else {
+                    false
+                }
+            }
+        }else{
+            true
+        }
+    }
+
+
+    /**
+     * Checks the given document with the help of ProB
+     * @param uri the source to check
+     * @param settings the settings for this document
+     * @return a list of all problems found
+     *
+     * @throws CouldNotFindProBHomeException the given path ist not "DEFAULT" and wrong
+     */
+    override fun checkDocument(uri: String, settings: Settings): List<Diagnostic> {
+
+        val path = URI(uri).path
+       //Files.exists(Path.of(URI(uri)))
+
+        communicator.sendDebugMessage("try to use ${settings.probHome} as prob version instead of " + System.getProperty("prob.home"), MessageType.Info)
+        val result = checkProBVersionSetting(settings.probHome)
+        if(!result){
+          throw CouldNotFindProBHomeException("searched at ${settings.probHome} for prob but found nothing - make sure " +
+                  "you point to the prob directory not to probcli.sh/probcli")
+        }
+
+        communicator.sendDebugMessage("success!", MessageType.Info)
+        communicator.sendDebugMessage("checking document", MessageType.Info)
+        return kernel.check(path, ProBSettings(wdChecks = settings.wdChecks, strictChecks = settings.strictChecks,
+                performanceHints = settings.performanceHints))
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelModule.kt b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..25465911a116652a3a391224b3e8aac7e766e4b5
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/ProBKernelModule.kt
@@ -0,0 +1,12 @@
+package b.language.server.proBMangement.prob
+
+import b.language.server.communication.CommunicatorInterface
+import com.google.inject.AbstractModule
+import de.prob.MainModule
+
+class ProBKernelModule(private val communicator : CommunicatorInterface) : AbstractModule() {
+    override fun configure() {
+        install(MainModule())
+        bind(CommunicatorInterface::class.java).toInstance(communicator)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/Util.kt b/src/main/kotlin/b/language/server/proBMangement/prob/Util.kt
new file mode 100644
index 0000000000000000000000000000000000000000..335d7e180c2631e73e8adcbe9daf5c491fa8096a
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/Util.kt
@@ -0,0 +1,48 @@
+package b.language.server.proBMangement.prob
+
+import de.prob.animator.domainobjects.ErrorItem
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.Range
+
+fun convertErrorItems(errorItems: List<ErrorItem>, currentLoadedFile : String) : List<Diagnostic>{
+    return  errorItems.map { errorItem ->
+        errorItem.locations.map { location ->
+            Diagnostic(Range(
+                    Position(location.startLine - 1, location.startColumn),
+                    Position(location.endLine - 1, location.endColumn)),
+                    errorItem.message,
+                    getErrorItemType(errorItem.type),
+                    location.filename)
+        }.ifEmpty { //Fallback when errors from prob do not have position infos
+            listOf(Diagnostic(Range(
+                    Position(0,0),
+                    Position(0,0)),
+                    errorItem.message,
+                    getErrorItemType(errorItem.type),
+                    currentLoadedFile))
+        }
+    }.flatten()
+}
+
+fun getErrorItemType(errorItem: ErrorItem.Type) : DiagnosticSeverity{
+    return when(errorItem){
+        ErrorItem.Type.ERROR -> {
+            DiagnosticSeverity.Error
+        }
+        ErrorItem.Type.WARNING -> {
+            DiagnosticSeverity.Warning
+        }
+        ErrorItem.Type.INTERNAL_ERROR -> {
+            DiagnosticSeverity.Error
+        }
+        ErrorItem.Type.MESSAGE -> {
+            DiagnosticSeverity.Information
+        }
+        else -> {
+            DiagnosticSeverity.Error
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/prob/WarningListener.kt b/src/main/kotlin/b/language/server/proBMangement/prob/WarningListener.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7df1aac275b4086287523067fdcbc56357b6f4a5
--- /dev/null
+++ b/src/main/kotlin/b/language/server/proBMangement/prob/WarningListener.kt
@@ -0,0 +1,21 @@
+package b.language.server.proBMangement.prob
+
+import de.prob.animator.IWarningListener
+import de.prob.animator.domainobjects.ErrorItem
+import org.eclipse.lsp4j.Diagnostic
+
+/**
+ * Custom collector to collect warnings from prob kernel
+ */
+class InformationListener(val fallbackPath : String) : IWarningListener {
+    private val warningList : ArrayList<ErrorItem> = arrayListOf()
+
+
+    override fun warningsOccurred(warnings: MutableList<ErrorItem>?) {
+        warningList.addAll(warnings!!.toList())
+    }
+
+    fun getInformation() : List<Diagnostic>{
+        return convertErrorItems(warningList, fallbackPath)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/probCli/CommandCouldNotBeExecutedException.kt b/src/main/kotlin/b/language/server/proBMangement/probCli/CommandCouldNotBeExecutedException.kt
deleted file mode 100644
index d4ed1f9dbf3d8592d9d23f7c7c48b11484c9b005..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/proBMangement/probCli/CommandCouldNotBeExecutedException.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package b.language.server.proBMangement.probCli
-
-class CommandCouldNotBeExecutedException(message: String?) : Exception(message)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/probCli/PathCouldNotBeCreatedException.kt b/src/main/kotlin/b/language/server/proBMangement/probCli/PathCouldNotBeCreatedException.kt
deleted file mode 100644
index e359ab5367b11626dbbcdf93ad2ceb9df50265bd..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/proBMangement/probCli/PathCouldNotBeCreatedException.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package b.language.server.proBMangement.probCli
-
-class PathCouldNotBeCreatedException(message: String?) : Exception(message)
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/proBMangement/probCli/ProBCommandLineAccess.kt b/src/main/kotlin/b/language/server/proBMangement/probCli/ProBCommandLineAccess.kt
deleted file mode 100644
index 3f18caef3e27d7d90c0c172086729431926c4e88..0000000000000000000000000000000000000000
--- a/src/main/kotlin/b/language/server/proBMangement/probCli/ProBCommandLineAccess.kt
+++ /dev/null
@@ -1,252 +0,0 @@
-package b.language.server.proBMangement.probCli
-
-import b.language.server.communication.CommunicatorInterface
-import b.language.server.dataStorage.Problem
-import b.language.server.dataStorage.Settings
-import b.language.server.proBMangement.ProBInterface
-import com.google.gson.Gson
-import org.eclipse.lsp4j.*
-import java.io.*
-import java.net.URI
-
-
-/**
- * Access ProB via command line
- */
-class ProBCommandLineAccess(val communicator : CommunicatorInterface) : 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> {
-        communicator.sendDebugMessage("checking document ($uri) with proB", MessageType.Info )
-        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 has not been created due some issue.")
-        }
-        communicator.sendDebugMessage("creation successful", MessageType.Info)
-        val command = buildCommand(settings, path, errorPath)
-        communicator.sendDebugMessage("sending command <$command> to proB", MessageType.Info)
-
-        performActionOnDocument(command)
-
-        val problems = readProblems(errorPath.path)
-        communicator.sendDebugMessage("deleting tmp", MessageType.Info )
-        errorDict.delete()
-        communicator.sendDebugMessage("found the following problems: $problems", MessageType.Info)
-
-        return transformProblems(problems)
-    }
-
-
-    /**
-     * Constructs the commandline call to proB depending on the given settings
-     * Produces something like
-     * [/home/sebastian/prob_prolog/probcli,  -p, MAX_INITIALISATIONS, 0, -version ,  -p, NDJSON_ERROR_LOG_FILE ,...]
-     * @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) : ProcessBuilder{
-        val additionalArgument = "-p"
-        val version = "-version"
-        val configuration = "MAX_INITIALISATIONS"
-        val maxInitAmount = "0"
-        val ndjson = "NDJSON_ERROR_LOG_FILE"
-        val releaseJavaParser = "-release_java_parser"
-        val wdCheck = "-wd-check"
-        val strictClashChecking = "STRICT_CLASH_CHECKING"
-        val typeCheckDefinitions = "TYPE_CHECK_DEFINITIONS"
-        val lint = "-lint"
-        val tRUE = "TRUE"
-        val performanceHints = "" +
-                "PERFORMANCE_INFO"
-
-
-        //voiding stdout and stderr
-        val outputSink = if(System.getProperty("os.name").toLowerCase().contains("win")){
-            File("NUL")
-        }else{
-            File("/dev/null")
-        }
-
-        communicator.sendDebugMessage("voiding err and output to: ${outputSink.absolutePath}", MessageType.Info)
-
-        val command = mutableListOf<String>()
-
-
-        command.add(settings.probHome.absolutePath)
-        command.add(additionalArgument)
-        command.add(configuration)
-        command.add(maxInitAmount)
-        command.add(version)
-        command.add(additionalArgument)
-        command.add(ndjson)
-        command.add(errorPath.absolutePath)
-
-        if (settings.wdChecks){
-            command.add(wdCheck)
-            command.add(releaseJavaParser)
-        }
-
-        if(settings.strictChecks){
-            command.add(additionalArgument)
-            command.add(strictClashChecking)
-            command.add(tRUE)
-            command.add(additionalArgument)
-            command.add(typeCheckDefinitions)
-            command.add(tRUE)
-            command.add(lint)
-        }
-
-
-        if(settings.performanceHints) {
-            command.add(additionalArgument)
-            command.add(performanceHints)
-            command.add(tRUE)
-        }
-
-        command.add(fileToCheck.absolutePath)
-
-
-
-        communicator.sendDebugMessage("creating cli call $command", MessageType.Info)
-
-        try {
-            return ProcessBuilder()
-                    .command(command)
-                    .redirectOutput(outputSink)
-                    .redirectError(outputSink)
-
-        }catch (e : IllegalArgumentException){
-            communicator.sendDebugMessage("illegal argument exception ${e.cause}", MessageType.Info)
-        }
-        return ProcessBuilder()
-    }
-
-
-    /**
-     * 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{
-        communicator.sendDebugMessage("creating errorDict $errorDict and errorFile $errorPath", MessageType.Info)
-        errorDict.mkdirs()
-        FileWriter(errorPath, false).close()
-        errorPath.deleteOnExit()
-        errorDict.deleteOnExit()
-        return errorDict.exists() && errorPath.exists()
-    }
-
-    /**
-     * Executes the given command
-     * @param command to execute
-     * @throws IOException failed to reach probcli
-     */
-    private fun performActionOnDocument(command : ProcessBuilder) {
-        communicator.sendDebugMessage("execution of ${command.command()}", MessageType.Info)
-
-        val process: Process = command.start()
-
-        communicator.sendDebugMessage("waiting for process to return", MessageType.Info)
-
-        // process.waitFor() //we must wait here to ensure correct behavior when reading an error
-        val exitStatus = process.waitFor()
-        communicator.sendDebugMessage("exit status of execution: $exitStatus", MessageType.Info)
-    }
-
-
-
-    /**
-     * 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 ->
-                        val range = Range(
-                                Position(problem.start.line, problem.start.col),
-                                Position(problem.end.line, problem.end.col))
-                        val diagnostic = Diagnostic(
-                        range,
-                        problem.message,
-                        when (problem.type) {
-                            "error" -> {
-                                DiagnosticSeverity.Error
-                            }
-                            "warning" -> {
-                                DiagnosticSeverity.Warning
-                            }
-                            "information" -> {
-                                DiagnosticSeverity.Information
-                            }
-                            else -> {
-                                DiagnosticSeverity.Hint
-                            }
-                        },
-                        problem.file
-                        )
-                    diagnostic.relatedInformation =
-                            listOf(DiagnosticRelatedInformation(Location(problem.file, range), "probcli v.${problem.version}"))
-                    diagnostic
-
-                }
-    }
-
-}
\ No newline at end of file
diff --git a/src/test/kotlin/b/language/server/ProBCommandLineTest.kt b/src/test/kotlin/b/language/server/ProBCommandLineTest.kt
deleted file mode 100644
index 6ea73886635bfd4d941aee314186b307ae0fe397..0000000000000000000000000000000000000000
--- a/src/test/kotlin/b/language/server/ProBCommandLineTest.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-package b.language.server
-
-import b.language.server.communication.Communicator
-import b.language.server.dataStorage.Position
-import b.language.server.dataStorage.Problem
-import b.language.server.dataStorage.Settings
-import b.language.server.proBMangement.probCli.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
-import kotlin.test.assertTrue
-
-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(Communicator).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(5, 65)), message,  DiagnosticSeverity.Hint, problemFile, " probcli v.$version" )
-        assertEquals(diagnostic, transformedProblem)
-
-    }
-
-
-    @Test
-    fun test_createFolders_success(@TempDir tempPath : File = File("tmp")){
-        val errorDict = File(tempPath.path+"/tmp")
-        val errorPath = File(tempPath.path+"/tmp/hallo.njson")
-        val result = ProBCommandLineAccess().createFolder(errorDict, errorPath)
-        assertTrue(result)
-    }
-*/
-
-}
\ No newline at end of file
diff --git a/src/test/kotlin/b/language/server/prob2/proBMangement/UtilTest.kt b/src/test/kotlin/b/language/server/prob2/proBMangement/UtilTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0eea8cf11c1a91a295309e6f67f06cda0e611535
--- /dev/null
+++ b/src/test/kotlin/b/language/server/prob2/proBMangement/UtilTest.kt
@@ -0,0 +1,68 @@
+package b.language.server.prob2.proBMangement
+
+import b.language.server.proBMangement.prob.convertErrorItems
+import b.language.server.proBMangement.prob.getErrorItemType
+import de.prob.animator.domainobjects.ErrorItem
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.Range
+import org.junit.jupiter.api.Test
+import kotlin.test.assertEquals
+
+class UtilTest {
+
+    /**
+     * as we using functional programming we don“t test the logic but the functionality
+     */
+    @Test
+    fun generateErrorItem()
+    {
+        val startLine = 100
+        val statCol = 100
+        val endLine = 101
+        val endCol = 101
+        val message = "hello"
+        val file = "/test"
+
+         val errorItem = ErrorItem(message, ErrorItem.Type.INTERNAL_ERROR,
+                 listOf(ErrorItem.Location(file, startLine,statCol,endLine,endCol)))
+
+         val diagnostic = Diagnostic(
+                 Range(
+                         Position(startLine-1, statCol),
+                         Position(endLine-1, endCol)),
+                 message, DiagnosticSeverity.Error, file)
+
+        val errorItemAfter = convertErrorItems(listOf(errorItem)).first()
+
+        assertEquals(diagnostic, errorItemAfter)
+
+    }
+
+    @Test
+    fun errorCodeTranslation_Error1()
+    {
+        val result = getErrorItemType(ErrorItem.Type.INTERNAL_ERROR)
+
+        assertEquals(DiagnosticSeverity.Error, result)
+    }
+
+    @Test
+    fun errorCodeTranslation_Error2()
+    {
+        val result = getErrorItemType(ErrorItem.Type.ERROR)
+
+        assertEquals(DiagnosticSeverity.Error, result)
+    }
+
+    @Test
+    fun errorCodeTranslation_Warning()
+    {
+        val result = getErrorItemType(ErrorItem.Type.WARNING)
+
+        assertEquals(DiagnosticSeverity.Warning, result)
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/test/resources/Lift.mch b/src/test/resources/Lift.mch
new file mode 100644
index 0000000000000000000000000000000000000000..2aa64ac79146448a2b7f351d4dbf080844e7484d
--- /dev/null
+++ b/src/test/resources/Lift.mch
@@ -0,0 +1,19 @@
+MACHINE Lift
+
+VARIABLES  floor
+
+INVARIANT  floor : 0..100 /* NAT */
+
+INITIALISATION floor :=
+
+
+
+
+OPER1ATIONS
+
+	inc = PRE floor<100 THEN floor := floor + 1 END ;
+	dec = PRE floor>0 THEN floor := floor - 1 END;
+	open_door = skip;
+	close_door = skip
+
+END