@Nullable
    VarTracker copy() {
      RecordVarExprent copy = root.copy();
      Map<RecordVarExprent, RecordVarExprent> mapToNew = new HashMap<>();
      Queue<Map.Entry<RecordVarExprent, RecordVarExprent>> queue = new ArrayDeque<>();
      queue.add(Map.entry(root, copy));
      while (!queue.isEmpty()) {
        Map.Entry<RecordVarExprent, RecordVarExprent> nextPair = queue.poll();
        mapToNew.put(nextPair.getKey(), nextPair.getValue());
        List<RecordVarExprent> oldComponents = nextPair.getKey().getComponents();
        List<RecordVarExprent> newComponents = nextPair.getValue().getComponents();
        if (oldComponents.size() != newComponents.size()) {
          return null;
        }
        for (int i = 0; i < oldComponents.size(); i++) {
          queue.add(Map.entry(oldComponents.get(i), newComponents.get(i)));
        }
      }
      Map<VarExprent, RecordVarExprent> newVarRecordTracker = new HashMap<>();
      for (Map.Entry<VarExprent, RecordVarExprent> entry : varRecordTracker.entrySet()) {
        RecordVarExprent newExprent = mapToNew.get(entry.getValue());
        newVarRecordTracker.put(entry.getKey(), newExprent);
      }
      VarTracker newTracker = new VarTracker(copy);
      newTracker.varRecordTracker.putAll(newVarRecordTracker);
      newTracker.varTempAssignmentTracker.addAll(varTempAssignmentTracker);
      return newTracker;
    }
@Nullable
    VarTracker copy()