if (ErlangRunner.validName(f.getName()))
            ErlangRunner.compileErl(f, null);
        // Based on
        // http://erlang.org/pipermail/erlang-questions/2010-March/050226.html
        OtpNode self = new OtpNode(ourNode, uniqueID); // identify self
        thisMbox = self.createMbox("thisMbox");
        // Now build environment variables to ensure that dialyzer will
        // find a directory to put its plt file in.
        // This is actually a dialyzer bug which manifests itself on
        // Windows -
        // there is no need for dialyzer_options:build(Opts) to call
        // dialyzer_plt:get_default_plt()
        // before build_options(Opts, DefaultOpts1).
        List<String> envpList = new LinkedList<String>();
        
        Map<String,String> newValues = new TreeMap<String,String>();
        newValues.put("HOME",new File(ErlangQSMOracle.ErlangFolder).getAbsolutePath());
        newValues.put("ERL_MAX_PORTS","1024");// to limit the size of each Erlang instance to a few meg from a few hundred meg
        for (Entry<String, String> entry : System.getenv().entrySet())
          if (!newValues.containsKey(entry.getKey()))
            envpList.add(entry.getKey() + "=" + entry.getValue());
        
        for(Entry<String, String> entry : newValues.entrySet())
          envpList.add(entry.getKey() + "=" + entry.getValue());
        erlangProcess = Runtime
            .getRuntime()
            .exec(new String[] {
                ErlangRunner.getErlangBin() + "erl",
                "-pa",
                new File(ErlangQSMOracle.ErlangFolder).getAbsolutePath(),
                "-pa",
                new File(ErlangQSMOracle.ErlangTyper).getAbsolutePath(),
                // the easiest way to substitute our module in place
                // of the original Erlang's one, otherwise I'd
                // have to rely on tracerunner:compileAndLoad
                "-run", "tracerunner", "start", ourNode,
                runnerMode, "-sname", traceRunnerNode,
                "-noshell", "-setcookie", uniqueID },
                envpList.toArray(new String[0]),
                new File(ErlangQSMOracle.ErlangFolder));
        stdDumper = new Thread(new Runnable() {
          @Override
          public void run() {
            ExperimentRunner.dumpStreams(erlangProcess,
                timeBetweenChecks, new HandleProcessIO() {
                  @Override
                  public void OnHeartBeat() {
                    // no prodding is done - we are
                    // being prodded by Erlang instead.
                  }
                  @Override
                  public void StdErr(StringBuffer b) {
                    if (displayErlangOutput)
                      System.out.print("[ERLANG] "
                          + b.toString());
                  }
                  @Override
                  public void StdOut(StringBuffer b) {
                    if (displayErlangOutput)
                      System.out.print("[ERLERR] "
                          + b.toString());
                  }
                });
          }
        });
        stdDumper.setDaemon(true);
        stdDumper.start();
        if (delay > 0)
          Thread.sleep(delay);
        // At this point, the process may have not yet started or
        // already terminated, it is easy to find out which of the
        // two has happened by doing
        int timeout = serverTimeout;
        while (!self.ping(traceRunnerNode, 500) && timeout > 0) {
          try {
            erlangProcess.exitValue();
            // process terminated, record this as a failure
            timeout = 0;
          } catch (IllegalThreadStateException e) {
            // process not yet terminated, hence we keep waiting
            --timeout;
          }
        }
        ourBox = new OtpErlangTuple(new OtpErlangObject[] {
            thisMbox.self(), self.createRef() });
        if (timeout <= 0) {
          final long endTime = System.currentTimeMillis();
          throw new IllegalArgumentException(
              "timeout waiting for a server to start after "
                  + (endTime - startTime) + "ms");