protected function setPresetValues($property_name, &$component_data_info, &$component_data_local) {
    if (empty($component_data_local[$property_name])) {
      return;
    }

    // Treat the selected preset as an array, even if it's single-valued.
    if ($component_data_info[$property_name]['format'] == 'array') {
      $preset_keys = $component_data_local[$property_name];
      $multiple_presets = TRUE;
    }
    else {
      $preset_keys = [$component_data_local[$property_name]];
      $multiple_presets = FALSE;
    }

    // First, gather up the values that the selected preset items want to set.
    // We will then apply them to the data.
    $forced_values = [];
    $suggested_values = [];

    foreach ($preset_keys as $preset_key) {
      $selected_preset_info = $component_data_info[$property_name]['presets'][$preset_key];

      // Ensure these are both preset as at least empty arrays.
      // TODO: handle filling this in in ComponentDataInfoGatherer?
      // TODO: testing should cover that it's ok to have these absent.
      $selected_preset_info['data'] += [
        'force' => [],
        'suggest' => [],
      ];

      // Values which are forced by the preset.
      foreach ($selected_preset_info['data']['force'] as $forced_property_name => $forced_data) {
        // Literal value. (This is the only type we support at the moment.)
        if (isset($forced_data['value'])) {
          $this->collectPresetValue(
            $forced_values,
            $multiple_presets,
            $forced_property_name,
            $component_data_info[$forced_property_name],
            $forced_data['value']
          );
        }

        // TODO: processed value, using chain of processing instructions.
      }

      // Values which are only suggested by the preset.
      foreach ($selected_preset_info['data']['suggest'] as $suggested_property_name => $suggested_data) {
        // Literal value. (This is the only type we support at the moment.)
        if (isset($suggested_data['value'])) {
          $this->collectPresetValue(
            $suggested_values,
            $multiple_presets,
            $suggested_property_name,
            $component_data_info[$suggested_property_name],
            $suggested_data['value']
          );
        }

        // TODO: processed value, using chain of processing instructions.
      }
    }

    // Set the collected data values into the actual component data, if
    // applicable.
    foreach ($forced_values as $forced_property_name => $forced_data) {
      $component_data_local[$forced_property_name] = $forced_data;
    }

    foreach ($suggested_values as $suggested_property_name => $suggested_data) {
      // Suggested values from the preset only get set if there is nothing
      // already set there in the incoming data.
      // TODO: boolean FALSE counts as non-empty for a boolean property in
      // other places! ARGH!
      if (!empty($component_data_local[$suggested_property_name])) {
        continue;
      }

      $component_data_local[$suggested_property_name] = $suggested_data;
    }
  }