@Override
    public MeterCellId allocateMeterId(DeviceId deviceId, MeterScope meterScope) {
        if (userDefinedIndexMode) {
            log.warn("Unable to allocate meter id when user defined index mode is enabled");
            return null;
        }
        MeterTableKey meterTableKey = MeterTableKey.key(deviceId, meterScope);
        MeterCellId meterCellId;
        long id;
        // First, search for reusable key
        meterCellId = firstReusableMeterId(meterTableKey);
        if (meterCellId != null) {
            return meterCellId;
        }
        // If there was no reusable meter id we have to generate a new value
        // using start and end index as lower and upper bound respectively.
        long startIndex = getStartIndex(meterTableKey);
        long endIndex = getEndIndex(meterTableKey);
        // If the device does not give us MeterFeatures fallback to queryMeters
        if (startIndex == -1L || endIndex == -1L) {
            // Only meaningful for OpenFlow today
            long maxMeters = queryMaxMeters(deviceId);
            if (maxMeters == 0L) {
                return null;
            } else {
                // OpenFlow meter index starts from 1, ends with max
                startIndex = 1L;
                endIndex = maxMeters;
            }
        }

        do {
            id = meterIdGenerators.getAndIncrement(meterTableKey);
        } while (id < startIndex);
        if (id > endIndex) {
            return null;
        }

        // For backward compatibility if we are using global scope,
        // return a MeterId, otherwise we create a PiMeterCellId
        if (meterScope.isGlobal()) {
            return MeterId.meterId(id);
        } else {
            return PiMeterCellId.ofIndirect(PiMeterId.of(meterScope.id()), id);
        }

    }
@Test
    public void testQueryMeters() {
        initMeterStore(false);

        assertThat(mid1, is(meterStore.allocateMeterId(did3, MeterScope.globalScope())));
        assertNull(meterStore.allocateMeterId(did4, MeterScope.globalScope()));
    }