class GetPeriodicMeterReadsGasCommandExecutor extends
        AbstractPeriodicMeterReadsCommandExecutor<PeriodicMeterReadsRequestDto, PeriodicMeterReadGasResponseDto> {

    @Override
    public PeriodicMeterReadGasResponseDto execute(final DlmsConnectionManager conn, final DlmsDevice device,
            final PeriodicMeterReadsRequestDto periodicMeterReadsQuery) throws ProtocolAdapterException {

        if (periodicMeterReadsQuery == null) {
            throw new IllegalArgumentException(
                    "PeriodicMeterReadsQuery should contain PeriodType, BeginDate and EndDate.");
        }

        final PeriodTypeDto queryPeriodType = periodicMeterReadsQuery.getPeriodType();
        final DateTime from = new DateTime(periodicMeterReadsQuery.getBeginDate());
        final DateTime to = new DateTime(periodicMeterReadsQuery.getEndDate());

        final AttributeAddressForProfile profileBufferAddress = this.getProfileBufferAddress(queryPeriodType,
                periodicMeterReadsQuery.getChannel(), from, to, device);

        final List<AttributeAddress> scalerUnitAddresses = this.getScalerUnitAddresses(
                periodicMeterReadsQuery.getChannel(), profileBufferAddress);

        final Optional<ProfileCaptureTime> intervalTime = this.getProfileCaptureTime(device,
                this.dlmsObjectConfigService, Medium.GAS);

        LOGGER.info("Retrieving current billing period and profiles for gas for period type: {}, from: " + "{}, to: {}",
                queryPeriodType, from, to);

        /*
         * workaround for a problem when using with_list and retrieving a profile
         * buffer, this will be returned erroneously.
         */
        final List<GetResult> getResultList = new ArrayList<>();

        final List<AttributeAddress> allAttributeAddresses = new ArrayList<>();
        allAttributeAddresses.add(profileBufferAddress.getAttributeAddress());
        allAttributeAddresses.addAll(scalerUnitAddresses);

        for (final AttributeAddress address : allAttributeAddresses) {

            conn.getDlmsMessageListener().setDescription(
                    String.format(FORMAT_DESCRIPTION, periodicMeterReadsQuery.getChannel(), queryPeriodType, from, to,
                            JdlmsObjectToStringUtil.describeAttributes(address)));

            getResultList.addAll(this.dlmsHelper.getAndCheck(conn, device,
                    "retrieve periodic meter reads for " + queryPeriodType + ", channel "
                            + periodicMeterReadsQuery.getChannel(), address));
        }

        LOGGER.info("Received getResult: {} ", getResultList);

        final DataObject resultData = this.dlmsHelper.readDataObject(getResultList.get(0), PERIODIC_G_METER_READS);
        final List<DataObject> bufferedObjectsList = resultData.getValue();

        final List<PeriodicMeterReadsGasResponseItemDto> periodicMeterReads = new ArrayList<>();
        for (final DataObject bufferedObject : bufferedObjectsList) {
            final List<DataObject> bufferedObjectValue = bufferedObject.getValue();

            try {
                periodicMeterReads.add(this.convertToResponseItem(
                        new ConversionContext(periodicMeterReadsQuery, bufferedObjectValue, getResultList,
                                profileBufferAddress, scalerUnitAddresses, intervalTime), periodicMeterReads));
            } catch (final BufferedDateTimeValidationException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }

        LOGGER.info("Resulting periodicMeterReads: {} ", periodicMeterReads);

        return new PeriodicMeterReadGasResponseDto(queryPeriodType, periodicMeterReads);
    }

    @Autowired public  GetPeriodicMeterReadsGasCommandExecutor(final DlmsHelper dlmsHelper,
            final AmrProfileStatusCodeHelper amrProfileStatusCodeHelper,
            final DlmsObjectConfigService dlmsObjectConfigService);

}