private static AbstractExecutable parseTo(ExecutablePO executablePO) {
   if (executablePO == null) {
     return null;
   }
   String type = executablePO.getType();
   try {
     Class<? extends AbstractExecutable> clazz = ClassUtil.forName(type, AbstractExecutable.class);
     Constructor<? extends AbstractExecutable> constructor = clazz.getConstructor();
     AbstractExecutable result = constructor.newInstance();
     result.setId(executablePO.getUuid());
     result.setName(executablePO.getName());
     result.setParams(executablePO.getParams());
     List<ExecutablePO> tasks = executablePO.getTasks();
     if (tasks != null && !tasks.isEmpty()) {
       Preconditions.checkArgument(result instanceof DefaultChainedExecutable);
       for (ExecutablePO subTask : tasks) {
         ((DefaultChainedExecutable) result).addTask(parseTo(subTask));
       }
     }
     return result;
   } catch (ReflectiveOperationException e) {
     throw new IllegalArgumentException("cannot parse this job:" + executablePO.getId(), e);
   }
 }