protected function saveItemResponses($emptyAllowed = true)
    {
        if ($this->getRequestParameter('itemDefinition') && $this->getRequestParameter('itemResponse')) {

            $itemDefinition = $this->getRequestParameter('itemDefinition');
            $serviceContext = $this->getServiceContext();
            $itemResponse = $this->getRequestParameter('itemResponse')
                ? json_decode($this->getRequestParameter('itemResponse'), true)
                : null;

            if (!is_null($itemResponse) && !empty($itemDefinition)) {
                $responses = $this
                    ->getRunnerService()
                    ->parsesItemResponse($serviceContext, $itemDefinition, $itemResponse);

                //still verify allowSkipping & empty responses
                if (
                    !$emptyAllowed
                    && $this->getRunnerService()->getTestConfig()->getConfigValue('enableAllowSkipping')
                    && !TestRunnerUtils::doesAllowSkipping($serviceContext->getTestSession())) {
                    if ($this->getRunnerService()->emptyResponse($serviceContext, $responses)) {
                        throw new QtiRunnerEmptyResponsesException();
                    }
                }

                return $this->getRunnerService()->storeItemResponse($serviceContext, $itemDefinition, $responses);
            }
        }
        return false;
    }