private Task mapTask(
     PuzzleDto puzzle,
     ChallengeTemplate challengeTemplate,
     Organization organization,
     Map<String, ByteArrayOutputStream> files,
     Duration gameDuration,
     Runner runner,
     Endpoint endpoint,
     Set<Language> languages)
     throws IOException {
   Task task = new Task();
   task.setCanonicalName(
       fixCanonicalName(challengeTemplate.getCanonicalName() + "-" + puzzle.getCanonicalName()));
   task.setName(puzzle.getCanonicalName());
   task.setEndpoint(endpoint);
   task.setDescription(puzzle.getCanonicalName());
   task.setInstructions(
       storage.uploadPublic(
           instructionsBucket,
           instructionsFileName(challengeTemplate, puzzle.getInstructionsFile()),
           new ByteArrayInputStream(files.get(puzzle.getInstructionsFile()).toByteArray()),
           "application/pdf"));
   task.setDuration(gameDuration);
   task.setRunner(runner);
   task.setLanguages(languages);
   task.setOrganization(organization);
   return task;
 }
  private UUID createChallengeTemplate(
      CodingContestGameDto dto, UUID organizationId, Map<String, ByteArrayOutputStream> files)
      throws IOException {
    ChallengeTemplate challengeTemplate =
        challengeTemplateRepository.findOneByCanonicalName(dto.getCanonicalName());
    if (challengeTemplate != null) {
      return challengeTemplate.getId();
    }
    Organization organization = organizationRepository.findOne(organizationId);
    if (organization == null) {
      throw new CodunoIllegalArgumentException("organization.invalid");
    }

    if (dto.getPuzzles()
        .stream()
        .findAny()
        .filter(puzzleDto -> puzzleDto.getValidationClass() != null)
        .isPresent()) {
      throw new CodunoIllegalArgumentException("ccc.game.structure.unsuported");
    }

    Runner runner = getRunner("/io");
    Endpoint taskEndpoint = getEndpoint("CCC general task", "ccc-io-task");
    Set<Language> languages = new HashSet<>(languageRepository.findAll());
    Duration gameDuration = parseGameDuration(dto.getTimeframe());

    challengeTemplate = mapChallengeTemplate(dto, organization, gameDuration);

    for (PuzzleDto puzzle : dto.getPuzzles()) {
      Task task =
          mapTask(
              puzzle,
              challengeTemplate,
              organization,
              files,
              gameDuration,
              runner,
              taskEndpoint,
              languages);
      Map<String, ByteArrayOutputStream> testFiles = null;
      if (puzzle.getInputFilePath() != null) {
        testFiles = unzip(files.get(puzzle.getInputFilePath()).toByteArray());
      }
      for (PuzzleTestDto puzzleTest : puzzle.getTests()) {
        Test test = mapTest(puzzleTest, runner, testFiles);
        task.addTest(test);
      }
      task = taskRepository.save(task);
      challengeTemplate.addTask(task);
    }
    return challengeTemplateRepository.save(challengeTemplate).getId();
  }