@Override
 public void initTest(long seed) {
   if (currentExplorer != null) {
     currentExplorer.stop();
   }
   currentExplorer = null;
 }
  /**
   * Explores the next step locally. Local refers to the same machine, at one point we had
   * distributed version as well. If no explorer is currently running, starts a new one and waits
   * for the results. If one is already running, waits for the results from that explorer. A new
   * explorer is started once the selection is made to already search for the next step concurrently
   * while the generator is executing the previous one.
   *
   * @param suite Current test suite.
   * @param state State to use for exploration, includes exploration configuration and initial suite
   *     coverage.
   * @param path Path executed so far for this test before exploring for this step.
   * @param root We use this to write the trace.
   * @return The next step to take according to exploration results.
   */
  private String exploreLocal(
      TestSuite suite, ExplorationState state, List<String> path, TraceNode root) {
    if (currentExplorer == null) {
      currentExplorer = new MainExplorer(root);
      currentExplorer.init(fsm, suite, state, path, config.getParallelism());
      currentExplorer.explore();
    }
    // get the choice of next step based on best exploration score
    // the exploration was already started at the end of previous session..
    String result = currentExplorer.getResult();
    int test = suite.getAllTestCases().size();
    int step = suite.getCurrentTest().getSteps().size() + 1;
    // update time trace to track how much time each step takes to explore. for providing statistics
    // to user.
    TimeTrace trace = new TimeTrace(test, step, result, currentExplorer.getDuration());
    traces.add(trace);

    // tracking coverage means we want to trace all possible options that could have been taken
    if (trackCoverage) {
      // grab all possible values from the explorer and add to list of unique
      Map<String, Collection<String>> observed = currentExplorer.getPossibleVariableValues();
      for (String key : observed.keySet()) {
        Collection<String> possibles = possibleValues.get(key);
        if (possibles == null) {
          possibles = new LinkedHashSet<>();
          possibleValues.put(key, possibles);
        }
        possibles.addAll(observed.get(key));
      }

      // grab all possible states from the explorer and add to list of unique
      observed = currentExplorer.getPossibleStates();
      for (String key : observed.keySet()) {
        Collection<String> possibles = possibleStates.get(key);
        if (possibles == null) {
          possibles = new LinkedHashSet<>();
          possibleStates.put(key, possibles);
        }
        possibles.addAll(observed.get(key));
      }

      // grab all possible state pairs from the explorer and add to list of unique
      observed = currentExplorer.getPossibleStatePairs();
      for (String key : observed.keySet()) {
        Collection<String> possibles = possibleStatePairs.get(key);
        if (possibles == null) {
          possibles = new LinkedHashSet<>();
          possibleStatePairs.put(key, possibles);
        }
        possibles.addAll(observed.get(key));
      }

      possibleStepPairs.addAll(currentExplorer.getPossibleStepPairs());
    }

    if (explorationEndCondition.endTest(suite, null)) {
      currentExplorer.stop();
      currentExplorer = null;
    } else {
      currentExplorer.stop();
      List<String> newScript = new ArrayList<>();
      newScript.addAll(path);
      newScript.add(result);
      currentExplorer = new MainExplorer(root);
      currentExplorer.init(fsm, suite, state, newScript, config.getParallelism());
      currentExplorer.explore();
    }

    return result;
  }