def do_ReadPropertyMultipleRequest(self, apdu):
        """Respond to a ReadPropertyMultiple Request."""
        if _debug: ReadWritePropertyMultipleServices._debug("do_ReadPropertyMultipleRequest %r", apdu)

        # response is a list of read access results (or an error)
        resp = None
        read_access_result_list = []

        # loop through the request
        for read_access_spec in apdu.listOfReadAccessSpecs:
            # get the object identifier
            objectIdentifier = read_access_spec.objectIdentifier
            if _debug: ReadWritePropertyMultipleServices._debug("    - objectIdentifier: %r", objectIdentifier)

            # check for wildcard
            if (objectIdentifier == ('device', 4194303)) and self.localDevice is not None:
                if _debug: ReadWritePropertyMultipleServices._debug("    - wildcard device identifier")
                objectIdentifier = self.localDevice.objectIdentifier

            # get the object
            obj = self.get_object_id(objectIdentifier)
            if _debug: ReadWritePropertyMultipleServices._debug("    - object: %r", obj)

            # build a list of result elements
            read_access_result_element_list = []

            # loop through the property references
            for prop_reference in read_access_spec.listOfPropertyReferences:
                # get the property identifier
                propertyIdentifier = prop_reference.propertyIdentifier
                if _debug: ReadWritePropertyMultipleServices._debug("    - propertyIdentifier: %r", propertyIdentifier)

                # get the array index (optional)
                propertyArrayIndex = prop_reference.propertyArrayIndex
                if _debug: ReadWritePropertyMultipleServices._debug("    - propertyArrayIndex: %r", propertyArrayIndex)

                # check for special property identifiers
                if propertyIdentifier in ('all', 'required', 'optional'):
                    if not obj:
                        # build a property access error
                        read_result = ReadAccessResultElementChoice()
                        read_result.propertyAccessError = ErrorType(errorClass='object', errorCode='unknownObject')

                        # make an element for this error
                        read_access_result_element = ReadAccessResultElement(
                            propertyIdentifier=propertyIdentifier,
                            propertyArrayIndex=propertyArrayIndex,
                            readResult=read_result,
                            )

                        # add it to the list
                        read_access_result_element_list.append(read_access_result_element)
                    else:
                        for propId, prop in obj._properties.items():
                            if _debug: ReadWritePropertyMultipleServices._debug("    - checking: %r %r", propId, prop.optional)

                            if (propertyIdentifier == 'all'):
                                pass
                            elif (propertyIdentifier == 'required') and (prop.optional):
                                if _debug: ReadWritePropertyMultipleServices._debug("    - not a required property")
                                continue
                            elif (propertyIdentifier == 'optional') and (not prop.optional):
                                if _debug: ReadWritePropertyMultipleServices._debug("    - not an optional property")
                                continue

                            # read the specific property
                            read_access_result_element = read_property_to_result_element(obj, propId, propertyArrayIndex)

                            # check for undefined property
                            if read_access_result_element.readResult.propertyAccessError \
                                and read_access_result_element.readResult.propertyAccessError.errorCode == 'unknownProperty':
                                continue

                            # add it to the list
                            read_access_result_element_list.append(read_access_result_element)

                else:
                    # read the specific property
                    read_access_result_element = read_property_to_result_element(obj, propertyIdentifier, propertyArrayIndex)

                    # add it to the list
                    read_access_result_element_list.append(read_access_result_element)

            # build a read access result
            read_access_result = ReadAccessResult(
                objectIdentifier=objectIdentifier,
                listOfResults=read_access_result_element_list
                )
            if _debug: ReadWritePropertyMultipleServices._debug("    - read_access_result: %r", read_access_result)

            # add it to the list
            read_access_result_list.append(read_access_result)

        # this is a ReadPropertyMultiple ack
        if not resp:
            resp = ReadPropertyMultipleACK(context=apdu)
            resp.listOfReadAccessResults = read_access_result_list
            if _debug: ReadWritePropertyMultipleServices._debug("    - resp: %r", resp)

        # return the result
        self.response(resp)
Respond to a ReadPropertyMultiple Request.