class GrpcJobManagementModelConverters {

    public static Task toCoreTask(com.netflix.titus.grpc.protogen.Task grpcTask) {
        Map<String, String> taskContext = grpcTask.getTaskContextMap();

        String originalId = Preconditions.checkNotNull(
                taskContext.get(TASK_ATTRIBUTES_TASK_ORIGINAL_ID), TASK_ATTRIBUTES_TASK_ORIGINAL_ID + " missing in Task entity"
        );
        String resubmitOf = taskContext.get(TASK_ATTRIBUTES_TASK_RESUBMIT_OF);
        int taskResubmitNumber = Integer.parseInt(taskContext.get(TASK_ATTRIBUTES_RESUBMIT_NUMBER));
        int systemResubmitNumber = Integer.parseInt(grpcTask.getTaskContextMap().getOrDefault(TASK_ATTRIBUTES_SYSTEM_RESUBMIT_NUMBER, "0"));
        int evictionResubmitNumber = Integer.parseInt(grpcTask.getTaskContextMap().getOrDefault(TASK_ATTRIBUTES_EVICTION_RESUBMIT_NUMBER, "0"));

        String taskIndexStr = taskContext.get(TASK_ATTRIBUTES_TASK_INDEX);

        // Based on presence of the task index, we decide if it is batch or service task.
        boolean isBatchTask = taskIndexStr != null;
        Task.TaskBuilder<?, ?> builder = isBatchTask ? JobModel.newBatchJobTask() : JobModel.newServiceJobTask();
        builder.withId(grpcTask.getId())
                .withJobId(grpcTask.getJobId())
                .withStatus(toCoreTaskStatus(grpcTask.getStatus()))
                .withStatusHistory(grpcTask.getStatusHistoryList().stream().map(GrpcJobManagementModelConverters::toCoreTaskStatus).collect(Collectors.toList()))
                .withResubmitNumber(taskResubmitNumber)
                .withOriginalId(originalId)
                .withResubmitOf(resubmitOf)
                .withSystemResubmitNumber(systemResubmitNumber)
                .withEvictionResubmitNumber(evictionResubmitNumber)
                .withTaskContext(taskContext)
                .withAttributes(buildAttributesMapForCoreTask(grpcTask));

        if (isBatchTask) { // Batch job
            ((BatchJobTask.Builder) builder).withIndex(Integer.parseInt(taskIndexStr));
        } else {
            ((ServiceJobTask.Builder) builder).withMigrationDetails(toCoreMigrationDetails(grpcTask.getMigrationDetails()));
        }

        return builder.build();
    }

    private  GrpcJobManagementModelConverters();

}