protected function processHookData($hook_file_data) {
    //print_r($hook_file_data);

    // check file_exists?

    /*
    // Developer trapdoor for generating the sample hook definitions file for
    // our tests. This limits the number of files to just a few from core.
    $intersect = array(
      'system.api.php',
      'node.api.php',
    );
    $hook_file_data = array_intersect_key($hook_file_data, array_fill_keys($intersect, TRUE));
    // End.
    */

    // Get hook_hook_info() from Drupal.
    $hook_info = $this->getDrupalHookInfo();

    // Build list of hooks
    $hook_groups = array();
    foreach ($hook_file_data as $file_data) {
      $hook_data_raw = $this->processHookFile($file_data['path']);

      $file_name = basename($file_data['path'], '.php');
      $group = $file_data['group'];

      // Create an array in the form of:
      // array(
      //   'filename' => array(
      //     array('hook' => 'hook_foo', 'description' => 'hook_foo description'),
      //     ...
      //   ),
      //   ...
      // );
      foreach ($hook_data_raw['names'] as $key => $hook) {
        // The destination is possibly specified per-hook; if not, then given
        // for the whole file.
        if (isset($file_data['hook_destinations'][$hook])) {
          $destination = $file_data['hook_destinations'][$hook];
        }
        else {
          $destination = $file_data['destination'];
        }

        // Also try to get destinations from hook_hook_info().
        // Argh why don't we have the short name here yet????
        // @todo: clean up!
        $short_name = substr($hook, 5);
        if (isset($hook_info[$short_name])) {
          //print_r($hook_info);
          $destination = '%module.' . $hook_info[$short_name]['group'] . '.inc';
        }

        // Process hook dependendies for the file.
        $hook_dependencies = array();
        if (isset($file_data['hook_dependencies'])) {
          // Incoming data is of the form:
          //  'required hook' => array('dependent hooks')
          // where the latter may be a regexp.
          foreach ($file_data['hook_dependencies'] as $required_hook => $dependency_data) {
            foreach ($dependency_data as $match) {
              if (preg_match("@$match@", $hook)) {
                $hook_dependencies[] = $required_hook;
              }
            }
          }
        }

        // See if the hook has any callbacks as dependencies. We assume that
        // mention of a string of the form 'callback_foo()' means it's needed
        // for the hook.
        // TODO: see if there's a way to label this in the resulting source
        // as associated with the hook that requested this.
        $matches = array();
        preg_match_all("@(callback_\w+)\(\)@", $hook_data_raw['documentation'][$key], $matches);
        if (!empty($matches[1])) {
          $hook_dependencies += $matches[1];
        }

        // Because we're working through the raw data array, we keep the incoming
        // sort order.
        // But if there are multiple hook files for one module / group, then
        // they will go sequentially one after the other.
        // TODO: should this be improved, eg to group also by filename?
        $hook_groups[$group][$hook] = array(
          'type' => $hook_data_raw['type'][$key],
          'name' => $hook,
          'definition'  => $hook_data_raw['definitions'][$key],
          'description' => $hook_data_raw['descriptions'][$key],
          // Don't store this!! TODO!! just use it for callback dependencies!!!
          //'documentation' => $hook_data_raw['documentation'][$key],
          'destination' => $destination,
          'dependencies'  => $hook_dependencies,
          'group'       => $group,
          'core'        => $file_data['core'] ?? NULL,
          'file_path'   => $file_data['path'],
          'body'        => $hook_data_raw['bodies'][$key],
        );
        //dsm($hook_groups);
        //drush_print_r($hook_groups);

      } // foreach hook_data
    } // foreach files

    //dsm($hook_groups);
    //print_r($hook_groups);

    return $hook_groups;
  }