async function matchSubclassesPostprocess(
  refExportsAnalyzerResult,
  targetClassesAnalyzerResult,
  refClassesAResult,
  customConfig,
) {
  // eslint-disable-next-line no-unused-vars
  const cfg = {
    ...customConfig,
  };

  /**
   * Step 1: a 'flat' data structure
   * Create a key value storage map for exports/class matches
   * - key: `${exportSpecifier}::${normalizedSource}::${project}` from reference project
   * - value: an array of import file matches like `${targetProject}::${normalizedSource}::${className}`
   * @example
   * {
   *   'LionDialog::./reference-project/my/export.js::my-project' : {
   *      meta: {...},
   *      files: [
   *        'target-project-a::./import/file.js::MyDialog',
   *        'target-project-b::./another/import/file.js::MyOtherDialog'
   *      ],
   *    ]}
   * }
   */
  const resultsObj = {};

  for (const exportEntry of refExportsAnalyzerResult.queryOutput) {
    const exportsProjectObj = refExportsAnalyzerResult.analyzerMeta.targetProject;
    const exportsProjectName = exportsProjectObj.name;

    // Look for all specifiers that are exported, like [import {specifier} 'lion-based-ui/foo.js']
    for (const exportEntryResult of exportEntry.result) {
      if (!exportEntryResult.exportSpecifiers) {
        continue;
      }

      for (const exportSpecifier of exportEntryResult.exportSpecifiers) {
        // Get all unique imports (name::source::project combinations) that match current
        // exportSpecifier
        const filteredImportsList = new Set();
        const exportId = `${exportSpecifier}::${exportEntry.file}::${exportsProjectName}`;

        // eslint-disable-next-line no-shadow
        const importProject = targetClassesAnalyzerResult.analyzerMeta.targetProject.name;

        // TODO: What if this info is retrieved from cached importProject/target project?
        const importProjectPath = cfg.targetProjectPath;
        for (const { result, file } of targetClassesAnalyzerResult.queryOutput) {
          const importerFilePath = /** @type {PathFromSystemRoot} */ (
            path.resolve(importProjectPath, file)
          );
          for (const classEntryResult of result) {
            /**
             * @example
             * Example context (read by 'find-classes'/'find-exports' analyzers)
             * - export (/folder/exporting-file.js):
             * `export class X {}`
             * - import (target-project-a/importing-file.js):
             * `import { X } from '@reference-repo/folder/exporting-file.js'
             *
             *  class Z extends Mixin(X) {}
             * `
             * Example variables (extracted by 'find-classes'/'find-exports' analyzers)
             * - exportSpecifier: 'X'
             * - superClasses: [{ name: 'X', ...}, { name: 'Mixin', ...}]
             */
            const classMatch =
              // [{ name: 'X', ...}, ...].find(klass => klass.name === 'X')
              classEntryResult.superClasses &&
              classEntryResult.superClasses.find(
                klass => klass.rootFile.specifier === exportSpecifier,
              );

            if (!classMatch) {
              continue;
            }

            /**
             * @example
             * - project "reference-project"
             * - exportFile './foo.js'
             * `export const z = 'bar'`
             * - project "target-project"
             * - importFile './file.js'
             * `import { z } from 'reference-project/foo.js'`
             */
            const isFromSameSource =
              exportEntry.file ===
              (await fromImportToExportPerspective({
                importee: classMatch.rootFile.file,
                importer: importerFilePath,
                importeeProjectPath: cfg.referenceProjectPath,
              }));

            if (classMatch && isFromSameSource) {
              const memberOverrides = getMemberOverrides(
                refClassesAResult,
                classMatch,
                exportEntry,
                exportEntryResult,
                exportSpecifier,
              );

              let projectFileId = `${importProject}::${file}::${classEntryResult.name}`;
              if (cfg.addSystemPathsInResult) {
                projectFileId += `::${importerFilePath}`;
              }

              filteredImportsList.add({
                projectFileId,
                memberOverrides,
              });
            }
          }
        }
        storeResult(resultsObj, exportId, filteredImportsList, exportEntry.meta);
      }
    }
  }

  /**
   * Step 2: a rich data structure
   * Transform resultObj from step 1 into an array of objects
   * @example
   * [{
   *   exportSpecifier: {
   *     // name under which it is registered in npm ("name" attr in package.json)
   *     name: 'RefClass',
   *     project: 'exporting-ref-project',
   *     filePath: './ref-src/core.js',
   *     id: 'RefClass::ref-src/core.js::exporting-ref-project',
   *     meta: {...},
   *
   *     // most likely via post processor
   *   },
   *   // All the matched targets (files importing the specifier), ordered per project
   *   matchesPerProject: [
   *     {
   *       project: 'importing-target-project',
   *       files: [
   *         { file:'./target-src/indirect-imports.js', className: 'X'},
   *         ...
   *       ],
   *     },
   *     ...
   *   ],
   * }]
   */
  const resultsArray = Object.entries(resultsObj)
    .map(([id, flatResult]) => {
      const [exportSpecifierName, filePath, project] = id.split('::');
      const { meta } = flatResult;

      const exportSpecifier = {
        name: exportSpecifierName,
        project,
        filePath,
        id,
        ...(meta || {}),
      };

      // Although we only handle 1 target project, this structure (matchesPerProject, assuming we
      // deal with multiple target projects)
      // allows for easy aggregation of data in dashboard.
      const matchesPerProject = [];
      flatResult.files.forEach(({ projectFileId, memberOverrides }) => {
        // eslint-disable-next-line no-shadow
        const [project, file, identifier, filePath] = projectFileId.split('::');
        let projectEntry = matchesPerProject.find(m => m.project === project);
        if (!projectEntry) {
          matchesPerProject.push({ project, files: [] });
          projectEntry = matchesPerProject[matchesPerProject.length - 1];
        }
        const entry = { file, identifier, memberOverrides };
        if (filePath) {
          // @ts-ignore
          entry.filePath = filePath;
        }
        projectEntry.files.push(entry);
      });

      return {
        exportSpecifier,
        matchesPerProject,
      };
    })
    .filter(r => Object.keys(r.matchesPerProject).length);

  return /** @type {AnalyzerQueryResult} */ resultsArray;
}
@param {FindExportsAnalyzerResult} refExportsAnalyzerResult
@param {FindClassesAnalyzerResult} targetClassesAnalyzerResult
@param {FindClassesAnalyzerResult} refClassesAResult
@param {MatchSubclassesConfig} customConfig
@returns {Promise<AnalyzerQueryResult>}