diff --git a/de.prob.core/.classpath b/de.prob.core/.classpath
index 5004b8808efadf10e19fa4e2470fc73ccdd87d92..335ff9a8928bfc22ed8542d5eabf96a22f2a582b 100644
--- a/de.prob.core/.classpath
+++ b/de.prob.core/.classpath
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+	<classpathentry exported="true" kind="lib" path="lib/dependencies/jfmi-1.0.2-SNAPSHOT.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/dependencies/jna-3.4.0.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="output" path="bin"/>
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/answerparser-2.4.22-SNAPSHOT.jar"/>
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/bparser-2.4.22-SNAPSHOT.jar"/>
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/cliparser-2.4.22-SNAPSHOT.jar"/>
@@ -18,4 +19,5 @@
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/xmlpull-1.1.3.1.jar"/>
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/xpp3_min-1.1.4c.jar"/>
 	<classpathentry exported="true" kind="lib" path="lib/dependencies/xstream-1.4.3.jar"/>
+	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/de.prob.core/META-INF/MANIFEST.MF b/de.prob.core/META-INF/MANIFEST.MF
index f909299e5350c0dd7344b7c0f9de8f1aaa2ec559..83fe4c54078113f1ed4d0d5a83910db86a9c88ae 100644
--- a/de.prob.core/META-INF/MANIFEST.MF
+++ b/de.prob.core/META-INF/MANIFEST.MF
@@ -82,6 +82,7 @@ Export-Package: com.thoughtworks.xstream,
  de.prob.core.sablecc.parser,
  de.prob.core.translator,
  de.prob.core.types,
+ de.prob.cosimulation,
  de.prob.eventb.translator,
  de.prob.eventb.translator.flow,
  de.prob.eventb.translator.internal,
@@ -113,7 +114,10 @@ Export-Package: com.thoughtworks.xstream,
  org.apache.commons.lang.mutable,
  org.apache.commons.lang.reflect,
  org.apache.commons.lang.text,
- org.apache.commons.lang.time
+ org.apache.commons.lang.time,
+ org.ptolemy.fmi,
+ org.ptolemy.fmi.driver,
+ org.ptolemy.fmi.type
 Bundle-Activator: de.prob.core.internal.Activator
 Eclipse-BuddyPolicy: registered
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
@@ -132,4 +136,6 @@ Bundle-ClassPath: .,
  lib/dependencies/jsr305-1.3.9.jar,
  lib/dependencies/xmlpull-1.1.3.1.jar,
  lib/dependencies/xpp3_min-1.1.4c.jar,
- lib/dependencies/xstream-1.4.3.jar
+ lib/dependencies/xstream-1.4.3.jar,
+ lib/dependencies/jfmi-1.0.2-SNAPSHOT.jar,
+ lib/dependencies/jna-3.4.0.jar
diff --git a/de.prob.core/build.gradle b/de.prob.core/build.gradle
index a4692401acacc2acb2529817321b113b81f4a2ec..60dd16f13dc3acdbf16941f1423292a2600a4663 100644
--- a/de.prob.core/build.gradle
+++ b/de.prob.core/build.gradle
@@ -14,4 +14,6 @@ dependencies {
  compile 'commons-lang:commons-lang:2.6'
  compile 'commons-codec:commons-codec:1.6'
  compile 'com.thoughtworks.xstream:xstream:1.4.3'
+ compile group: 'net.java.dev.jna', name: 'jna', version: '3.4.0'
+ compile group: 'edu.berkeley.eecs.ptolemy', name: 'jfmi', version: '1.0.2-SNAPSHOT'
 }
\ No newline at end of file
diff --git a/de.prob.core/build.properties b/de.prob.core/build.properties
index 1a6cddddba5661de2f965051163daed933d90407..99230d528427c77989fe9534724cf6533e521d2e 100644
--- a/de.prob.core/build.properties
+++ b/de.prob.core/build.properties
@@ -8,6 +8,8 @@ bin.includes = META-INF/,\
                lib/dependencies/commons-codec-1.6.jar,\
                lib/dependencies/xmlpull-1.1.3.1.jar,\
                lib/dependencies/xpp3_min-1.1.4c.jar,\
