public function getInventedHooks($module_root_name) {
    // Get the module's folder.
    $module_folder = $this->environment->getExtensionPath('module', $module_root_name);

    // Bail if the folder doesn't exist yet: there is nothing to do.
    if (!file_exists($module_folder)) {
      return array();
    }

    // An array of short hook names that we'll populate from what we extract
    // from the files.
    $hooks = array();

    // Only consider hooks which are invented by this module: it is legitimate
    // for modules to invoke hooks invented by other modules. We assume the
    // module follows the convention of using its name as a prefix.
    $hook_prefix = $module_root_name . '_';

    foreach ($this->getFolderIterator($module_folder) as $filename => $object) {
      //print_r("$filename\n");
      $contents = file_get_contents("$filename");

      // List of patterns to match on.
      // They should all have capturing groups for:
      //  - 1. hook name
      //  - 2. optional parameters
      $hook_invocation_patterns = array(
        // module_invoke_all() calls (the key here is arbitrary).
        'module_invoke_all' => array(
          // The pattern for this item.
          'pattern' =>
            "/
            module_invoke_all \(
              ' ( $hook_prefix \w+ ) ' # Hook name, with the hook prefix.
              (?:
                , \s*
                (
                  [^)]* # Capture further parameters: anything up to the closing ')'.
                )
              )? # The further parameters are optional.
            /x",
        ),
        // module_invoke() calls.
        'module_invoke' => array(
          'pattern' =>
            "/
            module_invoke \(
              [^,]+ # The \$module parameter.
              , \s*
              ' ( $hook_prefix \w+ ) ' # Hook name, with the hook prefix.
              (?:
                , \s*
                (
                  [^)]* # Capture further parameters: anything up to the closing ')'.
                )
              )? # The further parameters are optional.
            /x",
        ),
        // drupal_alter() calls.
        'drupal_alter' => array(
          'pattern' =>
            "/
            drupal_alter \(
              ' ( $hook_prefix \w+ ) ' # Hook name, with the hook prefix.
              (?:
                , \s*
                (
                  [^)]* # Capture further parameters: anything up to the closing ')'.
                )
              )? # The further parameters are optional.
            /x",
          // A process callback to apply to each hook name the pattern finds.
          // This is because the hook name in drupal_alter() needs a suffix to
          // be added to it.
          'process callback' => function ($hook_name) {
            return $hook_name . '_alter';
          },
        ),
      );

      // Process the file for each pattern.
      foreach ($hook_invocation_patterns as $pattern_info) {
        $pattern = $pattern_info['pattern'];

        $matches = array();
        preg_match_all($pattern, $contents, $matches);
        // Matches are:
        //  - 1: the first parameter, which is the hook short name.
        //  - 2: the remaining parameters, if any.

        // If we get matches, turn then into keyed arrays and merge them into
        // the cumulative array. This removes duplicates (caused by a hook being
        // invoked in different files).
        if (!empty($matches[1])) {
          //drush_print_r($matches);
          $file_hooks = array_combine($matches[1], $matches[2]);
          //drush_print_r($file_hooks);

          foreach ($file_hooks as $hook_short_name => $parameters) {
            // Perform additional processing on the hook short name, if needed.
            if (isset($pattern_info['process callback'])) {
              $hook_short_name = $pattern_info['process callback']($hook_short_name);
            }

            // If this hook is already in our list, we take the longest parameters
            // string, on the assumption that this may be more complete if some
            // parameters are options.
            if (isset($hooks[$hook_short_name])) {
              // Replace the existing hook if the new parameters are longer.
              if (strlen($parameters) > strlen($hooks[$hook_short_name])) {
                $hooks[$hook_short_name] = $parameters;
              }
            }
            else {
              $hooks[$hook_short_name] = $parameters;
            }
          }
        }
      }
    }
    //drush_print_r($hooks);

    return $hooks;
  }