diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/controller/TasksController.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/controller/TasksController.java
index 2f3a89270658263c2462870e0fe66fde01441ab9..248854552e18f436e64205a1920b7f57711d1741 100644
--- a/src/main/java/cz/muni/ics/kypo/training/adaptive/controller/TasksController.java
+++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/controller/TasksController.java
@@ -1,5 +1,6 @@
 package cz.muni.ics.kypo.training.adaptive.controller;
 
+import cz.muni.ics.kypo.training.adaptive.dto.training.TaskCopyDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskUpdateDTO;
 import cz.muni.ics.kypo.training.adaptive.service.TaskService;
@@ -82,8 +83,9 @@ public class TasksController {
             @ApiParam(value = "Training phase ID", required = true)
             @PathVariable(name = "phaseId") Long phaseId,
             @ApiParam(value = "Task ID", required = true)
-            @PathVariable(name = "taskId") Long taskId) {
-        TaskDTO createdTask = taskService.cloneTask(definitionId, phaseId, taskId);
+            @PathVariable(name = "taskId") Long taskId,
+            @RequestBody @Valid TaskCopyDTO taskCopyDTO) {
+        TaskDTO createdTask = taskService.cloneTask(definitionId, phaseId, taskId, taskCopyDTO);
         return new ResponseEntity<>(createdTask, HttpStatus.CREATED);
     }
 
diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/dto/training/TaskCopyDTO.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/dto/training/TaskCopyDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..942accf9ed48a05512b4348c08e6b2bb047d73fa
--- /dev/null
+++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/dto/training/TaskCopyDTO.java
@@ -0,0 +1,82 @@
+package cz.muni.ics.kypo.training.adaptive.dto.training;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.PositiveOrZero;
+
+public class TaskCopyDTO {
+
+    @ApiModelProperty(value = "Short description of task", required = true, example = "Task title")
+    @NotEmpty(message = "Task title must not be blank")
+    private String title;
+
+    @ApiModelProperty(value = "The information that are displayed to a player", required = true, example = "Capture the flag")
+    @NotEmpty(message = "Task content must not be blank")
+    private String content;
+
+    @ApiModelProperty(value = "Keyword that must be found in the task. Necessary in order to get to the next phase", required = true, example = "secretFlag")
+    @NotEmpty(message = "Answer of task cannot be null")
+    private String answer;
+
+    @ApiModelProperty(value = "Description how to get the answer", required = true, example = "Open secret.txt")
+    @NotEmpty(message = "Solution of task cannot be null")
+    private String solution;
+
+    @ApiModelProperty(value = "It defines the allowed number of incorrect answers submitted by the player", required = true, example = "5")
+    @NotNull(message = "Limit of the number of provided incorrect answers must be specified")
+    @PositiveOrZero(message = "Limit of the number of provided incorrect answers must not be a negative number")
+    private Integer incorrectAnswerLimit;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public String getSolution() {
+        return solution;
+    }
+
+    public void setSolution(String solution) {
+        this.solution = solution;
+    }
+
+    public Integer getIncorrectAnswerLimit() {
+        return incorrectAnswerLimit;
+    }
+
+    public void setIncorrectAnswerLimit(Integer incorrectAnswerLimit) {
+        this.incorrectAnswerLimit = incorrectAnswerLimit;
+    }
+
+    @Override
+    public String toString() {
+        return "TaskCopyDTO{" +
+                "title='" + title + '\'' +
+                ", content='" + content + '\'' +
+                ", answer='" + answer + '\'' +
+                ", solution='" + solution + '\'' +
+                ", incorrectAnswerLimit=" + incorrectAnswerLimit +
+                '}';
+    }
+}
diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/mapper/BeanMapper.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/mapper/BeanMapper.java
index 861e6022770bed61c9232411b9d8d284e101c8f8..192e806c87e91ceaa035497ea765f44a0edf3b6f 100644
--- a/src/main/java/cz/muni/ics/kypo/training/adaptive/mapper/BeanMapper.java
+++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/mapper/BeanMapper.java
@@ -20,6 +20,7 @@ import cz.muni.ics.kypo.training.adaptive.dto.questionnaire.QuestionUpdateDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.questionnaire.QuestionnairePhaseDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.questionnaire.QuestionnaireUpdateDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.DecisionMatrixRowDTO;
+import cz.muni.ics.kypo.training.adaptive.dto.training.TaskCopyDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskUpdateDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TrainingPhaseDTO;
@@ -59,6 +60,8 @@ public interface BeanMapper {
 
     Task toEntity(TaskUpdateDTO taskUpdateDto);
 
+    Task toEntity(TaskCopyDTO taskCopyDTO);
+
     @Mapping(target = "phaseType", constant = "INFO")
     InfoPhaseDTO toDto(InfoPhase infoPhase);
 
diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/TaskService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/TaskService.java
index e275b1efd99f3a92f7a21a5f628d66a42f7c5afb..a4498217eef466dea946e73f7b2d94c6e6c03997 100644
--- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/TaskService.java
+++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/TaskService.java
@@ -2,6 +2,7 @@ package cz.muni.ics.kypo.training.adaptive.service;
 
 import cz.muni.ics.kypo.training.adaptive.domain.Task;
 import cz.muni.ics.kypo.training.adaptive.domain.TrainingPhase;
+import cz.muni.ics.kypo.training.adaptive.dto.training.TaskCopyDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskDTO;
 import cz.muni.ics.kypo.training.adaptive.dto.training.TaskUpdateDTO;
 import cz.muni.ics.kypo.training.adaptive.mapper.BeanMapper;
@@ -9,7 +10,6 @@ import cz.muni.ics.kypo.training.adaptive.repository.TaskRepository;
 import cz.muni.ics.kypo.training.adaptive.repository.TrainingPhaseRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -50,19 +50,14 @@ public class TaskService {
         return BeanMapper.INSTANCE.toDto(persistedEntity);
     }
 
-    public TaskDTO cloneTask(Long trainingDefinitionId, Long phaseId, Long taskId) {
-        Task taskToBeCloned = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task was not found"));
-        // TODO throw proper exception once kypo2-training is migrated
+    public TaskDTO cloneTask(Long trainingDefinitionId, Long phaseId, Long taskId, TaskCopyDTO taskCopyDTO) {
+        Task task = BeanMapper.INSTANCE.toEntity(taskCopyDTO);
 
         TrainingPhase trainingPhase = trainingPhaseRepository.findById(phaseId)
                 .orElseThrow(() -> new RuntimeException("Game phase was not found"));
 
         // TODO add check to trainingDefinitionId (field structure will be probably changed)
 
-        Task task = new Task();
-        BeanUtils.copyProperties(taskToBeCloned, task);
-
         task.setId(null);
         task.setTrainingPhase(trainingPhase);
         task.setOrder(taskRepository.getCurrentMaxOrder(phaseId) + 1);