-               lib/dependencies/xstream-1.4.3.jar
+               lib/dependencies/xstream-1.4.3.jar,\
+               lib/dependencies/jfmi-1.0.2-SNAPSHOT.jar,\
+               lib/dependencies/jna-3.4.0.jar
              
 
diff --git a/de.prob.core/src/de/prob/cosimulation/FMU.java b/de.prob.core/src/de/prob/cosimulation/FMU.java
new file mode 100644
index 0000000000000000000000000000000000000000..d726cdea926eb06c21100d0c7da0774fb18d216a
--- /dev/null
+++ b/de.prob.core/src/de/prob/cosimulation/FMU.java
@@ -0,0 +1,240 @@
+package de.prob.cosimulation;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.ptolemy.fmi.FMICallbackFunctions;
+import org.ptolemy.fmi.FMILibrary;
+import org.ptolemy.fmi.FMIModelDescription;
+import org.ptolemy.fmi.FMIScalarVariable;
+import org.ptolemy.fmi.FMUFile;
+import org.ptolemy.fmi.FMULibrary;
+
+import com.sun.jna.Function;
+import com.sun.jna.NativeLibrary;
+import com.sun.jna.Pointer;
+
+public class FMU {
+
+	private static final double TIMEOUT = 1000;
+
+	/** The modelIdentifier from modelDescription.xml. */
+	String _modelIdentifier;
+
+	/** The NativeLibrary that contains the functions. */
+	NativeLibrary _nativeLibrary;
+	private Pointer component;
+
+	private final FMIModelDescription modelDescription;
+
+	private final Map<String, FMIScalarVariable> variables = new HashMap<String, FMIScalarVariable>();
+
+	private final Set<IFMUListener> listeners = new HashSet<IFMUListener>();
+
+	public void registerListener(final IFMUListener listener) {
+		listeners.add(listener);
+	}
+
+	public void unregisterListener(final IFMUListener listener) {
+		listeners.remove(listener);
+	}
+
+	public FMU(final String fmuFileName) throws IOException {
+		modelDescription = FMUFile.parseFMUFile(fmuFileName);
+		String sharedLibrary = FMUFile.fmuSharedLibrary(modelDescription);
+
+		for (FMIScalarVariable fmiScalarVariable : modelDescription.modelVariables) {
+			variables.put(fmiScalarVariable.name, fmiScalarVariable);
+		}
+
+		_nativeLibrary = NativeLibrary.getInstance(sharedLibrary);
+
+		// The modelName may have spaces in it.
+		_modelIdentifier = modelDescription.modelIdentifier;
+
+		// The URL of the fmu file.
+		String fmuLocation = new File(fmuFileName).toURI().toURL().toString();
+
+		// The tool to use if we have tool coupling.
+		String mimeType = "application/x-fmu-sharedlibrary";
+
+		// Timeout in ms., 0 means wait forever.
+		double timeout = TIMEOUT;
+
+		// There is no simulator UI.
+		byte visible = 0;
+		// Run the simulator without user interaction.
+		byte interactive = 0;
+		// Callbacks
+		FMICallbackFunctions.ByValue callbacks = new FMICallbackFunctions.ByValue(
+				new FMULibrary.FMULogger(), new FMULibrary.FMUAllocateMemory(),
+				new FMULibrary.FMUFreeMemory(),
+				new FMULibrary.FMUStepFinished());
+		// Logging tends to cause segfaults because of vararg callbacks.
+		byte loggingOn = (byte) 0;
+
+		component = instantiateFMU(fmuLocation, mimeType, timeout, visible,
+				interactive, callbacks, loggingOn);
+
+		if (component.equals(Pointer.NULL)) {
+			throw new RuntimeException("Could not instantiate model.");
+		}
+	}
+
+	public String getFmiVersion() {
+		assert _nativeLibrary != null;
+		Function function = getFunction("_fmiGetVersion");
+		return (String) function.invoke(String.class, new Object[0]);
+	}
+
+	public void initialize(final double startTime, final double endTime) {
+		invoke("_fmiInitializeSlave", new Object[] { component, startTime,
+				(byte) 1, endTime }, "Could not initialize slave: ");
+	}
+
+	public boolean getBoolean(final String name) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		return fmiScalarVariable.getBoolean(component);
+	}
+
+	public double getDouble(final String name) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		return fmiScalarVariable.getDouble(component);
+	}
+
+	public int getInt(final String name) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		return fmiScalarVariable.getInt(component);
+	}
+
+	public String getString(final String name) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		return fmiScalarVariable.getString(component);
+	}
+
+	public void set(final String name, final boolean b) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		fmiScalarVariable.setBoolean(component, b);
+	}
+
+	public void set(final String name, final int i) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		fmiScalarVariable.setInt(component, i);
+	}
+
+	public void set(final String name, final double d) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		fmiScalarVariable.setDouble(component, d);
+	}
+
+	public void set(final String name, final String s) {
+		FMIScalarVariable fmiScalarVariable = variables.get(name);
+		fmiScalarVariable.setString(component, s);
+	}
+
+	public double doStep(final double time, final double delta_t) {
+		Function doStep = getFunction("_fmiDoStep");
+		invoke(doStep, new Object[] { component, time, delta_t, (byte) 1 },
+				"Could not simulate, time was " + time + ": ");
+
+		for (IFMUListener l : listeners) {
+			l.trigger(variables);
+		}
+		return time + delta_t;
+	}
+
+	public void terminate() {
+		invoke("_fmiTerminateSlave", new Object[] { component },
+				"Could not terminate slave: ");
+		invoke("_fmiFreeSlaveInstance", new Object[] { component },
+				"Could not dispose resources of slave: ");
+		component = null;
+	}
+
+	@Override
+	protected void finalize() throws Throwable {
+		this.terminate();
+		super.finalize();
+	}
+
+	public void reset() {
+		invoke("_fmiResetSlave", new Object[] { component },
+				"Could not reset slave: ");
+	}
+
+	public FMIModelDescription getModelDescription() {
+		return modelDescription;
+	}
+
+	private Pointer instantiateFMU(final String fmuLocation,
+			final String mimeType, final double timeout, final byte visible,
+			final byte interactive,
+			final FMICallbackFunctions.ByValue callbacks, final byte loggingOn) {
+		Function instantiateSlave = getFunction("_fmiInstantiateSlave");
+		Pointer fmiComponent = (Pointer) instantiateSlave.invoke(Pointer.class,
+				new Object[] { _modelIdentifier, modelDescription.guid,
+						fmuLocation, mimeType, timeout, visible, interactive,
+						callbacks, loggingOn });
+		return fmiComponent;
+	}
+
+	/**
+	 * Return a function by name.
+	 * 
+	 * @param name
+	 *            The name of the function. The value of the modelIdentifier is
+	 *            prepended to the value of this parameter to yield the function
+	 *            name.
+	 * @return the function.
+	 */
+	public Function getFunction(final String name) {
+		// This is syntactic sugar.
+		return _nativeLibrary.getFunction(_modelIdentifier + name);
+	}
+
+	/**
+	 * Invoke a function that returns an integer representing the FMIStatus
+	 * return value.
+	 * 
+	 * @param name
+	 *            The name of the function.
+	 * @param arguments
+	 *            The arguments to be passed to the function.
+	 * @param message
+	 *            The error message to be used if there is a problem. The
+	 *            message should end with ": " because the return value of the
+	 *            function will be printed after the error message.
+	 */
+	public void invoke(final String name, final Object[] arguments,
+			final String message) {
+		Function function = getFunction(name);
+		invoke(function, arguments, message);
+	}
+
+	/**
+	 * Invoke a function that returns an integer representing the FMIStatus
+	 * return value.
+	 * 
+	 * @param function
+	 *            The function to be invoked.
+	 * @param arguments
+	 *            The arguments to be passed to the function.
+	 * @param message
+	 *            The error message to be used if there is a problem. The
+	 *            message should end with ": " because the return value of the
+	 *            function will be printed after the error message.
+	 */
+	public void invoke(final Function function, final Object[] arguments,
+			final String message) {
+		int fmiFlag = ((Integer) function.invoke(Integer.class, arguments))
+				.intValue();
+		if (fmiFlag > FMILibrary.FMIStatus.fmiWarning) {
+			throw new RuntimeException(message + fmiFlag);
+		}
+	}
+
+}
diff --git a/de.prob.core/src/de/prob/cosimulation/IFMUListener.java b/de.prob.core/src/de/prob/cosimulation/IFMUListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..2001ffddf65a1e1aa8941b133b3d81cf65cb5b6b
--- /dev/null
+++ b/de.prob.core/src/de/prob/cosimulation/IFMUListener.java
@@ -0,0 +1,11 @@
+package de.prob.cosimulation;
+
+import java.util.Map;
+
+import org.ptolemy.fmi.FMIScalarVariable;
+
+public interface IFMUListener {
+
+	void trigger(Map<String, FMIScalarVariable> variables);
+
+}