function buildFeatures(deviceName, expose, parentType) {
  const { type, name, property, access, value_min: minValue, value_max: maxValue, unit: deviceUnit, values } = expose;
  const { names = {}, feature, getFeatureIndexes = () => [''] } = exposesMap[type] || {};
  const byName = buildByName(names, name, parentType);

  if (!byName) {
    return [];
  }

  // Read only ?
  // eslint-disable-next-line no-bitwise
  const readOnly = (access & 2) === 0;

  // Has feedback ?
  // eslint-disable-next-line no-bitwise
  const hasFeedback = !readOnly && (access & 1) === 1;

  const createdFeature = { read_only: readOnly, has_feedback: hasFeedback, ...(feature || {}), ...(byName || {}) };

  // Min value
  const min = minValue !== undefined ? minValue : createdFeature.min;

  // Max value
  let { max } = createdFeature;
  if (maxValue !== undefined) {
    max = maxValue;
  } else if (values !== undefined) {
    max = values.length;
  }

  // Unit
  const unit = mapUnit(deviceUnit, createdFeature.unit);

  // Force override values
  const definedFeature = createdFeature.forceOverride
    ? // We force to override with Gladys mapping
      { ...createdFeature, min, max, unit, ...(byName || {}) }
    : // Values from z2m are kept
      { ...createdFeature, min, max, unit };
  // Clean additional attribute
  delete definedFeature.forceOverride;

  // Add missing properties
  const typeFeaturesIndexes = getFeatureIndexes(values);
  const featureIndexes = typeFeaturesIndexes.length === 0 ? [0] : typeFeaturesIndexes;

  return featureIndexes.map((suffixIndex) => completeFeature(deviceName, definedFeature, property, suffixIndex));
}
@description Build a Gladys feature according to Zigbee "expose" values.
@param {string} deviceName - Device friendly name.
@param {object} expose - Zigbee "expose" values.
@param {string} parentType - Requested parent type.
@returns {Array} The related Gladys features.
@example buildFeature('MyDevice', {}, 'light');