private DeletionTaskRecoveryInfo parseTaskProto(DeletionServiceDeleteTaskProto proto)
      throws IOException {
    int taskId = proto.getId();
    String user = proto.hasUser() ? proto.getUser() : null;
    Path subdir = null;
    List<Path> basePaths = null;
    if (proto.hasSubdir()) {
      subdir = new Path(proto.getSubdir());
    }
    List<String> basedirs = proto.getBasedirsList();
    if (basedirs != null && basedirs.size() > 0) {
      basePaths = new ArrayList<Path>(basedirs.size());
      for (String basedir : basedirs) {
        basePaths.add(new Path(basedir));
      }
    }

    FileDeletionTask task = new FileDeletionTask(taskId, this, user, subdir, basePaths);
    return new DeletionTaskRecoveryInfo(task, proto.getSuccessorIdsList(), proto.getDeletionTime());
  }
  private void recordDeletionTaskInStateStore(FileDeletionTask task) {
    if (!stateStore.canRecover()) {
      // optimize the case where we aren't really recording
      return;
    }
    if (task.taskId != FileDeletionTask.INVALID_TASK_ID) {
      return; // task already recorded
    }

    task.taskId = generateTaskId();

    FileDeletionTask[] successors = task.getSuccessorTasks();

    // store successors first to ensure task IDs have been generated for them
    for (FileDeletionTask successor : successors) {
      recordDeletionTaskInStateStore(successor);
    }

    DeletionServiceDeleteTaskProto.Builder builder = DeletionServiceDeleteTaskProto.newBuilder();
    builder.setId(task.taskId);
    if (task.getUser() != null) {
      builder.setUser(task.getUser());
    }
    if (task.getSubDir() != null) {
      builder.setSubdir(task.getSubDir().toString());
    }
    builder.setDeletionTime(
        System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(debugDelay, TimeUnit.SECONDS));
    if (task.getBaseDirs() != null) {
      for (Path dir : task.getBaseDirs()) {
        builder.addBasedirs(dir.toString());
      }
    }
    for (FileDeletionTask successor : successors) {
      builder.addSuccessorIds(successor.taskId);
    }

    try {
      stateStore.storeDeletionTask(task.taskId, builder.build());
    } catch (IOException e) {
      LOG.error("Unable to store deletion task " + task.taskId + " for " + task.getSubDir(), e);
    }
  }