@Override
  public void run(Object thisPointer, CallFrame callingFrame) {
    System.out.println("Method " + self.getName() + " was called.");

    // setup call frame
    CallFrame callFrame = self.metaCreateCallFrame();
    callFrame.setCallingFrame(callFrame);
    callFrame.setThis(thisPointer);
    if (self.getScope() == Scope.MEMBER && callFrame.getThis() == null) {
      throw new ModelException("Member variable without this pointer.");
    }
    for (Variable localVar : self.getVariable()) {
      callFrame.getLocalVariable().add(localVar.metaCreateSlot());
    }

    // run body
    for (Statement statement : self.getBody()) {
      if (statement instanceof Assignment) {
        callFrame
            .slotForVariable(((Assignment) statement).getAssignTo())
            .setValue(((Assignment) statement).getAssignWith().evaluate(callFrame));
      } else if (statement instanceof MethodCall) {
        Method method = ((MethodCall) statement).getCalledMethod();
        if (method.getScope() == Scope.MEMBER) {
          method.run(((MethodCall) statement).getTarget().evaluate(callFrame), callFrame);
        }
      }
    }

    // destroy call frame
    for (Slot slot : new ListImpl<Slot>((callFrame.getLocalVariable()))) {
      slot.metaDelete();
    }
    callFrame.metaDelete();
  }
  private Assignment doOnePass(FactorGraph mdl, Assignment initial) {
    Assignment ret = (Assignment) initial.duplicate();
    for (int vidx = 0; vidx < ret.size(); vidx++) {
      Variable var = mdl.get(vidx);
      DiscreteFactor subcpt = constructConditionalCpt(mdl, var, ret);
      int value = subcpt.sampleLocation(r);
      ret.setValue(var, value);
    }

    return ret;
  }
 // Warning: destructively modifies ret's assignment to fullAssn (I could save and restore, but I
 // don't care
 private DiscreteFactor constructConditionalCpt(
     FactorGraph mdl, Variable var, Assignment fullAssn) {
   List ptlList = mdl.allFactorsContaining(var);
   LogTableFactor ptl = new LogTableFactor(var);
   for (AssignmentIterator it = ptl.assignmentIterator(); it.hasNext(); it.advance()) {
     Assignment varAssn = it.assignment();
     fullAssn.setValue(var, varAssn.get(var));
     ptl.setRawValue(varAssn, sumValues(ptlList, fullAssn));
   }
   ptl.normalize();
   return ptl;
 }