diff --git a/gradle.properties b/gradle.properties
index 6e0801f892720a1742cb422b03dda5d813a51cd5..a0eb503a16d7367e0eb623f3b9a3ce1ea26a77fb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-glpkPath = /usr/local/lib/jni
+glpkPath = C:/ProgrammeAlbert/glpk-4.65/w64
diff --git a/jastadd-mquat-solver-emfer/.gitignore b/jastadd-mquat-solver-emfer/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..567609b1234a9b8806c5a05da6c866e480aa148d
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/jastadd-mquat-solver-emfer/build.gradle b/jastadd-mquat-solver-emfer/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..9c88b3719c4486cf81cec0d7d5a7abbca59ae6d6
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/build.gradle
@@ -0,0 +1,35 @@
+
+apply plugin: 'java'
+
+sourceCompatibility = 1.8
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
+    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
+    compile project(':jastadd-mquat-base')
+    compile project(':jastadd-mquat-solver')
+    compile "org.eclipse.emf:org.eclipse.emf.ecore:2.9.0-v20130528-0742"
+    compile "org.eclipse.emf:org.eclipse.emf.common:2.9.0-v20130528-0742"
+    // compile "org.eclipse.emf:org.eclipse.emf.ecore.xmi:2.9.0-v20130528-0742"
+    compile files("./libs/libEMFER.jar")
+    testCompile group: 'junit', name: 'junit', version: '4.12'
+    testCompile project(path: ':jastadd-mquat-solver', configuration: 'testArtifacts')
+}
+group 'de.tudresden.inf.st'
+version '1.0.0-SNAPSHOT'
+
+apply plugin: 'java'
+
+sourceCompatibility = 1.8
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    testCompile group: 'junit', name: 'junit', version: '4.12'
+}
diff --git a/jastadd-mquat-solver-emfer/libs/libEMFER.jar b/jastadd-mquat-solver-emfer/libs/libEMFER.jar
new file mode 100644
index 0000000000000000000000000000000000000000..ad56ac74b12afb1e057eb1e61566945e513bb11a
Binary files /dev/null and b/jastadd-mquat-solver-emfer/libs/libEMFER.jar differ
diff --git a/jastadd-mquat-solver-emfer/message.txt b/jastadd-mquat-solver-emfer/message.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/message.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..d58e06d912c6593b3b8094e83b5d8c054084cf6a
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java
@@ -0,0 +1,211 @@
+package uniks;
+
+import de.tudresden.inf.st.mquat.jastadd.model.*;
+import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver;
+import de.tudresden.inf.st.mquat.solving.Solver;
+import de.tudresden.inf.st.mquat.solving.SolverUtils;
+import de.tudresden.inf.st.mquat.solving.SolvingException;
+import de.tudresden.inf.st.mquat.utils.StopWatch;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import uniks.ttc18.ECompMapping;
+import uniks.ttc18.ESolution;
+import uniks.ttc18.Ttc18Factory;
+
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class EMFeRSolver implements BenchmarkableSolver {
+
+  private static final Logger logger = LogManager.getLogger(EMFeRSolver.class);
+
+  private Solution lastSolution;
+  private long lastSolvingTime;
+
+  private int solutionCounter;
+
+  private StopWatch stopWatch;
+
+  private long maxSolvingTime;
+  private boolean timedOut;
+
+  public EMFeRSolver() {
+    this(Long.MAX_VALUE);
+  }
+
+  public EMFeRSolver(long maxSolvingTime) {
+    this.maxSolvingTime = maxSolvingTime;
+    reset();
+  }
+
+  private static void assignResource(Assignment assignment, Resource resource) {
+    Implementation impl = assignment.getImplementation();
+
+    ResourceMapping mapping = new ResourceMapping(impl.getResourceRequirement().getInstance(0), resource, new de.tudresden.inf.st.mquat.jastadd.model.List<>());
+    SolverUtils.populateResourceMapping(mapping, impl.getResourceRequirement(), resource);
+    assignment.setResourceMapping(mapping);
+  }
+
+  private int checkAssignment(Solution solution, List<Solution> solutions, List<Assignment> assignments, List<Set<Resource>> possibleResources, int index, Stack<Resource> usedResources) {
+    int checkCounter = 0;
+
+    Assignment assignment = assignments.get(index);
+    for (Resource resource : possibleResources.get(index)) {
+
+      if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) {
+        return checkCounter;
+      }
+
+      if (usedResources.contains(resource)) continue;
+      assignResource(assignment, resource);
+      usedResources.push(resource);
+      checkCounter++;
+      if (index == assignments.size() - 1) {
+        if (solution.isValid()) {
+          solutionCounter++;
+          if (solutions.isEmpty() || solution.computeObjective() < solutions.get(solutions.size() - 1).computeObjective()) {
+            Solution clone = solution.deepCopy();
+            solutions.add(clone);
+            logger.info("found a better solution with an objective of {}.", solution.computeObjective());
+          }
+
+        }
+      } else {
+        checkCounter += checkAssignment(solution, solutions, assignments, possibleResources, index + 1, usedResources);
+      }
+      usedResources.pop();
+    }
+    return checkCounter;
+  }
+
+  @Override
+  public Solution solve(Root model) throws SolvingException {
+    reset();
+    if (model.getNumRequest() == 0) {
+      return Solution.emptySolutionOf(model);
+    }
+
+    ESolution eSolution = Ttc18Factory.eINSTANCE.createESolution();
+
+    EMFeRTrafos emFeRTrafos = new EMFeRTrafos(model);
+
+    emFeRTrafos.createTopLevelMappings(eSolution);
+
+    for (ECompMapping compMapping : eSolution.getCompMappings())
+    {
+      emFeRTrafos.createAssignments(eSolution, compMapping);
+    }
+
+    int numAssignments = 0;
+    int numSoftwareSolutions = 0;
+    int numTotalSoftwareSolutions = 0;
+
+    stopWatch = StopWatch.start();
+
+    List<Solution> solutions = new ArrayList<>();
+
+    // iterate all possible assignments
+    // Note, that this only considers assignments of one configuration to each hardware component
+
+
+    Solution currentSolution = Solution.createSoftwareSolution(model);
+
+    Solution emferSolution = emFeRTrafos.transform(eSolution);
+
+    //    currentSolution.trace().process(new LoggerProcessor());
+
+    de.tudresden.inf.st.mquat.jastadd.model.List<Resource> resources = model.getHardwareModel().getResources();
+
+    boolean hasNextSoftwareAssignment;
+    do {
+
+      numTotalSoftwareSolutions++;
+
+      if (currentSolution.isSoftwareValid()) {
+
+        numSoftwareSolutions++;
+
+        List<Assignment> assignments = currentSolution.allAssignments();
+
+        // initialize the lists of possible assignments
+        List<Set<Resource>> possibleResources = new ArrayList<>(assignments.size());
+
+        for (Assignment assignment : assignments) {
+          Set<Resource> resourceList = new HashSet<>();
+          for (Resource resource : resources) {
+            assignResource(assignment, resource);
+            if (assignment.isValid()) {
+              resourceList.add(resource);
+            }
+          }
+          possibleResources.add(resourceList);
+        }
+
+        numAssignments += checkAssignment(currentSolution, solutions, assignments, possibleResources, 0, new Stack<>());
+      }
+
+      if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) {
+        this.timedOut = true;
+        logger.warn("Timeout! Solving terminated!");
+        break;
+      }
+
+      hasNextSoftwareAssignment = currentSolution.nextSoftwareAssignment();
+    } while (hasNextSoftwareAssignment);
+
+    logger.info("Number of total software solutions: {}", numTotalSoftwareSolutions);
+    logger.info("Number of iterated software solutions: {}", numSoftwareSolutions);
+    logger.info("Number of iterated solutions: {}", numAssignments);
+    logger.info("Number of correct solutions: {}", solutionCounter);
+
+    if (solutions.size() > 0) {
+      lastSolution = solutions.get(solutions.size() - 1);
+    } else {
+      lastSolution = Solution.emptySolutionOf(model);
+      logger.warn("Found no solution!");
+    }
+
+    lastSolvingTime = stopWatch.time(TimeUnit.MILLISECONDS);
+
+    return lastSolution;
+  }
+
+  private void reset() {
+    this.lastSolution = null;
+    this.solutionCounter = 0;
+    this.lastSolvingTime = 0;
+    this.timedOut = false;
+  }
+
+  @Override
+  public String getName() {
+    return "simple";
+  }
+
+  @Override
+  public long getLastSolvingTime() {
+    return lastSolvingTime;
+  }
+
+  @Override
+  public double getLastObjective() {
+    if (lastSolution != null) {
+      return lastSolution.computeObjective();
+    } else {
+      // TODO throw exception or do something reasonable
+      return 0d;
+    }
+  }
+
+  @Override
+  public Solver setTimeout(long timeoutValue, TimeUnit timeoutUnit) {
+    this.maxSolvingTime = timeoutUnit.toMillis(timeoutValue);
+    return this;
+  }
+
+  @Override
+  public boolean hadTimeout() {
+    return this.timedOut;
+  }
+}
diff --git a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0c104f1eda572afde181004898e3433ce3e20c4
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java
@@ -0,0 +1,110 @@
+package uniks;
+
+import de.tudresden.inf.st.mquat.jastadd.model.*;
+import uniks.ttc18.EAssignment;
+import uniks.ttc18.ECompMapping;
+import uniks.ttc18.ESolution;
+import uniks.ttc18.Ttc18Factory;
+
+import java.io.IOException;
+import java.nio.file.*;
+
+public class EMFeRTrafos
+{
+   private Root model;
+
+   public EMFeRTrafos(Root model)
+   {
+      this.model = model;
+   }
+
+   public void createTopLevelMappings(ESolution eSolution)
+   {
+      org.eclipse.emf.common.util.EList<ECompMapping> compMappings = eSolution.getCompMappings();
+
+      if ( ! compMappings.isEmpty())
+      {
+         return;
+      }
+
+      for ( Request request : model.getRequests())
+      {
+         String requName = request.getName().toString();
+         ComponentRef target = request.getTarget();
+         Name targetName = target.getName();
+
+         ECompMapping eCompMapping = Ttc18Factory.eINSTANCE.createECompMapping();
+         eCompMapping.setRequName(requName);
+         eCompMapping.setCompName(targetName.toString());
+         compMappings.add(eCompMapping);
+      }
+   }
+
+   public void createAssignments(ESolution eSolution, ECompMapping compMapping)
+   {
+      String compName = compMapping.getCompName();
+      Component comp = findComp(model, compName);
+      Implementation implementation = comp.getImplementation(0);
+      EAssignment eAssignment = Ttc18Factory.eINSTANCE.createEAssignment();
+      String implName = implementation.getName().toString();
+      eAssignment.setImplName(implName);
+      compMapping.setAssignment(eAssignment);
+
+
+      for (ComponentRequirement componentRequirement : implementation.getComponentRequirements())
+      {
+         String requCompName = componentRequirement.getComponentRef().getRef().getName().toString();
+
+         ECompMapping subMapping = Ttc18Factory.eINSTANCE.createECompMapping();
+         subMapping.setRequName(implName);
+         subMapping.setCompName(requCompName);
+         eAssignment.getCompMappings().add(subMapping);
+
+         createAssignments(eSolution, subMapping);
+      }
+
+   }
+
+   private Component findComp(Root model, String compName)
+   {
+      for (Component comp : model.getSoftwareModel().getComponents())
+      {
+         if (comp.getName().toString().equals(compName))
+         {
+            return comp;
+         }
+      }
+      return null;
+   }
+
+   public Solution transform(ESolution eSolution)
+   {
+      Solution result = new Solution();
+      result.setModel(model);
+
+
+
+      // top level
+      for (ECompMapping eCompMap : eSolution.getCompMappings())
+      {
+         Assignment assignment = new Assignment();
+         assignment.setRequest(findRequest(eCompMap.getRequName()));
+         assignment.setTopLevel(true);
+         result.addAssignment(assignment);
+      }
+
+      return result;
+   }
+
+   private Request findRequest(String requName)
+   {
+      for (Request r : model.getRequests())
+      {
+         if (r.getName().toString().equals(requName))
+         {
+            return r;
+         }
+      }
+      return null;
+   }
+}
diff --git a/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRHandwrittenTest.java b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRHandwrittenTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..db93225ab06c59e9589879cdd0c8d723d93c2900
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRHandwrittenTest.java
@@ -0,0 +1,11 @@
+package de.tudresden.inf.st.mquat.solving;
+
+import uniks.EMFeRSolver;
+
+public class EMFeRHandwrittenTest extends HandwrittenTestSuite {
+
+  @Override
+  protected Solver getSolver() {
+    return new EMFeRSolver(10000);
+  }
+}
diff --git a/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab6ae20d1ea5b0aa4be9468633d7b42df97fa060
--- /dev/null
+++ b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java
@@ -0,0 +1,94 @@
+package de.tudresden.inf.st.mquat.solving;
+
+import de.tudresden.inf.st.mquat.generator.ScenarioDescription;
+import de.tudresden.inf.st.mquat.generator.ScenarioGenerator;
+import de.tudresden.inf.st.mquat.jastadd.model.Root;
+import de.tudresden.inf.st.mquat.jastadd.model.Solution;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import uniks.EMFeRSolver;
+
+import java.io.IOException;
+import java.nio.file.*;
+
+public class EMFeRSolverTest {
+
+  private static Logger logger;
+
+  @BeforeClass
+  public static void initLogger() {
+    logger = LogManager.getLogger(EMFeRSolverTest.class);
+  }
+
+  /**
+   * tests the simple solver with one very simple use case
+   */
+  @Test
+  public void testSimpleSolver() throws SolvingException {
+    int tlc = 1;
+    int iac = 2;
+    int isd = 0;
+    int cac = 0;
+    int csd = 0;
+    int dep = 2;
+    int imp = 1;
+    int mod = 3;
+    double res = 1.5d;
+    int nfp = 0;
+    int req = 1;
+    int cpu = 1;
+    int seed = 0;
+
+    ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed));
+
+    Root model = generator.generate();
+    EMFeRSolver solver = new EMFeRSolver(20000);
+
+    Solution solution = solver.solve(model);
+
+    Assert.assertNotNull(solution);
+
+    logger.info("the best solution is {} and has an objective of {}.", (solution.isValid() ? "valid" : "invalid"), solution.computeObjective());
+
+  }
+
+  @Test
+  public void testListener()
+  {
+    Path path = Paths.get(".");
+
+    try
+    {
+      WatchService watcher = FileSystems.getDefault().newWatchService();
+      path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
+
+      Files.write(Paths.get("./message.txt"), "Hello World".getBytes());
+
+      WatchKey event = watcher.take();
+
+      for (WatchEvent we : event.pollEvents())
+      {
+         System.out.println("" + we.kind() + " " + we.context());
+
+         String context = we.context().toString();
+
+         String content = new String(Files.readAllBytes(Paths.get(context)));
+
+         System.out.println(content);
+      }
+
+    }
+    catch (IOException e)
+    {
+      e.printStackTrace();
+    }
+    catch (InterruptedException e)
+    {
+      e.printStackTrace();
+    }
+  }
+
+}
diff --git a/settings.gradle b/settings.gradle
index 00ff37f0ee12bb9f694350d30e9c45f27ed3ef0f..e6ec605b4b6a0cfc2bf60b28f153b9c9ee023035 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,4 +5,6 @@ include ':jastadd-mquat-benchmark'
 include ':jastadd-mquat-solver'
 include ':jastadd-mquat-solver-ilp'
 include ':jastadd-mquat-solver-simple'
+include ':jastadd-mquat-solver-emfer'
+include 'jastadd-mquat-solver-emfer'