public function submit(Paper $paper, array $answers, $clientIp)
    {
        $submitted = [];

        $this->om->startFlushSuite();

        foreach ($answers as $answerData) {
            $question = $paper->getQuestion($answerData['questionId']);

            if (empty($question)) {
                throw new InvalidDataException('Submitted answers are invalid', [[
                    'path' => '/questionId',
                    'message' => 'question is not part of the attempt',
                ]]);
            }

            $existingAnswer = $paper->getAnswer($answerData['questionId']);
            $decodedQuestion = $this->itemSerializer->deserialize($question, new Item());

            try {
                if (empty($existingAnswer)) {
                    $answer = $this->answerManager->create($decodedQuestion, $answerData);
                } else {
                    $answer = $this->answerManager->update($decodedQuestion, $existingAnswer, $answerData);
                }
            } catch (InvalidDataException $e) {
                throw new InvalidDataException('Submitted answers are invalid', $e->getErrors());
            }

            $answer->setIp($clientIp);
            $answer->setTries($answer->getTries() + 1);

            // Calculate new answer score
            $score = $this->itemManager->calculateScore($decodedQuestion, $answer);
            $answer->setScore($score);

            $paper->addAnswer($answer);
            $submitted[] = $answer;
        }

        $this->om->persist($paper);
        $this->om->endFlushSuite();

        return $submitted;
    }