diff --git a/Py4Mod/py4mod/DymInterface.py b/Py4Mod/py4mod/DymInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..3dd365bf07d324f8001b197236a40db7ce02a45c
--- /dev/null
+++ b/Py4Mod/py4mod/DymInterface.py
@@ -0,0 +1,192 @@
+import os
+import re
+from dymola.dymola_interface import DymolaInterface
+from dymola.dymola_exception import DymolaException
+from modelicares import SimRes
+import numpy as np
+
+class DymInterface(object):
+	def __init__(self, dymola_path = "", use64bit = True, port = -1, showwindow  = False, debug = False, allowremote = False, nolibraryscripts = False):
+		"""
+		Creates a wrapper for Dymola and starts Dymola.
+		
+		@param str dymolapath: The path to ``Dymola.exe``. Default is an empty string, which means that the path should be auto-detected.
+		@param bool use64bit: If ``True``, the 64-bit Dymola is used. If ``False``, the 32-bit Dymola is used. Default is ``True``.
+		@param int port: The port number to use for connecting to Dymola. Default is ``-1``, which means that a port should be auto-assigned.
+		@param bool showwindow: This flag controls whether the Dymola window will be visible or not when calling functions in the interface. The default value is ``False``, which means that Dymola will be hidden.
+		@param bool debug: For debugging the Dymola Python interface. Note that it is intended for debugging the interface, not Modelica models. Setting this variable to ``True`` outputs debug messages in the console. For advanced users only.
+		@param bool allowremote: By default, Dymola only allows local connections. The default value is ``False``. Set this flag to ``True`` to allow access from other machines.
+		@param bool nolibraryscripts: Corresponds to the command-line argument with the same name. The default value is ``False``.
+		@raises: :class:DymolaException <dymola.dymola_exception.DymolaException>
+		"""
+		#dymola parameters
+		self.__dymola = None				#dymola wrapper object
+		self.__dymola_path = dymola_path	
+		self.__use64bit = use64bit
+		self.__port = port
+		self.__showwindow  = showwindow
+		self.__debug = debug
+		self.__allowremote = allowremote
+		self.__nolibraryscripts = nolibraryscripts
+		
+		#model variables
+		self.modelName=""
+		self.resultFileName=""
+		                             
+		try:
+			#Instantiate the Dymola interface and starts Dymola   
+			self.__dymola = DymolaInterface(self.__dymola_path, self.__use64bit, self.__port, self.__showwindow, self.__debug, self.__allowremote, self.__nolibraryscripts)
+
+			# Set Dymola options                    
+			self.__dymola.ExecuteCommand("experimentSetupOutput(events=false);")
+			self.__dymola.ExecuteCommand("Advanced.OutputModelicaCode:=true;")
+			self.__dymola.ExecuteCommand("Advanced.OutputModelicaCodeWithAliasVariables = true;")
+			#dymola.ExecuteCommand("Advanced.StoreProtectedVariables:=true;")
+			
+		except DymolaException as ex:
+			raise Exception(ex)
+	
+	
+	def changeWorkingDirectory(self, dir=""):
+		"""
+		Change directory to the given path
+		If the given path is the empty string, the function simply returns the current working directory
+		
+		@param str Dir: Directory to change to. If directory="" this function return the current directory
+		@raises: exception
+		"""
+		if dir=="":
+			test = self.__dymola.cd()
+			cwd=self.__dymola.getLastError().replace(' ',"").replace('=true', "").replace('\n',"")
+			return cwd
+		
+		if not os.path.exists(dir):
+			raise Except("File Error: " + os.path.abspath(fileName) + " does not exists!!!")
+				
+		self.__dymola.cd(dir)
+	
+		
+	def loadFile(self, fName, mustRead=True, changeDirectory=False):
+		"""
+		Reads the file specified by fName.
+		This corresponds to File->Open in the menus. 
+		
+		@param str fName: File-path to open.
+		@param bool mustRead=False means that if the file already is opened/read, it is not opened/read again. 
+			If mustRead=true in such a case the user is promted for removing the present one and open it again. 
+			The value false can be useful in scriping, when only wanting to assure that a certain file has been read.
+		@param bool changeDirectory: If true we automatically change to the directory of the file.
+		@returns: true if successful
+		@raises: :class:DymolaException <dymola.dymola_exception.DymolaException>
+		"""
+		if not os.path.isfile(fName):
+			msg = "File Error: " + os.path.abspath(fileName) + " does not exists!!!"
+			raise Exception(msg)
+		if not self.__dymola.openModel(fName, mustRead, changeDirectory):
+			return False
+		return True
+			
+
+	def dymApplyModifiers(self, modifierList):
+		""" Applies modifiers in modifierList, which is of format
+			modifierList=[['submodule1','param1','value1'],['submodule2','param2','value2'],...]        
+		"""
+		#function not tested 
+		cmdString=""
+		for i in range(len(modifierList)):
+			cmdString+= modifierList[i][0] + "." + modifierList[i][1] + "=" + str(modifierList[i][2]) + ";"            
+		self.__dymola.ExecuteCommand(cmdString) 
+	
+	
+	def buildModel(self, model):
+		"""
+		Compile the model (with current settings). 
+		This corresponds to Translate in the menus
+		
+		@param str problem: Name of model, e.g. Modelica.Mechanics.Rotational.Components.Clutch.
+		@raises: Exception
+	
+		"""
+		self.modelName=model
+		try:
+			if not self.__dymola.translateModel(model):
+				msg = 'Translation failed. Below is the Translation log: \n' + self.__dymola.getLastError()
+				raise Exception(msg)
+		except DymolaException as err:
+			msg = 'Error in dymTranslate: {}'.format(err)
+			raise Exception(msg)
+	
+	
+	def simulateModel(self, model, startTime=0, stopTime=10, 
+						numberOfIntervals=0, outputInterval=1, method='Dassl', tolerance=0.0001, 
+						fixedstepsize=0.0, resultFile="dsres", initialNames=[], initialValues=[], 
+						finalNames=[], autoLoad=False):
+		"""Simulates the model in the mode specified in simMode. The results are stored in 
+        files with the name resultName. It returns a list of the Variable Names andanother
+        list with the values they had at the start of the simulation.
+        
+		@param str model: Name of model, e.g. Modelica.Mechanics.Rotational.Components.Clutch.
+		@param float startTime: Start of simulation.
+		@param float stopTime: End of simulation.
+		@param int numberOfIntervals: Number of output points.
+		@param float outputInterval: Distance between output points.
+		@param str method: Integration method.
+		@param float tolerance: Tolerance of integration.
+		@param float fixedstepsize: Fixed step size for Euler.
+		@param str resultFile: Where to store result.
+		@param str[] initialNames: Parameters and start-values to set. Dimension ``[:]
+		"""
+		try:				
+			# starts simulation
+			result = self.__dymola.simulateExtendedModel(model, startTime, stopTime, 
+						numberOfIntervals,  outputInterval, method, tolerance, 
+						fixedstepsize, resultFile, initialNames, initialValues, 
+						finalNames, autoLoad)
+			self.resultFileName=resultFile
+						
+			if not result:
+				err_msg = "Simulation failed. Below is the simulation log:\n" + self.__dymola.getLastError()
+				raise Exception(err_msg)
+				
+		except DymolaException as err:
+			err_msg = str("Dymola failed. Below is the log:\n" + str(err))
+			raise Exception(err_msg)
+		
+			
+	def getResultsFast(self, outputVarList=[]):
+		""" Returns the trajectories for the variables in outputVarList in
+		the format of numpy.array by using ModelicaRes
+		
+		This Method can work faster than getSolutions() if the number of solutions is big
+        """
+		file = os.path.join(self.changeWorkingDirectory(""), self.resultFileName + ".mat")
+		sim=SimRes(file)
+		arrTraj=[]        
+		for item in outputVarList:
+			if np.array_equal(sim('Time').samples.values,sim(item).samples.times):
+				arrTraj.append(sim(item).samples.values)
+			else:
+				arrTraj.append(np.array(np.interp(sim('Time').samples.values,sim(item).samples.times,sim(item).samples.values),'float32'))            
+		return np.array(arrTraj)
+	
+	
+	def getResults(self, outputVarList = []):
+		""" Returns the trajectories for the variables in outputVarList in
+		the format of numpy.array by using DymolaInterface in the same order as outputVarList
+		"""
+		sizeTraj = self.__dymola.readTrajectorySize(self.resultFileName + ".mat")
+		arrTraj = np.array(self.__dymola.readTrajectory(self.resultFileName + ".mat", outputVarList, sizeTraj))    
+		return arrTraj
+	
+	
+	def getResultVarNames(self):
+		""" Returns the variablen names from the simulation result."""
+		varNames = self.__dymola.readTrajectoryNames(self.resultFileName + ".mat")
+		varNames.sort()
+		return varNames
+		
+	
+	def close(self):
+		if self.__dymola is not None:
+			self.__dymola.close()
+			self.__dymola = None 
\ No newline at end of file
diff --git a/Py4Mod/py4mod/ModelicaModel.py b/Py4Mod/py4mod/ModelicaModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..7fb8d803debe4b6c9ff7fe34a88396fa310c153c
--- /dev/null
+++ b/Py4Mod/py4mod/ModelicaModel.py
@@ -0,0 +1,693 @@
+from shutil import copyfile
+from shutil import copy
+from bisect import bisect
+import numpy as np
+import re
+import ast
+# moved interface imports for Dymola and OM to create Interface to allow for OMInterface use with Python 3.x
+
+class ModelicaModel(object):
+	def __init__(self, model, mainPath):
+		"""Constructor of the class ModelicaModel, reads and format a model that
+		is given by the path of the project and the Name it has in this Project
+		"""
+		self._model = model # model identifier in package hierarchy [e.g. packageName.subPackageName.modelName]
+		self._mainPath = mainPath # path where either the model file itself or the corresponding package.mo can be found
+		if not self._mainPath[-1] == "\\":
+			self._mainPath = self._mainPath + "\\"
+		self._modelName = self.getModelName() # actual name of model extracted from self._model
+		self._modelPath = self.__getModelPath() # complete path of the model file deduced from self._mainPath and self._model			  
+		self._modelLines = self.__readModel()
+		self._formatModel()
+		self._values = {}
+		self.interface = None				#interface object
+		self.interaceName = ""				#"DYMOLA" or "OPENMODELICA"
+
+		
+	#-------------------------- FUNCTIONS TO USE DYMOLA OR OPENMODELICA -------------------------#
+	def createInterface(self, interface, **kwargs):
+		if interface=='DYMOLA':
+			from DymolaFunctions import DymInterface
+			
+			dymola_path = ""	
+			use64bit = True
+			port = -1
+			showwindow  = False
+			debug = False
+			allowremote = False
+			nolibraryscripts = False
+		
+			for key, value in kwargs.items():
+				if key=='dymola_path':
+					dymola_path=value
+				elif key=='use64bit':
+					use64bit=value
+				elif key=='port':
+					port=value
+				elif key=='showwindow':
+					showwindow=value
+				elif key=='debug':
+					debug=value
+				elif key=='allowremote':
+					allowremote=value
+				elif key=='nolibraryscripts':
+					nolibraryscripts=value
+						
+			self.interface = DymInterface(dymola_path, use64bit, port, showwindow, debug, allowremote, nolibraryscripts)
+			self.interfaceName=interface
+
+		elif interface=='OPENMODELICA':
+			from OMInterface import OMInterface
+			self.interface = OMInterface()
+			for key,value in kwargs.items():
+				if key=='om_path':
+					self.interface.setModelicaPath(value)
+			self.interfaceName=interface
+		
+		else:
+			raise Exception('The possible Interfaces are "{}" and "{}"'.format('DYMOLA', 'OPENMODELICA'))
+	
+	def changeWorkingDirectory(self, dir=""):
+		"""
+		Change directory to the given path
+		If the given path is the empty string, the function simply returns the current working directory
+		
+		@param str Dir: Directory to change to. If directory="" this function return the current directory
+		@raises: exception
+		"""
+		if self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+		
+		if dir=="": 
+			return self.interface.changeWorkingDirectory(dir)		
+		
+		self.interface.changeWorkingDirectory(dir)	
+		
+	def loadFile(self, fName):
+		"""
+		Reads the file specified by fName.
+		This corresponds to File->Open in the menus. 
+		
+		@param str fName: File-path to open.
+		@raises: Exception()
+		"""
+		if self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+		
+		self.interface.loadFile(fName)			
+		
+	def buildModel(self, **kwargs):
+		"""
+		builds self._model by generating c code and build it.
+
+		other arguments for modelica interface:
+		@input float startTime: the start time of the simulation. <default> = 0.0
+		@input float stopTime: the stop time of the simulation. <default> = 1.0
+		@input float numberOfIntervals: number of intervals in the result file. <default> = 500
+		@input float tolerance: tolerance used by the integration method. <default> = 1e-6
+		@input str method: integration method used for simulation. <default> = "dassl"
+		@input str fileNamePrefix: fileNamePrefix. <default> = ""
+		@input str options: options. <default> = ""
+		@input str outputFormat: Format for the result file. <default> = "mat"
+		@input str variableFilter: Filter for variables that should store in result file. <default> = .*
+		@input str cflags: compiler flags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html)
+		@input str simflags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		"""
+		if self.interfaceName=='OPENMODELICA':
+			self.interface.buildModel(self._model, **kwargs)
+		
+		elif self.interfaceName=='DYMOLA':
+			self.interface.buildModel(self._model)				
+		
+		elif self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+
+	def simulate(self, **kwargs):
+		"""
+		DYMOLA: Simulates self._model 
+		optional arguments for the dymola interface:
+		@param float startTime: Start of simulation.
+		@param float stopTime: End of simulation.
+		@param int numberOfIntervals: Number of output points.
+		@param float outputInterval: Distance between output points.
+		@param str method: Integration method.
+		@param float tolerance: Tolerance of integration.
+		@param float fixedstepsize: Fixed step size for Euler.
+		@param str resultFile: Where to store result.
+		@param str[] initialNames: Parameters and start-values to set. Dimension ``[:]
+		
+		MODELICA: simulates or re-simulate the model that was compiled with ModelicaModel.buildModel()
+		 - optional arguments for the modelica interface
+		 @input str simFlags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		Note: Model must be built before this function can be called!
+		"""
+		
+		if self.interfaceName=='DYMOLA':
+			startTime=0
+			stopTime=10
+			numberOfIntervals=0
+			outputInterval=1
+			method='Dassl'
+			tolerance=0.0001 
+			fixedstepsize=0.0
+			resultFile="dsres"
+			initialNames=[]
+			initialValues=[] 
+			finalNames=[]
+			autoLoad=False
+			
+			for key, value in kwargs.items():
+				if key=='startTime':
+					startTime=value
+				elif key=='stopTime':
+					stopTime=value	
+				elif key=='numberOfIntervals':
+					numberOfIntervals=value	
+				elif key=='outputInterval':
+					outputInterval=value	
+				elif key=='method':
+					method=value	
+				elif key=='tolerance':
+					tolerance=value	
+				elif key=='fixedstepsize':
+					fixedstepsize=value	
+				elif key=='resultFile':
+					resultFile=value
+				elif key=='initialNames':
+					initialNames=value
+				elif key=='initialValues':
+					initialValues=value
+				elif key=='finalNames':
+					finalNames=value
+				elif key=='autoLoad':
+					autoLoad=value
+					
+			self.interface.simulateModel(self._model, startTime, stopTime, 	numberOfIntervals, 
+						outputInterval, method, tolerance, fixedstepsize, resultFile, 
+						initialNames, initialValues, finalNames, autoLoad)
+	
+		elif self.interfaceName=='OPENMODELICA':
+			simflags=None
+			for key, value in kwargs.items():
+				if key=='simflags':
+					simflags=value
+									
+			self.interface.simulate(simflags)
+		
+		elif self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+
+	def getResults(self, outputVarList = []):
+		if self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+			
+		return self.interface.getResultsFast(outputVarList)
+			
+	def getResultVarNames(self):
+		if self.interface is None:
+			raise Exception('The interface has not yet been initialized !!!')
+		
+		return self.interface.getResultVarNames()
+			
+	def close(self):
+		"""
+		Terminate execution of the interface
+		"""
+		if self.interfaceName=='OPENMODELICA':
+			self.interface.buildModel(self._model, **kwargs)
+		
+		self.interface.close()
+		self.interface=None
+
+
+	#-------------------------- FUNCTIONS TO WORK ON MODELICA CODE ------------------------------#
+	def getSubmodelNames(self, subModelType):
+		"""Searches every instance of the type subModelType and returns a list with
+		the names they have in the model.
+		"""
+		subModelNames = []
+		for i in range(self.__var_start, self.__var_end +1):
+			mo = re.search(subModelType + r" +(\w+)[ (]?", self._modelLines[i])
+			if mo:
+				name = mo.group(1)
+				subModelNames.append(name)
+		return subModelNames
+		
+	def getSubmodelModifierValue(self,listSubmodelNames,modifierName):
+		modValue = []
+		positions=[]
+		for submodelName in listSubmodelNames:
+			positions.append(self.__getLinePositionName(submodelName))
+		for pos in positions:
+			mo = re.search(modifierName + r"=(\d+)", self._modelLines[pos])
+			if mo:
+				val = mo.group(1)
+				modValue.append(val)
+		return modValue
+		 
+	def getSubModelTypesAll(self):
+		""" Returns a list of all submodeltypes that the model contains
+		"""
+		submodeltypes= []
+		for i in range(self.__var_start,self.__var_end):
+			mo = re.search(r" *(?:inner)? ([\w\.]+) +(?:\w+)[ (]?", self._modelLines[i])
+			if mo:
+				submodeltype = mo.group(1)
+				if not (submodeltype in submodeltypes):
+					submodeltypes.append(submodeltype)
+		return submodeltypes
+		
+	
+	def changeSubmodelTypeAll(self, oldType, newType, positions = []):
+		"""Changes the type of all submodels with the type oldType to the type newType.
+		ATTENTION: this can lead to Problems if the equations (e.g. connections) don't
+		match with the new type.
+		"""
+		if positions == []:		
+			positions = self.__getLinePositionSubmodel(oldType)
+		for i in positions:
+			mo = re.search(oldType + r" ", self._modelLines[i])
+			start = mo.start()
+			end = mo.end() - 1
+			self._modelLines[i] = self._modelLines[i][:start] + newType + self._modelLines[i][end:] 
+		self.__writeModel()
+		
+	def changeSubmodelType(self, listSubmodelNames, oldType, newType):
+		"""Changes the type of all submodels in listSubmodelNames from oldType to type newType.
+		ATTENTION: this can lead to Problems if the equations (e.g. connections) don't
+		match with the new type.
+		"""
+		positions=[]
+		for submodelName in listSubmodelNames:
+			positions.append(self.__getLinePositionName(submodelName))
+		for pos in positions:
+			mo = re.search(oldType + r" ", self._modelLines[pos])
+			start = mo.start()
+			end = mo.end() - 1
+			self._modelLines[pos] = self._modelLines[pos][:start] + newType + self._modelLines[pos][end:] 
+		self.__writeModel()   
+		
+	def changeSubmodelName(self, dictSubmodelNames):
+		"""Changes the names of the submodels in the declaration according to dictSubmodelNames, which includes the 
+		renaming entries in the manner {"oldSubmodelName":"newSubmodelName"}
+		ATTENTION: corresponding connections, which include the old submodel name, must be changed seperatedly by using changeConnection
+		or changeConnectionPin
+		"""		
+		for submodelNameOld,submodelNameNew in dictSubmodelNames.iteritems():
+			pos = self.__getLinePositionName(submodelNameOld)
+			self._modelLines[pos] = re.sub(submodelNameOld,submodelNameNew,self._modelLines[pos])
+		self.__writeModel()
+		
+	def changeVars(self, varList, overwrite = True):
+		"""Changes or adds the initial values of variables/parameters that are specified
+		in the variable-section of the model.
+		The list varList contains the variables and the values that should be set.
+		The items stored in varList have the form of ["Submodel.Subsubmodel", value]
+		if you set the value of a differential variable the variable name has to end
+		with ".start".
+		E.g. if you want to change the startvalue of zLoad.v.re to 4, varList 
+		has to contain the item ["zLoad.v.re.start", 4].
+		If the overwrite flag is set to False, existing Values won't be changed.
+		"""	   
+		for item in varList:
+			name = item[0]
+			mo = re.search(r"^(\w+)\.", name)
+			mainName = mo.group(1)
+			pos = self.__getLinePositionName(mainName)
+			line = self._modelLines[pos]
+			self.__addLinetoValues(mainName)
+			self.__addtoValues(item)
+			#mo = re.search(r"^(\s+\w* *\w[\w\.]+\w) ", line)
+			mo = re.search(r"^(\s*\w* *\w[\w\.]+\w) ", line)
+			prefix =  mo.group(1)
+			line = prefix + " " + self.__writeVariableString(self._values[mainName], mainName) + "\n"
+			self._modelLines[pos] = line
+
+		self.__writeModel()
+		
+	def getValues(self, varList):
+		"""Returns a list of the current initial values of the variables and parameters given in varList."""
+		values = []
+		for item in varList:
+			name = item
+			mo = re.search(r"^(\w+)\.", name)
+			mainName = mo.group(1)			
+			self.__addLinetoValues(mainName)
+			value = self.__searchinValues(item)
+			values.append(value)
+		return values
+					 
+	def deleteValues(self, varList):
+		"""Deletes the initial values for variables or parameters given in varList.
+		You can delete single values or a whole group of values.
+		E.g if you want to delete the value for zLoad.v.re and zLoad.v.im
+		var list can be ["zLoad.v.re", "zLoad.v.im"] or ["zLoad.v"].
+		"""
+		for item in varList:
+			name = item
+			mo = re.search(r"^(\w+)\.", name)
+			mainName = mo.group(1)
+			pos = self.__getLinePositionName(mainName)
+			line = self._modelLines[pos]
+			self.__addLinetoValues(mainName)
+			self.__deletefromValues(self._values, item.split("."))
+			#mo = re.search(r"^(\s+\w* *\w[\w\.]+\w) ", line)
+			mo = re.search(r"^(\s*\w* *\w[\w\.]+\w) ", line)
+			prefix =  mo.group(1)
+
+			if mainName in self._values.keys():				
+				line = prefix + " " + self.__writeVariableString(self._values[mainName], mainName) + "\n"
+			else: 
+				line = prefix + " " + mainName + "\n"
+			self._modelLines[pos] = line
+		self.__writeModel()		  
+
+	def addConnection(self, pin1, pin2):
+		"""Creates a new connection between pin1 and pin2 in the equation-section."""
+		line = "  connect(" + pin1 + "," + pin2 + ");\n"
+		self._modelLines.insert(self.__eq_end, line)
+		self.__eq_end = self.__eq_end + 1
+		self.__writeModel()
+		
+	def getConnection(self, name):
+		"""Returns the pins of connections which contain name.
+		Name can be either just a Submodel so that this function returns all connection that
+		exist for this Submodel specific connector.
+		The function returns two lists, the first list contains the pins that conatins name and the
+		second one contains the pin that are part of the connections.
+		"""
+		pin1 = []
+		pin2 = []
+		for i in range(self.__eq_start, self.__eq_end):
+			line = self._modelLines[i]
+			if "connect" in line and name in line:
+				mo = re.search(r"connect\( ?([\w\.\[\]]+) ?, ?([\w\.\[\]]+) ?\)", line)
+				if name in mo.group(1):
+					pin1.append(mo.group(1))
+					pin2.append(mo.group(2))
+				else:
+					pin1.append(mo.group(2))
+					pin2.append(mo.group(1))
+		return [pin1, pin2]
+		
+	def changeConnection(self, listConnectionPins):
+		"""
+		Changes the definition of a specific connection allowing to redefine both pins
+		The items stored in listConnectionPins must be in the form of ["oldConnectionPin1","oldConnectionPin2","newConnectionPin1","newConnectionPin2"]
+		"""		
+		for i in range(self.__eq_start, self.__eq_end):
+			line = self._modelLines[i]
+			if "connect" in line and listConnectionPins[0] in line and listConnectionPins[1] in line:
+				line=re.sub(listConnectionPins[0],listConnectionPins[2],line)
+				self._modelLines[i]=re.sub(listConnectionPins[1],listConnectionPins[3],line)
+		self.__writeModel()
+		
+	def changeConnectionPin(self, listConnectionPin):
+		"""
+		Substitutes all the appearances of a specific connection pin by a new one
+		listConnectionPin should be in the form of ["oldConnectionPin","newConnectionPin"]
+		"""		
+		for i in range(self.__eq_start, self.__eq_end):
+			line = self._modelLines[i]
+			if "connect" in line and listConnectionPin[0] in line:
+				self._modelLines[i]=re.sub(listConnectionPin[0],listConnectionPin[1],line)
+		self.__writeModel()		
+	
+	def copyModelToDir(self, destDir="", postfix=""):
+		"""Copys the model to the given directory and with the given postfix. At the destination directory no package integration is done.		
+		The newly created model and its references are now stored in this class.
+		"""
+		
+		oldModelPath = self._modelPath
+		
+		self._mainPath=destDir		
+		self._model=self._modelName + postfix # incorporates that the model is extracted from any package				
+		self._modelPath = self.__getModelPath()
+		self._modelName = self.getModelName()
+		
+		copyfile(oldModelPath, self._modelPath) 
+		
+		if self._modelLines[0][0:6] == "within": # remove package integration				 
+			self._modelLines[0]="within ;\n"
+			
+		self._modelLines[1] = "model " + self._modelName + "\n"
+		self._modelLines[-1] = "end " + self._modelName + ";"
+		
+		self.__writeModel()
+		
+	   
+	def copyModelIntoPackage(self, newModelName):
+		"""Copys the model and gives it a new name.		
+		The newly created model is integrated in the original package and is now the one that is stored in this class.
+		"""		
+		# Sets a new model name and creates the corresponding newly named file
+		mo = re.search(r"([\w\.]+\.)\w+$", self._model)
+		if not mo==None:
+			self._model = mo.group(1) + newModelName 
+		else:
+			self._model = newModelName
+		self._modelName = self.getModelName()		
+
+		oldModelPath = self._modelPath		
+		self._modelPath = self.__getModelPath()
+		copyfile(oldModelPath, self._modelPath)
+		
+		self._modelLines[1] = "model " + self._modelName + "\n"
+		self._modelLines[-1] = "end " + self._modelName + ";"		
+		self.__writeModel()								
+			
+		# Integrate newly create model in the package
+		packagePath = self._modelPath[:-(len(self._modelName + ".mo"))] + "package.order"
+		package = open(packagePath, "r")
+		packageData = [line for line in package]
+		package.close()
+		
+		if not(self._modelName + "\n"  in packageData):
+			i = bisect(packageData, self._modelName + "\n")
+			packageData.insert(i, self._modelName + "\n")
+			
+		package = open(packagePath, "w")
+		package.writelines(packageData)
+		package.close()
+
+		
+				
+	#--------------------------HELPER-FUNCTIONS-------------------------------#
+
+	def __getModelPath(self):
+		"""Creates the modelpath out of the projectpath and the model."""
+		modelpath = re.sub(r"\.", "\\\\", self._model)
+		modelpath = self._mainPath + modelpath + ".mo"
+		return  modelpath
+
+	def getModelName(self):
+		"""Extracts the modelname out of the name that the model has in 
+		the project.
+		e.g.:
+		When the model is "ACS_PowerSystems.SinglePhase.Examples.StatPh_Examples.Line_PQLoad"
+		it will return "Line_PQLoad"
+		"""		
+		mo = re.search(r"\.(\w+)$", self._model)
+		if not mo==None:
+			modelName = mo.group(1)
+		else:
+			modelName = self._model
+		return modelName
+		
+	def __readModel(self):
+		"""Reads the lines in the modelfile into a list"""
+		modelFile = open(self.__getModelPath(), "r")
+		modelLines = [line for line in modelFile]
+		modelFile.close()
+		return modelLines
+	
+	def __writeModel(self):
+		"""Writes the lines stored in the private list modelLines back into the file"""
+		modelFile = open(self._modelPath, "w")
+		modelFile.writelines(self._modelLines)
+		modelFile.close()  
+	
+	def _formatModel(self):
+		"""Reformats the sourcecode of the model in a way so that it is easier for the script to work on it."""
+		annotation = False
+		annotation_next = False
+		mergelines = False
+		
+		model_end = len(self._modelLines)-1
+		self.__var_start = 0
+		self.__var_end = 0
+		self.__eq_start = 0
+		self.__eq_end = 0	
+		
+		i = 0
+		while i <= model_end :
+			if self._modelLines[i][0:5] == "model":
+				self.__var_start = i+1
+				i = i + 1
+				continue
+			elif self._modelLines[i][0:8] == "equation":
+				self.__var_end = i
+				self.__eq_start = i + 1
+				i = i + 1
+				continue
+			elif self._modelLines[i][0:3] == "end":
+				self.__eq_end = i
+				i = i + 1
+				continue			
+				
+			if "annotation" in self._modelLines[i]:
+				ann_start = self._modelLines[i].find("annotation")
+				if not self._modelLines[i][:ann_start].lstrip() == "":
+					self._modelLines.insert(i+1, "   " + self._modelLines[i][ann_start:])
+					self._modelLines[i] = self._modelLines[i][:ann_start] + "\n"
+					model_end = model_end + 1
+					annotation_next = True
+				else:
+					annotation = True
+					mergelines = False
+					
+			if not annotation and not self._modelLines[i] == "\n":
+				if self._modelLines[i+1].lstrip()[0:10] == "annotation":
+					annotation_next = True
+				if mergelines == True:
+					self._modelLines[i-1] = self._modelLines[i-1][:-1] + self._modelLines[i].lstrip()
+					del self._modelLines[i]
+					i = i - 1
+					model_end = model_end - 1
+					mergelines = False
+				if  not (self._modelLines[i][-2:] == ";\n") and not(annotation_next):
+					mergelines = True
+			elif annotation:
+				if self._modelLines[i][-2:] == ";\n":
+					annotation = False
+			i = i + 1
+			if annotation_next == True:
+				annotation_next = False
+				annotation = True
+				mergelines = False
+		self.__writeModel()
+		
+	def __readVariableString(self, varStr):
+		"""Transforms an initialization string into a dictionary.
+		E.g. (Vnom(displayUnit="kV")=20e3,v(re(start=1),im(start=2)), i(re(start=3), im(start=4)))
+		becomes {"Vnom":{"displayUnit":"kV","value":20e3},"v":{"re":{"start":1},"im":{"start":2}},"i":{"re":{"start":3},"im":{"start":4}}}.
+		"""
+		varStr = re.sub(r"\s", "", varStr)		
+		varStr = re.sub(r"\)=(\d*(\.\d+)?(e\d+)?)",r",value=\1)",varStr)
+		varStr = re.sub(r"=", "\":", varStr)
+		varStr = re.sub(r"\(", "\":{\"", varStr)
+		varStr = re.sub(r"\)", "}", varStr)
+		varStr = re.sub(r",", ",\"", varStr)
+		
+		#marks the string values that aren't enclosed by qutoes in modelicacode e.g. "smoothnessSetting":Modelica.Blocks.Types.Smoothness.ConstantSegments
+		blocklist = re.findall(r":([\w]+\.[\w\.]+)}",varStr)
+		for item in blocklist:
+			tmpStr = item
+			varStr = re.sub(re.escape(tmpStr), "\"!" + tmpStr + "!\"", varStr)
+		
+		varStr = varStr[2:]
+				
+		dic = ast.literal_eval(varStr)
+		
+		return dic
+				
+	def __writeVariableString(self, dic, name):
+		"""Recursive function that turns a dictionary into a string that can be used 
+		to initialize a variable.
+		"""
+		varStr = name + "("
+		for key in dic.keys():
+			if type(dic[key]) == dict:
+				tmpStr = self.__writeVariableString(dic[key], key)
+			elif type(dic[key]) == str:
+				#checks if the string should have quotes or not
+				mo = re.search(r"!(.+)!", dic[key])
+				if mo is None:
+					tmpStr = key + " = \""+ str(dic[key]) + "\""
+				else:
+					tmpStr = key + " = " + str(mo.group(1))
+			else:
+				tmpStr = key + " = " + str(dic[key])
+			varStr = varStr + " " + tmpStr + ","
+		varStr = varStr[:-1] + ")"
+		return varStr
+		 
+	def __getLinePositionName(self, name):
+		"""Returns the linenumber of the line in which the  variable with the name 
+		"name" are declared.
+		"""
+		for i in range(self.__var_start,self.__var_end):
+			#mo = re.search( r" +(\w+) *\(", self._modelLines[i])
+			#mo = re.search( r" +(\w+) *?(\([\w,\(\)=\"\. ]*\))?\s+$", self._modelLines[i])
+			#mo = re.search( r" +(\w+) *?(\([\w,\(\)=\"\. -]*\))?\s+$", self._modelLines[i])						
+			mo = re.search(r" *([\w\.]*) " + name + r" *?(\([\w,\(\)=\"\. -_]*\))?\s+", self._modelLines[i])				   
+			if mo:
+				break
+		return i
+ 
+	def __getLinePositionSubmodel(self, subModelType):
+		"""Returns a list which contains the linenumbers of lines in which 
+		variables with the type subModelType are declared.
+		"""
+		lines = []
+		for i in range(self.__var_start,self.__var_end):
+			mo = re.search(subModelType + r" +(\w+)[ (]?", self._modelLines[i])
+			if mo:
+				lines.append(i)
+		return lines	   
+			
+	def __addtoValues(self, item):
+		"""Adds a item with the form ["Submodel.Subsubmodel", value]. To the 
+		dictionary self._values in which all initial values are stored.
+		"""
+		name = item[0]
+		value = item[1]
+		l = name.split(".")
+		dic = self._values[l[0]]
+		for i in range(1, len(l)-1):
+			if not dic.has_key(l[i]):
+				dic[l[i]] = {}
+			dic = dic[l[i]]
+		dic[l[-1]] = value
+		
+	def __deletefromValues(self, dic, item):
+		"""Deletes an entry from a nested dictionary."""
+		key = item[0]
+		if not len(item) == 1:
+			self.__deletefromValues(dic[key], item[1:])
+			if dic[key] == {}:
+				del dic[key]
+		else:
+			del dic[key]
+		
+	def __searchinValues(self, name):
+		"""Searches a Variable in the dictionary self._values and returns the initial value of this variable."""
+		l = name.split(".")
+		dic = self._values[l[0]]
+		for i in range(1, len(l)-1):
+			if not dic.has_key(l[i]):
+				dic[l[i]] = {}
+			dic = dic[l[i]]
+		value = dic[l[-1]]
+		return value
+		
+	def __addLinetoValues(self, name):
+		"""Adds the initial values of the variable withe the name "name" given 
+		in the modelfile to self._modelLines.
+		"""
+		pos = self.__getLinePositionName(name)
+		line = self._modelLines[pos]
+		if not name in self._values:
+			#mo = re.search(r" +(\w+(\([\w,\(\)=\"\. ]*\))?)\s+$", line)			
+			#mo = re.search(r" *([\w\.]*) " + name + r" *?(\([\w,\(\)=\"\. -_]*\))?\s+", line)
+			#mo = re.search(r" +(\w+(\([\w,\(\)=\"\. _]*\))?)(\s+\"\w+\")?\s+$", line)
+			mo = re.search(r" +(\w+(\([\w,\(\)=\"\.\: _\\/-]*\))?)(\s+\"\w+\")?\s+$", line)
+			varstr = mo.group(1)[len(name):]	  
+			
+			if not varstr == "":
+				tmpDic = self.__readVariableString(varstr)
+			else:
+				tmpDic = {}
+			self._values[name] = tmpDic
+			
+		
diff --git a/Py4Mod/py4mod/OMInterface.py b/Py4Mod/py4mod/OMInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..166294a00c194d564e9fba9ff6f5a6acb8951496
--- /dev/null
+++ b/Py4Mod/py4mod/OMInterface.py
@@ -0,0 +1,473 @@
+import os
+import sys
+import platform
+import subprocess
+import numpy as np
+import xml.etree.ElementTree as ET
+
+from modelicares import SimRes
+from OMPython import OMCSessionZMQ
+
+class OMInterface(object):
+	def __init__(self):
+		"""
+		create an OMCSessionZMQ object
+		"""
+		#create an OMCSessionZMQ object
+		self.__omc = OMCSessionZMQ()
+		
+		#model variables
+		self.modelName=""
+		self.resultFileName=""
+		self.exeFile=""
+		self.__xmlInitFile=""
+		
+		#xml init file variables
+		self.__xmlFile=None
+		self.__xmlTree=None
+		self.__xmlRoot=None
+		self.__modelVariables=[]
+		
+		#class flags
+		self.__buildFlag=False
+		self.__simulationFlag=False
+		self.__readXMLinitFileFlag=False
+	
+		
+	# request to OMC
+	def __requestApi(self, apiName, entity=None, properties=None):
+		if (entity is not None and properties is not None):
+			exp = '{}({}, {})'.format(apiName, entity, properties)
+		elif entity is not None and properties is None:
+			if (apiName == "loadFile" or apiName == "importFMU"):
+				exp = '{}("{}")'.format(apiName, entity)
+			else:
+				exp = '{}({})'.format(apiName, entity)
+		else:
+			exp = '{}()'.format(apiName)
+		try:
+			res = self.__omc.sendExpression(exp)
+		except Exception as e:
+			print(e)
+			res = None
+		return res
+		
+	
+	def close(self):
+		"""
+		Terminate execution of Modelica environment
+		"""
+		self.__requestApi("exit", 0)
+	
+	
+	def changeWorkingDirectory(self, dir=""):
+		"""
+		Change directory to the given path (which may be either relative or absolute) 
+		If the given path is the empty string, the function simply returns the current working directory
+		
+		@param str Dir: Directory to change to. If directory="" this function return the current working directory
+		@raises: exception
+		"""
+		if dir=="":
+			exp='cd("")'
+			return self.__omc.sendExpression(exp)
+		
+		if not os.path.exists(dir):
+			raise Exception('File Error: {} does not exists!!!'.format(os.path.abspath(dir)))
+		
+		exp = 'cd("{}")'.format(str(dir))
+		res=self.__omc.sendExpression(exp)
+		
+		if not (res==dir):
+			raise Exception(res)
+			
+	
+	def loadLibrary(self, lName):
+		"""
+		Loads a Modelica library from the path indicated by the
+		environment variable OPENMODELICALIBRARY (e.g. in C:\OpenModelica1.12.0-64bit\lib\omlibrary)
+		You can use the method OMInterface.getAvailableLibraries to see all available libraries in OPENMODELICALIBRARY
+		
+		@param str lName: the model name to load
+		@raises: Exception()
+		"""
+		if lName not in (self.getAvailableLibraries()):
+			raise Exception('The library "{}" was not found in the environment variable OPENMODELICALIBRARY'.format(lName))
+	
+		loadmodelError = ''
+		loadModelResult = self.__requestApi("loadModel", lName)
+		loadmodelError = self.__requestApi('getErrorString')
+		if loadmodelError:
+			raise Exception(loadmodelError)
+	
+	
+	def getAvailableLibraries(self):
+		"""
+		Looks for all libraries that are visible from the getModelicaPath().
+		@return a list with the abailable libraries
+		"""
+		return self.__requestApi("getAvailableLibraries")
+		
+		
+	def loadFile(self, fName):
+		"""
+		Reads the file specified by fName.
+		This corresponds to File->Open in the menus. 
+		
+		@param str fName: File-path to open.
+		@raises: Exception()
+		"""
+		# if file does not exists
+		if not os.path.exists(fName):  
+			raise Exception("File Error: " + os.path.abspath(fileName) + " does not exists!!!")
+			
+		loadfileResult = self.__requestApi("loadFile", fName)
+		
+		if not loadfileResult:
+			"""
+			if loadfileError:
+				specError = 'Parser error: Unexpected token near: optimization (IDENT)'
+				if specError in loadfileError:
+					self.__requestApi("setCommandLineOptions", '"+g=Optimica"')
+					self.__requestApi("loadFile", fName)
+			"""
+			loadfileError = self.__requestApi("getErrorString")
+			raise Exception('loadFile Error: ' + loadfileError)
+			
+	
+	def getModelicaPath(self):
+		"""
+		get the environment variable OPENMODELICALIBRARY
+		"""
+		return self.__requestApi("getModelicaPath")
+		
+	
+	def setModelicaPath(self, path):
+		"""
+		set the environment variable OPENMODELICALIBRARY
+		@return true if successful
+		**not tested
+		"""
+		exp = 'setModelicaPath("{}")'.format(path)
+		return self.__omc.sendExpression(exp)
+	
+	
+	def getComponents(self, cName):
+		"""
+		Returns a list of component declarations within class cName: "{{Atype, varidA,
+		"commentA"}, {Btype, varidB, "commentB"}, {...}}" and so on.
+		"""
+		return self.__requestApi("getComponents", cName)
+		#return self.__omc.getComponents(cName)
+		
+	
+	def isModel(self, model):
+		"""
+		Returns True if the given class has restriction model.
+		"""
+		return self.__requestApi("isModel", str(model))
+	
+	
+	def getPackages(self):
+		"""
+		Returns a list of names of libraries and their path on the system, for example:
+		(("Modelica","/usr/lib/omlibrary/Modelica 3.2.1"),("ModelicaServices","/usr/lib/omlibrary/ModelicaServices 3.2.1"))
+		"""
+		return self.__requestApi("getLoadedLibraries")
+	
+	
+	def buildModel(self, mName, **kwargs):
+		"""
+		builds a modelica model by generating c code and build it.
+		The only required argument is the className, while all others have some default values.
+
+		@input str mName:  Name of model, e.g. Modelica.Mechanics.Rotational.Components.Clutch.
+		@input str model: the model that should simulated
+		@input float startTime: the start time of the simulation. <default> = 0.0
+		@input float stopTime: the stop time of the simulation. <default> = 1.0
+		@input float numberOfIntervals: number of intervals in the result file. <default> = 500
+		@input float tolerance: tolerance used by the integration method. <default> = 1e-6
+		@input str method: integration method used for simulation. <default> = "dassl"
+		@input str fileNamePrefix: fileNamePrefix. <default> = ""
+		@input str options: options. <default> = ""
+		@input str outputFormat: Format for the result file. <default> = "mat"
+		@input str variableFilter: Filter for variables that should store in result file. <default> = .*
+
+		@input str cflags: compiler flags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html)
+		@input str simflags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		
+		@raises: Exception()
+		"""
+		self.modelName=mName
+		
+		#check if the model exists
+		if not self.isModel(mName):
+			raise Exception('The model "{}" does not exists'.format(mName))
+		
+		command = "buildModel(" + mName 
+		for k,v in kwargs.items():
+			if isinstance(v, str):
+				command += ', {}="{}"'.format(k, v)
+			else: 
+				#command += ", " + k + "=" + str(v)
+				command += ', {}={}'.format(k, v)
+		command+= ")"
+
+		#d: Shows additional information from the initialization process.
+		self.__omc.sendExpression("setCommandLineOptions(\"+d=initialization\")")
+		
+		buildModelResult = self.__omc.sendExpression(command)
+	
+		#print warnings
+		if self.__requestApi("countMessages")[2]:
+			print('WARNINGS:')
+			self.__requestApi("getErrorString")
+
+		if ('' in buildModelResult):
+			raise Exception(buildModelError)
+	
+		self.exeFile=str(buildModelResult[0])
+		self.__xmlInitFile=str(buildModelResult[1])
+		self.__buildFlag=True
+		
+		
+	def simulate(self, simflags=None):
+		"""
+		to simulate or re-simulate model by calling the c programm according to the simulation options. 
+		It can be called:
+		•only without any arguments: simulate the model
+		
+		Note: Model must be built before this function can be called!
+		"""
+			
+		if (platform.system() == "Windows"):
+			exeFile = self.exeFile + ".exe"
+		else:
+			exeFile = self.exeFile
+		
+		if simflags is not None:
+			if not isinstance(simflags, str):
+				raise Exception('simflags must be a string')
+			cmd = exeFile + ' {}'.format(simflags)
+		else:
+			cmd = exeFile
+					
+		#exeFile = os.path.join(self.changeWorkingDirectory(), exeFile).replace("\\", "/")
+		#check_exeFile_ = os.path.exists(exeFile)		
+			
+		if (os.path.exists(exeFile)):
+			omhome = os.path.join(os.environ.get("OPENMODELICAHOME"), 'bin').replace("\\", "/")
+			my_env = os.environ.copy()
+			my_env["PATH"] = omhome + os.pathsep + my_env["PATH"]
+			#process = subprocess.Popen(cmd, cwd=self.changeWorkingDirectory(), env=my_env)
+			process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.changeWorkingDirectory(), env=my_env)
+				
+			while True:
+				output = process.stdout.readline()
+				output = output.decode('utf8')
+
+				if output == '' and process.poll() is not None:
+					break
+				if output:
+					if 'stdout            | info    | ' in output:
+						sys.stdout.write('INFO: {}'.format(output.replace('stdout            | info    | ',"")))
+						#print('INFO: {}'.format(output.replace('stdout            | info    | ',"")))
+					elif 'stdout            | warning |' in output:
+						sys.stdout.write('WARNING: {}'.format(output.replace('stdout            | warning | ',"")))
+						#print('WARNING: {}'.format(output.replace('stdout            | warning | ',"")))
+					else:
+						sys.stdout.write(output)
+						#print(output)
+						
+			rc = process.poll()
+			process.terminate()
+			
+			if (rc is not 0):
+				raise Exception(str(stderr))	#not tested
+			
+			self.__simulationFlag = True
+			self.resultFileName = os.path.join(self.changeWorkingDirectory(), self.modelName + '_res.mat')
+		
+		else:
+			print("Error: application file not generated yet")
+			
+	def simulateModel(self, model, **kwargs):
+		"""
+		Simulates a modelica model by generating c code, build it and run the simulation executable.
+		The only required argument is the className, while all others have some default values.
+		input str model: the model that should simulated
+		input float startTime: the start time of the simulation. <default> = 0.0
+		input float stopTime: the stop time of the simulation. <default> = 1.0
+		input float numberOfIntervals: number of intervals in the result file. <default> = 500
+		input float tolerance: tolerance used by the integration method. <default> = 1e-6
+		input str method:integration method used for simulation. <default> = "dassl"
+		input str fileNamePrefix: fileNamePrefix. <default> = ""
+		input str options: options. <default> = ""
+		input str outputFormat: Format for the result file. <default> = "mat"
+		input str variableFilter: Filter for variables that should store in result file. <default> = .*
+
+		input str cflags: compiler flags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html)
+		input str simflags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		output dict results={String resultFile, String simulationOptions, String messages, Real timeFrontend, Real timeBackend, 
+			Real timeSimCode, Real timeTemplates, Real timeCompile, Real timeSimulation, Real timeTotal}
+		
+		Note: this function can not be used with the functions: simulate(), setValue(), getSimulationValues(), setSimulationOptions(), buildModel()
+		"""
+
+		command = "simulate(" + model 
+		for k,v in kwargs.items():
+			if isinstance(v, str):
+				command += ', {}="{}"'.format(k, v)
+			else: 
+				#command += ", " + k + "=" + str(v)
+				command += ', {}={}'.format(k, v)
+		command+= ")"
+		
+		results = self.__omc.sendExpression(command)
+		if not results:
+			err_msg = self.__omc.sendExpression("getErrorString()")
+			raise Exception(err_msg)
+
+		self.resultFileName = os.path.join(self.changeWorkingDirectory(), results['resultFile'])
+		self.__simulationFlag = True
+		
+		return results
+		
+	def getResultVarNames(self):
+		""" Returns the variablen names from the simulation result."""
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+		
+		validSolution = self.__omc.sendExpression("readSimulationResultVars(\"" + self.resultFileName + "\")")
+		return validSolution
+	
+	
+	# to extract simulation results
+	def getResults(self, outputVarList = []):
+		"""
+		Returns the solutions for the variables in outputVarList in
+		the format of numpy.array by using OMPython in the same order as outputVarList
+		"""
+		
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+
+		if all(isinstance(a, str) for a in outputVarList):
+			outputList = self.getResultVarNames()
+			for v in outputVarList:
+				if v == 'time':
+					continue
+				if v not in outputList:
+					raise Exception('!!! {} does not exist\n'.format(v))
+									
+			variables = ",".join(outputVarList)
+			exp = "readSimulationResult(\"" + self.resultFileName + '", {' + variables + '})'
+	        
+			res = self.__omc.sendExpression(exp)
+			exp2 = "closeSimulationResultFile()"
+			self.__omc.sendExpression(exp2)
+			
+			return np.array(res)
+			
+	
+	def getResultsFast(self, outputVarList=[]):
+		"""
+		Returns the trajectories for the variables in outputVarList in
+		the format of numpy.array by using ModelicaRes
+		
+		This Method can work faster than getSolutions() if the number of solutions is big
+		"""
+		
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+		
+		if all(isinstance(a, str) for a in outputVarList):
+			outputList = self.getResultVarNames()
+			for v in outputVarList:
+				if v == 'time':
+					continue
+				if v not in outputList:
+					raise Exception('!!! {} does not exist\n'.format(v))
+					
+			sim=SimRes(self.resultFileName)
+			arrTraj=[]        
+			for item in outputVarList:
+				if np.array_equal(sim('Time').samples.values,sim(item).samples.times):
+					arrTraj.append(sim(item).samples.values)
+				else:
+					arrTraj.append(np.array(np.interp(sim('Time').samples.values,sim(item).samples.times,sim(item).samples.values),'float32'))            
+			return np.array(arrTraj)
+	
+	
+	#========== functions that reads/edits file ModelName_init.xml file ==================
+	def __readXMLinitFile(self):
+		self.__xmlFile = os.path.join(self.changeWorkingDirectory(), self.__xmlInitFile)
+		self.__xmlTree = ET.parse(self.__xmlFile)
+		self.__xmlRoot = self.__xmlTree.getroot()
+	
+		#get model parameters and store it in the list self.__modelParameters
+		for scalarVariable in self.__xmlRoot.iter('ScalarVariable'):
+			name = scalarVariable.get("name")
+			changeable = scalarVariable.get("isValueChangeable")
+			scalarVariable_children = scalarVariable.getchildren()
+			start = None
+			for attr in scalarVariable_children:
+				start = attr.get('start')
+			self.__modelVariables.append(ModelicaVariable(name, changeable, start))
+				
+	
+	def setValue(self, values):
+		"""
+		change simulation variables in the xml model description file
+		@values is a dict
+		
+		Note: Model must be built before this function can be called!
+		"""
+		if not self.__buildFlag:
+			raise Exception("Model must be built before OMInterface.setValue() can be called!")
+		
+		if not self.__readXMLinitFileFlag:
+			self.__readXMLinitFile()
+		
+		for n in values:
+			index = self.__first(n)
+			if index==-1:
+				raise Exception('Error: {} is not a variable'.format(n))
+			else: 
+				if self.__modelVariables[index].changeable == 'false':
+					raise Exception('!!! value cannot be set for {}'.format(n))
+						
+				else:
+					self.__modelVariables[index].start = float(values.get(n))
+					for scalarVariable in self.__xmlRoot.iter('ScalarVariable'):
+						if scalarVariable.get('name') == str(n):
+							scalarVariable_children = scalarVariable.getchildren()
+							for attr in scalarVariable_children:
+								val = float(values.get(n))
+								attr.set('start', str(val))
+								self.__xmlTree.write(self.__xmlFile, encoding='UTF-8', xml_declaration=True)				
+	
+	def __first(self, name):
+		"""
+		to search variable in self.__modelVariables 
+		"""
+		index=0
+		for item in  self.__modelVariables:
+			if (item.name == name):
+				return index
+			index+=1
+		return -1
+		
+class ModelicaVariable(object):
+	"""
+	To represent modelica ModelVariables
+	This class is used to store the values reads from the xlm init file
+	"""
+	def __init__(self, name, changeable, start):
+		self.name = name				#name of the variable
+		self.changeable = changeable	#is a parameter or a 
+		self.start = start				#initial condition for state variables 
+		
\ No newline at end of file
diff --git a/Py4Mod/py4mod/README.md b/Py4Mod/py4mod/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a5186757765148205903bde67d0a2bae78ec8d05
--- /dev/null
+++ b/Py4Mod/py4mod/README.md
@@ -0,0 +1,32 @@
+# Funktionennamen
+
+The following table gives a comparison between the names of the functions of the interfaces and a small description of their function. It is important to keep in mind that some functions receive different arguments depending on the chosen interface.
+
+
+| DymolaInterface          | OpenModelica Interface   | ModelicaModel          |                                                                                                        |
+| ------------------------ | ------------------------ | -------------          | ------------------------------------------------------------------------------------------------------ |
+| __init__                 | __init__                 | createInterface        | In OM creates an OMCSessionZMQ object, in DymInterface starts Dymola                                   |
+| changeWorkingDirectory   | changeWorkingDirectory   | changeWorkingDirectory | Change directory to the given path                                                                     |
+|  **                      | loadLibrary              |     ---                | Loads a Modelica library from the path indicated by the environment variable OPENMODELICALIBRARY       |
+|  ---                     | getAvailableLibraries    |     ---                | Looks for all libraries that are visible from the getModelicaPath()                                    |
+| loadFile                 | loadFile                 | loadFile               | Reads the file specified by fName. This corresponds to File->Open in the menus.                        |
+|  ---                     | getModelicaPath          |     ---                | Returns the environment variable OPENMODELICALIBRARY                                                   |
+|  ---                     | setModelicaPath          |     ---                | To set the environment variable OPENMODELICALIBRARY                                                    |
+|  ---                     | getComponents            |     ---                | To get list of all ModelicaVariable names                                                              |
+|  ---                     | isModel                  |     ---                | Returns True if the given class has restriction model.                                                 |
+|  ---                     | getPackages              |     ---                | Returns a list of names of loaded libraries and their path on the system                               |
+| dymApplyModifiers        | setValue                 |     ---                | In Dymola applies modifiers in modifierList. In OM chage the starts values in the XML init file        |
+| buildModel               | buildModel               | buildModel             | Builds a modelica model by generating c code and build it                                              |
+| simulateModel            | simulate                 | simulate               | In OM simulate or re-simulate model by calling the .exe file (generated with buildModel()). In Dymola simulates the model and compiles it if it has not been compiled before |
+| ---                      | simulateModel            | ---                    | In OM simulates a modelica model by generating c code, build it and run the simulation executable.     |
+| getResultVarNames        | getResultVarNames        | getResultVarNames      | Returns the variablen names from the simulation result                                                 |
+| getResultsFast           | getResultsFast           | getResults             | Returns the trajectories for the variables in outputVarList by using ModelicaRes                       |
+| getResults               | getResults               |     ---                | To extract simulation results by using OMPython/DymolaInterface                                        |
+| close                    | close                    | close                  | To close dymola or OM                                                                                  |
+
+<br />
+** This function is not necesary in Dymola <br />
+--- This function is not implemented in the Interface 
+
+<br />
+The functions that have not been implemented in ModelicaModel but in any of the interfaces can be easily called with the class variable self.interface. 
diff --git a/Py4Mod/py4mod/archive/OMFunctions_old.py b/Py4Mod/py4mod/archive/OMFunctions_old.py
new file mode 100644
index 0000000000000000000000000000000000000000..de47a0d886b4d9f60d36d42548c6aef9b343e480
--- /dev/null
+++ b/Py4Mod/py4mod/archive/OMFunctions_old.py
@@ -0,0 +1,572 @@
+import os
+import sys
+import platform
+import subprocess
+import numpy as np
+import xml.etree.ElementTree as ET
+from modelicares import SimRes
+from OMPython import OMCSessionZMQ
+
+class ModelicaVariable(object):
+	"""
+	To represent modelica ModelVariables
+	"""
+	def __init__(self, name, start, changable, variability, description, causality, alias, aliasvariable):
+		self.name = name
+		self.start = start
+		self.changable = changable
+		self.description = description
+		self.variability = variability
+		self.causality = causality
+		self.alias = alias
+		self.aliasvariable = aliasvariable
+	
+	
+class OMInterface(object):
+	def __init__(self, modelica_path=None):
+		"""
+		create an OMCSessionZMQ object
+		
+		@param str modelica_path: The path to the directory "openmodelica_install_directory\lib\omlibrary". 
+			Default is used the environment variable OPENMODELICALIBRARY
+		"""
+	
+		#create an OMCSessionZMQ object
+		self.__omc = OMCSessionZMQ()
+		
+		#set dymola path
+		if modelica_path is not None:
+			self.setModelicaPath(modelica_path)
+		
+		#model variables
+		self.modelName=""
+		self.resultFileName=""
+		
+		#variables to describe the modelName_init.xml file.
+		#This is the file that description the building model
+		self.__xmlFile=None			#Modelica xml Representation 
+		self.__xmlTree=None			#xml File tree structure
+		self.__xmlRoot=None			#xml File root element
+		
+		#list of variables with detailes such as name, value, changeable, and description, 
+		#where changeable means if value for corresponding quantity name is changeable or not.	
+		#To describe each variable, we use the class ModelicaVariable()
+		self.__variablesList=[]		
+
+		#class flags
+		self.__buildFlag=False
+		self.__simulationFlag=False
+	
+	
+	def changeWorkingDirectory(self, dir=""):
+		"""
+		Change directory to the given path (which may be either relative or absolute) 
+		If the given path is the empty string, the function simply returns the current working directory
+		
+		@param str Dir: Directory to change to. If directory="" this function return the current working directory
+		@raises: exception
+		"""
+		if dir=="":
+			exp='cd("")'
+			return self.__omc.sendExpression(exp)
+		
+		if not os.path.exists(dir):
+			raise Exception('File Error: {} does not exists!!!'.format(os.path.abspath(dir)))
+		
+		exp = 'cd("{}")'.format(str(dir))
+		res=self.__omc.sendExpression(exp)
+		
+		if not (res==dir):
+			raise Exception(res)
+		
+		
+	def loadLibrary(self, lName):
+		"""
+		Loads a Modelica library from the path indicated by the
+		environment variable OPENMODELICALIBRARY (e.g. in C:\OpenModelica1.12.0-64bit\lib\omlibrary)
+		You can use the method OMInterface.getAvailableLibraries to see all available libraries in OPENMODELICALIBRARY
+		
+		@param str lName: the model name to load
+		@raises: Exception()
+		"""
+		if lName not in (self.getAvailableLibraries()):
+			raise Exception('The library "{}" was not found in the environment variable OPENMODELICALIBRARY'.format(lName))
+	
+		loadmodelError = ''
+		loadModelResult = self.__requestApi("loadModel", lName)
+		loadmodelError = self.__requestApi('getErrorString')
+		if loadmodelError:
+			raise Exception(loadmodelError)
+			
+			
+	def getAvailableLibraries(self):
+		"""
+		Looks for all libraries that are visible from the getModelicaPath().
+		@return a list with the abailable libraries
+		"""
+		return self.__requestApi("getAvailableLibraries")
+	
+	
+	def loadFile(self, fName):
+		"""
+		Reads the file specified by fName.
+		This corresponds to File->Open in the menus. 
+		
+		@param str fName: File-path to open.
+		@raises: Exception()
+		"""
+		# if file does not exists
+		if not os.path.exists(fName):  
+			raise Exception("File Error: " + os.path.abspath(fileName) + " does not exists!!!")
+			
+		loadfileResult = self.__requestApi("loadFile", fName)
+		loadfileError = self.__requestApi("getErrorString")
+			
+		if loadfileError:
+			specError = 'Parser error: Unexpected token near: optimization (IDENT)'
+			if specError in loadfileError:
+				self.__requestApi("setCommandLineOptions", '"+g=Optimica"')
+				self.__requestApi("loadFile", fName)
+			else:
+				raise Exception('loadFile Error: ' + loadfileError)
+				
+	
+	def getModelicaPath(self):
+		"""
+		get the environment variable OPENMODELICALIBRARY
+		"""
+		return self.__requestApi("getModelicaPath")
+		
+	
+	def setModelicaPath(self, path):
+		"""
+		set the environment variable OPENMODELICALIBRARY
+		@return true if successful
+		**not tested
+		"""
+		exp = 'setModelicaPath("{}")'.format(path)
+		return self.__omc.sendExpression(exp)
+	
+			
+	def getComponents2(self):
+		"""
+		to get list of all ModelicaVariable names
+		"""
+		return self.__requestApi("listVariables")
+		#return self.__omc.getComponents(cName)
+	
+	
+	def getComponents(self):
+		"""
+		to get list of all ModelicaVariable names
+		Note: Model must be built before this function can be called!
+		"""
+		if not self.__buildFlag:
+			raise Exception("Model must be built before getComponents() can be called!")
+			
+		components = []
+		for k in self.__variablesList:
+			components.append(k.name)
+		
+		return components
+	
+	
+	def isModel(self, model):
+		"""
+		Returns True if the given class has restriction model.
+		"""
+		return self.__requestApi("isModel", str(model))
+	
+	
+	def getPackages(self):
+		"""
+		Returns a list of names of libraries and their path on the system, for example:
+		(("Modelica","/usr/lib/omlibrary/Modelica 3.2.1"),("ModelicaServices","/usr/lib/omlibrary/ModelicaServices 3.2.1"))
+		"""
+		return self.__requestApi("getLoadedLibraries")
+	
+	
+	def buildModel(self, mName):
+		"""
+		builds a modelica model by generating c code and build it.
+		The only required argument is the className, while all others have some default values.
+
+		@param str mName:  Name of model, e.g. Modelica.Mechanics.Rotational.Components.Clutch.
+		
+		@input str model: the model that should simulated
+		@input float startTime: the start time of the simulation. <default> = 0.0
+		@input float stopTime: the stop time of the simulation. <default> = 1.0
+		@input float numberOfIntervals: number of intervals in the result file. <default> = 500
+		@input float tolerance: tolerance used by the integration method. <default> = 1e-6
+		@input str method: integration method used for simulation. <default> = "dassl"
+		@input str fileNamePrefix: fileNamePrefix. <default> = ""
+		@input str options: options. <default> = ""
+		@input str outputFormat: Format for the result file. <default> = "mat"
+		@input str variableFilter: Filter for variables that should store in result file. <default> = .*
+
+		@input str cflags: compiler flags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html)
+		@input str simflags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		
+		@output String[2] buildModelResults;
+
+		@raises: Exception()
+		"""
+		self.modelName=mName
+		
+		#check if the model exists
+		if not self.isModel(mName):
+			raise Exception('The model "{}" does not exists'.format(mName))
+		
+		#d: Shows additional information from the initialization process.
+		self.__omc.sendExpression("setCommandLineOptions(\"+d=initialization\")")
+		
+		buildModelResult = self.__requestApi("buildModel", mName)
+
+		#print warnings
+		if self.__requestApi("countMessages")[2]:
+			print("building warnings:")
+		buildModelError = self.__requestApi("getErrorString")
+		
+		if ('' in buildModelResult):
+			raise Exception(buildModelError)
+	
+		#create list self.__variablesList. It displays details of ModelicaVariables such as name, value,
+		#changeable, and description, where changeable means if value for corresponding quantity name
+		#is changeable or not.
+		#Parse XML file:
+		self.__xmlFile = os.path.join(self.changeWorkingDirectory(), buildModelResult[1])
+		self.__xmlTree = ET.parse(self.__xmlFile)
+		self.__xmlRoot = self.__xmlTree.getroot()
+		
+		for sv in self.__xmlRoot.iter('ScalarVariable'):
+			name = sv.get('name')
+			changable = sv.get('isValueChangeable')
+			description = sv.get('description')
+			variability = sv.get('variability')
+			causality = sv.get('causality')
+			alias = sv.get('alias')
+			aliasvariable = sv.get('aliasVariable')
+			ch = sv.getchildren()
+			start = None
+			for att in ch:
+				start = att.get('start')
+			self.__variablesList.append(ModelicaVariable(name, start, changable, variability, description, causality, alias, aliasvariable))
+	
+		self.__buildFlag=True
+	
+	
+	def checkAvailability(self, names, chkList):
+		"""
+		check if names exist in a list
+		"""
+		try:
+			if isinstance(names, list):
+				nonExistingList = []
+				for n in names:
+					if n not in chkList:
+						nonExistingList.append(n)
+				if nonExistingList:
+					print('Error!!! ' + str(nonExistingList) + ' does not exist.')
+					return False
+			elif isinstance(names, str):
+				if names not in chkList:
+					print('Error!!! ' + names + ' does not exist.')
+					return False
+			else:
+				print('Error!!! Incorrect format')
+				return False
+			return True
+	
+		except Exception as e:
+			print(e)
+	
+	
+	def setSimulationOptions(self, **simOptions):
+		"""
+		change the simulation values 'startTime', 'stopTime', 'stepSize', 'tolerance', 'solver' in the xml model description file
+		
+		@input float startTime: the start time of the simulation.
+		@input float stopTime: the stop time of the simulation.
+		@input float stepSize: the step time of the simulation.
+		@input float tolerance: tolerance used by the integration method.
+		@input float solver: integration method
+		
+		Note: Model must be built before this function can be called!
+		"""
+		if not self.__buildFlag:
+			raise Exception("Model must be built before setSimulationOptions() can be called!")
+			
+		valuesList = self.getSimulationValues()
+		simNamesList = ['startTime', 'stopTime', 'stepSize', 'tolerance', 'solver']
+		try:
+			for key in simOptions:
+				if key in simNamesList:
+					if key == 'stopTime':
+						if float(simOptions[key]) <= float(valuesList[0]):
+							print('!!! stoptTime should be greater than startTime')
+							return
+					if key == 'startTime':
+						if float(simOptions[key]) >= float(valuesList[1]):
+							print('!!! startTime should be less than stopTime')
+							return
+					
+					for sim in self.__xmlRoot.iter('DefaultExperiment'):
+						sim.set(key, str(simOptions.get(key)))
+						self.__xmlTree.write(self.__xmlFile, encoding='UTF-8', xml_declaration=True)
+						
+				else:
+					print('!!!' + key + ' is not an option')
+					continue
+	
+		except Exception as e:
+			print(e)
+	
+	
+	def getSimulationValues(self):
+		"""
+		Read the simulation values 'startTime', 'stopTime', 'stepSize', 'tolerance', 'solver' from the xml model description file 
+		
+		Note: Model must be built before this function can be called!
+		"""
+		if self.__xmlFile is None:
+			raise Exception("Model must be built before setSimulationOptions() can be called!")
+			
+		simValuesList = []
+		
+		for attr in self.__xmlRoot.iter('DefaultExperiment'):
+			startTime = attr.get('startTime')
+			simValuesList.append(float(startTime))
+			stopTime = attr.get('stopTime')
+			simValuesList.append(float(stopTime))
+			stepSize = attr.get('stepSize')
+			simValuesList.append(float(stepSize))
+			tolerance = attr.get('tolerance')
+			simValuesList.append(float(tolerance))
+			solver = attr.get('solver')
+			simValuesList.append(solver)
+			
+		return simValuesList
+	
+	
+	def setValue(self, values):
+		"""
+		change simulation variables in the xml model description file
+		
+		Note: Model must be built before this function can be called!
+		"""
+		if not self.__buildFlag:
+			raise Exception("Model must be built before OMFunctions.setValue() can be called!")
+		
+		namesList=self.getComponents()
+		for n in values:
+			if n in namesList:
+				for l in self.__variablesList:
+					if (l.name == n):
+						if l.changable == 'false':
+							raise Exception('!!! value cannot be set for {}'.format(n))
+						
+						else:
+							l.start = float(values.get(n))
+							for paramVar in self.__xmlRoot.iter('ScalarVariable'):
+								if paramVar.get('name') == str(n):
+									c = paramVar.getchildren()
+									for attr in c:
+										val = float(values.get(n))
+										attr.set('start', str(val))
+										self.__xmlTree.write(self.__xmlFile, encoding='UTF-8', xml_declaration=True)
+			else:
+				raise Exception('Error: {} is not a variable'.format(n))
+	
+	
+	def simulate(self, simFlags=None):
+		"""
+		to simulate or re-simulate model by calling the c programm according to the simulation options. 
+		It can be called:
+		•only without any arguments: simulate the model
+		
+		Note: Model must be built before this function can be called!
+		"""
+	
+		if (platform.system() == "Windows"):
+			exeFile = self.modelName + ".exe"
+		else:
+			exeFile = self.modelName
+		
+		exeFile = os.path.join(self.changeWorkingDirectory(), exeFile).replace("\\", "/")
+		check_exeFile_ = os.path.exists(exeFile)
+		
+		if simFlags is not None:
+			if not isinstance(simFlags, str):
+				raise Exception('SimFlags must be a string')
+			cmd = exeFile + ' {}'.format(simFlags)
+		else:
+			cmd = exeFile
+			
+			
+		if (check_exeFile_):
+			omhome = os.path.join(os.environ.get("OPENMODELICAHOME"), 'bin').replace("\\", "/")
+			my_env = os.environ.copy()
+			my_env["PATH"] = omhome + os.pathsep + my_env["PATH"]
+			#process = subprocess.Popen(cmd, cwd=self.changeWorkingDirectory(), env=my_env)
+			process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.changeWorkingDirectory(), env=my_env)
+				
+			while True:
+				output = process.stdout.readline()
+				output = output.decode('utf8')
+
+				if output == '' and process.poll() is not None:
+					break
+				if output:
+					if 'stdout            | info    | ' in output:
+						sys.stdout.write('INFO: {}'.format(output.replace('stdout            | info    | ',"")))
+						#print('INFO: {}'.format(output.replace('stdout            | info    | ',"")))
+					elif 'stdout            | warning |' in output:
+						sys.stdout.write('WARNING: {}'.format(output.replace('stdout            | warning | ',"")))
+						#print('WARNING: {}'.format(output.replace('stdout            | warning | ',"")))
+					else:
+						sys.stdout.write(output)
+						#print(output)
+						
+			rc = process.poll()
+			process.terminate()
+			
+			if (rc is not 0):
+				raise Exception(str(stderr))	#not tested
+			
+			self.__simulationFlag = True
+			self.resultFileName = os.path.join(self.changeWorkingDirectory(), self.modelName + '_res.mat')
+		
+		else:
+			print("Error: application file not generated yet")
+	
+	
+	def simulateModel(self, model, **kwargs):
+		"""
+		Simulates a modelica model by generating c code, build it and run the simulation executable.
+		The only required argument is the className, while all others have some default values.
+		input str model: the model that should simulated
+		input float startTime: the start time of the simulation. <default> = 0.0
+		input float stopTime: the stop time of the simulation. <default> = 1.0
+		input float numberOfIntervals: number of intervals in the result file. <default> = 500
+		input float tolerance: tolerance used by the integration method. <default> = 1e-6
+		input str method:integration method used for simulation. <default> = "dassl"
+		input str fileNamePrefix: fileNamePrefix. <default> = ""
+		input str options: options. <default> = ""
+		input str outputFormat: Format for the result file. <default> = "mat"
+		input str variableFilter: Filter for variables that should store in result file. <default> = .*
+
+		input str cflags: compiler flags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html)
+		input str simflags: simflags. <default> = "" (more info: https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/simulationflags.html)
+		output dict results={String resultFile, String simulationOptions, String messages, Real timeFrontend, Real timeBackend, 
+			Real timeSimCode, Real timeTemplates, Real timeCompile, Real timeSimulation, Real timeTotal}
+		
+		Note: this function can not be used with the functions: simulate(), setValue(), getSimulationValues(), setSimulationOptions(), buildModel()
+		"""
+
+		command = "simulate(" + model 
+		for k,v in kwargs.items():
+			if isinstance(v, str):
+				command += ', {}="{}"'.format(k, v)
+			else: 
+				#command += ", " + k + "=" + str(v)
+				command += ', {}={}'.format(k, v)
+		command+= ")"
+		
+		results = self.__omc.sendExpression(command)
+		if not results:
+			err_msg = self.__omc.sendExpression("getErrorString()")
+			raise Exception(err_msg)
+
+		self.resultFileName = os.path.join(self.changeWorkingDirectory(), results['resultFile'])
+		self.__simulationFlag = True
+		
+		return results
+	
+	
+	def getResultVarNames(self):
+		""" Returns the variablen names from the simulation result."""
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+		
+		validSolution = self.__omc.sendExpression("readSimulationResultVars(\"" + self.resultFileName + "\")")
+		return validSolution
+	
+	
+	# to extract simulation results
+	def getResults(self, outputVarList = []):
+		"""
+		Returns the solutions for the variables in outputVarList in
+		the format of numpy.array by using OMPython in the same order as outputVarList
+		"""
+		
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+
+		if all(isinstance(a, str) for a in outputVarList):
+			outputList = self.getResultVarNames()
+			for v in outputVarList:
+				if v == 'time':
+					continue
+				if v not in outputList:
+					raise Exception('!!! {} does not exist\n'.format(v))
+									
+			variables = ",".join(outputVarList)
+			exp = "readSimulationResult(\"" + self.resultFileName + '", {' + variables + '})'
+	        
+			res = self.__omc.sendExpression(exp)
+			exp2 = "closeSimulationResultFile()"
+			self.__omc.sendExpression(exp2)
+			
+			return np.array(res)
+	
+	
+	def getResultsFast(self, outputVarList=[]):
+		"""
+		Returns the trajectories for the variables in outputVarList in
+		the format of numpy.array by using ModelicaRes
+		
+		This Method can work faster than getSolutions() if the number of solutions is big
+		"""
+		
+		# check for result file exits
+		if not os.path.exists(self.resultFileName):
+			raise Exception("Error: Result file does not exist.")
+		
+		if all(isinstance(a, str) for a in outputVarList):
+			outputList = self.getResultVarNames()
+			for v in outputVarList:
+				if v == 'time':
+					continue
+				if v not in outputList:
+					raise Exception('!!! {} does not exist\n'.format(v))
+					
+			sim=SimRes(self.resultFileName)
+			arrTraj=[]        
+			for item in outputVarList:
+				if np.array_equal(sim('Time').samples.values,sim(item).samples.times):
+					arrTraj.append(sim(item).samples.values)
+				else:
+					arrTraj.append(np.array(np.interp(sim('Time').samples.values,sim(item).samples.times,sim(item).samples.values),'float32'))            
+			return np.array(arrTraj)
+	
+	
+	# request to OMC
+	def __requestApi(self, apiName, entity=None, properties=None):
+		if (entity is not None and properties is not None):
+			exp = '{}({}, {})'.format(apiName, entity, properties)
+		elif entity is not None and properties is None:
+			if (apiName == "loadFile" or apiName == "importFMU"):
+				exp = '{}("{}")'.format(apiName, entity)
+			else:
+				exp = '{}({})'.format(apiName, entity)
+		else:
+			exp = '{}()'.format(apiName)
+		try:
+			res = self.__omc.sendExpression(exp)
+		except Exception as e:
+			print(e)
+			res = None
+		return res
+	
\ No newline at end of file
diff --git a/Py4Mod/py4mod/modelicafunctions.py b/Py4Mod/py4mod/modelicafunctions.py
deleted file mode 100644
index 7c77cb22b38c3d170a2e2a39febb440a5c956e79..0000000000000000000000000000000000000000
--- a/Py4Mod/py4mod/modelicafunctions.py
+++ /dev/null
@@ -1,605 +0,0 @@
-import dymola.dymola_enums
-from dymola.dymola_interface import DymolaInterface
-from dymola.dymola_exception import DymolaException
-
-from shutil import copyfile
-from bisect import bisect
-import numpy as np
-import re
-import ast
-from modelicares import SimRes
-
-class ModelicaModel(object):
-    def __init__(self, model, mainPath):
-        """Constructor of the class ModelicaModel, reads and format a model that
-        is given by the path of the project and the Name it has in this Project
-        """
-        self._model = model # model identifier in package hierarchy [e.g. packageName.subPackageName.modelName]
-        self._mainPath = mainPath # path where either the model file itself or the corresponding package.mo can be found
-        if not self._mainPath[-1] == "\\":
-            self._mainPath = self._mainPath + "\\"
-        self._modelName = self.getModelName() # actual name of model extracted from self._model
-        self._modelPath = self.__getModelPath() # complete path of the model file deduced from self._mainPath and self._model              
-        self._modelLines = self.__readModel()
-        self._formatModel()
-        self._values = {}
-        
-    #-------------------------- FUNCTIONS TO USE DYMOLA API ------------------------------#
-        
-    def dymOpen(self):
-        self.__dymObj = None
-        try:
-            # Instantiate the Dymola interface and start Dymola
-            self.__dymObj = DymolaInterface()                                              
-            self.__dymObj.openModel(self._modelPath)              
-
-            # Set Dymola options                    
-            self.__dymObj.ExecuteCommand("experimentSetupOutput(events=false);")
-            self.__dymObj.ExecuteCommand("Advanced.OutputModelicaCode:=true;")
-            self.__dymObj.ExecuteCommand("Advanced.OutputModelicaCodeWithAliasVariables = true;")
-            #dymola.ExecuteCommand("Advanced.StoreProtectedVariables:=true;")
-        except DymolaException as ex:
-            print("Error in dymOpen: " + str(ex))             
-                    
-    def dymTranslate(self):
-        try:            
-            result = self.__dymObj.ExecuteCommand("translateModel(\"" + self._model + "\")") 
-            if not result:
-                    print("Translation failed. Below is the translation log.")
-                    log = self.__dymObj.getLastError()
-                    print(log)
-                    exit(1)   
-        except DymolaException as ex:
-            print("Error in dymTranslate: " + str(ex))
-            
-            
-    def dymApplyModifiers(self, modifierList):
-        """ Applies modifiers in modifierList, which is of format
-            modifierList=[['submodule1','param1','value1'],['submodule2','param2','value2'],...]        
-        """
-        cmdString=""
-        for i in range(len(modifierList)):
-            cmdString+= modifierList[i][0] + "." + modifierList[i][1] + "=" + str(modifierList[i][2]) + ";"            
-        self.__dymObj.ExecuteCommand(cmdString) 
-
-        
-    def dymSimulate(self, simOptions = "", resultName = "simResult"):
-        """Simulates the model in the mode specified in simMode. The results are stored in 
-        files with the name resultName. It returns a list of the Variable Names andanother
-        list with the values they had at the start of the simulation.
-        """
-        try:    
-            if simOptions != "":
-                simOptions = simOptions + ","           
-
-            result = self.__dymObj.ExecuteCommand("simulateModel(\"" + self._model + "\" , " + simOptions + "resultFile = \"" + resultName + "\")") 
-
-            if not result:
-                print("Simulation failed. Below is the translation log.")
-                log = self.__dymObj.getLastError()
-                print(log)
-                exit(1)        
-        except DymolaException as ex:
-            print("Error in dymSimulate: " + str(ex))
-            
-            
-    def dymSimulateMultiResults(self, resultName = "simResult", simOptions = "", initialNames="", initialValues="", resultNames=""):      
-        try:
-            # Simulate Model
-            if simOptions != "":
-                simOptions = "," + simOptions + ","            
-            result = self.__dymObj.ExecuteCommand("simulateMultiResultsModel(\"" + self._model + "\"" + simOptions + "initialNames={" + initialNames + "}, initialValues=" + initialValues + ", resultFile = \"" + resultName + "\"," + "resultNames={\"" + resultNames + "\"})") 
-            if not result:
-                print("Simulation failed. Below is the translation log.")
-                log = self.__dymObj.getLastError()
-                print(log)
-                exit(1)        
-        except DymolaException as ex:
-            print("Error in dymSimulateMultiResults: " + str(ex))             
-        return result
-
-    def dymGetResultsFast(self, resultName = "simResult", outputVarList = []):
-        """ Returns the trajectories for the variables in outputVarList in
-        the format of numpy.array by using ModelicaRes
-        """
-        sim=SimRes(re.sub(self._modelName+".mo",resultName + ".mat",self._modelPath))
-        arrTraj=[]        
-        for item in outputVarList:
-            if np.array_equal(sim('Time').samples.values,sim(item).samples.times):
-                arrTraj.append(sim(item).samples.values)
-            else:
-                arrTraj.append(np.array(np.interp(sim('Time').samples.values,sim(item).samples.times,sim(item).samples.values),'float32'))            
-        return np.array(arrTraj)
-
-    def dymGetResults(self, resultName = "simResult", outputVarList = []):
-        """ Returns the trajectories for the variables in outputVarList in
-        the format of numpy.array by using DymolaInterface
-        """
-        sizeTraj = self.__dymObj.readTrajectorySize(resultName + ".mat")
-        arrTraj = np.array(self.__dymObj.readTrajectory(resultName + ".mat", outputVarList, sizeTraj))    
-        return arrTraj
-        
-    def dymGetResultVarNames(self, resultName = "simResult"):
-        """ Returns the variablen names from the simulation result."""
-        varNames = self.__dymObj.readTrajectoryNames(resultName + ".mat")
-        varNames.sort()
-        return varNames
-        
-        
-    def dymClose(self):
-        if self.__dymObj is not None:
-            self.__dymObj.close()
-            self.__dymObj = None 
-            
-    #-------------------------- FUNCTIONS TO WORK ON MODELICA CODE ------------------------------#
-                   
-    def getSubmodelNames(self, subModelType):
-        """Searches every instance of the type subModelType and returns a list with
-        the names they have in the model.
-        """
-        subModelNames = []
-        for i in range(self.__var_start, self.__var_end +1):
-            mo = re.search(subModelType + r" +(\w+)[ (]?", self._modelLines[i])
-            if mo:
-                name = mo.group(1)
-                subModelNames.append(name)
-        return subModelNames
-        
-    def getSubmodelModifierValue(self,listSubmodelNames,modifierName):
-        modValue = []
-        positions=[]
-        for submodelName in listSubmodelNames:
-            positions.append(self.__getLinePositionName(submodelName))
-        for pos in positions:
-            mo = re.search(modifierName + r"=(\d+)", self._modelLines[pos])
-            if mo:
-                val = mo.group(1)
-                modValue.append(val)
-        return modValue
-         
-    def getSubModelTypesAll(self):
-        """ Returns a list of all submodeltypes that the model contains
-        """
-        submodeltypes= []
-        for i in range(self.__var_start,self.__var_end):
-            mo = re.search(r" *(?:inner)? ([\w\.]+) +(?:\w+)[ (]?", self._modelLines[i])
-            if mo:
-                submodeltype = mo.group(1)
-                if not (submodeltype in submodeltypes):
-                    submodeltypes.append(submodeltype)
-        return submodeltypes
-        
-    
-    def changeSubmodelTypeAll(self, oldType, newType, positions = []):
-        """Changes the type of all submodels with the type oldType to the type newType.
-        ATTENTION: this can lead to Problems if the equations (e.g. connections) don't
-        match with the new type.
-        """
-        if positions == []:        
-            positions = self.__getLinePositionSubmodel(oldType)
-        for i in positions:
-            mo = re.search(oldType + r" ", self._modelLines[i])
-            start = mo.start()
-            end = mo.end() - 1
-            self._modelLines[i] = self._modelLines[i][:start] + newType + self._modelLines[i][end:] 
-        self.__writeModel()
-        
-    def changeSubmodelType(self, listSubmodelNames, oldType, newType):
-        """Changes the type of all submodels in listSubmodelNames from oldType to type newType.
-        ATTENTION: this can lead to Problems if the equations (e.g. connections) don't
-        match with the new type.
-        """
-        positions=[]
-        for submodelName in listSubmodelNames:
-            positions.append(self.__getLinePositionName(submodelName))
-        for pos in positions:
-            mo = re.search(oldType + r" ", self._modelLines[pos])
-            start = mo.start()
-            end = mo.end() - 1
-            self._modelLines[pos] = self._modelLines[pos][:start] + newType + self._modelLines[pos][end:] 
-        self.__writeModel()   
-        
-    def changeSubmodelName(self, dictSubmodelNames):
-        """Changes the names of the submodels in the declaration according to dictSubmodelNames, which includes the 
-        renaming entries in the manner {"oldSubmodelName":"newSubmodelName"}
-        ATTENTION: corresponding connections, which include the old submodel name, must be changed seperatedly by using changeConnection
-        or changeConnectionPin
-        """        
-        for submodelNameOld,submodelNameNew in dictSubmodelNames.iteritems():
-            pos = self.__getLinePositionName(submodelNameOld)
-            self._modelLines[pos] = re.sub(submodelNameOld,submodelNameNew,self._modelLines[pos])
-        self.__writeModel()
-        
-    def changeVars(self, varList, overwrite = True):
-        """Changes or adds the initial values of variables/parameters that are specified
-        in the variable-section of the model.
-        The list varList contains the variables and the values that should be set.
-        The items stored in varList have the form of ["Submodel.Subsubmodel", value]
-        if you set the value of a differential variable the variable name has to end
-        with ".start".
-        E.g. if you want to change the startvalue of zLoad.v.re to 4, varList 
-        has to contain the item ["zLoad.v.re.start", 4].
-        If the overwrite flag is set to False, existing Values won't be changed.
-        """       
-        for item in varList:
-            name = item[0]
-            mo = re.search(r"^(\w+)\.", name)
-            mainName = mo.group(1)
-            pos = self.__getLinePositionName(mainName)
-            line = self._modelLines[pos]
-            self.__addLinetoValues(mainName)
-            self.__addtoValues(item)
-            #mo = re.search(r"^(\s+\w* *\w[\w\.]+\w) ", line)
-            mo = re.search(r"^(\s*\w* *\w[\w\.]+\w) ", line)
-            prefix =  mo.group(1)
-            line = prefix + " " + self.__writeVariableString(self._values[mainName], mainName) + "\n"
-            self._modelLines[pos] = line
-
-        self.__writeModel()
-        
-    def getValues(self, varList):
-        """Returns a list of the current initial values of the variables and parameters given in varList."""
-        values = []
-        for item in varList:
-            name = item
-            mo = re.search(r"^(\w+)\.", name)
-            mainName = mo.group(1)            
-            self.__addLinetoValues(mainName)
-            value = self.__searchinValues(item)
-            values.append(value)
-        return values
-                     
-    def deleteValues(self, varList):
-        """Deletes the initial values for variables or parameters given in varList.
-        You can delete single values or a whole group of values.
-        E.g if you want to delete the value for zLoad.v.re and zLoad.v.im
-        var list can be ["zLoad.v.re", "zLoad.v.im"] or ["zLoad.v"].
-        """
-        for item in varList:
-            name = item
-            mo = re.search(r"^(\w+)\.", name)
-            mainName = mo.group(1)
-            pos = self.__getLinePositionName(mainName)
-            line = self._modelLines[pos]
-            self.__addLinetoValues(mainName)
-            self.__deletefromValues(self._values, item.split("."))
-            #mo = re.search(r"^(\s+\w* *\w[\w\.]+\w) ", line)
-            mo = re.search(r"^(\s*\w* *\w[\w\.]+\w) ", line)
-            prefix =  mo.group(1)
-
-            if mainName in self._values.keys():                
-                line = prefix + " " + self.__writeVariableString(self._values[mainName], mainName) + "\n"
-            else: 
-                line = prefix + " " + mainName + "\n"
-            self._modelLines[pos] = line
-        self.__writeModel()          
-
-    def addConnection(self, pin1, pin2):
-        """Creates a new connection between pin1 and pin2 in the equation-section."""
-        line = "  connect(" + pin1 + "," + pin2 + ");\n"
-        self._modelLines.insert(self.__eq_end, line)
-        self.__eq_end = self.__eq_end + 1
-        self.__writeModel()
-        
-    def getConnection(self, name):
-        """Returns the pins of connections which contain name.
-        Name can be either just a Submodel so that this function returns all connection that
-        exist for this Submodel specific connector.
-        The function returns two lists, the first list contains the pins that conatins name and the
-        second one contains the pin that are part of the connections.
-        """
-        pin1 = []
-        pin2 = []
-        for i in range(self.__eq_start, self.__eq_end):
-            line = self._modelLines[i]
-            if "connect" in line and name in line:
-                mo = re.search(r"connect\( ?([\w\.\[\]]+) ?, ?([\w\.\[\]]+) ?\)", line)
-                if name in mo.group(1):
-                    pin1.append(mo.group(1))
-                    pin2.append(mo.group(2))
-                else:
-                    pin1.append(mo.group(2))
-                    pin2.append(mo.group(1))
-        return [pin1, pin2]
-        
-    def changeConnection(self, listConnectionPins):
-        """
-        Changes the definition of a specific connection allowing to redefine both pins
-        The items stored in listConnectionPins must be in the form of ["oldConnectionPin1","oldConnectionPin2","newConnectionPin1","newConnectionPin2"]
-        """        
-        for i in range(self.__eq_start, self.__eq_end):
-            line = self._modelLines[i]
-            if "connect" in line and listConnectionPins[0] in line and listConnectionPins[1] in line:
-                line=re.sub(listConnectionPins[0],listConnectionPins[2],line)
-                self._modelLines[i]=re.sub(listConnectionPins[1],listConnectionPins[3],line)
-        self.__writeModel()
-        
-    def changeConnectionPin(self, listConnectionPin):
-        """
-        Substitutes all the appearances of a specific connection pin by a new one
-        listConnectionPin should be in the form of ["oldConnectionPin","newConnectionPin"]
-        """        
-        for i in range(self.__eq_start, self.__eq_end):
-            line = self._modelLines[i]
-            if "connect" in line and listConnectionPin[0] in line:
-                self._modelLines[i]=re.sub(listConnectionPin[0],listConnectionPin[1],line)
-        self.__writeModel()        
-    
-    def copyModelToDir(self, destDir="", postfix=""):
-        """Copys the model to the given directory and with the given postfix. At the destination directory no package integration is done.        
-        The newly created model and its references are now stored in this class.
-        """
-        
-        oldModelPath = self._modelPath
-        
-        self._mainPath=destDir        
-        self._model=self._modelName + postfix # incorporates that the model is extracted from any package                
-        self._modelPath = self.__getModelPath()
-        self._modelName = self.getModelName()
-        
-        copyfile(oldModelPath, self._modelPath) 
-        
-        if self._modelLines[0][0:6] == "within": # remove package integration                 
-            self._modelLines[0]="within ;\n"
-            
-        self._modelLines[1] = "model " + self._modelName + "\n"
-        self._modelLines[-1] = "end " + self._modelName + ";"
-        
-        self.__writeModel()
-        
-       
-    def copyModelIntoPackage(self, newModelName):
-        """Copys the model and gives it a new name.        
-        The newly created model is integrated in the original package and is now the one that is stored in this class.
-        """        
-        # Sets a new model name and creates the corresponding newly named file
-        mo = re.search(r"([\w\.]+\.)\w+$", self._model)
-        if not mo==None:
-            self._model = mo.group(1) + newModelName 
-        else:
-            self._model = newModelName
-        self._modelName = self.getModelName()        
-
-        oldModelPath = self._modelPath        
-        self._modelPath = self.__getModelPath()
-        copyfile(oldModelPath, self._modelPath)
-        
-        self._modelLines[1] = "model " + self._modelName + "\n"
-        self._modelLines[-1] = "end " + self._modelName + ";"        
-        self.__writeModel()                                
-            
-        # Integrate newly create model in the package
-        packagePath = self._modelPath[:-(len(self._modelName + ".mo"))] + "package.order"
-        package = open(packagePath, "r")
-        packageData = [line for line in package]
-        package.close()
-        
-        if not(self._modelName + "\n"  in packageData):
-            i = bisect(packageData, self._modelName + "\n")
-            packageData.insert(i, self._modelName + "\n")
-            
-        package = open(packagePath, "w")
-        package.writelines(packageData)
-        package.close()
-        
-                
-    #--------------------------HELPER-FUNCTIONS-------------------------------#
-
-    def __getModelPath(self):
-        """Creates the modelpath out of the projectpath and the model."""
-        modelpath = re.sub(r"\.", "\\\\", self._model)
-        modelpath = self._mainPath + modelpath + ".mo"
-        print(modelpath)
-        return  modelpath
-
-    def getModelName(self):
-        """Extracts the modelname out of the name that the model has in 
-        the project.
-        e.g.:
-        When the model is "ACS_PowerSystems.SinglePhase.Examples.StatPh_Examples.Line_PQLoad"
-        it will return "Line_PQLoad"
-        """        
-        mo = re.search(r"\.(\w+)$", self._model)
-        if not mo==None:
-            modelName = mo.group(1)
-        else:
-            modelName = self._model
-        return modelName
-        
-    def __readModel(self):
-        """Reads the lines in the modelfile into a list"""
-        modelFile = open(self.__getModelPath(), "r")
-        modelLines = [line for line in modelFile]
-        modelFile.close()
-        return modelLines
-    
-    def __writeModel(self):
-        """Writes the lines stored in the private list modelLines back into the file"""
-        modelFile = open(self._modelPath, "w")
-        modelFile.writelines(self._modelLines)
-        modelFile.close()  
-    
-    def _formatModel(self):
-        """Reformats the sourcecode of the model in a way so that it is easier for the script to work on it."""
-        annotation = False
-        annotation_next = False
-        mergelines = False
-        
-        model_end = len(self._modelLines)-1
-        self.__var_start = 0
-        self.__var_end = 0
-        self.__eq_start = 0
-        self.__eq_end = 0    
-        
-        i = 0
-        while i <= model_end :
-            if self._modelLines[i][0:5] == "model":
-                self.__var_start = i+1
-                i = i + 1
-                continue
-            elif self._modelLines[i][0:8] == "equation":
-                self.__var_end = i
-                self.__eq_start = i + 1
-                i = i + 1
-                continue
-            elif self._modelLines[i][0:3] == "end":
-                self.__eq_end = i
-                i = i + 1
-                continue            
-                
-            if "annotation" in self._modelLines[i]:
-                ann_start = self._modelLines[i].find("annotation")
-                if not self._modelLines[i][:ann_start].lstrip() == "":
-                    self._modelLines.insert(i+1, "   " + self._modelLines[i][ann_start:])
-                    self._modelLines[i] = self._modelLines[i][:ann_start] + "\n"
-                    model_end = model_end + 1
-                    annotation_next = True
-                else:
-                    annotation = True
-                    mergelines = False
-                    
-            if not annotation and not self._modelLines[i] == "\n":
-                if self._modelLines[i+1].lstrip()[0:10] == "annotation":
-                    annotation_next = True
-                if mergelines == True:
-                    self._modelLines[i-1] = self._modelLines[i-1][:-1] + self._modelLines[i].lstrip()
-                    del self._modelLines[i]
-                    i = i - 1
-                    model_end = model_end - 1
-                    mergelines = False
-                if  not (self._modelLines[i][-2:] == ";\n") and not(annotation_next):
-                    mergelines = True
-            elif annotation:
-                if self._modelLines[i][-2:] == ";\n":
-                    annotation = False
-            i = i + 1
-            if annotation_next == True:
-                annotation_next = False
-                annotation = True
-                mergelines = False
-        self.__writeModel()
-        
-    def __readVariableString(self, varStr):
-        """Transforms an initialization string into a dictionary.
-        E.g. (Vnom(displayUnit="kV")=20e3,v(re(start=1),im(start=2)), i(re(start=3), im(start=4)))
-        becomes {"Vnom":{"displayUnit":"kV","value":20e3},"v":{"re":{"start":1},"im":{"start":2}},"i":{"re":{"start":3},"im":{"start":4}}}.
-        """
-        varStr = re.sub(r"\s", "", varStr)        
-        varStr = re.sub(r"\)=(\d*(\.\d+)?(e\d+)?)",r",value=\1)",varStr)
-        varStr = re.sub(r"=", "\":", varStr)
-        varStr = re.sub(r"\(", "\":{\"", varStr)
-        varStr = re.sub(r"\)", "}", varStr)
-        varStr = re.sub(r",", ",\"", varStr)
-        
-        #marks the string values that aren't enclosed by qutoes in modelicacode e.g. "smoothnessSetting":Modelica.Blocks.Types.Smoothness.ConstantSegments
-        blocklist = re.findall(r":([\w]+\.[\w\.]+)}",varStr)
-        for item in blocklist:
-            tmpStr = item
-            varStr = re.sub(re.escape(tmpStr), "\"!" + tmpStr + "!\"", varStr)
-        
-        varStr = varStr[2:]
-                
-        dic = ast.literal_eval(varStr)
-        
-        return dic
-                
-    def __writeVariableString(self, dic, name):
-        """Recursive function that turns a dictionary into a string that can be used 
-        to initialize a variable.
-        """
-        varStr = name + "("
-        for key in dic.keys():
-            if type(dic[key]) == dict:
-                tmpStr = self.__writeVariableString(dic[key], key)
-            elif type(dic[key]) == str:
-                #checks if the string should have quotes or not
-                mo = re.search(r"!(.+)!", dic[key])
-                if mo is None:
-                    tmpStr = key + " = \""+ str(dic[key]) + "\""
-                else:
-                    tmpStr = key + " = " + str(mo.group(1))
-            else:
-                tmpStr = key + " = " + str(dic[key])
-            varStr = varStr + " " + tmpStr + ","
-        varStr = varStr[:-1] + ")"
-        return varStr
-         
-    def __getLinePositionName(self, name):
-        """Returns the linenumber of the line in which the  variable with the name 
-        "name" are declared.
-        """
-        for i in range(self.__var_start,self.__var_end):
-            #mo = re.search( r" +(\w+) *\(", self._modelLines[i])
-            #mo = re.search( r" +(\w+) *?(\([\w,\(\)=\"\. ]*\))?\s+$", self._modelLines[i])
-            #mo = re.search( r" +(\w+) *?(\([\w,\(\)=\"\. -]*\))?\s+$", self._modelLines[i])                        
-            mo = re.search(r" *([\w\.]*) " + name + r" *?(\([\w,\(\)=\"\. -_]*\))?\s+", self._modelLines[i])                   
-            if mo:
-                break
-        return i
- 
-    def __getLinePositionSubmodel(self, subModelType):
-        """Returns a list which contains the linenumbers of lines in which 
-        variables with the type subModelType are declared.
-        """
-        lines = []
-        for i in range(self.__var_start,self.__var_end):
-            mo = re.search(subModelType + r" +(\w+)[ (]?", self._modelLines[i])
-            if mo:
-                lines.append(i)
-        return lines       
-            
-    def __addtoValues(self, item):
-        """Adds a item with the form ["Submodel.Subsubmodel", value]. To the 
-        dictionary self._values in which all initial values are stored.
-        """
-        name = item[0]
-        value = item[1]
-        l = name.split(".")
-        dic = self._values[l[0]]
-        for i in range(1, len(l)-1):
-            if not dic.has_key(l[i]):
-                dic[l[i]] = {}
-            dic = dic[l[i]]
-        dic[l[-1]] = value
-        
-    def __deletefromValues(self, dic, item):
-        """Deletes an entry from a nested dictionary."""
-        key = item[0]
-        if not len(item) == 1:
-            self.__deletefromValues(dic[key], item[1:])
-            if dic[key] == {}:
-                del dic[key]
-        else:
-            del dic[key]
-        
-    def __searchinValues(self, name):
-        """Searches a Variable in the dictionary self._values and returns the initial value of this variable."""
-        l = name.split(".")
-        dic = self._values[l[0]]
-        for i in range(1, len(l)-1):
-            if not dic.has_key(l[i]):
-                dic[l[i]] = {}
-            dic = dic[l[i]]
-        value = dic[l[-1]]
-        return value
-        
-    def __addLinetoValues(self, name):
-        """Adds the initial values of the variable withe the name "name" given 
-        in the modelfile to self._modelLines.
-        """
-        pos = self.__getLinePositionName(name)
-        line = self._modelLines[pos]
-        if not name in self._values:
-            #mo = re.search(r" +(\w+(\([\w,\(\)=\"\. ]*\))?)\s+$", line)            
-            #mo = re.search(r" *([\w\.]*) " + name + r" *?(\([\w,\(\)=\"\. -_]*\))?\s+", line)
-			#mo = re.search(r" +(\w+(\([\w,\(\)=\"\. _]*\))?)(\s+\"\w+\")?\s+$", line)
-            mo = re.search(r" +(\w+(\([\w,\(\)=\"\.\: _\\/-]*\))?)(\s+\"\w+\")?\s+$", line)
-            varstr = mo.group(1)[len(name):]      
-			
-            if not varstr == "":
-                tmpDic = self.__readVariableString(varstr)
-            else:
-                tmpDic = {}
-            self._values[name] = tmpDic
-            
-        
diff --git a/Scripts/InterfaceExamples/.gitkeep b/Scripts/InterfaceExamples/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Scripts/InterfaceExamples/ExampleDymolaInterface/.gitkeep b/Scripts/InterfaceExamples/ExampleDymolaInterface/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Scripts/InterfaceExamples/ExampleDymolaInterface/DymolaExample.py b/Scripts/InterfaceExamples/ExampleDymolaInterface/DymolaExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4cc9b7a2c44bdc4c5789742a673f094da39ea15
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleDymolaInterface/DymolaExample.py
@@ -0,0 +1,34 @@
+"""
+example of how to use the DymolaInterface
+"""
+
+from py4mod.DymInterface import DymInterface
+
+#Instantiate the Dymola interface and start Dymola
+dymola = DymInterface(showwindow=True)
+print("")
+
+try:
+    # Call a function in Dymola and check its return value
+    result = dymola.simulateModel("Modelica.Mechanics.Rotational.Examples.CoupledClutches")
+
+    print('cwd:{}\n'.format(dymola.changeWorkingDirectory()))
+    print("VarNames:")	
+    print(dymola.getResultVarNames())
+    print("\n\n\n")	
+	
+    print("J1.J")	
+    print(dymola.getResults(["J1.J", "fixed.flange.phi"]))
+    print("\n\n\n")
+
+    print("J1.J")	
+    print(dymola.getResultsFast(["J1.J", "fixed.flange.phi"]))
+    print("\n\n\n")
+	
+except Exception as err:
+    print("Error: " + str(err))
+	
+finally:
+    if dymola is not None:
+        dymola.close()
+        dymola = None
diff --git a/Scripts/InterfaceExamples/ExampleModelicaModel/test_ModelicaModel.py b/Scripts/InterfaceExamples/ExampleModelicaModel/test_ModelicaModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb47c6e6a0a9cfca56720560a440e274ee1cef65
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleModelicaModel/test_ModelicaModel.py
@@ -0,0 +1,80 @@
+#test of ModelicaFunctions.py
+import os
+import sys
+sys.path.append(r"C:\\Users\\Martin\\Desktop\\hiwi\\git\\python-for-modelica\\Py4Mod\\py4mod")
+
+from ModelicaModel import ModelicaModel
+
+try:
+	#Instantiate ModelicaModel
+	interface = ModelicaModel("ModPowerSystems.DynPhasorThreePhase.Examples.BasicCircuits.VoltageSource_RL", r"C:\\Users\\Martin\\Desktop\\hiwi\\git\\modpowersystems\\")
+	
+	#initialize the OM interface
+	interface.createInterface("OPENMODELICA")
+	
+	#load ModPowerSystems package
+	interface.loadFile(r"C:/Users/Martin/Desktop/hiwi/git/modpowersystems/ModPowerSystems/package.mo")
+	
+	#print loaded packages
+	print("\nLoaded Packages:")
+	print(*interface.interface.getPackages(), sep='\n')
+	print("")
+	
+	#change working directory
+	cwd = os.getcwd()
+	wd=os.path.join(cwd, 'test_modelicaFunctions')
+	if not os.path.exists(wd):
+		os.makedirs(wd)
+	interface.changeWorkingDirectory(wd.replace("\\","/"))
+	
+	#create a copy of the model
+	interface.copyModelIntoPackage("VoltageSource_RL_copy")
+	
+	#get all submodeltypes that the model contains
+	print("submodels:")
+	print(interface.getSubModelTypesAll())
+	
+	#get sub models type ModPowerSystems.DynPhasorThreePhase.Basics.Resistor
+	print(interface.getSubmodelNames("Resistor"))
+	
+	#get value of resistors
+	#print('start value resistor 1: {}'.format(interface.getValues(["ModPowerSystems.DynPhasorThreePhase.Basics.Resistor.R[1]"])))
+	#print('start value resistor 2:{}'.format(interface.getValues(["resistor.R[2]"])))
+	#print('start value resistor 3:{}'.format(interface.getValues(["resistor.R[3]"])))
+	
+	#build model
+	print("\nBuild model ModPowerSystems.DynPhasorThreePhase.Examples.BasicCircuits.VoltageSource_RL")
+	interface.buildModel(startTime=5, stopTime=10, simflags="-override=resistor.R[2]=10")
+	
+	
+	#simulate model
+	
+	#create the file with the initial values:
+	initFile=os.path.join(wd, 'init_values.csv')
+	f = open(initFile,'w')
+	file='startTime=0 \n stopTime=30 \n resistor.R[1]=10 \n resistor.R[2]=20 \n resistor.R[3]=30 \n'.replace(" ", "")
+	f.write(file)	
+	f.close()
+	
+	#it is important that the parameter file concludes with a blank line and that no
+	#spaces can be inserted before or after the equal sign, otherwise the
+	#OpenModelica compiler does not inherit the parameters in the model.
+	
+	sim_flags='-overrideFile {}'.format(initFile).replace("\\","/")
+	print("\nSimulate Model:")
+	interface.simulate(simflags=sim_flags)
+		
+	#check start value of the resistors
+	test = interface.getResults(["resistor.R[1]", "resistor.R[2]", "resistor.R[3]", "time"])
+	print('\nresistor.R[1]: {}'.format(test[0][0]))
+	print('resistor.R[2]: {}'.format(test[1][0]))
+	print('resistor.R[3]: {}'.format(test[2][0]))
+	print('time: {}'.format(test[3]))
+	print("\n")
+		
+	print(test)
+	
+
+except Exception as err:
+	print(err)
+	exit(1)
\ No newline at end of file
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/.gitkeep b/Scripts/InterfaceExamples/ExampleOMInterface/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/test_OMFunctions_old.py b/Scripts/InterfaceExamples/ExampleOMInterface/test_OMFunctions_old.py
new file mode 100644
index 0000000000000000000000000000000000000000..24c29acea259b59766591ab8243ae8112ab54af5
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleOMInterface/test_OMFunctions_old.py
@@ -0,0 +1,77 @@
+#test of OMFunctions.py
+import os
+import sys
+sys.path.append(r"C:\\Users\\Martin\\Desktop\\hiwi\\git\\python-for-modelica\\Py4Mod\\py4mod")
+
+from OMFunctions_old import OMInterface
+
+#Instantiate OMInterface
+print("")
+modelica = OMInterface()
+print("")
+
+#load Modelica-package 
+try:
+	modelica.loadLibrary("Modelica")
+except Exception as err:
+	print(err)
+	
+#print loaded packages
+print("Loaded Packages:")
+print(*modelica.getPackages(), sep='\n')
+print("")
+
+#change working directory
+cwd = os.getcwd()
+wd=os.path.join(cwd, 'test')
+if not os.path.exists(wd):
+	os.makedirs(wd)
+modelica.changeWorkingDirectory(wd.replace("\\","/"))
+	
+#check the current working directory 
+print('current working directory: "{}"\n'.format(modelica.changeWorkingDirectory("")))
+
+#build model
+model = "Modelica.Blocks.Examples.PID_Controller"
+try:
+	modelica.buildModel(model)
+except Exception as err:
+	print(err)
+	exit()
+	
+print("\nget component names")
+print(modelica.getComponents())
+#print(*modelica.getComponents(), sep='\n')
+
+#change sim option values
+modelica.setSimulationOptions(stopTime=10, stepSize=20)
+
+#get simulation values
+simNamesList = ['startTime', 'stopTime', 'stepSize', 'tolerance', 'solver']
+simValues = modelica.getSimulationValues()
+print("\nsimulation values:")
+for index, value in enumerate(simValues):
+	print('{}={}'.format(simNamesList[index], value))
+print("")
+
+#set spring.w_rel to 10 deg:
+modelica.setValue({"spring.w_rel":10})
+
+#simulate model
+print("Simulate model:")
+modelica.simulate()
+
+#get output variables
+print("\noutput variables:")
+print(*modelica.getResultVarNames(), sep='\n')
+print("\n")
+
+#get solutions
+print("get simulation results:")
+test = modelica.getResults(["time", "PI.I.y","inertia1.phi"])
+print('time: ')
+print(test[0])
+print("\n")
+print('PI.I.y: ')
+print(test[1])
+print("")
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/test_OMInterface.py b/Scripts/InterfaceExamples/ExampleOMInterface/test_OMInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9742844d9afec608fd7e6bdd4ae615a05f5cae5
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleOMInterface/test_OMInterface.py
@@ -0,0 +1,74 @@
+#test of OMInterface.py
+import os
+import sys
+import time
+import numpy as np
+
+sys.path.append(r"C:\\Users\\Martin\\Desktop\\hiwi\\git\\python-for-modelica\\Py4Mod\\py4mod")
+from OMInterface import OMInterface
+
+#Instantiate OMInterface
+print("")
+modelica = OMInterface()
+print("")
+
+#load Modelica-package 
+try:
+	modelica.loadLibrary("Modelica")
+except Exception as err:
+	print(err)
+	
+#print loaded packages
+print("Loaded Packages:")
+print(*modelica.getPackages(), sep='\n')
+print("")
+
+#change working directory
+cwd = os.getcwd()
+wd=os.path.join(cwd, 'test_OMInterface')
+if not os.path.exists(wd):
+	os.makedirs(wd)
+modelica.changeWorkingDirectory(wd.replace("\\","/"))
+	
+#check the current working directory 
+print('current working directory: "{}"'.format(modelica.changeWorkingDirectory("")))
+
+#build model
+model = "Modelica.Blocks.Examples.PID_Controller"
+print("Build Model:")
+try:
+	modelica.buildModel(model, startTime=5, stopTime=10)
+except Exception as err:
+	print(err)
+	exit()
+	
+#simulate model
+print("\nSimulate model:")
+modelica.simulate('-override spring.w_rel=12')
+
+#get output variables
+print("\noutput variables:")
+print(*modelica.getResultVarNames(), sep='\n')
+
+#get solutions
+start = time.time()
+print("\nget simulation results:")
+test = modelica.getResults(["time", "PI.I.y","spring.w_rel"])
+print(test)
+end = time.time()
+print('time elapsed: {}'.format(end-start))
+
+#get solutions
+start = time.time()
+print("\nget simulation results fast:")
+test = modelica.getResultsFast(["time", "PI.I.y","spring.w_rel"])
+print(test)
+end = time.time()
+print('time elapsed: {}'.format(end-start))
+
+#test setValue():
+values={"spring.w_rel":30}
+modelica.setValue(values)
+modelica.simulate()
+test = modelica.getResults(["spring.w_rel"])
+print('spring.w_rel[0]={}'.format(test[0][0]))
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/test_performance.py b/Scripts/InterfaceExamples/ExampleOMInterface/test_performance.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0ba583476b0805c16a6e52e086930cb30bca2ae
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleOMInterface/test_performance.py
@@ -0,0 +1,83 @@
+"""
+comparison between the time used by the function simulate() and simulateModel() to simulate 5 times 25s the model "Modelica.Blocks.Examples.PID_Controller"
+"""
+
+import time
+import os
+import sys
+sys.path.append("C:/Users/Martin/Desktop/hiwi/git/python-for-modelica/Py4Mod/py4mod")
+
+from OMInterface import OMInterface
+
+#Instantiate OMInterface
+print("")
+modelica = OMInterface()
+print("")
+
+#load Modelica-package 
+try:
+	modelica.loadLibrary("Modelica")
+
+	#change working directory
+	cwd = os.getcwd()
+	wd=os.path.join(cwd, 'test_performance')
+	if not os.path.exists(wd):
+		os.makedirs(wd)
+	modelica.changeWorkingDirectory(wd.replace("\\","/"))
+	
+	print("using the funcion simulateModel()...")
+	start0 = time.time()
+	for x in range(0, 5):
+		start = time.time()
+		print('starts {}.simulation'.format(x+1))
+
+		#simulate model
+		modelica.simulateModel("Modelica.Blocks.Examples.PID_Controller", startTime=0.0, stopTime=25.0,
+			simflags="-override=spring.w_rel=10,PI.Dzero.k=5.0")
+	
+		end = time.time()
+		print('time elapsed {}.simulation: {}seg'.format(x+1, end - start))
+	
+	end = time.time()
+	print('total time elapsed: {}'.format(end - start0))
+	
+	
+	print("\n======================\n")
+	
+	print("using the function simulate()...")
+	start0 = time.time()
+	
+	for x in range(0, 5):
+		start = time.time()
+		print('starts {}.simulation'.format(x+1))
+		if x==0:
+			#build model
+			modelica.buildModel("Modelica.Blocks.Examples.PID_Controller")		
+		
+		#create the file with the initial values:
+		initFile=os.path.join(wd, 'init_values.csv')
+		f = open(initFile,'w')
+		file='startTime=0 \n stopTime=25 \n spring.w_rel=10.0 \n PI.Dzero.k=5.0 \n'.replace(" ", "")
+		f.write(file)	
+		f.close()
+	
+		sim_flags='-overrideFile {}'.format(initFile).replace("\\","/")
+		modelica.simulate(simflags=sim_flags)
+	
+		end = time.time()
+		print('time elapsed {}.simulation: {}seg'.format(x+1, end - start))
+		
+	print('total time elapsed: {}'.format(end - start0))
+	print("\n======================")
+	
+	#check start value of spring.w_rel and PI.Dzero.k and time
+	test = modelica.getResults(["spring.w_rel", "PI.Dzero.k", "time"])
+	print('\nspring.w_rel[0]: {}'.format(test[0][0]))
+	print('PI.Dzero.k[0]: {}'.format(test[1][0]))
+	print('time: {}'.format(test[2]))
+	print("\n")
+		
+
+except Exception as err:
+	print(err)
+	exit()
\ No newline at end of file
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_override.py b/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_override.py
new file mode 100644
index 0000000000000000000000000000000000000000..9792134d544ec62c0036fec17d79eaf505e4df49
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_override.py
@@ -0,0 +1,52 @@
+"""
+example of how to use the function simulateModel and the sim flag -override
+"""
+
+import os
+import sys
+sys.path.append(r"C:\\Users\\Martin\\Desktop\\hiwi\\git\\python-for-modelica\\Py4Mod\\py4mod")
+
+from OMInterface import OMInterface
+
+#Instantiate OMInterface
+print("")
+modelica = OMInterface()
+print("")
+
+#load Modelica-package 
+try:
+	modelica.loadLibrary("Modelica")
+except Exception as err:
+	print(err)
+	
+
+#example how to set init values with the sim flag -override
+try: 
+	#change working directory
+	cwd = os.getcwd()
+	wd=os.path.join(cwd, 'test_simflag_override')
+	if not os.path.exists(wd):
+		os.makedirs(wd)
+	modelica.changeWorkingDirectory(wd.replace("\\","/"))
+
+	#build model
+	print("Build model Modelica.Blocks.Examples.PID_Controller")
+	modelica.buildModel("Modelica.Blocks.Examples.PID_Controller", startTime=5, stopTime=10)
+
+
+	#simulate model
+	#you can edit the initial values with the sim flag -override
+	modelica.simulate(simflags="-override=spring.w_rel=20,PI.Dzero.k=5.0,stopTime=50")
+
+	
+	#check start value of spring.w_rel and PI.Dzero.k
+	test = modelica.getResults(["spring.w_rel", "PI.Dzero.k", "time"])
+	print('\nspring.w_rel[0]: {}'.format(test[0][0]))
+	print('PI.Dzero.k[0]: {}'.format(test[1][0]))
+	print('time: {}'.format(test[2]))
+	print("\n")
+	
+except Exception as err:
+	print(err)
+	
+
diff --git a/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_overrideFile.py b/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_overrideFile.py
new file mode 100644
index 0000000000000000000000000000000000000000..2575df30925ae80be0c9d5b5d9ae6046ff355a7b
--- /dev/null
+++ b/Scripts/InterfaceExamples/ExampleOMInterface/test_simflag_overrideFile.py
@@ -0,0 +1,61 @@
+"""
+example of how to use the function simulateModel and set initial values from a file
+"""
+
+import os
+import sys
+sys.path.append("C:/Users/Martin/Desktop/hiwi/git/python-for-modelica/Py4Mod/py4mod")
+
+from OMInterface import OMInterface
+
+#Instantiate OMInterface
+print("")
+modelica = OMInterface()
+print("")
+
+#load Modelica-package 
+try:
+	modelica.loadLibrary("Modelica")
+except Exception as err:
+	print(err)
+	
+#example how to set initial values from a file
+try: 
+	#change working directory
+	cwd = os.getcwd()
+	wd=os.path.join(cwd, 'test_simflag_overrideFile')
+	if not os.path.exists(wd):
+		os.makedirs(wd)
+	modelica.changeWorkingDirectory(wd.replace("\\","/"))
+	
+	#build model
+	print("Build model Modelica.Blocks.Examples.PID_Controller")
+	modelica.buildModel("Modelica.Blocks.Examples.PID_Controller")
+	
+	#simulate model
+	#you can use one file to set initial values
+	#Note that: -overrideFile CANNOT be used with -override. Use when variables for -override are too many.
+	
+	#create the file with the initial values:
+	#it is important that the parameter file concludes with a blank line and that no
+	#spaces can be inserted before or after the equal sign, otherwise the
+	#OpenModelica compiler does not inherit the parameters in the model.
+	initFile=os.path.join(wd, 'init_values.csv')
+	f = open(initFile,'w')
+	file='startTime=0 \n stopTime=30 \n spring.w_rel=20.0 \n PI.Dzero.k=10.0 \n'.replace(" ", "")
+	f.write(file)	
+	f.close()
+
+	sim_flags='-overrideFile {}'.format(initFile).replace("\\","/")
+	print("Simulate Model:")
+	modelica.simulate(simflags=sim_flags)
+	
+	#check start value of spring.w_rel and PI.Dzero.k and time
+	test = modelica.getResults(["spring.w_rel", "PI.Dzero.k", "time"])
+	print('\nspring.w_rel[0]: {}'.format(test[0][0]))
+	print('PI.Dzero.k[0]: {}'.format(test[1][0]))
+	print('time: {}'.format(test[2]))
+	print("\n")
+
+except Exception as err:
+	print(err)