/**
   * Handles the remote dispatch of a local event so that runners on other nodes can eventually
   * receive the data.
   */
  @Override
  public void newStateAdded(ITransition sourceTransition, IState newStateId) {
    if (sourceTransition == null) {
      return;
    }

    NewStateChange change =
        new NewStateChange(
            sourceTransition.getFiredFrom().getId(),
            sourceTransition.getId(),
            newStateId.getId(),
            convert(newStateId.getOutgoingTransitions()),
            "me");

    if (appliedRemoteChanges.contains(change)) {
      appliedRemoteChanges.remove(change);
      return;
    }

    List<IDesignSpaceChange> push = null;
    synchronized (hashSet) {
      hashSet.add(change);
      if (hashSet.size() > 0) {
        push = new ArrayList<IDesignSpaceChange>();
        push.addAll(hashSet);
        hashSet.clear();
      }
    }

    if (push != null) {
      remote.doUpdates(push, identifier);
      //			process(updates);
    }
  }
  @Override
  public void newRootAdded(IState state) {
    NewRootChange newRootChange =
        new NewRootChange(state.getId(), convert(state.getOutgoingTransitions()), "me");

    if (appliedRemoteChanges.contains(newRootChange)) {
      appliedRemoteChanges.remove(newRootChange);
      return;
    }

    List<IDesignSpaceChange> changeList = null;
    synchronized (hashSet) {
      hashSet.add(newRootChange);
      changeList = new ArrayList<IDesignSpaceChange>();
      changeList.addAll(hashSet);
      hashSet.clear();
    }

    if (changeList != null) {
      remote.doUpdates(changeList, identifier);
      //			if (updates != null) {
      //				process(updates);
      //			}
    }

    System.out.println("Root added " + state.getId());
  }