@Override
  public void init(Resource problemApp) {
    this.setProblemResource(problemApp);
    this.setProblemType(problemApp.getProblemType());
    this.preconditionsOk = false;
    this.curInstance = null;
    this.selectedVm = null;
    this.costs = 0;
    this.app = null;

    this.costs = Configuration.getInstance().getAppInsertIntoVmCosts();

    if (problemApp instanceof App) { // only apps can be inserted
      app = (App) problemApp;
      if (app.getVm() == null) { // only new apps can be inserted
        prediction = 0;
        int curFitFactor = 0;

        for (PhysicalMachine pm : Monitor.getInstance().getPms()) {
          if (pm.isRunning()) {
            for (VirtualMachine vm : pm.getVms()) {
              curFitFactor = calculateFit(app, vm);
              if (curFitFactor > prediction) {
                preconditionsOk = true;
                prediction = curFitFactor;
                this.selectedVm = vm;
              }
            }
          }
        }
      }
    }
  }
  @Override
  public void execute() {
    globalTickExecution = Monitor.getInstance().getGlobalTicks();
    // remove the app from the request- queue???
    if (app.getOriginalRequest() != null) {
      RequestGenerator.getInstance().removeRequestFromQueue(app.getOriginalRequest());
    }

    selectedVm.createApp(this.app);
  }
  @Override
  public boolean evaluate() {
    if (curInstance == null) {
      curInstance = createInstance(0, selectedVm); // create a Instance with the past values
    }

    if (app.getSuspendedTicks() > 0
        || app.getVm().getSuspendedTicks() > 0
        || app.getVm().getPm().getSuspendedTicks() > 0) {
      return false;
    } else if (waitForEvaluation > 0) {
      waitForEvaluation--;
      return false;
    } else {
      // System.out.println("APP - Running Ticks: " + app.getRunningTicks());
      LinkedList<Integer> cpuusagehist = selectedVm.getPm().getCpuUsageHistory(10);

      LinkedList<Integer> memusagehist = selectedVm.getPm().getMemoryUsageHistory(10);

      LinkedList<Integer> storageusagehist = selectedVm.getPm().getStorageUsageHistory(10);

      double evaluation =
          (255
                  - calculateUsageRatio(cpuusagehist, 85)
                  - calculateUsageRatio(memusagehist, 85)
                  - calculateUsageRatio(storageusagehist, 85))
              / 255;

      // subtract SLA Violations
      evaluation -=
          (app.getCpuSlaErrorcount() + app.getMemorySlaErrorcount() + app.getStorageSlaErrorcount())
              / 10;

      // minimum of 0
      // evaluation = Math.max(0, evaluation);
      Monitor.getInstance().logExecution(app, this, evaluation, this.globalTickExecution);
      curInstance.setValue(getKnowledgeBase().attribute(63), evaluation);
      this.setLocalEvaluation(evaluation);
      getKnowledgeBase().add(curInstance);
    }
    return true;
  }