public static function forChallengeMessage(
        $challenge_message,
        $code = 0,
        Exception $previous = null
    ) {
        $message = self::DEFAULT_MESSAGE;

        $reason_messages = [];

        if ((self::CODE_FOR_INVALID_SIGNATURE & $code) === self::CODE_FOR_INVALID_SIGNATURE) {
            $reason_messages[] = self::MESSAGE_FOR_INVALID_SIGNATURE;
        }

        if ((self::CODE_FOR_INVALID_MESSAGE_TYPE & $code) === self::CODE_FOR_INVALID_MESSAGE_TYPE) {
            $reason_messages[] = self::MESSAGE_FOR_INVALID_MESSAGE_TYPE;
        }

        $message .= sprintf(
            self::MESSAGE_EXTENSION_FOR_REASONS_FORMAT,
            implode(self::MESSAGE_REASON_GLUE, $reason_messages)
        );

        $instance = new static($message, $code, $previous);
        $instance->challenge_message = $challenge_message;

        return $instance;
    }