protected function convertStatusCode($code, $message, \Exception $exception = null)
    {
        $messageData = json_decode($message, true);

        if (is_array($messageData) && !empty($messageData[JSONConstants::ERROR_EXCEPTION])) {
            $jsonError = $messageData[JSONConstants::ERROR_EXCEPTION];

            if (!empty($messageData[JSONConstants::ERROR_MESSAGE])
                && is_string($messageData[JSONConstants::ERROR_MESSAGE])
            ) {
                $message = $messageData[JSONConstants::ERROR_MESSAGE];
            }

            $exceptionName = '\\Dkd\\PhpCmis\\Exception\\Cmis' . ucfirst($jsonError) . 'Exception';

            if (class_exists($exceptionName)) {
                return new $exceptionName($message, null, $exception);
            }
        }

        if (empty($message) && $exception !== null) {
            $message = $exception->getMessage();
        }

        // fall back to status code
        switch ($code) {
            case 301:
            case 302:
            case 303:
            case 307:
                return new CmisConnectionException(
                    'Redirects are not supported (HTTP status code ' . $code . '): ' . $message,
                    null,
                    $exception
                );
            case 400:
                return new CmisInvalidArgumentException($message, null, $exception);
            case 401:
                return new CmisUnauthorizedException($message, null, $exception);
            case 403:
                return new CmisPermissionDeniedException($message, null, $exception);
            case 404:
                return new CmisObjectNotFoundException($message, null, $exception);
            case 405:
                return new CmisNotSupportedException($message, null, $exception);
            case 407:
                return new CmisProxyAuthenticationException($message, null, $exception);
            case 409:
                return new CmisConstraintException($message, null, $exception);
            default:
                return new CmisRuntimeException($message, null, $exception);
        }
    }