public PythonRunner(
      Map<String, String> environment,
      Repositories repositories,
      Scheduler scheduler,
      Hierarchy loggerRepository,
      String pythonPath,
      BufferedWriter out,
      BufferedWriter err)
      throws Exception {

    init();

    this.staticContext = new StaticContext(scheduler, loggerRepository).repository(repositories);
    this.environment = environment;

    final PySystemState systemState = new PySystemState();
    interpreter = new PythonInterpreter(null, systemState);
    for (String path : pythonPath.split(":")) {
      systemState.path.add(new PyString(path));
    }
    interpreter.setOut(out);
    interpreter.setErr(err);
    scriptContext = staticContext.scriptContext();

    // XPM module
    final PyModule xpmModule = new PyModule("xpm", (PyObject) null);
    systemState.modules.__setitem__("xpm", xpmModule);

    // Add classes
    for (PyType type : TYPES.values()) {
      xpmModule.__setattr__(type.getName(), type);
    }

    // Add constants
    Scripting.forEachConstant(
        (name, value) -> {
          xpmModule.__setattr__(name, wrap(value));
        });

    // Add functions
    Scripting.forEachFunction(
        m -> {
          xpmModule.__setattr__(m.getKey(), new PythonMethod(null, m));
        });

    // Add Python specific functions
    for (MethodFunction m : Scripting.getMethodFunctions(PythonFunctions.class)) {
      xpmModule.__setattr__(m.getKey(), new PythonMethod(null, m));
    }

    // XPM object: wrap properties
    final XPM xpm = new XPM();
    ClassDescription xpmDescription = ClassDescription.analyzeClass(XPM.class);
    for (Map.Entry<Object, MethodFunction> x : xpmDescription.getMethods().entrySet()) {
      final Object key = x.getKey();
      if (key instanceof String) {
        xpmModule.__setattr__((String) key, new PythonMethod(xpm, x.getValue()));
      } else {
        throw new XPMRuntimeException("Could not handle key ", key);
      }
    }

    // Add properties
    xpmModule.__setattr__("tasks", wrap(new Tasks()));
    xpmModule.__setattr__("logger", wrap(new ScriptingLogger("xpm")));
    xpmModule.__setattr__("env", wrap(environment));
  }
 @Override
 public void close() throws Exception {
   interpreter.close();
   scriptContext.close();
   staticContext.close();
 }